diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cce16aa..2f45b60a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: cache: true - name: Verify pinned engine, typed Parquet and SQL boundary run: >- - bash scripts/with-duckdb.sh go test ./internal/query ./internal/telemetry ./internal/observability ./internal/ingest + bash scripts/with-duckdb.sh go test ./internal/engine ./internal/telemetry ./internal/observability ./internal/ingest -run 'TestPinnedEngine|TestSQLBoundary|TestLogicalType|TestVariant|TestUnsupportedFormat|TestCommitBatchAllocation|TestDependencies|TestExportsBound|TestMaximumAttributeNesting|TestHTTPRejectsExcessiveAttributeNesting' -count=1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5341b303..f627e1f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -104,7 +104,7 @@ jobs: run: | set -euo pipefail version="${GITHUB_REF_NAME}" - bash scripts/with-duckdb.sh go test ./internal/query -run 'TestPinnedEngine|TestSQLBoundary' -count=1 + bash scripts/with-duckdb.sh go test ./internal/engine -run 'TestPinnedEngine|TestSQLBoundary' -count=1 mkdir -p stage bash scripts/with-duckdb.sh go build -trimpath -ldflags "-s -w -X main.version=${version}" -o stage/fanout ./cmd/fanout for doc in LICENSE NOTICE README.md THIRD_PARTY_NOTICES TRADEMARK.md; do diff --git a/cmd/fanout-docgen/mcptools.go b/cmd/fanout-docgen/mcptools.go index 39b696ed..ebade5ea 100644 --- a/cmd/fanout-docgen/mcptools.go +++ b/cmd/fanout-docgen/mcptools.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/labstack/fanout/internal/mcp" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) // toolCount is set by renderMCPTools so the summary line can report it. @@ -156,7 +156,7 @@ func renderMCPTools() ([]byte, error) { } b.WriteString("## Panel SQL relations\n\n") - relations := panel.SQLRelations() + relations := query.SQLRelations() names := make([]string, 0, len(relations)) for name := range relations { names = append(names, name) diff --git a/cmd/fanout/main.go b/cmd/fanout/main.go index 32c9b5a0..249a3402 100644 --- a/cmd/fanout/main.go +++ b/cmd/fanout/main.go @@ -37,12 +37,12 @@ import ( "github.com/labstack/fanout/internal/auth" "github.com/labstack/fanout/internal/config" "github.com/labstack/fanout/internal/dashboard" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/ingest" "github.com/labstack/fanout/internal/intelligence" "github.com/labstack/fanout/internal/mcp" appmetrics "github.com/labstack/fanout/internal/metrics" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/server" "github.com/labstack/fanout/internal/settings" @@ -134,7 +134,7 @@ func main() { defer repository.Close() // DuckDB is the query facade over open Parquet and its indexed trace sidecars. - q, err := query.NewDuck(ctx, cfg, repository) + q, err := engine.NewDuck(ctx, cfg, repository) if err != nil { slog.Error("duckdb init failed", "err", err) os.Exit(1) @@ -275,9 +275,9 @@ func main() { // Route both HTTP and MCP reads through Duck's retrying adapter. Passing the // raw *sql.DB here bypassed the Telemetry maintenance-race protection. queries := observability.New(q, q, cfg.RetentionDays) - panels := panel.NewExecutor(q, cfg.RetentionDays) + panels := query.NewExecutor(q, cfg.RetentionDays) panels.SetRollupReader(queries) - api.RegisterPanelRoutes(e, panels) + api.RegisterQueryRoutes(e, panels) api.RegisterFanQLRoutes(e, q, panels) api.RegisterAnnotationRoutes(e, annotations.New(q)) api.RegisterTraceRoutes(e, queries, cfg.RetentionDays) diff --git a/docs/diagrams/architecture.json b/docs/diagrams/architecture.json index fd061a64..cca9323d 100644 --- a/docs/diagrams/architecture.json +++ b/docs/diagrams/architecture.json @@ -279,17 +279,17 @@ ], "sources": [ { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 240, "end_line": 244 }, { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 505, "end_line": 522 }, { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 627, "end_line": 653 } diff --git a/docs/diagrams/persistence.json b/docs/diagrams/persistence.json index b812b1cb..252d2453 100644 --- a/docs/diagrams/persistence.json +++ b/docs/diagrams/persistence.json @@ -147,7 +147,7 @@ "row": 1, "sources": [ { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 240, "end_line": 244 } @@ -162,12 +162,12 @@ "row": 2, "sources": [ { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 627, "end_line": 653 }, { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 692, "end_line": 693 }, @@ -187,17 +187,17 @@ "row": 1, "sources": [ { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 505, "end_line": 522 }, { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 1437, "end_line": 1437 }, { - "path": "internal/query/duck.go", + "path": "internal/engine/duck.go", "line": 1622, "end_line": 1622 } diff --git a/docs/testing.md b/docs/testing.md index c32982c9..b58198a4 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -181,7 +181,7 @@ The native tests exercise whole-window totals, bounded newest buckets and width-aware 24-hour bucket selection: ```sh -just test ./internal/panel -run 'TestGaugeTotalsMatchStat|TestBudgetKeepsCompleteNewestBuckets|TestWidthAwareCellBuckets' +just test ./internal/query -run 'TestGaugeTotalsMatchStat|TestBudgetKeepsCompleteNewestBuckets|TestWidthAwareCellBuckets' ``` Use the pinned engine wrapper through `just test`, with the workspace's offline diff --git a/internal/agent/committed_panic_test.go b/internal/agent/committed_panic_test.go index a3d7f8d1..07e519c9 100644 --- a/internal/agent/committed_panic_test.go +++ b/internal/agent/committed_panic_test.go @@ -11,7 +11,7 @@ import ( agtypes "github.com/ag-ui-protocol/ag-ui/sdks/community/go/pkg/core/types" "github.com/labstack/fanout/internal/dashboard" fanoutmcp "github.com/labstack/fanout/internal/mcp" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" ) @@ -27,14 +27,14 @@ func TestRuntimePanicDistinguishesCommittedSave(t *testing.T) { if _, err := db.DB.Exec(`INSERT INTO users(id,email) VALUES ('owner','owner@example.test')`); err != nil { t.Fatal(err) } - service := dashboard.New(db.DB, panel.NewExecutor(nil, 30)) - server := fanoutmcp.NewWithIntelligence(registryQueries{}, service, panel.NewExecutor(nil, 30), nil, "test") + service := dashboard.New(db.DB, query.NewExecutor(nil, 30)) + server := fanoutmcp.NewWithIntelligence(registryQueries{}, service, query.NewExecutor(nil, 30), nil, "test") registry, err := NewToolRegistry(t.Context(), server.MCP()) if err != nil { t.Fatal(err) } defer registry.Close() - spec := panel.Dashboard{Name: "Committed", Panels: []panel.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "hello"}}} + spec := query.Dashboard{Name: "Committed", Panels: []query.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "hello"}}} input, err := json.Marshal(map[string]any{"dashboard": spec}) if err != nil { t.Fatal(err) diff --git a/internal/agent/dashboard_eval_golden_test.go b/internal/agent/dashboard_eval_golden_test.go index 0fdb27f9..a2f59273 100644 --- a/internal/agent/dashboard_eval_golden_test.go +++ b/internal/agent/dashboard_eval_golden_test.go @@ -14,8 +14,8 @@ import ( agtypes "github.com/ag-ui-protocol/ag-ui/sdks/community/go/pkg/core/types" "github.com/labstack/fanout/internal/config" "github.com/labstack/fanout/internal/dashboard" + "github.com/labstack/fanout/internal/engine" fanoutmcp "github.com/labstack/fanout/internal/mcp" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" "github.com/labstack/fanout/internal/telemetry" @@ -31,7 +31,7 @@ func TestDashboardEvalGoldensCurrent(t *testing.T) { t.Fatal(err) } defer repo.Close() - engine, err := query.NewDuck(t.Context(), cfg, repo) + engine, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -41,7 +41,7 @@ func TestDashboardEvalGoldensCurrent(t *testing.T) { if err = repo.Commit(t.Context(), telemetrystore.Batch{ID: "eval_fixture", Spans: []telemetry.Span{{Namespace: "shop", ServiceName: "checkout", TraceID: "trace", SpanID: "span", Name: "request", Kind: "SPAN_KIND_SERVER", StartUnixNanos: from.UnixNano(), EndUnixNanos: from.Add(time.Millisecond).UnixNano(), DurationMS: 1, StatusCode: "STATUS_CODE_OK", IngestedAt: from.UnixNano()}}}); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(engine, 30) + executor := query.NewExecutor(engine, 30) db, err := controlstore.NewSQLite(":memory:") if err != nil { t.Fatal(err) @@ -67,8 +67,8 @@ func TestDashboardEvalGoldensCurrent(t *testing.T) { t.Fatal("embedded AI tools lost the shared MCP inventory guidance") } ctx := dashboard.WithOwner(t.Context(), "owner") - authored := panel.Dashboard{Name: "Eval fixture", Time: panel.Time{From: &from, To: &to}, Panels: []panel.Panel{ - {ID: "actual_latency", Title: "Latency", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"p95(duration_ms)"}, Where: []string{"service = 'checkout'", "namespace = 'shop'"}}, Unit: "ms", Thresholds: []panel.Threshold{{Value: 100, Status: "warn"}}}, + authored := query.Dashboard{Name: "Eval fixture", Time: query.Time{From: &from, To: &to}, Panels: []query.Panel{ + {ID: "actual_latency", Title: "Latency", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, Where: []string{"service = 'checkout'", "namespace = 'shop'"}}, Unit: "ms", Thresholds: []query.Threshold{{Value: 100, Status: "warn"}}}, {ID: "actual_text", Title: "Explanation", Viz: "text", Content: "Seeded checkout request.", Description: "Fixture context."}, }} authoredJSON := evalObject(t, authored) @@ -91,13 +91,13 @@ func TestDashboardEvalGoldensCurrent(t *testing.T) { if created.ID == "" || created.Version != 1 { t.Fatalf("missing tool save: %+v", saved) } - added := panel.Panel{ID: "added_panel", Title: "Added fixture panel", Viz: "timeseries", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}} + added := query.Panel{ID: "added_panel", Title: "Added fixture panel", Viz: "timeseries", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}} addedJSON := evalObject(t, added) edited, err := service.Edit(t.Context(), "owner", created.ID, []dashboard.Operation{{Op: "add_panel", Panel: &added, After: "actual_latency"}}, created.Version, dashboard.Author{Kind: "agent", ID: "owner"}, "Add fixture") if err != nil { t.Fatal(err) } - statAdded := panel.Panel{ID: "added_stat", Title: "Added stat", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}} + statAdded := query.Panel{ID: "added_stat", Title: "Added stat", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}} statJSON := evalObject(t, statAdded) statEdited, err := service.Edit(t.Context(), "owner", created.ID, []dashboard.Operation{{Op: "add_panel", Panel: &statAdded}}, edited.Version, dashboard.Author{Kind: "agent", ID: "owner"}, "Add stat fixture") if err != nil { @@ -123,11 +123,11 @@ func TestDashboardEvalGoldensCurrent(t *testing.T) { t.Fatal(err) } evalStableSave(editedOutput) - results, err := executor.Run(t.Context(), panel.RunRequest{Dashboard: created.Spec}) + results, err := executor.Run(t.Context(), query.RunRequest{Dashboard: created.Spec}) if err != nil { t.Fatal(err) } - addedResults, err := executor.Run(t.Context(), panel.RunRequest{Dashboard: edited.Spec}) + addedResults, err := executor.Run(t.Context(), query.RunRequest{Dashboard: edited.Spec}) if err != nil { t.Fatal(err) } diff --git a/internal/agent/fragment_content_test.go b/internal/agent/fragment_content_test.go index 21e26da8..8827557a 100644 --- a/internal/agent/fragment_content_test.go +++ b/internal/agent/fragment_content_test.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" fanoutmcp "github.com/labstack/fanout/internal/mcp" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "reflect" "strings" @@ -66,7 +66,7 @@ func TestFragmentActivityPersistsExactContent(t *testing.T) { if err != nil { t.Fatal(err) } - server := fanoutmcp.NewWithIntelligence(registryQueries{}, nil, panel.NewExecutor(nil, 30), nil, "test") + server := fanoutmcp.NewWithIntelligence(registryQueries{}, nil, query.NewExecutor(nil, 30), nil, "test") tools, err := NewToolRegistry(t.Context(), server.MCP()) if err != nil { t.Fatal(err) diff --git a/internal/agent/runtime_test.go b/internal/agent/runtime_test.go index 6da5ae3a..7eb3409e 100644 --- a/internal/agent/runtime_test.go +++ b/internal/agent/runtime_test.go @@ -16,7 +16,7 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/auth" fanoutmcp "github.com/labstack/fanout/internal/mcp" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/dashboard" controlstore "github.com/labstack/fanout/internal/store" @@ -346,9 +346,9 @@ func TestBuildOriginSkipsMissingMessageIdentity(t *testing.T) { type originValidator struct{} -func (originValidator) Validate(_ context.Context, d *panel.Dashboard) error { - panel.Normalize(d) - if problems := panel.Validate(d); len(problems) > 0 { +func (originValidator) Validate(_ context.Context, d *query.Dashboard) error { + query.Normalize(d) + if problems := query.Validate(d); len(problems) > 0 { return problems } return nil diff --git a/internal/agent/service_input_test.go b/internal/agent/service_input_test.go index 9cea3c4d..c1165ced 100644 --- a/internal/agent/service_input_test.go +++ b/internal/agent/service_input_test.go @@ -10,9 +10,9 @@ import ( "github.com/labstack/fanout/internal/config" "github.com/labstack/fanout/internal/dashboard" + "github.com/labstack/fanout/internal/engine" fanoutmcp "github.com/labstack/fanout/internal/mcp" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" "github.com/labstack/fanout/internal/telemetry" @@ -27,7 +27,7 @@ func TestToolRegistryUnknownServiceBoundsOversizedAliases(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -46,7 +46,7 @@ func TestToolRegistryUnknownServiceBoundsOversizedAliases(t *testing.T) { if err := repo.Commit(t.Context(), batch); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(duck, 7) + executor := query.NewExecutor(duck, 7) server := fanoutmcp.NewWithIntelligence(observability.New(duck, duck, 7), nil, executor, nil, "test") registry, err := NewToolRegistry(t.Context(), server.MCP()) if err != nil { @@ -81,7 +81,7 @@ func TestToolRegistryNoDataAndDashboardPanelErrors(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -99,14 +99,14 @@ func TestToolRegistryNoDataAndDashboardPanelErrors(t *testing.T) { if _, err := db.DB.Exec(`INSERT INTO users(id,email) VALUES ('owner','owner@example.test')`); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(duck, 7) + executor := query.NewExecutor(duck, 7) server := fanoutmcp.NewWithIntelligence(observability.New(duck, duck, 7), dashboard.New(db.DB, executor), executor, nil, "test") registry, err := NewToolRegistry(t.Context(), server.MCP()) if err != nil { t.Fatal(err) } defer registry.Close() - spec := panel.Dashboard{Name: "Empty", Time: panel.Time{From: &from, To: &to}, Panels: []panel.Panel{{ID: "p", Title: "Collector requests", Viz: "stat", Query: &panel.Query{From: "spans", Where: []string{"service = 'collector'"}, Measures: []string{"count()"}}}}} + spec := query.Dashboard{Name: "Empty", Time: query.Time{From: &from, To: &to}, Panels: []query.Panel{{ID: "p", Title: "Collector requests", Viz: "stat", Query: &query.Spec{From: "spans", Where: []string{"service = 'collector'"}, Measures: []string{"count()"}}}}} for _, tc := range []struct { name, code, want string args any diff --git a/internal/agent/tools_integration_test.go b/internal/agent/tools_integration_test.go index 677e0dcc..d2b96b00 100644 --- a/internal/agent/tools_integration_test.go +++ b/internal/agent/tools_integration_test.go @@ -11,7 +11,7 @@ import ( "github.com/labstack/fanout/internal/intelligence" fanoutmcp "github.com/labstack/fanout/internal/mcp" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" ) @@ -113,9 +113,9 @@ func TestRuntimeDashboardHistoryUsesAuthenticatedOwner(t *testing.T) { if _, err := db.DB.Exec(`INSERT INTO users(id,email) VALUES ('owner','owner@example.test'),('other','other@example.test')`); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(nil, 30) + executor := query.NewExecutor(nil, 30) service := dashboard.New(db.DB, executor) - created, err := service.Create(t.Context(), "owner", panel.Dashboard{Name: "History", Panels: []panel.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "first"}}}, dashboard.Author{Kind: "user", ID: "owner"}) + created, err := service.Create(t.Context(), "owner", query.Dashboard{Name: "History", Panels: []query.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "first"}}}, dashboard.Author{Kind: "user", ID: "owner"}) if err != nil { t.Fatal(err) } diff --git a/internal/alert/engine.go b/internal/alert/engine.go index 46717003..cab86261 100644 --- a/internal/alert/engine.go +++ b/internal/alert/engine.go @@ -12,8 +12,8 @@ import ( "sync" "time" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/intelligence" - "github.com/labstack/fanout/internal/query" ) const pruneHistDays = 7 @@ -21,7 +21,7 @@ const pruneHistDays = 7 // Engine drives the alert evaluation loop. type Engine struct { store *Store - duck *query.Duck // may be nil in tests + duck *engine.Duck // may be nil in tests detector *intelligence.Detector // may be nil in tests mu sync.RWMutex programs map[string]Program // rule ID → compiled program @@ -34,7 +34,7 @@ type Engine struct { // NewEngine creates an Engine ready to Run. func NewEngine( store *Store, - duck *query.Duck, + duck *engine.Duck, detector *intelligence.Detector, interval time.Duration, histDays int, @@ -190,12 +190,12 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { case noAlert && triggered && rule.ForSeconds == 0: // Immediately firing. a := Alert{ - RuleID: rule.ID, - Service: svc, - State: "firing", - Value: primaryValue(rule, env), - FiredAt: nowStr, - LastEval: nowStr, + RuleID: rule.ID, + Service: svc, + State: "firing", + Value: primaryValue(rule, env), + FiredAt: nowStr, + LastEvaluatedAt: nowStr, } saved, upsertErr := e.store.UpsertAlert(a) if upsertErr != nil { @@ -207,11 +207,11 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { case noAlert && triggered && rule.ForSeconds > 0: // Enter pending state; wait for the for-duration to elapse. a := Alert{ - RuleID: rule.ID, - Service: svc, - State: "pending", - Value: primaryValue(rule, env), - LastEval: nowStr, + RuleID: rule.ID, + Service: svc, + State: "pending", + Value: primaryValue(rule, env), + LastEvaluatedAt: nowStr, } if _, upsertErr := e.store.UpsertAlert(a); upsertErr != nil { slog.Error("alert: upsert pending", "rule", rule.ID, "service", svc, "err", upsertErr) @@ -232,7 +232,7 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { // Promote to firing. existing.State = "firing" existing.FiredAt = nowStr - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr saved, upsertErr := e.store.UpsertAlert(existing) if upsertErr != nil { slog.Error("alert: promote to firing", "rule", rule.ID, "service", svc, "err", upsertErr) @@ -241,9 +241,9 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { e.fireWebhookAsync(rule, saved, env, "firing") } else { // Still waiting. - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr if _, upsertErr := e.store.UpsertAlert(existing); upsertErr != nil { - slog.Error("alert: update pending last_eval", "rule", rule.ID, "service", svc, "err", upsertErr) + slog.Error("alert: update pending last_evaluated_at", "rule", rule.ID, "service", svc, "err", upsertErr) } } @@ -255,7 +255,7 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { case !noAlert && existing.State == "firing" && triggered: // Already firing; send repeat notification if repeat_interval has elapsed. - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr existing.Value = primaryValue(rule, env) if rule.RepeatIntervalS > 0 { ref := existing.RepeatedAt @@ -279,14 +279,14 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { } } if _, upsertErr := e.store.UpsertAlert(existing); upsertErr != nil { - slog.Error("alert: update firing last_eval", "rule", rule.ID, "service", svc, "err", upsertErr) + slog.Error("alert: update firing last_evaluated_at", "rule", rule.ID, "service", svc, "err", upsertErr) } case !noAlert && existing.State == "firing" && !triggered: // Condition cleared — resolve. existing.State = "resolved" existing.ResolvedAt = nowStr - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr saved, upsertErr := e.store.UpsertAlert(existing) if upsertErr != nil { slog.Error("alert: resolve alert", "rule", rule.ID, "service", svc, "err", upsertErr) @@ -301,10 +301,10 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { if rule.CooldownS > 0 && existing.ResolvedAt != "" { resolvedAt, parseErr := time.Parse(time.RFC3339, existing.ResolvedAt) if parseErr == nil && now.Sub(resolvedAt) < time.Duration(rule.CooldownS)*time.Second { - // Still in cooldown — update last_eval but don't re-fire. - existing.LastEval = nowStr + // Still in cooldown — update last_evaluated_at but don't re-fire. + existing.LastEvaluatedAt = nowStr if _, upsertErr := e.store.UpsertAlert(existing); upsertErr != nil { - slog.Error("alert: update cooldown last_eval", "rule", rule.ID, "service", svc, "err", upsertErr) + slog.Error("alert: update cooldown last_evaluated_at", "rule", rule.ID, "service", svc, "err", upsertErr) } return } @@ -314,7 +314,7 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { existing.State = "firing" existing.FiredAt = nowStr existing.ResolvedAt = "" - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr existing.Value = primaryValue(rule, env) saved, upsertErr := e.store.UpsertAlert(existing) if upsertErr != nil { @@ -327,7 +327,7 @@ func (e *Engine) transition(rule Rule, svc string, triggered bool, env Env) { existing.State = "pending" existing.FiredAt = "" existing.ResolvedAt = "" - existing.LastEval = nowStr + existing.LastEvaluatedAt = nowStr existing.Value = primaryValue(rule, env) if _, upsertErr := e.store.UpsertAlert(existing); upsertErr != nil { slog.Error("alert: re-pend from resolved", "rule", rule.ID, "service", svc, "err", upsertErr) @@ -419,7 +419,7 @@ SELECT c.service, c.error_rate, c.p50, c.p95, c.throughput, c.log_count, ((c.throughput - p.throughput) / NULLIF(p.throughput, 0)) * 100 as throughput_delta FROM current c LEFT JOIN previous p ON c.service = p.service` - resp := e.duck.ExecuteSQL(ctx, query.SQLRequest{Query: envSQL}) + resp := e.duck.ExecuteSQL(ctx, engine.SQLRequest{Query: envSQL}) if resp.Error != "" { slog.Error("alert: buildEnvs query failed", "err", resp.Error) return nil diff --git a/internal/alert/engine_env_test.go b/internal/alert/engine_env_test.go index e6cae527..80c17564 100644 --- a/internal/alert/engine_env_test.go +++ b/internal/alert/engine_env_test.go @@ -8,7 +8,7 @@ import ( _ "github.com/duckdb/duckdb-go/v2" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) // buildEnvs feeds CEL rules from a SQL aggregate over service_rollup. DuckDB @@ -39,7 +39,7 @@ INSERT INTO service_rollup VALUES t.Fatalf("seed service_rollup: %v", err) } - eng := NewEngine(nil, &query.Duck{DB: db}, nil, time.Minute, 7) + eng := NewEngine(nil, &engine.Duck{DB: db}, nil, time.Minute, 7) envs := eng.buildEnvs(context.Background()) env, ok := envs["svc-a"] if !ok { diff --git a/internal/alert/store.go b/internal/alert/store.go index 1768400d..332eb575 100644 --- a/internal/alert/store.go +++ b/internal/alert/store.go @@ -105,7 +105,7 @@ func genAlertToAlert(ga generated.Alert) Alert { FiredAt: ga.FiredAt.String, ResolvedAt: ga.ResolvedAt.String, RepeatedAt: ga.RepeatedAt.String, - LastEval: ga.LastEval.String, + LastEvaluatedAt: ga.LastEvaluatedAt.String, LastDeliveryStatus: ga.LastDeliveryStatus.String, LastDeliveryAt: ga.LastDeliveryAt.String, CreatedAt: ga.CreatedAt, @@ -126,7 +126,7 @@ func alertToUpsertParams(a Alert) generated.UpsertAlertParams { FiredAt: nullString(a.FiredAt), ResolvedAt: nullString(a.ResolvedAt), RepeatedAt: nullString(a.RepeatedAt), - LastEval: nullString(a.LastEval), + LastEvaluatedAt: nullString(a.LastEvaluatedAt), LastDeliveryStatus: nullString(a.LastDeliveryStatus), LastDeliveryAt: nullString(a.LastDeliveryAt), } diff --git a/internal/alert/types.go b/internal/alert/types.go index a7fb7f40..02e3ddf7 100644 --- a/internal/alert/types.go +++ b/internal/alert/types.go @@ -32,7 +32,7 @@ type Alert struct { FiredAt string `json:"fired_at,omitempty"` ResolvedAt string `json:"resolved_at,omitempty"` RepeatedAt string `json:"repeated_at,omitempty"` - LastEval string `json:"last_eval,omitempty"` + LastEvaluatedAt string `json:"last_evaluated_at,omitempty"` LastDeliveryStatus string `json:"last_delivery_status,omitempty"` LastDeliveryAt string `json:"last_delivery_at,omitempty"` CreatedAt string `json:"created_at"` diff --git a/internal/api/annotations.go b/internal/api/annotations.go index 6921c7de..606b25ac 100644 --- a/internal/api/annotations.go +++ b/internal/api/annotations.go @@ -7,7 +7,7 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/annotations" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) type AnnotationReader interface { @@ -34,7 +34,7 @@ func annotationError(err error) error { return echo.NewHTTPError(http.StatusBadRequest, err.Error()).Wrap(err) case errors.Is(err, context.DeadlineExceeded): return echo.NewHTTPError(http.StatusGatewayTimeout, "Annotations took longer than 10 seconds").Wrap(err) - case errors.Is(err, query.ErrParquetReadWait): + case errors.Is(err, engine.ErrParquetReadWait): return echo.NewHTTPError(http.StatusServiceUnavailable, "annotations unavailable").Wrap(err) case errors.Is(err, context.Canceled): return nil diff --git a/internal/api/annotations_test.go b/internal/api/annotations_test.go index 4806c1a5..e06f4d8a 100644 --- a/internal/api/annotations_test.go +++ b/internal/api/annotations_test.go @@ -12,7 +12,7 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/annotations" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) type annotationFake struct{} @@ -23,7 +23,7 @@ func (annotationFake) Read(context.Context, annotations.Request) (annotations.Re func TestAnnotationErrorsWrapped(t *testing.T) { original := errors.New("storage failed") - for _, cause := range []error{annotations.ErrRequest, context.DeadlineExceeded, query.ErrParquetReadWait, original} { + for _, cause := range []error{annotations.ErrRequest, context.DeadlineExceeded, engine.ErrParquetReadWait, original} { wrapped := fmt.Errorf("annotation query: %w", cause) got := annotationError(wrapped) var httpErr *echo.HTTPError @@ -50,7 +50,7 @@ func TestAnnotationErrorMappings(t *testing.T) { }{ {"request", annotations.ErrRequest, 400, annotations.ErrRequest.Error()}, {"deadline", context.DeadlineExceeded, 504, "Annotations took longer than 10 seconds"}, - {"parquet", query.ErrParquetReadWait, 503, "annotations unavailable"}, + {"parquet", engine.ErrParquetReadWait, 503, "annotations unavailable"}, {"canceled", context.Canceled, 200, ""}, {"unknown", errors.New("storage failed"), 500, "annotations unavailable"}, } { diff --git a/internal/api/auth_middleware.go b/internal/api/auth_middleware.go index f58e917f..d931d9a1 100644 --- a/internal/api/auth_middleware.go +++ b/internal/api/auth_middleware.go @@ -308,7 +308,7 @@ func classifyRoute(method, path string) (routePolicy, bool) { } case strings.HasPrefix(path, "/api/alerting/rules/"): return routePolicy{kind: routePolicyCapability, capability: ManageAlerts}, unsafe - case path == "/api/panels/query" || path == "/api/panels/exemplars" || path == "/api/panels/variables/resolve" || path == "/api/annotations": + case path == "/api/queries/run" || path == "/api/queries/exemplars" || path == "/api/queries/variables/resolve" || path == "/api/annotations": return routePolicy{kind: routePolicyCapability, capability: ReadTelemetry}, method == http.MethodPost case path == "/api/fanql/parse" || path == "/api/fanql/format" || path == "/api/fanql/complete": return routePolicy{kind: routePolicyCapability, capability: ReadTelemetry}, method == http.MethodPost diff --git a/internal/api/auth_test.go b/internal/api/auth_test.go index 6cecd594..2271cb93 100644 --- a/internal/api/auth_test.go +++ b/internal/api/auth_test.go @@ -181,7 +181,7 @@ func TestRoutePolicyClassification(t *testing.T) { {http.MethodGet, "/api/dashboards/dashboard-1/versions/1", routePolicyCapability, ManageOwnDashboards}, {http.MethodPost, "/api/dashboards/dashboard-1/versions/1/restore", routePolicyCapability, ManageOwnDashboards}, {http.MethodPost, "/api/agent/runs", routePolicyCapability, RunAgent}, - {http.MethodPost, "/api/panels/variables/resolve", routePolicyCapability, ReadTelemetry}, + {http.MethodPost, "/api/queries/variables/resolve", routePolicyCapability, ReadTelemetry}, {http.MethodPost, "/api/fanql/parse", routePolicyCapability, ReadTelemetry}, {http.MethodPost, "/api/fanql/format", routePolicyCapability, ReadTelemetry}, {http.MethodPost, "/api/fanql/complete", routePolicyCapability, ReadTelemetry}, diff --git a/internal/api/dashboard.go b/internal/api/dashboard.go index c4e8d8ca..63ef4364 100644 --- a/internal/api/dashboard.go +++ b/internal/api/dashboard.go @@ -8,7 +8,7 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type DashboardHandler struct{ dashboards *dashboard.Service } @@ -30,11 +30,11 @@ func RegisterDashboardRoutes(e *echo.Echo, dashboards *dashboard.Service) { const dashboardBodyLimit = 512 << 10 type createDashboardBody struct { - Spec panel.Dashboard `json:"spec"` + Spec query.Dashboard `json:"spec"` } type replaceDashboardBody struct { - Spec panel.Dashboard `json:"spec"` + Spec query.Dashboard `json:"spec"` BaseVersion int `json:"base_version,omitempty"` Message string `json:"message,omitempty"` } diff --git a/internal/api/dashboard_history_test.go b/internal/api/dashboard_history_test.go index 3e83b13a..1f4bbe5e 100644 --- a/internal/api/dashboard_history_test.go +++ b/internal/api/dashboard_history_test.go @@ -10,7 +10,7 @@ import ( "github.com/labstack/fanout/internal/auth" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestHistoricalDashboardHTTPReadRequiresOwnerAndReturnsSaveChanges(t *testing.T) { @@ -28,7 +28,7 @@ func TestHistoricalDashboardHTTPReadRequiresOwnerAndReturnsSaveChanges(t *testin t.Fatal(err) } service := dashboard.New(s.db.DB, structuralValidator{}) - first, err := service.Create(t.Context(), owner.ID, panel.Dashboard{Name: "History", Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}}, dashboard.Author{Kind: "agent", ID: owner.ID}) + first, err := service.Create(t.Context(), owner.ID, query.Dashboard{Name: "History", Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}}, dashboard.Author{Kind: "agent", ID: owner.ID}) if err != nil { t.Fatal(err) } diff --git a/internal/api/dashboard_test.go b/internal/api/dashboard_test.go index 6f18b201..20d5463d 100644 --- a/internal/api/dashboard_test.go +++ b/internal/api/dashboard_test.go @@ -10,14 +10,14 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type structuralValidator struct{} -func (structuralValidator) Validate(_ context.Context, d *panel.Dashboard) error { - panel.Normalize(d) - if problems := panel.Validate(d); len(problems) > 0 { +func (structuralValidator) Validate(_ context.Context, d *query.Dashboard) error { + query.Normalize(d) + if problems := query.Validate(d); len(problems) > 0 { return problems } return nil @@ -104,7 +104,7 @@ func TestDashboardLifecycleOverHTTP(t *testing.T) { type failingValidator struct{ err error } -func (v failingValidator) Validate(context.Context, *panel.Dashboard) error { return v.err } +func (v failingValidator) Validate(context.Context, *query.Dashboard) error { return v.err } func TestDashboardValidationTimeoutIs504(t *testing.T) { s := newTestAuthServer(t) @@ -139,7 +139,7 @@ func TestDashboardBrowserSummaryKeepsOwnerScopedBuildProvenance(t *testing.T) { } service := dashboard.New(s.db.DB, structuralValidator{}) origin := dashboard.BuildOrigin{ThreadID: "source", MessageID: "request", RequestExcerpt: "Private request"} - _, err = service.Create(dashboard.WithBuildOrigin(t.Context(), origin), owner.ID, panel.Dashboard{Name: "Origin", Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hi"}}}, dashboard.Author{Kind: "agent", ID: owner.ID}) + _, err = service.Create(dashboard.WithBuildOrigin(t.Context(), origin), owner.ID, query.Dashboard{Name: "Origin", Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hi"}}}, dashboard.Author{Kind: "agent", ID: owner.ID}) if err != nil { t.Fatal(err) } diff --git a/internal/api/errors.go b/internal/api/errors.go index 63c3de65..1398be9f 100644 --- a/internal/api/errors.go +++ b/internal/api/errors.go @@ -6,14 +6,14 @@ import ( "net/http" "github.com/labstack/echo/v5" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type apiError struct { status int Code string `json:"code"` Message string `json:"message"` - Problems panel.Problems `json:"problems,omitempty"` + Problems query.Problems `json:"problems,omitempty"` } func (e *apiError) Error() string { return e.Message } diff --git a/internal/api/errors_test.go b/internal/api/errors_test.go index 0b99e3af..cd4b5fa5 100644 --- a/internal/api/errors_test.go +++ b/internal/api/errors_test.go @@ -12,7 +12,7 @@ import ( "testing" "github.com/labstack/echo/v5" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestHTTPFailuresCarryStatusCodesAndSafeMessages(t *testing.T) { @@ -65,7 +65,7 @@ func TestSpecificFailuresPreserveCodesAndSpecProblems(t *testing.T) { e.HTTPErrorHandler = HTTPErrorHandler e.GET("/api/specific", func(*echo.Context) error { return newAPIError(409, "already_current", "Already current.") }) e.GET("/api/spec", func(c *echo.Context) error { - _, err := writeProblems(c, panel.Problems{{Path: "panels[0].viz", Message: "Unsupported."}}) + _, err := writeProblems(c, query.Problems{{Path: "panels[0].viz", Message: "Unsupported."}}) return err }) for _, path := range []string{"/api/specific", "/api/spec"} { diff --git a/internal/api/fanql.go b/internal/api/fanql.go index 0406f10a..8ccf160a 100644 --- a/internal/api/fanql.go +++ b/internal/api/fanql.go @@ -7,16 +7,16 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/fanql" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type FanQLHandler struct { - parser panel.Parser - engine PanelEngine + parser query.Parser + engine QueryEngine completer *fanql.Completer } -func RegisterFanQLRoutes(e *echo.Echo, parser panel.Parser, engine PanelEngine) { +func RegisterFanQLRoutes(e *echo.Echo, parser query.Parser, engine QueryEngine) { h := &FanQLHandler{parser: parser, engine: engine, completer: fanql.NewCompleter(engine)} read := RequireCapability(ReadTelemetry) e.POST("/api/fanql/parse", h.parse, read) @@ -56,18 +56,18 @@ func (h *FanQLHandler) parse(c *echo.Context) error { compiled, problems := fanql.Compile(req.Text, req.Options) if len(problems) != 0 { failure := &fanqlFailure{apiError: newAPIError(http.StatusBadRequest, "invalid_fanql", "The query has problems.")} - failure.Problems = panel.PresentProblems(problems) + failure.Problems = query.PresentProblems(problems) if req.Preview { failure.Preview = &fanqlPreview{Text: req.Text, Note: "not executable"} } return failure } return c.JSON(http.StatusOK, struct { - Query panel.Query `json:"query"` - Canonical string `json:"canonical"` + Query query.Spec `json:"query"` + Canonical string `json:"canonical"` Viz struct { Requested string `json:"requested,omitempty"` - Compatible []panel.VizCompat `json:"compatible"` + Compatible []query.VizCompat `json:"compatible"` Edits []fanql.VizEdit `json:"edits"` } `json:"viz"` Notices []fanql.Notice `json:"notices"` @@ -75,7 +75,7 @@ func (h *FanQLHandler) parse(c *echo.Context) error { Query: compiled.Query, Canonical: compiled.Canonical, Viz: struct { Requested string `json:"requested,omitempty"` - Compatible []panel.VizCompat `json:"compatible"` + Compatible []query.VizCompat `json:"compatible"` Edits []fanql.VizEdit `json:"edits"` }{Requested: req.Viz, Compatible: compiled.Compatible, Edits: compiled.Edits}, Notices: fanqlNotices(compiled.Notices), @@ -85,7 +85,7 @@ func (h *FanQLHandler) parse(c *echo.Context) error { func (h *FanQLHandler) format(c *echo.Context) error { var req struct { fanql.Options - Query panel.Query `json:"query"` + Query query.Spec `json:"query"` } if err := decodeStrict(c, &req, 512<<10); err != nil { return err @@ -98,7 +98,7 @@ func (h *FanQLHandler) format(c *echo.Context) error { } if len(problems) != 0 { failure := newAPIError(http.StatusBadRequest, "invalid_spec", "The query spec is invalid.") - failure.Problems = panel.PresentProblems(problems) + failure.Problems = query.PresentProblems(problems) return failure } formatted.Notices = fanqlNotices(formatted.Notices) @@ -106,7 +106,7 @@ func (h *FanQLHandler) format(c *echo.Context) error { } func fanqlError(err error) error { - return newAPIError(http.StatusServiceUnavailable, "unavailable", panel.PresentError(err, panel.ReadError)) + return newAPIError(http.StatusServiceUnavailable, "unavailable", query.PresentError(err, query.ReadError)) } func (h *FanQLHandler) complete(c *echo.Context) error { diff --git a/internal/api/fanql_corpus_test.go b/internal/api/fanql_corpus_test.go index 56cd97e0..57786662 100644 --- a/internal/api/fanql_corpus_test.go +++ b/internal/api/fanql_corpus_test.go @@ -13,7 +13,7 @@ import ( "github.com/labstack/fanout/internal/auth" "github.com/labstack/fanout/internal/fanql" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type nonExecutingFanQLPanels struct { @@ -21,7 +21,7 @@ type nonExecutingFanQLPanels struct { calls int } -func (p *nonExecutingFanQLPanels) Run(context.Context, panel.RunRequest) ([]panel.Result, error) { +func (p *nonExecutingFanQLPanels) Run(context.Context, query.RunRequest) ([]query.Result, error) { p.calls++ return nil, fmt.Errorf("FanQL parsing must not execute telemetry") } @@ -51,8 +51,8 @@ func TestNonExecution(t *testing.T) { var tc struct { Text string `json:"text"` Viz string `json:"viz"` - Query *panel.Query `json:"query"` - Problems panel.Problems `json:"problems"` + Query *query.Spec `json:"query"` + Problems query.Problems `json:"problems"` GateProblems bool `json:"gate_problems"` } if err := decoder.Decode(&tc); err == io.EOF { diff --git a/internal/api/fanql_test.go b/internal/api/fanql_test.go index 211ffde4..afdbb187 100644 --- a/internal/api/fanql_test.go +++ b/internal/api/fanql_test.go @@ -12,11 +12,11 @@ import ( "github.com/labstack/fanout/internal/auth" "github.com/labstack/fanout/internal/fanql" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type fakeFanQLParser struct { - panel.Parser + query.Parser err error } @@ -43,13 +43,13 @@ func (*fakeFanQLParser) RenderSQL(context.Context, map[string]any) (string, erro type fakeFanQLPanels struct{ fakePanels } -func (*fakeFanQLPanels) Schema(_ context.Context, req panel.SchemaRequest) (*panel.Schema, error) { - return &panel.Schema{Window: req.Window, Signals: map[string]panel.SignalSchema{ - "logs": {Columns: []panel.ColumnSchema{{Field: panel.Field{Name: "severity", Type: panel.TypeString}, Values: []panel.Option{{Value: "ERROR"}, {Value: "INFO"}, {Value: "WARN"}}}}}, +func (*fakeFanQLPanels) Schema(_ context.Context, req query.SchemaRequest) (*query.Schema, error) { + return &query.Schema{Window: req.Window, Signals: map[string]query.SignalSchema{ + "logs": {Columns: []query.ColumnSchema{{Field: query.Field{Name: "severity", Type: query.TypeString}, Values: []query.Option{{Value: "ERROR"}, {Value: "INFO"}, {Value: "WARN"}}}}}, }}, nil } -func serveFanQL(t *testing.T, parser panel.Parser, engine PanelEngine, method, path, body string) *httptest.ResponseRecorder { +func serveFanQL(t *testing.T, parser query.Parser, engine QueryEngine, method, path, body string) *httptest.ResponseRecorder { t.Helper() s := newTestAuthServer(t) if _, err := s.users.CreateWithAudit("admin@example.com", "", "admin", auth.AuditEvent{EventType: "user.created", Outcome: "success"}); err != nil { @@ -81,16 +81,16 @@ func TestFanQLParseReturnsQueryCanonicalAndVizzes(t *testing.T) { text := "spans where status:error | count() by service" rec := serveFanQL(t, nil, &fakePanels{}, http.MethodPost, "/api/fanql/parse", `{"text":"`+text+`"}`) var body struct { - Query panel.Query `json:"query"` - Canonical string `json:"canonical"` + Query query.Spec `json:"query"` + Canonical string `json:"canonical"` Viz struct { - Compatible []panel.VizCompat `json:"compatible"` + Compatible []query.VizCompat `json:"compatible"` Edits []fanql.VizEdit `json:"edits"` } `json:"viz"` Notices []fanql.Notice `json:"notices"` } fanqlResponse(t, rec, http.StatusOK, &body) - want := panel.Query{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}, Measures: []string{"count()"}, By: []string{"service"}} + want := query.Spec{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}, Measures: []string{"count()"}, By: []string{"service"}} if !reflect.DeepEqual(body.Query, want) || body.Canonical != text || body.Notices == nil || len(body.Notices) != 0 { t.Fatalf("response: %s", rec.Body) } @@ -122,7 +122,7 @@ func TestFanQLParseProblemsHaveNoQuery(t *testing.T) { var body struct { Code string `json:"code"` Message string `json:"message"` - Problems panel.Problems `json:"problems"` + Problems query.Problems `json:"problems"` Preview *struct { Text string `json:"text"` Note string `json:"note"` @@ -152,9 +152,9 @@ func TestFanQLParseProblemsHaveNoQuery(t *testing.T) { func TestFanQLParseSearchBarAndViz(t *testing.T) { rec := serveFanQL(t, nil, &fakePanels{}, http.MethodPost, "/api/fanql/parse", `{"text":"service:api timeout","source":"logs"}`) var body struct { - Query panel.Query `json:"query"` + Query query.Spec `json:"query"` Viz struct { - Compatible []panel.VizCompat `json:"compatible"` + Compatible []query.VizCompat `json:"compatible"` Requested string `json:"requested"` } `json:"viz"` Notices []fanql.Notice `json:"notices"` @@ -198,7 +198,7 @@ func TestFanQLFormat(t *testing.T) { if string(failure["code"]) != `"unavailable"` || failure["problems"] != nil { t.Fatalf("operational: %s", rec.Body) } - q := panel.Query{From: "logs"} + q := query.Spec{From: "logs"} for i := range 16 { q.Where = append(q.Where, "body = '"+strings.Repeat("x", 480)+fmt.Sprint(i)+"'") } @@ -216,7 +216,7 @@ func TestFanQLFormat(t *testing.T) { t.Fatal("format truncated a body literal") } } - q = panel.Query{From: "logs"} + q = query.Spec{From: "logs"} for i := range 16 { q.Where = append(q.Where, "coalesce(body, '"+strings.Repeat("𝔘", 110)+strings.Repeat("`", 30)+fmt.Sprint(i)+"') = ''") } @@ -239,7 +239,7 @@ func TestFanQLFormat(t *testing.T) { func TestFanQLComplete(t *testing.T) { rec := serveFanQL(t, nil, &fakeFanQLPanels{}, http.MethodPost, "/api/fanql/complete", `{"text":"logs where sev","cursor":14}`) var body struct { - Replace panel.TextSpan `json:"replace"` + Replace query.TextSpan `json:"replace"` Items []struct { Label string `json:"label"` } `json:"items"` @@ -251,7 +251,7 @@ func TestFanQLComplete(t *testing.T) { Notices []fanql.Notice `json:"notices"` } fanqlResponse(t, rec, http.StatusOK, &body) - if body.Replace != (panel.TextSpan{Start: 11, End: 14}) || len(body.Items) == 0 || body.Items[0].Label != "severity" || body.Schema.Window != "24h" || body.Schema.Warm || !body.Schema.Recent { + if body.Replace != (query.TextSpan{Start: 11, End: 14}) || len(body.Items) == 0 || body.Items[0].Label != "severity" || body.Schema.Window != "24h" || body.Schema.Warm || !body.Schema.Recent { t.Fatalf("complete: %s", rec.Body) } rec = serveFanQL(t, nil, &fakeFanQLPanels{}, http.MethodPost, "/api/fanql/complete", `{"text":"logs where sev","cursor":14,"window":"","namespace":"prod"}`) diff --git a/internal/api/health.go b/internal/api/health.go index 55dd46d8..391d8947 100644 --- a/internal/api/health.go +++ b/internal/api/health.go @@ -14,18 +14,18 @@ import ( "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) // HealthHandler handles health check endpoints type HealthHandler struct { - duck *query.Duck + duck *engine.Duck cfg config.Config started time.Time } // NewHealthHandler creates a new health handler -func NewHealthHandler(duck *query.Duck, cfg config.Config) *HealthHandler { +func NewHealthHandler(duck *engine.Duck, cfg config.Config) *HealthHandler { return &HealthHandler{duck: duck, cfg: cfg, started: time.Now()} } @@ -196,7 +196,7 @@ func (h *HealthHandler) checkTelemetry() CheckResult { // Use the same snapshot gate as public reads so a short compaction/retention // publication cannot race the Parquet scan and report a false outage. err := h.duck.QueryRowScan(ctx, []any{&one}, "SELECT 1 FROM telemetry.spans LIMIT 1") - if errors.Is(err, query.ErrParquetReadWait) { + if errors.Is(err, engine.ErrParquetReadWait) { return CheckResult{ Status: "degraded", LatencyMs: time.Since(start).Milliseconds(), @@ -347,7 +347,7 @@ FROM rollup_state`).Scan(&updatedAt, &cacheCount, &ageSeconds) } // RegisterHealthRoutes registers health check endpoints -func RegisterHealthRoutes(e *echo.Echo, duck *query.Duck, cfg config.Config) { +func RegisterHealthRoutes(e *echo.Echo, duck *engine.Duck, cfg config.Config) { h := NewHealthHandler(duck, cfg) e.GET("/healthz", h.Liveness) e.GET("/readyz", h.Readiness) diff --git a/internal/api/health_test.go b/internal/api/health_test.go index f6b407f0..e81a87de 100644 --- a/internal/api/health_test.go +++ b/internal/api/health_test.go @@ -13,7 +13,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/labstack/echo/v5" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) func TestLiveness(t *testing.T) { @@ -131,7 +131,7 @@ func TestReadiness_HealthyTelemetryAndRollups(t *testing.T) { mock.ExpectQuery("SELECT\\s+MAX\\(updated_at\\),\\s+COUNT\\(\\*\\),\\s+COALESCE\\(date_diff\\('second', MAX\\(updated_at\\), now\\(\\)\\), 0\\)"). WillReturnRows(sqlmock.NewRows([]string{"max", "count", "age_seconds"}).AddRow(time.Now().UTC(), 2, int64(30))) - h := NewHealthHandler(&query.Duck{DB: db}, config.Config{ + h := NewHealthHandler(&engine.Duck{DB: db}, config.Config{ DataDir: os.TempDir(), RollupInterval: time.Minute, DuckDBMemory: "3GB", @@ -184,7 +184,7 @@ func TestReadiness_HealthyTelemetryAndRollups(t *testing.T) { } func TestTelemetryReadinessReportsPublicationContentionAsDegraded(t *testing.T) { - duck := &query.Duck{} + duck := &engine.Duck{} entered := make(chan struct{}) release := make(chan struct{}) done := make(chan error, 1) @@ -214,7 +214,7 @@ func TestTelemetryReadinessReportsPublicationContentionAsDegraded(t *testing.T) // period elapses — the wedged-first-rollup case the check exists to expose. func TestCheckMaintenance_DegradedWhenNeverRanPastGrace(t *testing.T) { h := &HealthHandler{ - duck: &query.Duck{}, + duck: &engine.Duck{}, cfg: config.Config{RollupInterval: time.Minute}, started: time.Now().Add(-10 * time.Minute), } diff --git a/internal/api/presentation_test.go b/internal/api/presentation_test.go index f6ead325..3fd61e0a 100644 --- a/internal/api/presentation_test.go +++ b/internal/api/presentation_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestHTTPProblemMessagesAndHintsUseAuthorPresentation(t *testing.T) { @@ -24,7 +24,7 @@ func TestHTTPProblemMessagesAndHintsUseAuthorPresentation(t *testing.T) { `Binder Error: query_count in telemetry.service_rollup cannot compare DOUBLE with INTEGER` + "\nCandidate bindings: \"telemetry.edge_rollup.query_count\", \"resource_inventory.service\"\nLINE 1: SELECT query_count FROM telemetry.service_rollup", } { t.Run(message, func(t *testing.T) { - rec := servePanels(t, &fakePanels{err: panel.Problems{{Path: "panels[0].sql", Message: message, Hint: message}}}, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]}}`) + rec := servePanels(t, &fakePanels{err: query.Problems{{Path: "panels[0].sql", Message: message, Hint: message}}}, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]}}`) body := rec.Body.String() if rec.Code != 400 || forbidden.MatchString(body) { t.Fatalf("unsafe problems: %d %s", rec.Code, body) diff --git a/internal/api/panels.go b/internal/api/queries.go similarity index 77% rename from internal/api/panels.go rename to internal/api/queries.go index 5c5eb08b..7f3dcec5 100644 --- a/internal/api/panels.go +++ b/internal/api/queries.go @@ -9,34 +9,34 @@ import ( "time" "github.com/labstack/echo/v5" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" ) -type PanelEngine interface { - Exemplars(context.Context, panel.ExemplarRequest) (panel.ExemplarResponse, error) - Run(context.Context, panel.RunRequest) ([]panel.Result, error) - ResolveVariables(context.Context, panel.ResolveRequest) (map[string][]panel.Option, error) - Schema(context.Context, panel.SchemaRequest) (*panel.Schema, error) +type QueryEngine interface { + Exemplars(context.Context, query.ExemplarRequest) (query.ExemplarResponse, error) + Run(context.Context, query.RunRequest) ([]query.Result, error) + ResolveVariables(context.Context, query.ResolveRequest) (map[string][]query.Option, error) + Schema(context.Context, query.SchemaRequest) (*query.Schema, error) } -type PanelHandler struct{ engine PanelEngine } +type QueryHandler struct{ engine QueryEngine } // panelDeadline bounds one batch. Each panel has its own 10-second timeout; // the batch allows a little more for queueing behind the read pool. const panelDeadline = 20 * time.Second -func RegisterPanelRoutes(e *echo.Echo, engine PanelEngine) { - h := &PanelHandler{engine: engine} +func RegisterQueryRoutes(e *echo.Echo, engine QueryEngine) { + h := &QueryHandler{engine: engine} read := RequireCapability(ReadTelemetry) - e.POST("/api/panels/query", h.query, read) - e.POST("/api/panels/exemplars", h.exemplars, read) - e.POST("/api/panels/variables/resolve", h.resolve, read) + e.POST("/api/queries/run", h.query, read) + e.POST("/api/queries/exemplars", h.exemplars, read) + e.POST("/api/queries/variables/resolve", h.resolve, read) e.GET("/api/telemetry/schema", h.schema, read) } -func (h *PanelHandler) query(c *echo.Context) error { - var req panel.RunRequest +func (h *QueryHandler) query(c *echo.Context) error { + var req query.RunRequest if err := decodeStrict(c, &req, 512<<10); err != nil { return err } @@ -47,8 +47,8 @@ func (h *PanelHandler) query(c *echo.Context) error { return c.JSON(http.StatusOK, map[string]any{"results": results}) } -func (h *PanelHandler) resolve(c *echo.Context) error { - var req panel.ResolveRequest +func (h *QueryHandler) resolve(c *echo.Context) error { + var req query.ResolveRequest if err := decodeStrict(c, &req, 512<<10); err != nil { return err } @@ -61,10 +61,10 @@ func (h *PanelHandler) resolve(c *echo.Context) error { return c.JSON(http.StatusOK, map[string]any{"options": options}) } -func (h *PanelHandler) schema(c *echo.Context) error { +func (h *QueryHandler) schema(c *echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), panelDeadline) defer cancel() - schema, err := h.engine.Schema(ctx, panel.SchemaRequest{Window: c.QueryParam("window"), Namespace: c.QueryParam("namespace")}) + schema, err := h.engine.Schema(ctx, query.SchemaRequest{Window: c.QueryParam("window"), Namespace: c.QueryParam("namespace")}) if err != nil { return panelError(c, err, "schema unavailable") } @@ -110,17 +110,17 @@ func decodeStrict(c *echo.Context, value any, limit int64) error { // writeProblems answers a spec validation failure with 400 and the problem // list. It reports whether it handled err. func writeProblems(c *echo.Context, err error) (bool, error) { - var problems panel.Problems + var problems query.Problems if !errors.As(err, &problems) { return false, nil } failure := newAPIError(http.StatusBadRequest, "invalid_spec", "The dashboard spec is invalid.") - failure.Problems = panel.PresentProblems(problems) + failure.Problems = query.PresentProblems(problems) return true, failure } -func (h *PanelHandler) exemplars(c *echo.Context) error { - var req panel.ExemplarRequest +func (h *QueryHandler) exemplars(c *echo.Context) error { + var req query.ExemplarRequest if err := decodeStrict(c, &req, 512<<10); err != nil { return err } @@ -140,7 +140,7 @@ func exemplarHTTPError(c *echo.Context, err error) error { return echo.NewHTTPError(http.StatusGatewayTimeout, "Exemplars took longer than 10 seconds").Wrap(err) case errors.Is(err, context.Canceled): return nil - case errors.Is(err, query.ErrParquetReadWait): + case errors.Is(err, engine.ErrParquetReadWait): return echo.NewHTTPError(http.StatusServiceUnavailable, "exemplars unavailable").Wrap(err) default: return echo.NewHTTPError(http.StatusInternalServerError, "exemplars unavailable").Wrap(err) diff --git a/internal/api/panels_test.go b/internal/api/queries_test.go similarity index 61% rename from internal/api/panels_test.go rename to internal/api/queries_test.go index 0413343d..78fa890b 100644 --- a/internal/api/panels_test.go +++ b/internal/api/queries_test.go @@ -9,35 +9,35 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type fakePanels struct { - run panel.RunRequest + run query.RunRequest problem bool err error } -func (f *fakePanels) Run(_ context.Context, req panel.RunRequest) ([]panel.Result, error) { +func (f *fakePanels) Run(_ context.Context, req query.RunRequest) ([]query.Result, error) { f.run = req if f.err != nil { return nil, f.err } if f.problem { - return nil, panel.Problems{{Path: "panels[0].viz", Message: "unsupported viz"}} + return nil, query.Problems{{Path: "panels[0].viz", Message: "unsupported viz"}} } - return []panel.Result{{ID: "a", Status: panel.StatusOK}}, nil + return []query.Result{{ID: "a", Status: query.StatusOK}}, nil } -func (f *fakePanels) ResolveVariables(context.Context, panel.ResolveRequest) (map[string][]panel.Option, error) { - return map[string][]panel.Option{"service": {{Value: "checkout", Count: 3}}}, nil +func (f *fakePanels) ResolveVariables(context.Context, query.ResolveRequest) (map[string][]query.Option, error) { + return map[string][]query.Option{"service": {{Value: "checkout", Count: 3}}}, nil } -func (f *fakePanels) Schema(_ context.Context, req panel.SchemaRequest) (*panel.Schema, error) { - return &panel.Schema{Window: req.Window, SQLRelations: panel.SQLRelations()}, nil +func (f *fakePanels) Schema(_ context.Context, req query.SchemaRequest) (*query.Schema, error) { + return &query.Schema{Window: req.Window, SQLRelations: query.SQLRelations()}, nil } -func servePanels(t *testing.T, engine PanelEngine, method, path, body string) *httptest.ResponseRecorder { +func servePanels(t *testing.T, engine QueryEngine, method, path, body string) *httptest.ResponseRecorder { t.Helper() s := newTestAuthServer(t) if _, err := s.users.CreateWithAudit("admin@example.com", "", "admin", auth.AuditEvent{EventType: "user.created", Outcome: "success"}); err != nil { @@ -47,7 +47,7 @@ func servePanels(t *testing.T, engine PanelEngine, method, path, body string) *h if err != nil { t.Fatal(err) } - RegisterPanelRoutes(s.e, engine) + RegisterQueryRoutes(s.e, engine) var reader *strings.Reader if body != "" { reader = strings.NewReader(body) @@ -61,7 +61,7 @@ func servePanels(t *testing.T, engine PanelEngine, method, path, body string) *h func TestPanelQueryRoute(t *testing.T) { engine := &fakePanels{} - rec := servePanels(t, engine, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]},"vars":{"service":"checkout","route":"$__all"},"widths":{"a":640}}`) + rec := servePanels(t, engine, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]},"vars":{"service":"checkout","route":"$__all"},"widths":{"a":640}}`) if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), `"results"`) { t.Fatalf("status %d body %s", rec.Code, rec.Body) } @@ -69,25 +69,25 @@ func TestPanelQueryRoute(t *testing.T) { t.Fatalf("request = %+v", engine.run) } engine.problem = true - rec = servePanels(t, engine, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]}}`) + rec = servePanels(t, engine, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]}}`) var body struct { - Problems []panel.Problem `json:"problems"` + Problems []query.Problem `json:"problems"` } if rec.Code != http.StatusBadRequest || json.Unmarshal(rec.Body.Bytes(), &body) != nil || body.Problems[0].Path != "panels[0].viz" { t.Fatalf("problems response %d %s", rec.Code, rec.Body) } - rec = servePanels(t, engine, http.MethodPost, "/api/panels/query", `{"dashboard":{},"unknown":1}`) + rec = servePanels(t, engine, http.MethodPost, "/api/queries/run", `{"dashboard":{},"unknown":1}`) if rec.Code != http.StatusBadRequest { t.Fatalf("unknown field status %d", rec.Code) } } func TestPanelQueryOperationalErrors(t *testing.T) { - rec := servePanels(t, &fakePanels{err: context.DeadlineExceeded}, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]}}`) + rec := servePanels(t, &fakePanels{err: context.DeadlineExceeded}, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]}}`) if rec.Code != http.StatusGatewayTimeout || !strings.Contains(rec.Body.String(), `"code":"timeout"`) { t.Fatalf("deadline %d %s", rec.Code, rec.Body) } - rec = servePanels(t, &fakePanels{err: context.Canceled}, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]}}`) + rec = servePanels(t, &fakePanels{err: context.Canceled}, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]}}`) if rec.Body.Len() != 0 { t.Fatalf("cancelled wrote body %s", rec.Body) } @@ -95,14 +95,14 @@ func TestPanelQueryOperationalErrors(t *testing.T) { func TestPanelQueryRejectsUnknownHistogramTemporality(t *testing.T) { engine := &fakePanels{} - rec := servePanels(t, engine, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"Hist","panels":[{"id":"h","title":"Hist","viz":"histogram","query":{"from":"metrics","measures":["count()"],"histogram":{"field":"value","buckets":"explicit","temporality":"delta"}}}]}}`) + rec := servePanels(t, engine, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"Hist","panels":[{"id":"h","title":"Hist","viz":"histogram","query":{"from":"metrics","measures":["count()"],"histogram":{"field":"value","buckets":"explicit","temporality":"delta"}}}]}}`) if rec.Code != http.StatusBadRequest || !strings.Contains(rec.Body.String(), "temporality") || engine.run.Dashboard.Name != "" { t.Fatalf("removed option reached executor: %d %s", rec.Code, rec.Body) } } func TestVariableAndSchemaRoutes(t *testing.T) { - rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/panels/variables/resolve", `{"dashboard":{"name":"x","panels":[]}}`) + rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/queries/variables/resolve", `{"dashboard":{"name":"x","panels":[]}}`) if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), `"checkout"`) { t.Fatalf("resolve %d %s", rec.Code, rec.Body) } @@ -114,8 +114,8 @@ func TestVariableAndSchemaRoutes(t *testing.T) { func TestPanelRoutesAreClassified(t *testing.T) { for _, tc := range []struct{ method, path string }{ - {http.MethodPost, "/api/panels/query"}, - {http.MethodPost, "/api/panels/variables/resolve"}, + {http.MethodPost, "/api/queries/run"}, + {http.MethodPost, "/api/queries/variables/resolve"}, {http.MethodGet, "/api/telemetry/schema"}, } { policy, ok := classifyRoute(tc.method, tc.path) @@ -123,41 +123,41 @@ func TestPanelRoutesAreClassified(t *testing.T) { t.Errorf("%s %s = %+v %v", tc.method, tc.path, policy, ok) } } - if _, ok := classifyRoute(http.MethodGet, "/api/panels/query"); ok { - t.Error("GET /api/panels/query allowed") + if _, ok := classifyRoute(http.MethodGet, "/api/queries/run"); ok { + t.Error("GET /api/queries/run allowed") } } type partialBatchPanels struct{ fakePanels } -func (f *partialBatchPanels) Run(ctx context.Context, _ panel.RunRequest) ([]panel.Result, error) { +func (f *partialBatchPanels) Run(ctx context.Context, _ query.RunRequest) ([]query.Result, error) { // Executor owns the batch deadline; a transport-created deadline would be // indistinguishable from genuine caller cancellation inside Run. if _, ok := ctx.Deadline(); ok { return nil, context.DeadlineExceeded } - return []panel.Result{{ID: "fast", Status: panel.StatusOK}, {ID: "slow", Status: panel.StatusError, Error: "Not run: the dashboard ran out of time. Narrow the time range or split the dashboard."}}, nil + return []query.Result{{ID: "fast", Status: query.StatusOK}, {ID: "slow", Status: query.StatusError, Error: "Not run: the dashboard ran out of time. Narrow the time range or split the dashboard."}}, nil } func TestPanelBatchHTTPKeepsPartialResults(t *testing.T) { - rec := servePanels(t, &partialBatchPanels{}, http.MethodPost, "/api/panels/query", `{"dashboard":{"name":"x","panels":[]}}`) + rec := servePanels(t, &partialBatchPanels{}, http.MethodPost, "/api/queries/run", `{"dashboard":{"name":"x","panels":[]}}`) if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), "Not run: the dashboard ran out of time. Narrow the time range or split the dashboard.") { t.Fatalf("partial batch %d %s", rec.Code, rec.Body) } } -func (f *fakePanels) Exemplars(context.Context, panel.ExemplarRequest) (panel.ExemplarResponse, error) { - return panel.ExemplarResponse{Traces: []panel.Exemplar{}}, nil +func (f *fakePanels) Exemplars(context.Context, query.ExemplarRequest) (query.ExemplarResponse, error) { + return query.ExemplarResponse{Traces: []query.Exemplar{}}, nil } func TestExemplarRoutePolicy(t *testing.T) { - rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/panels/exemplars", `{"dashboard":{"name":"Inline","panels":[]},"panel_id":"latency","from":"2026-10-01T12:00:00Z","to":"2026-10-01T12:05:00Z","dimensions":{}}`) + rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/queries/exemplars", `{"dashboard":{"name":"Inline","panels":[]},"panel_id":"latency","from":"2026-10-01T12:00:00Z","to":"2026-10-01T12:05:00Z","dimensions":{}}`) if rec.Code != 200 || !strings.Contains(rec.Body.String(), `"traces":[]`) { t.Fatalf("%d %s", rec.Code, rec.Body) } - policy, ok := classifyRoute(http.MethodPost, "/api/panels/exemplars") + policy, ok := classifyRoute(http.MethodPost, "/api/queries/exemplars") if !ok || policy.capability != ReadTelemetry { t.Fatalf("policy: %+v %v", policy, ok) } - if _, ok := classifyRoute(http.MethodGet, "/api/panels/exemplars"); ok { + if _, ok := classifyRoute(http.MethodGet, "/api/queries/exemplars"); ok { t.Fatal("GET accepted") } } diff --git a/internal/api/panel_request_errors_test.go b/internal/api/query_request_errors_test.go similarity index 63% rename from internal/api/panel_request_errors_test.go rename to internal/api/query_request_errors_test.go index e681a84b..9c23081e 100644 --- a/internal/api/panel_request_errors_test.go +++ b/internal/api/query_request_errors_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" ) @@ -17,8 +17,8 @@ type failedExemplars struct { failure error } -func (f *failedExemplars) Exemplars(context.Context, panel.ExemplarRequest) (panel.ExemplarResponse, error) { - return panel.ExemplarResponse{}, f.failure +func (f *failedExemplars) Exemplars(context.Context, query.ExemplarRequest) (query.ExemplarResponse, error) { + return query.ExemplarResponse{}, f.failure } func TestExemplarHTTPErrorMapping(t *testing.T) { @@ -28,14 +28,14 @@ func TestExemplarHTTPErrorMapping(t *testing.T) { status int message string }{ - {"problem", panel.Problems{{Path: "panel_id", Message: "missing"}}, 400, "problems"}, + {"problem", query.Problems{{Path: "panel_id", Message: "missing"}}, 400, "problems"}, {"deadline", fmt.Errorf("wrapped: %w", context.DeadlineExceeded), 504, "Exemplars took longer than 10 seconds"}, {"cancel", context.Canceled, 200, ""}, - {"read_wait", fmt.Errorf("wrapped: %w", query.ErrParquetReadWait), 503, "exemplars unavailable"}, + {"read_wait", fmt.Errorf("wrapped: %w", engine.ErrParquetReadWait), 503, "exemplars unavailable"}, {"internal", errors.New("failure"), 500, "exemplars unavailable"}, } { t.Run(tc.name, func(t *testing.T) { - rec := servePanels(t, &failedExemplars{failure: tc.err}, http.MethodPost, "/api/panels/exemplars", `{"dashboard":{"name":"x","panels":[]}}`) + rec := servePanels(t, &failedExemplars{failure: tc.err}, http.MethodPost, "/api/queries/exemplars", `{"dashboard":{"name":"x","panels":[]}}`) if rec.Code != tc.status || !strings.Contains(rec.Body.String(), tc.message) { t.Fatalf("%d %s", rec.Code, rec.Body) } @@ -48,12 +48,12 @@ func TestExemplarHTTPErrorMapping(t *testing.T) { func TestStrictJSONTrailingData(t *testing.T) { for _, suffix := range []string{` {}`, ` null`, ` garbage`, strings.Repeat(" ", 512<<10) + `{}`} { - rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/panels/exemplars", `{"dashboard":{"name":"x","panels":[]}}`+suffix) + rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/queries/exemplars", `{"dashboard":{"name":"x","panels":[]}}`+suffix) if rec.Code != 400 { t.Fatalf("trailing data accepted: %d", rec.Code) } } - rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/panels/exemplars", `{"dashboard":{"name":"x","panels":[]}}`+" \n\t") + rec := servePanels(t, &fakePanels{}, http.MethodPost, "/api/queries/exemplars", `{"dashboard":{"name":"x","panels":[]}}`+" \n\t") if rec.Code != 200 { t.Fatalf("whitespace rejected: %d %s", rec.Code, rec.Body) } diff --git a/internal/cmd/e2eseed/main_test.go b/internal/cmd/e2eseed/main_test.go index 6eae3a6c..82ab02f5 100644 --- a/internal/cmd/e2eseed/main_test.go +++ b/internal/cmd/e2eseed/main_test.go @@ -16,9 +16,9 @@ import ( "github.com/labstack/fanout/internal/config" "github.com/labstack/fanout/internal/dashboard" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/ingest" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" collectorlogs "go.opentelemetry.io/proto/otlp/collector/logs/v1" @@ -61,12 +61,12 @@ func TestAllPanelsFixtureValidates(t *testing.T) { if err != nil { t.Fatal(err) } - var spec panel.Dashboard + var spec query.Dashboard if err := decodeFixture(data, &spec); err != nil { t.Fatal(err) } - panel.Normalize(&spec) - if problems := panel.Validate(&spec); len(problems) != 0 { + query.Normalize(&spec) + if problems := query.Validate(&spec); len(problems) != 0 { t.Fatalf("invalid fixture: %v", problems) } cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 4, RollupInterval: time.Hour} @@ -75,12 +75,12 @@ func TestAllPanelsFixtureValidates(t *testing.T) { t.Fatal(err) } t.Cleanup(func() { _ = repo.Close() }) - engine, err := query.NewDuck(t.Context(), cfg, repo) + engine, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = engine.Close() }) - if _, problems, err := panel.Check(t.Context(), engine, &spec); err != nil || len(problems) != 0 { + if _, problems, err := query.Check(t.Context(), engine, &spec); err != nil || len(problems) != 0 { t.Fatalf("fixture check: %v; %v", err, problems) } types := map[string]bool{} @@ -98,7 +98,7 @@ func TestAllPanelsFixtureValidates(t *testing.T) { } } -func decodeFixture(data []byte, spec *panel.Dashboard) error { +func decodeFixture(data []byte, spec *query.Dashboard) error { decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() return decoder.Decode(spec) @@ -115,7 +115,7 @@ func TestAllPanelsFixtureRejectsUnknownFields(t *testing.T) { } { t.Run(mutation.name, func(t *testing.T) { mutated := bytes.Replace(data, []byte(mutation.old), []byte(mutation.replacement), 1) - var spec panel.Dashboard + var spec query.Dashboard if err := decodeFixture(mutated, &spec); err == nil { t.Fatal("fixture accepted an unknown field") } @@ -389,12 +389,12 @@ func TestPerformanceFixtureValidatesAndExecutes(t *testing.T) { if err != nil { t.Fatal(err) } - var spec panel.Dashboard + var spec query.Dashboard if err := decodeFixture(data, &spec); err != nil { t.Fatal(err) } - panel.Normalize(&spec) - if problems := panel.Validate(&spec); len(problems) != 0 { + query.Normalize(&spec) + if problems := query.Validate(&spec); len(problems) != 0 { t.Fatalf("invalid fixture: %v", problems) } if len(spec.Panels) != 12 || spec.Time.Range != "24h" || spec.Time.Refresh != "off" { @@ -442,16 +442,16 @@ func TestPerformanceFixtureValidatesAndExecutes(t *testing.T) { if _, err := collectormetrics.NewMetricsServiceClient(conn).Export(t.Context(), &metricRequest); err != nil { t.Fatal(err) } - engine, err := query.NewDuck(t.Context(), cfg, repo) + engine, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = engine.Close() }) - if _, problems, err := panel.Check(t.Context(), engine, &spec); err != nil || len(problems) != 0 { + if _, problems, err := query.Check(t.Context(), engine, &spec); err != nil || len(problems) != 0 { t.Fatalf("fixture check: %v; %v", err, problems) } from := base.Add(-24 * time.Hour) - results, err := panel.NewExecutor(engine, 30).Run(t.Context(), panel.RunRequest{Dashboard: spec, Time: &panel.Time{From: &from, To: &base}}) + results, err := query.NewExecutor(engine, 30).Run(t.Context(), query.RunRequest{Dashboard: spec, Time: &query.Time{From: &from, To: &base}}) if err != nil { t.Fatal(err) } @@ -460,7 +460,7 @@ func TestPerformanceFixtureValidatesAndExecutes(t *testing.T) { } seen := map[string]bool{} for _, result := range results { - if seen[result.ID] || result.Status != panel.StatusOK || result.Frame == nil || result.Frame.Rows == 0 { + if seen[result.ID] || result.Status != query.StatusOK || result.Frame == nil || result.Frame.Rows == 0 { t.Fatalf("unpopulated/duplicate panel: %+v", result) } seen[result.ID] = true @@ -483,16 +483,16 @@ func TestPerformanceFixtureValidatesAndExecutes(t *testing.T) { // Execute the system SQL panels and the existing external-peer reader. system.Panels = system.Panels[8:] system.Panels = append(system.Panels[:2], system.Panels[3:]...) - executor := panel.NewExecutor(engine, 30) + executor := query.NewExecutor(engine, 30) executor.SetRollupReader(observability.New(engine, engine, 30)) from := base.Add(-time.Hour) - results, err := executor.Run(t.Context(), panel.RunRequest{Dashboard: system, Vars: map[string]panel.Value{"service": {All: true}}, Time: &panel.Time{From: &from, To: &base}}) + results, err := executor.Run(t.Context(), query.RunRequest{Dashboard: system, Vars: map[string]query.Value{"service": {All: true}}, Time: &query.Time{From: &from, To: &base}}) if err != nil { t.Fatal(err) } rows := map[string][]map[string]any{} for _, result := range results { - if result.Status != panel.StatusOK || result.Frame == nil { + if result.Status != query.StatusOK || result.Frame == nil { t.Fatalf("%s: %+v", result.ID, result) } for i := range result.Frame.Rows { diff --git a/internal/dashboard/changes.go b/internal/dashboard/changes.go index 93fe3a7d..1af49cde 100644 --- a/internal/dashboard/changes.go +++ b/internal/dashboard/changes.go @@ -5,7 +5,7 @@ import ( "encoding/json" "sort" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type PanelChange struct { @@ -48,12 +48,12 @@ type ChangeSet struct { // Changes compares normalized committed snapshots. Physical packing is reported // once; authored fields and only panels outside the longest common surviving // order get panel chips. Normalization applies to copies for diffing only. -func Changes(before, after panel.Dashboard) ChangeSet { +func Changes(before, after query.Dashboard) ChangeSet { // The zero base is a create: only added panel chips apply, for every consumer. created := before.Version == 0 && before.Name == "" && len(before.Panels) == 0 before = normalizedForDiff(before) after = normalizedForDiff(after) - old := map[string]panel.Panel{} + old := map[string]query.Panel{} for _, p := range before.Panels { old[p.ID] = p } @@ -124,12 +124,12 @@ func mustJSON(v any) []byte { return b } -func normalizedForDiff(spec panel.Dashboard) panel.Dashboard { +func normalizedForDiff(spec query.Dashboard) query.Dashboard { copy, err := clone(spec) if err != nil { panic(err) } - panel.Normalize(©) + query.Normalize(©) return copy } @@ -137,7 +137,7 @@ func normalizedForDiff(spec panel.Dashboard) panel.Dashboard { // same minimal moved set deterministically, including an ambiguous two-panel swap. func retainedOrder(before, after []string) map[string]bool { // Saved specs hold at most panel.MaxPanels panels, which bounds the table. - if len(before) > panel.MaxPanels || len(after) > panel.MaxPanels { + if len(before) > query.MaxPanels || len(after) > query.MaxPanels { return map[string]bool{} } lengths := make([][]int, len(before)+1) diff --git a/internal/dashboard/changes_test.go b/internal/dashboard/changes_test.go index 1bf66be0..f2a5448e 100644 --- a/internal/dashboard/changes_test.go +++ b/internal/dashboard/changes_test.go @@ -4,13 +4,13 @@ import ( "reflect" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestChangesReportOnlyPanelsOutsideTheLongestCommonOrder(t *testing.T) { - before := panel.Dashboard{Name: "Order"} + before := query.Dashboard{Name: "Order"} for _, id := range []string{"a", "b", "c", "d", "e"} { - before.Panels = append(before.Panels, panel.Panel{ID: id, Title: id, Viz: "text", Content: id}) + before.Panels = append(before.Panels, query.Panel{ID: id, Title: id, Viz: "text", Content: id}) } for _, tc := range []struct { name string @@ -25,10 +25,10 @@ func TestChangesReportOnlyPanelsOutsideTheLongestCommonOrder(t *testing.T) { {name: "add", order: []string{"a", "new", "b", "c", "d", "e"}, added: []string{"new"}}, } { t.Run(tc.name, func(t *testing.T) { - after := panel.Dashboard{Name: before.Name} + after := query.Dashboard{Name: before.Name} for _, id := range tc.order { if id == "new" { - after.Panels = append(after.Panels, panel.Panel{ID: id, Title: id, Viz: "text", Content: id}) + after.Panels = append(after.Panels, query.Panel{ID: id, Title: id, Viz: "text", Content: id}) } for _, p := range before.Panels { if p.ID == id { @@ -57,15 +57,15 @@ func TestChangesReportOnlyPanelsOutsideTheLongestCommonOrder(t *testing.T) { } func TestChangesIgnoreNewNormalizationDefaultsWithoutMutatingSnapshots(t *testing.T) { - before := panel.Dashboard{Name: "Old defaults", Panels: []panel.Panel{ + before := query.Dashboard{Name: "Old defaults", Panels: []query.Panel{ {ID: "a", Title: "A", Viz: "text", Content: "a"}, - {ID: "b", Title: "B", Viz: "timeseries", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}, + {ID: "b", Title: "B", Viz: "timeseries", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}, }} after, err := clone(before) if err != nil { t.Fatal(err) } - panel.Normalize(&after) + query.Normalize(&after) after.Panels[0].Content = "edited" original := mustJSON(before) got := Changes(before, after) @@ -79,7 +79,7 @@ func TestChangesIgnoreNewNormalizationDefaultsWithoutMutatingSnapshots(t *testin func TestDashboardChangesExcludeTheSpecFormatVersion(t *testing.T) { before := textSpec("Format") - panel.Normalize(&before) + query.Normalize(&before) after, _ := clone(before) after.Version++ if got := Changes(before, after); len(got.DashboardFields) != 0 { @@ -88,8 +88,8 @@ func TestDashboardChangesExcludeTheSpecFormatVersion(t *testing.T) { } func TestChangesNameOnlyCommittedPanelFields(t *testing.T) { - a := panel.Dashboard{Panels: []panel.Panel{{ID: "latency", Title: "Latency", Viz: "stat", Unit: "ms"}, {ID: "errors", Title: "Errors", Viz: "text", Content: "unchanged"}}} - b := panel.Dashboard{Panels: []panel.Panel{{ID: "latency", Title: "Latency", Viz: "stat", Unit: "s"}, {ID: "new", Title: "New", Viz: "text", Content: "note"}}} + a := query.Dashboard{Panels: []query.Panel{{ID: "latency", Title: "Latency", Viz: "stat", Unit: "ms"}, {ID: "errors", Title: "Errors", Viz: "text", Content: "unchanged"}}} + b := query.Dashboard{Panels: []query.Panel{{ID: "latency", Title: "Latency", Viz: "stat", Unit: "s"}, {ID: "new", Title: "New", Viz: "text", Content: "note"}}} got := Changes(a, b) if len(got.Panels) != 3 || got.Panels[0].PanelID != "latency" || got.Panels[0].Kind != "changed" || len(got.Panels[0].Fields) != 1 || got.Panels[0].Fields[0] != "unit" || got.Panels[1].PanelID != "new" || got.Panels[1].Kind != "added" || got.Panels[2].PanelID != "errors" || got.Panels[2].Kind != "removed" { t.Fatalf("changes=%+v", got) @@ -103,7 +103,7 @@ func TestChangesSeparatePackingFromAuthoredFieldsAndOrder(t *testing.T) { a := threePanels() PackMissing(a.Panels) b, _ := clone(a) - b.Panels = []panel.Panel{b.Panels[0], b.Panels[2]} + b.Panels = []query.Panel{b.Panels[0], b.Panels[2]} Compact(b.Panels) got := Changes(a, b) if !got.LayoutChanged || len(got.Panels) != 1 || got.Panels[0].PanelID != "b" || got.Panels[0].Kind != "removed" { @@ -125,7 +125,7 @@ func TestChangesSeparatePackingFromAuthoredFieldsAndOrder(t *testing.T) { } func TestChangesReportWholeAuthoredFieldsAndDashboardFields(t *testing.T) { - a := panel.Dashboard{Name: "Before", Panels: []panel.Panel{{ID: "p", Title: "Before", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}, Thresholds: []panel.Threshold{{Value: 10, Status: "warn"}}}}} + a := query.Dashboard{Name: "Before", Panels: []query.Panel{{ID: "p", Title: "Before", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}, Thresholds: []query.Threshold{{Value: 10, Status: "warn"}}}}} b, _ := clone(a) b.Name = "After" b.Description = "Description" @@ -141,7 +141,7 @@ func TestChangesReportWholeAuthoredFieldsAndDashboardFields(t *testing.T) { func TestCreateChangesHaveNoLayoutOrDashboardChips(t *testing.T) { after := textSpec("Created") PackMissing(after.Panels) - got := Changes(panel.Dashboard{}, after) + got := Changes(query.Dashboard{}, after) if got.LayoutChanged || len(got.DashboardFields) != 0 || len(got.Panels) != 1 || got.Panels[0].Kind != "added" { t.Fatalf("create changes=%+v", got) } diff --git a/internal/dashboard/concurrent_test.go b/internal/dashboard/concurrent_test.go index 4a24b67f..0d505956 100644 --- a/internal/dashboard/concurrent_test.go +++ b/internal/dashboard/concurrent_test.go @@ -14,7 +14,7 @@ import ( "time" "github.com/labstack/fanout/internal/db/generated" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" appstore "github.com/labstack/fanout/internal/store" "modernc.org/sqlite" ) @@ -166,21 +166,21 @@ func newConcurrentFileService(t *testing.T) *Service { return New(sqlite.DB, structural{}) } -func concurrentSpec(n int) panel.Dashboard { - d := panel.Dashboard{Name: "Race"} +func concurrentSpec(n int) query.Dashboard { + d := query.Dashboard{Name: "Race"} for i := 0; i < n; i++ { - d.Panels = append(d.Panels, panel.Panel{ID: fmt.Sprintf("p%d", i), Title: fmt.Sprintf("P%d", i), Viz: "text", Content: "base", Width: 12}) + d.Panels = append(d.Panels, query.Panel{ID: fmt.Sprintf("p%d", i), Title: fmt.Sprintf("P%d", i), Viz: "text", Content: "base", Width: 12}) } return d } -func storedVersionSpec(t *testing.T, s *Service, id string, version int) panel.Dashboard { +func storedVersionSpec(t *testing.T, s *Service, id string, version int) query.Dashboard { t.Helper() raw, err := generated.New(s.db).GetDashboardVersion(t.Context(), generated.GetDashboardVersionParams{DashboardID: id, Version: int64(version)}) if err != nil { t.Fatalf("version %d: %v", version, err) } - var d panel.Dashboard + var d query.Dashboard if err := json.Unmarshal([]byte(raw), &d); err != nil { t.Fatal(err) } diff --git a/internal/dashboard/defaults.go b/internal/dashboard/defaults.go index 04fa17e2..46318a62 100644 --- a/internal/dashboard/defaults.go +++ b/internal/dashboard/defaults.go @@ -1,34 +1,34 @@ package dashboard -import "github.com/labstack/fanout/internal/panel" +import "github.com/labstack/fanout/internal/query" // DefaultSpec is every owner's first dashboard: the shape of the whole system, // filterable to one service. -func DefaultSpec() panel.Dashboard { +func DefaultSpec() query.Dashboard { server := "kind = 'SPAN_KIND_SERVER'" service := "service = $service" where := []string{server, service} deploys := true - return panel.Dashboard{ - Version: panel.SpecVersion, + return query.Dashboard{ + Version: query.SpecVersion, Name: "System overview", Description: "Traffic, errors and latency, reachability, host and container capacity, and service versions.", - Time: panel.Time{Range: "1h", Refresh: "30s"}, - Annotations: &panel.Annotations{Deploys: &deploys}, - Variables: []panel.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true, Default: panel.AllValue}}, - Panels: []panel.Panel{ - {ID: "requests", Title: "Requests per second", Viz: "stat", Better: "higher", Query: &panel.Query{From: "spans", Where: where, Measures: []string{"rate()"}}}, - {ID: "errors", Better: "lower", Title: "Error rate", Viz: "stat", Query: &panel.Query{From: "spans", Where: where, Measures: []string{"error_rate()"}}, Thresholds: []panel.Threshold{{Value: 1, Status: "warn"}, {Value: 5, Status: "bad"}}}, - {ID: "latency_p95", Better: "lower", Title: "p95 latency", Viz: "stat", Query: &panel.Query{From: "spans", Where: where, Measures: []string{"p95(duration_ms)"}}, Thresholds: []panel.Threshold{{Value: 750, Status: "warn"}, {Value: 2000, Status: "bad"}}}, - {ID: "error_logs", Better: "lower", Title: "Error logs", Viz: "stat", Query: &panel.Query{From: "logs", Where: []string{"upper(severity) IN ('ERROR', 'FATAL')", service}, Measures: []string{"count()"}}, Thresholds: []panel.Threshold{{Value: 1, Status: "warn"}}}, - {ID: "traffic", Title: "Requests by service", Viz: "timeseries", Options: &panel.Options{Style: "stacked"}, Query: &panel.Query{From: "spans", Where: where, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "auto"}}, - {ID: "latency", Better: "lower", Title: "p95 latency by service", Viz: "timeseries", Query: &panel.Query{From: "spans", Where: where, Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "auto"}, Thresholds: []panel.Threshold{{Value: 2000, Status: "bad"}}}, - {ID: "error_services", Title: "Error rate by service", Viz: "bar", Width: 4, Click: &panel.Click{SetVariable: "service"}, Query: &panel.Query{From: "spans", Where: []string{server}, Measures: []string{"error_rate()"}, By: []string{"service"}, Limit: 10}}, - {ID: "endpoints", Title: "Slowest endpoints", Viz: "table", Width: 8, Query: &panel.Query{From: "spans", Where: []string{server, service, "http_route <> ''"}, Measures: []string{"p95(duration_ms)", "error_rate()", "rate()"}, By: []string{"service", "http_route"}, Sort: "p95", Limit: 15}}, - {ID: "check_states", Title: "Is it reachable?", Description: receiverDescription("httpcheck", "Endpoint and host.name; silence is bad after two intervals. Labels warn if all checks run on service hosts."), Viz: "state_timeline", Width: 12, SQL: reachabilitySQL, Better: "lower", Thresholds: []panel.Threshold{{Value: 1, Status: "bad"}}}, + Time: query.Time{Range: "1h", Refresh: "30s"}, + Annotations: &query.Annotations{Deploys: &deploys}, + Variables: []query.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true, Default: query.AllValue}}, + Panels: []query.Panel{ + {ID: "requests", Title: "Requests per second", Viz: "stat", Better: "higher", Query: &query.Spec{From: "spans", Where: where, Measures: []string{"rate()"}}}, + {ID: "errors", Better: "lower", Title: "Error rate", Viz: "stat", Query: &query.Spec{From: "spans", Where: where, Measures: []string{"error_rate()"}}, Thresholds: []query.Threshold{{Value: 1, Status: "warn"}, {Value: 5, Status: "bad"}}}, + {ID: "latency_p95", Better: "lower", Title: "p95 latency", Viz: "stat", Query: &query.Spec{From: "spans", Where: where, Measures: []string{"p95(duration_ms)"}}, Thresholds: []query.Threshold{{Value: 750, Status: "warn"}, {Value: 2000, Status: "bad"}}}, + {ID: "error_logs", Better: "lower", Title: "Error logs", Viz: "stat", Query: &query.Spec{From: "logs", Where: []string{"upper(severity) IN ('ERROR', 'FATAL')", service}, Measures: []string{"count()"}}, Thresholds: []query.Threshold{{Value: 1, Status: "warn"}}}, + {ID: "traffic", Title: "Requests by service", Viz: "timeseries", Options: &query.Options{Style: "stacked"}, Query: &query.Spec{From: "spans", Where: where, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "auto"}}, + {ID: "latency", Better: "lower", Title: "p95 latency by service", Viz: "timeseries", Query: &query.Spec{From: "spans", Where: where, Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "auto"}, Thresholds: []query.Threshold{{Value: 2000, Status: "bad"}}}, + {ID: "error_services", Title: "Error rate by service", Viz: "bar", Width: 4, Click: &query.Click{SetVariable: "service"}, Query: &query.Spec{From: "spans", Where: []string{server}, Measures: []string{"error_rate()"}, By: []string{"service"}, Limit: 10}}, + {ID: "endpoints", Title: "Slowest endpoints", Viz: "table", Width: 8, Query: &query.Spec{From: "spans", Where: []string{server, service, "http_route <> ''"}, Measures: []string{"p95(duration_ms)", "error_rate()", "rate()"}, By: []string{"service", "http_route"}, Sort: "p95", Limit: 15}}, + {ID: "check_states", Title: "Is it reachable?", Description: receiverDescription("httpcheck", "Endpoint and host.name; silence is bad after two intervals. Labels warn if all checks run on service hosts."), Viz: "state_timeline", Width: 12, SQL: reachabilitySQL, Better: "lower", Thresholds: []query.Threshold{{Value: 1, Status: "bad"}}}, {ID: "check_latency", Title: "Check latency", Description: receiverDescription("httpcheck", "Latest check duration by endpoint and reporting host.name."), Viz: "timeseries", Width: 12, SQL: checkLatencySQL, Unit: "ms"}, - {ID: "service_health", Title: "Is anything failing or slow?", Description: receiverDescription("otlp", "Service health and error trend with deploy markers."), Viz: "health", Width: 12, Query: &panel.Query{From: "spans", Where: []string{service}}}, - {ID: "service_map", Title: "Services and external dependencies", Description: receiverDescription("otlp", "Failing or slow services and external dependencies observed in client spans."), Viz: "service_map", Width: 12, Height: "l", Query: &panel.Query{From: "spans", Where: []string{service}}}, + {ID: "service_health", Title: "Is anything failing or slow?", Description: receiverDescription("otlp", "Service health and error trend with deploy markers."), Viz: "health", Width: 12, Query: &query.Spec{From: "spans", Where: []string{service}}}, + {ID: "service_map", Title: "Services and external dependencies", Description: receiverDescription("otlp", "Failing or slow services and external dependencies observed in client spans."), Viz: "service_map", Width: 12, Height: "l", Query: &query.Spec{From: "spans", Where: []string{service}}}, capacityPanel("hosts", "Is anything running out? Hosts", "hostmetrics", "CPU busy, memory used and the fullest filesystem; worst first. Not reporting after two intervals is bad.", hostCapacitySQL()), capacityPanel("containers", "Containers", "docker_stats", "CPU: 100% is one core. Status uses limits; memory only if no CPU limit. Silence after two intervals is bad.", containerCapacitySQL()), {ID: "versions", Title: "What changed?", Description: receiverDescription("otlp", "Service versions, first seen in the selected range, runtime and SDK."), Viz: "table", Width: 12, SQL: `WITH observations AS (` + versionObservationsSQL + `) SELECT namespace,service,version,min(seen) AS first_seen,runtime_name,runtime_version,sdk_language,sdk_version FROM observations WHERE version IS NOT NULL AND version<>'' GROUP BY namespace,service,version,runtime_name,runtime_version,sdk_language,sdk_version ORDER BY first_seen DESC,namespace,service,version`}, @@ -40,10 +40,10 @@ func receiverDescription(receiver, description string) string { return description + " Supplied by the Collector `" + receiver + "` receiver. [Collector setup](https://fanout.run/docs/get-started/send-telemetry#watch-hosts-containers-and-endpoints)." } -func capacityPanel(id, title, receiver, description, sql string) panel.Panel { - columns := []panel.ColumnFormat{{Field: "status", Format: "status"}, {Field: "cpu_percent", Format: "unit", Unit: "percent"}, {Field: "memory_percent", Format: "unit", Unit: "percent"}} +func capacityPanel(id, title, receiver, description, sql string) query.Panel { + columns := []query.ColumnFormat{{Field: "status", Format: "status"}, {Field: "cpu_percent", Format: "unit", Unit: "percent"}, {Field: "memory_percent", Format: "unit", Unit: "percent"}} if id == "hosts" { - columns = append(columns, panel.ColumnFormat{Field: "filesystem_percent", Format: "unit", Unit: "percent"}) + columns = append(columns, query.ColumnFormat{Field: "filesystem_percent", Format: "unit", Unit: "percent"}) } - return panel.Panel{ID: id, Title: title, Description: receiverDescription(receiver, description), Viz: "table", Width: 12, SQL: sql, Better: "lower", Thresholds: []panel.Threshold{{Value: 80, Status: "warn"}, {Value: 90, Status: "bad"}}, Options: &panel.Options{Columns: columns}} + return query.Panel{ID: id, Title: title, Description: receiverDescription(receiver, description), Viz: "table", Width: 12, SQL: sql, Better: "lower", Thresholds: []query.Threshold{{Value: 80, Status: "warn"}, {Value: 90, Status: "bad"}}, Options: &query.Options{Columns: columns}} } diff --git a/internal/dashboard/defaults_test.go b/internal/dashboard/defaults_test.go index 33bfdbe9..3f3acbdc 100644 --- a/internal/dashboard/defaults_test.go +++ b/internal/dashboard/defaults_test.go @@ -9,8 +9,8 @@ import ( "time" "github.com/labstack/fanout/internal/config" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -24,34 +24,34 @@ func TestDefaultSpecPassesTheFullCheck(t *testing.T) { } } -func defaultFixture(t *testing.T) (*panel.Executor, *telemetrystore.Repository) { +func defaultFixture(t *testing.T) (*query.Executor, *telemetrystore.Repository) { t.Helper() cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 2, RollupInterval: time.Hour} repo, err := telemetrystore.Open(cfg.TelemetryDir()) if err != nil { t.Fatal(err) } - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = d.Close(); _ = repo.Close() }) - e := panel.NewExecutor(d, 30) + e := query.NewExecutor(d, 30) e.SetRollupReader(observability.New(d, d, 30)) return e, repo } -func runDefault(t *testing.T, e *panel.Executor, start, end time.Time) map[string]panel.Result { +func runDefault(t *testing.T, e *query.Executor, start, end time.Time) map[string]query.Result { t.Helper() spec := DefaultSpec() - spec.Time = panel.Time{From: &start, To: &end} - results, err := e.Run(t.Context(), panel.RunRequest{Dashboard: spec}) + spec.Time = query.Time{From: &start, To: &end} + results, err := e.Run(t.Context(), query.RunRequest{Dashboard: spec}) if err != nil { t.Fatal(err) } - out := make(map[string]panel.Result) + out := make(map[string]query.Result) for _, r := range results { - if r.Status == panel.StatusError { + if r.Status == query.StatusError { t.Fatalf("%s: %s", r.ID, r.Error) } out[r.ID] = r @@ -59,7 +59,7 @@ func runDefault(t *testing.T, e *panel.Executor, start, end time.Time) map[strin return out } -func defaultValues(t *testing.T, r panel.Result, column string) []any { +func defaultValues(t *testing.T, r query.Result, column string) []any { t.Helper() if r.Frame != nil { for i, c := range r.Frame.Columns { @@ -92,7 +92,7 @@ func TestDefaultSystemPanelsUseExistingEmptyState(t *testing.T) { start := time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC) results := runDefault(t, e, start, start.Add(time.Hour)) for _, id := range []string{"check_states", "check_latency", "hosts", "containers", "versions"} { - if results[id].Status != panel.StatusEmpty { + if results[id].Status != query.StatusEmpty { t.Fatalf("%s: %+v", id, results[id]) } } @@ -278,8 +278,8 @@ func TestDefaultVersionsPreserveFirstSeenAndRuntimeSDKTuples(t *testing.T) { t.Fatal(err) } spec := DefaultSpec() - spec.Time = panel.Time{From: &start, To: &end} - results, err := e.Run(t.Context(), panel.RunRequest{Dashboard: spec, Panels: []string{"versions"}}) + spec.Time = query.Time{From: &start, To: &end} + results, err := e.Run(t.Context(), query.RunRequest{Dashboard: spec, Panels: []string{"versions"}}) if err != nil { t.Fatal(err) } @@ -371,8 +371,8 @@ func TestDefaultCapacityPreservesRetriesCountersNamespacesAndFreshness(t *testin for _, offset := range []time.Duration{2 * time.Minute, 3*time.Minute - time.Nanosecond, 3 * time.Minute, 6 * time.Minute, 6*time.Minute + time.Nanosecond} { end := start.Add(offset) spec := DefaultSpec() - spec.Time = panel.Time{From: &start, To: &end} - results, err := e.Run(t.Context(), panel.RunRequest{Dashboard: spec, Panels: []string{"hosts", "containers"}}) + spec.Time = query.Time{From: &start, To: &end} + results, err := e.Run(t.Context(), query.RunRequest{Dashboard: spec, Panels: []string{"hosts", "containers"}}) if err != nil { t.Fatal(err) } @@ -481,8 +481,8 @@ func TestDefaultContainersUseScopeCPUUnitsAndReportedLimitsForStatus(t *testing. t.Fatal("container CPU percentage must explain its denominator") } } - spec.Time = panel.Time{From: &start, To: &end} - results, err := e.Run(t.Context(), panel.RunRequest{Dashboard: spec, Panels: []string{"containers"}}) + spec.Time = query.Time{From: &start, To: &end} + results, err := e.Run(t.Context(), query.RunRequest{Dashboard: spec, Panels: []string{"containers"}}) if err != nil { t.Fatal(err) } diff --git a/internal/dashboard/edit.go b/internal/dashboard/edit.go index daaafa82..ac433dcc 100644 --- a/internal/dashboard/edit.go +++ b/internal/dashboard/edit.go @@ -8,7 +8,7 @@ import ( "slices" "strings" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) // Operation is one typed edit. Panels are addressed by their stable id, never @@ -17,12 +17,12 @@ type Operation struct { Op string `json:"op" jsonschema:"add_panel, update_panel, remove_panel, move_panel, set_variable, remove_variable, set_time or rename"` ID string `json:"id,omitempty" jsonschema:"update_panel, remove_panel, move_panel: the panel id"` After string `json:"after,omitempty" jsonschema:"add_panel: insert after this panel id (default: last); move_panel: move after this panel id (default: first)"` - Panel *panel.Panel `json:"panel,omitempty" jsonschema:"add_panel: the complete new panel"` + Panel *query.Panel `json:"panel,omitempty" jsonschema:"add_panel: the complete new panel"` Set map[string]any `json:"set,omitempty" jsonschema:"update_panel: panel fields to replace, e.g. {\"title\": \"…\", \"thresholds\": […]}; null removes a field"` - Variable *panel.Variable `json:"variable,omitempty" jsonschema:"set_variable: the variable, added or replaced by name"` + Variable *query.Variable `json:"variable,omitempty" jsonschema:"set_variable: the variable, added or replaced by name"` Name string `json:"name,omitempty" jsonschema:"remove_variable: the variable name; rename: the new dashboard name"` Description *string `json:"description,omitempty" jsonschema:"rename: the new description"` - Time *panel.Time `json:"time,omitempty" jsonschema:"set_time: the new default time"` + Time *query.Time `json:"time,omitempty" jsonschema:"set_time: the new default time"` } // maxOperations and maxPanels bound the work one edit can request before the @@ -34,35 +34,35 @@ const ( ) func opError(i int, format string, args ...any) error { - return panel.Problems{{Path: fmt.Sprintf("operations[%d]", i), Message: fmt.Sprintf(format, args...)}} + return query.Problems{{Path: fmt.Sprintf("operations[%d]", i), Message: fmt.Sprintf(format, args...)}} } // Apply runs operations in order on a copy of spec. The bool reports whether // panels were moved or resized, which requires a fresh pack. Additions keep // existing coordinates and receive their own placement in prepare. -func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) { +func Apply(spec query.Dashboard, ops []Operation) (query.Dashboard, bool, error) { out, err := clone(spec) if err != nil { - return panel.Dashboard{}, false, err + return query.Dashboard{}, false, err } if len(ops) > maxOperations { - return panel.Dashboard{}, false, panel.Problems{{Path: "operations", Message: fmt.Sprintf("an edit has at most %d operations", maxOperations)}} + return query.Dashboard{}, false, query.Problems{{Path: "operations", Message: fmt.Sprintf("an edit has at most %d operations", maxOperations)}} } repack, compact := false, false index := func(id string) int { - return slices.IndexFunc(out.Panels, func(p panel.Panel) bool { return p.ID == id }) + return slices.IndexFunc(out.Panels, func(p query.Panel) bool { return p.ID == id }) } for i, op := range ops { switch op.Op { case "add_panel": if op.Panel == nil { - return panel.Dashboard{}, false, opError(i, "add_panel needs panel") + return query.Dashboard{}, false, opError(i, "add_panel needs panel") } if index(op.Panel.ID) >= 0 { - return panel.Dashboard{}, false, opError(i, "a panel with id %q already exists", op.Panel.ID) + return query.Dashboard{}, false, opError(i, "a panel with id %q already exists", op.Panel.ID) } if len(out.Panels) >= maxPanels { - return panel.Dashboard{}, false, opError(i, "a dashboard has at most %d panels", maxPanels) + return query.Dashboard{}, false, opError(i, "a dashboard has at most %d panels", maxPanels) } p := *op.Panel p.Grid = nil @@ -70,7 +70,7 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) if op.After != "" { j := index(op.After) if j < 0 { - return panel.Dashboard{}, false, opError(i, "no panel has id %q", op.After) + return query.Dashboard{}, false, opError(i, "no panel has id %q", op.After) } at = j + 1 } @@ -78,21 +78,21 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) case "update_panel": j := index(op.ID) if j < 0 { - return panel.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) + return query.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) } for key := range op.Set { if !panelFields[key] { - return panel.Dashboard{}, false, opError(i, "unknown panel field %q", key) + return query.Dashboard{}, false, opError(i, "unknown panel field %q", key) } } for _, fixed := range []string{"id", "grid"} { if _, ok := op.Set[fixed]; ok { - return panel.Dashboard{}, false, opError(i, "%s cannot be set; it is managed by the server", fixed) + return query.Dashboard{}, false, opError(i, "%s cannot be set; it is managed by the server", fixed) } } updated, err := mergePanel(out.Panels[j], op.Set) if err != nil { - return panel.Dashboard{}, false, opError(i, "%v", err) + return query.Dashboard{}, false, opError(i, "%v", err) } _, width := op.Set["width"] _, height := op.Set["height"] @@ -101,14 +101,14 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) case "remove_panel": j := index(op.ID) if j < 0 { - return panel.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) + return query.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) } out.Panels = slices.Delete(out.Panels, j, j+1) compact = true case "move_panel": j := index(op.ID) if j < 0 { - return panel.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) + return query.Dashboard{}, false, opError(i, "no panel has id %q", op.ID) } p := out.Panels[j] out.Panels = slices.Delete(out.Panels, j, j+1) @@ -116,7 +116,7 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) if op.After != "" { k := index(op.After) if k < 0 { - return panel.Dashboard{}, false, opError(i, "no panel has id %q", op.After) + return query.Dashboard{}, false, opError(i, "no panel has id %q", op.After) } at = k + 1 } @@ -124,28 +124,28 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) repack = true case "set_variable": if op.Variable == nil { - return panel.Dashboard{}, false, opError(i, "set_variable needs variable") + return query.Dashboard{}, false, opError(i, "set_variable needs variable") } - k := slices.IndexFunc(out.Variables, func(v panel.Variable) bool { return v.Name == op.Variable.Name }) + k := slices.IndexFunc(out.Variables, func(v query.Variable) bool { return v.Name == op.Variable.Name }) if k >= 0 { out.Variables[k] = *op.Variable } else { out.Variables = append(out.Variables, *op.Variable) } case "remove_variable": - k := slices.IndexFunc(out.Variables, func(v panel.Variable) bool { return v.Name == op.Name }) + k := slices.IndexFunc(out.Variables, func(v query.Variable) bool { return v.Name == op.Name }) if k < 0 { - return panel.Dashboard{}, false, opError(i, "no variable is named %q", op.Name) + return query.Dashboard{}, false, opError(i, "no variable is named %q", op.Name) } out.Variables = slices.Delete(out.Variables, k, k+1) case "set_time": if op.Time == nil { - return panel.Dashboard{}, false, opError(i, "set_time needs time") + return query.Dashboard{}, false, opError(i, "set_time needs time") } out.Time = *op.Time case "rename": if op.Name == "" && op.Description == nil { - return panel.Dashboard{}, false, opError(i, "rename needs name or description") + return query.Dashboard{}, false, opError(i, "rename needs name or description") } if op.Name != "" { out.Name = op.Name @@ -154,36 +154,36 @@ func Apply(spec panel.Dashboard, ops []Operation) (panel.Dashboard, bool, error) out.Description = *op.Description } default: - return panel.Dashboard{}, false, opError(i, "unknown op %q; use add_panel, update_panel, remove_panel, move_panel, set_variable, remove_variable, set_time or rename", op.Op) + return query.Dashboard{}, false, opError(i, "unknown op %q; use add_panel, update_panel, remove_panel, move_panel, set_variable, remove_variable, set_time or rename", op.Op) } } if compact && !repack { - panel.Normalize(&out) + query.Normalize(&out) Compact(out.Panels) } return out, repack, nil } -func clone(spec panel.Dashboard) (panel.Dashboard, error) { +func clone(spec query.Dashboard) (query.Dashboard, error) { raw, err := json.Marshal(spec) if err != nil { - return panel.Dashboard{}, err + return query.Dashboard{}, err } - var out panel.Dashboard + var out query.Dashboard err = json.Unmarshal(raw, &out) return out, err } // mergePanel replaces the fields named in set and decodes strictly, so a // misspelled field is an error rather than a silent no-op. -func mergePanel(p panel.Panel, set map[string]any) (panel.Panel, error) { +func mergePanel(p query.Panel, set map[string]any) (query.Panel, error) { raw, err := json.Marshal(p) if err != nil { - return panel.Panel{}, err + return query.Panel{}, err } fields := map[string]any{} if err := json.Unmarshal(raw, &fields); err != nil { - return panel.Panel{}, err + return query.Panel{}, err } for key, value := range set { if value == nil { @@ -194,13 +194,13 @@ func mergePanel(p panel.Panel, set map[string]any) (panel.Panel, error) { } merged, err := json.Marshal(fields) if err != nil { - return panel.Panel{}, err + return query.Panel{}, err } decoder := json.NewDecoder(bytes.NewReader(merged)) decoder.DisallowUnknownFields() - var out panel.Panel + var out query.Panel if err := decoder.Decode(&out); err != nil { - return panel.Panel{}, err + return query.Panel{}, err } return out, nil } @@ -209,7 +209,7 @@ func mergePanel(p panel.Panel, set map[string]any) (panel.Panel, error) { // otherwise match set keys case-insensitively and silently ignore the edit. var panelFields = func() map[string]bool { fields := map[string]bool{} - t := reflect.TypeOf(panel.Panel{}) + t := reflect.TypeOf(query.Panel{}) for i := 0; i < t.NumField(); i++ { name, _, _ := strings.Cut(t.Field(i).Tag.Get("json"), ",") if name != "" && name != "-" { diff --git a/internal/dashboard/edit_test.go b/internal/dashboard/edit_test.go index 82bfdd2e..c0daffa8 100644 --- a/internal/dashboard/edit_test.go +++ b/internal/dashboard/edit_test.go @@ -7,13 +7,13 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) -func editBase() panel.Dashboard { - return panel.Dashboard{Name: "Ops", Time: panel.Time{Range: "1h"}, Panels: []panel.Panel{ - {ID: "a", Title: "A", Viz: "text", Content: "a", Grid: &panel.Grid{W: 4, H: 3}}, - {ID: "b", Title: "B", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}, Grid: &panel.Grid{X: 4, W: 3, H: 3}}, +func editBase() query.Dashboard { + return query.Dashboard{Name: "Ops", Time: query.Time{Range: "1h"}, Panels: []query.Panel{ + {ID: "a", Title: "A", Viz: "text", Content: "a", Grid: &query.Grid{W: 4, H: 3}}, + {ID: "b", Title: "B", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}, Grid: &query.Grid{X: 4, W: 3, H: 3}}, }} } @@ -21,9 +21,9 @@ func TestApplyOperations(t *testing.T) { description := "New purpose" out, repack, err := Apply(editBase(), []Operation{ {Op: "update_panel", ID: "b", Set: map[string]any{"title": "Requests", "thresholds": []any{map[string]any{"value": 10.0, "status": "warn"}}}}, - {Op: "add_panel", After: "a", Panel: &panel.Panel{ID: "c", Title: "C", Viz: "text", Content: "c"}}, + {Op: "add_panel", After: "a", Panel: &query.Panel{ID: "c", Title: "C", Viz: "text", Content: "c"}}, {Op: "move_panel", ID: "a"}, - {Op: "set_variable", Variable: &panel.Variable{Name: "service", Kind: "constant", Value: "checkout"}}, + {Op: "set_variable", Variable: &query.Variable{Name: "service", Kind: "constant", Value: "checkout"}}, {Op: "rename", Name: "Operations", Description: &description}, }) if err != nil { @@ -59,7 +59,7 @@ func TestApplyRejectsBadOperations(t *testing.T) { {{Op: "update_panel", ID: "missing", Set: map[string]any{"title": "x"}}}, {{Op: "update_panel", ID: "b", Set: map[string]any{"id": "c"}}}, {{Op: "update_panel", ID: "b", Set: map[string]any{"colour": "red"}}}, - {{Op: "add_panel", Panel: &panel.Panel{ID: "a", Title: "dup", Viz: "text", Content: "x"}}}, + {{Op: "add_panel", Panel: &query.Panel{ID: "a", Title: "dup", Viz: "text", Content: "x"}}}, {{Op: "remove_variable", Name: "nope"}}, {{Op: "explode"}}, {{Op: "update_panel", ID: "b", Set: map[string]any{"Title": "X"}}}, @@ -68,7 +68,7 @@ func TestApplyRejectsBadOperations(t *testing.T) { } for _, ops := range cases { _, _, err := Apply(editBase(), ops) - var problems panel.Problems + var problems query.Problems if !errors.As(err, &problems) || problems[0].Path != "operations[0]" { t.Errorf("%+v: err = %v", ops, err) } @@ -86,7 +86,7 @@ func TestApplyBoundsWorkBeforeValidation(t *testing.T) { } adds := make([]Operation, 0, maxPanels) for i := range maxPanels { - adds = append(adds, Operation{Op: "add_panel", Panel: &panel.Panel{ID: fmt.Sprintf("extra%d", i), Title: "x", Viz: "text", Content: "x"}}) + adds = append(adds, Operation{Op: "add_panel", Panel: &query.Panel{ID: fmt.Sprintf("extra%d", i), Title: "x", Viz: "text", Content: "x"}}) } adds = append(adds, Operation{Op: "remove_panel", ID: "extra0"}) start := time.Now() diff --git a/internal/dashboard/layout.go b/internal/dashboard/layout.go index ba1873a2..925512a7 100644 --- a/internal/dashboard/layout.go +++ b/internal/dashboard/layout.go @@ -4,7 +4,7 @@ import ( "cmp" "slices" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) // RowHeight is the grid row height in pixels; ui/host/src/dashboards/grid.tsx @@ -22,7 +22,7 @@ const ( var heightRows = map[string]int{"s": 3, "m": 6, "l": 10} var minimumRows = map[string]int{"stat": 4} -func firstFit(placed []panel.Grid, w, h int) (int, int) { +func firstFit(placed []query.Grid, w, h int) (int, int) { for y := 0; ; y++ { for x := 0; x+w <= columns; x++ { if fits(placed, x, y, w, h) { @@ -32,7 +32,7 @@ func firstFit(placed []panel.Grid, w, h int) (int, int) { } } -func fits(placed []panel.Grid, x, y, w, h int) bool { +func fits(placed []query.Grid, x, y, w, h int) bool { for _, g := range placed { if x < g.X+g.W && g.X < x+w && y < g.Y+g.H && g.Y < y+h { return false @@ -42,8 +42,8 @@ func fits(placed []panel.Grid, x, y, w, h int) bool { } // needsPack reports whether any panel lacks a usable position or two overlap. -func needsPack(panels []panel.Panel) bool { - placed := make([]panel.Grid, 0, len(panels)) +func needsPack(panels []query.Panel) bool { + placed := make([]query.Grid, 0, len(panels)) for _, p := range panels { g := p.Grid if g == nil || g.W < 1 || g.H < 1 || g.X < 0 || g.Y < 0 || g.W > columns || g.X > columns-g.W || g.Y > maxRow || g.H > maxHeight || !fits(placed, g.X, g.Y, g.W, g.H) { @@ -56,15 +56,15 @@ func needsPack(panels []panel.Panel) bool { // PackMissing preserves every valid, non-overlapping supplied grid and packs // only panels without usable coordinates around them. -func PackMissing(panels []panel.Panel) { +func PackMissing(panels []query.Panel) { packed := packMissing(panels) snapRowBands(panels, packed) fillRowBands(panels, packed) } -func packMissing(panels []panel.Panel) []int { +func packMissing(panels []query.Panel) []int { packed := make([]int, 0, len(panels)) - placed := make([]panel.Grid, 0, len(panels)) + placed := make([]query.Grid, 0, len(panels)) for i := range panels { g := panels[i].Grid if g == nil { @@ -93,7 +93,7 @@ func packMissing(panels []panel.Panel) []int { } h = max(h, minimumRows[panels[i].Viz]) x, y := firstFit(placed, w, h) - g := panel.Grid{X: x, Y: y, W: w, H: h} + g := query.Grid{X: x, Y: y, W: w, H: h} panels[i].Grid = &g packed = append(packed, i) placed = append(placed, g) @@ -103,9 +103,9 @@ func packMissing(panels []panel.Panel) []int { // Snap only newly packed panels. Scan rectangles, never individual grid cells // or row coordinates, so work depends on panel count rather than grid Y. -func snapRowBands(panels []panel.Panel, packed []int) { +func snapRowBands(panels []query.Panel, packed []int) { bottoms := make(map[int]int, len(packed)) - placed := make([]panel.Grid, len(panels)) + placed := make([]query.Grid, len(panels)) for i, p := range panels { placed[i] = *p.Grid } @@ -125,7 +125,7 @@ func snapRowBands(panels []panel.Panel, packed []int) { // Fill only newly packed bands whose entire trailing rectangle is free. // Share spare columns evenly, giving the leftmost panels the remainder. -func fillRowBands(panels []panel.Panel, packed []int) { +func fillRowBands(panels []query.Panel, packed []int) { slices.SortFunc(packed, func(a, b int) int { ga, gb := panels[a].Grid, panels[b].Grid return cmp.Or(cmp.Compare(ga.Y, gb.Y), cmp.Compare(ga.X, gb.X)) @@ -141,7 +141,7 @@ func fillRowBands(panels []panel.Panel, packed []int) { continue } band := packed[start:end] - placed := make([]panel.Grid, 0, len(panels)) + placed := make([]query.Grid, 0, len(panels)) for _, p := range panels { placed = append(placed, *p.Grid) } @@ -150,9 +150,9 @@ func fillRowBands(panels []panel.Panel, packed []int) { } // Remove this band's old rectangles before checking the new positions. for _, i := range band { - placed[i] = panel.Grid{} + placed[i] = query.Grid{} } - widened := make([]panel.Grid, 0, len(band)) + widened := make([]query.Grid, 0, len(band)) shift := 0 for j, i := range band { g := *panels[i].Grid @@ -179,7 +179,7 @@ func fillRowBands(panels []panel.Panel, packed []int) { // Compact repairs unusable grids, then closes vertical gaps without changing // usable columns or dimensions. Work depends on panel count, never grid Y. -func Compact(panels []panel.Panel) { +func Compact(panels []query.Panel) { packed := packMissing(panels) order := make([]int, 0, len(panels)) for i, p := range panels { @@ -188,7 +188,7 @@ func Compact(panels []panel.Panel) { } } slices.SortStableFunc(order, func(a, b int) int { return cmp.Compare(panels[a].Grid.Y, panels[b].Grid.Y) }) - placed := make([]panel.Grid, 0, len(order)) + placed := make([]query.Grid, 0, len(order)) for _, i := range order { g := *panels[i].Grid g.Y = 0 @@ -198,7 +198,7 @@ func Compact(panels []panel.Panel) { } } panels[i].Grid = &g - at, _ := slices.BinarySearchFunc(placed, g, func(a, b panel.Grid) int { return cmp.Compare(a.Y, b.Y) }) + at, _ := slices.BinarySearchFunc(placed, g, func(a, b query.Grid) int { return cmp.Compare(a.Y, b.Y) }) placed = slices.Insert(placed, at, g) } snapRowBands(panels, packed) diff --git a/internal/dashboard/layout_constraints_test.go b/internal/dashboard/layout_constraints_test.go index 1570950d..259c86a9 100644 --- a/internal/dashboard/layout_constraints_test.go +++ b/internal/dashboard/layout_constraints_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestAddPreservesSavedLayout(t *testing.T) { @@ -15,8 +15,8 @@ func TestAddPreservesSavedLayout(t *testing.T) { if err != nil { t.Fatal(err) } - r.Spec.Panels[0].Grid = &panel.Grid{X: 0, W: 8, H: 3} - r.Spec.Panels[1].Grid = &panel.Grid{X: 8, W: 4, H: 3} + r.Spec.Panels[0].Grid = &query.Grid{X: 0, W: 8, H: 3} + r.Spec.Panels[1].Grid = &query.Grid{X: 8, W: 4, H: 3} r, err = s.Replace(t.Context(), "owner", r.ID, r.Spec, 1, author, "Widen A") if err != nil { t.Fatal(err) @@ -39,7 +39,7 @@ func TestRemovalClosesRealGap(t *testing.T) { s := newTestService(t) spec := threePanels() for i := range spec.Panels { - spec.Panels[i].Grid = &panel.Grid{Y: i * 3, W: 12, H: 3} + spec.Panels[i].Grid = &query.Grid{Y: i * 3, W: 12, H: 3} } r, err := s.Create(t.Context(), "owner", spec, agent) if err != nil { @@ -67,7 +67,7 @@ func TestReplaceHugeGridIsBounded(t *testing.T) { t.Fatal(err) } r.Spec.Panels = r.Spec.Panels[:2] - r.Spec.Panels[1].Grid = &panel.Grid{Y: 1 << 40, W: 6, H: 3} + r.Spec.Panels[1].Grid = &query.Grid{Y: 1 << 40, W: 6, H: 3} started := time.Now() r, err = s.Replace(t.Context(), "owner", r.ID, r.Spec, 1, agent, "") if elapsed := time.Since(started); elapsed >= 100*time.Millisecond { @@ -94,9 +94,9 @@ func TestDefaultThresholdDirections(t *testing.T) { func TestEditCompactsBoundedGrids(t *testing.T) { d := threePanels() - d.Panels[0].Grid = &panel.Grid{W: 6, H: 3} - d.Panels[1].Grid = &panel.Grid{Y: 1 << 40, W: 6, H: 3} - d.Panels[2].Grid = &panel.Grid{X: 6, W: 6, H: 3} + d.Panels[0].Grid = &query.Grid{W: 6, H: 3} + d.Panels[1].Grid = &query.Grid{Y: 1 << 40, W: 6, H: 3} + d.Panels[2].Grid = &query.Grid{X: 6, W: 6, H: 3} started := time.Now() out, _, err := Apply(d, []Operation{{Op: "remove_panel", ID: "c"}}) if err != nil { @@ -108,10 +108,10 @@ func TestEditCompactsBoundedGrids(t *testing.T) { } func TestCompactFindsLowestFreeGap(t *testing.T) { - panels := []panel.Panel{ - {Grid: &panel.Grid{W: 6, H: 10}}, - {Grid: &panel.Grid{Y: 10, W: 12, H: 3}}, - {Grid: &panel.Grid{X: 6, Y: 20, W: 6, H: 3}}, + panels := []query.Panel{ + {Grid: &query.Grid{W: 6, H: 10}}, + {Grid: &query.Grid{Y: 10, W: 12, H: 3}}, + {Grid: &query.Grid{X: 6, Y: 20, W: 6, H: 3}}, } Compact(panels) if panels[2].Grid.Y != 0 { diff --git a/internal/dashboard/layout_test.go b/internal/dashboard/layout_test.go index 3354682e..201461b4 100644 --- a/internal/dashboard/layout_test.go +++ b/internal/dashboard/layout_test.go @@ -5,27 +5,27 @@ import ( "slices" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestPackedRowBandsSnapOnlyFreeNewPanels(t *testing.T) { for _, tc := range []struct { name string - panels []panel.Panel - want []panel.Grid + panels []query.Panel + want []query.Grid }{ - {"wall", []panel.Panel{ + {"wall", []query.Panel{ {Width: 4, Height: "s"}, {Width: 4, Height: "s"}, {Width: 4, Height: "s"}, {Width: 6, Height: "m"}, {Width: 6, Height: "m"}, {Viz: "service_map", Width: 6, Height: "l"}, {Viz: "health", Width: 6, Height: "m"}, {Viz: "heatmap", Width: 12, Height: "m"}, {Viz: "traces", Width: 12, Height: "m"}, {Viz: "log_patterns", Width: 12, Height: "m"}, - }, []panel.Grid{{X: 0, Y: 0, W: 4, H: 3}, {X: 4, Y: 0, W: 4, H: 3}, {X: 8, Y: 0, W: 4, H: 3}, {X: 0, Y: 3, W: 6, H: 6}, {X: 6, Y: 3, W: 6, H: 6}, {X: 0, Y: 9, W: 6, H: 10}, {X: 6, Y: 9, W: 6, H: 10}, {X: 0, Y: 19, W: 12, H: 6}, {X: 0, Y: 25, W: 12, H: 6}, {X: 0, Y: 31, W: 12, H: 6}}}, - {"text beside series", []panel.Panel{{Viz: "text", Width: 6, Height: "s"}, {Viz: "timeseries", Width: 6, Height: "m"}}, []panel.Grid{{X: 0, Y: 0, W: 6, H: 6}, {X: 6, Y: 0, W: 6, H: 6}}}, - {"authored short", []panel.Panel{{Grid: &panel.Grid{X: 0, Y: 0, W: 6, H: 3}}, {Width: 6, Height: "m"}}, []panel.Grid{{X: 0, Y: 0, W: 6, H: 3}, {X: 6, Y: 0, W: 6, H: 6}}}, - {"authored tall", []panel.Panel{{Grid: &panel.Grid{X: 0, Y: 0, W: 6, H: 10}}, {Width: 6, Height: "s"}}, []panel.Grid{{X: 0, Y: 0, W: 6, H: 10}, {X: 6, Y: 0, W: 6, H: 3}}}, - {"occupied hole", []panel.Panel{{Width: 3, Height: "s"}, {Width: 9, Height: "m"}, {Width: 3, Height: "s"}}, []panel.Grid{{X: 0, Y: 0, W: 3, H: 3}, {X: 3, Y: 0, W: 9, H: 6}, {X: 0, Y: 3, W: 3, H: 3}}}, + }, []query.Grid{{X: 0, Y: 0, W: 4, H: 3}, {X: 4, Y: 0, W: 4, H: 3}, {X: 8, Y: 0, W: 4, H: 3}, {X: 0, Y: 3, W: 6, H: 6}, {X: 6, Y: 3, W: 6, H: 6}, {X: 0, Y: 9, W: 6, H: 10}, {X: 6, Y: 9, W: 6, H: 10}, {X: 0, Y: 19, W: 12, H: 6}, {X: 0, Y: 25, W: 12, H: 6}, {X: 0, Y: 31, W: 12, H: 6}}}, + {"text beside series", []query.Panel{{Viz: "text", Width: 6, Height: "s"}, {Viz: "timeseries", Width: 6, Height: "m"}}, []query.Grid{{X: 0, Y: 0, W: 6, H: 6}, {X: 6, Y: 0, W: 6, H: 6}}}, + {"authored short", []query.Panel{{Grid: &query.Grid{X: 0, Y: 0, W: 6, H: 3}}, {Width: 6, Height: "m"}}, []query.Grid{{X: 0, Y: 0, W: 6, H: 3}, {X: 6, Y: 0, W: 6, H: 6}}}, + {"authored tall", []query.Panel{{Grid: &query.Grid{X: 0, Y: 0, W: 6, H: 10}}, {Width: 6, Height: "s"}}, []query.Grid{{X: 0, Y: 0, W: 6, H: 10}, {X: 6, Y: 0, W: 6, H: 3}}}, + {"occupied hole", []query.Panel{{Width: 3, Height: "s"}, {Width: 9, Height: "m"}, {Width: 3, Height: "s"}}, []query.Grid{{X: 0, Y: 0, W: 3, H: 3}, {X: 3, Y: 0, W: 9, H: 6}, {X: 0, Y: 3, W: 3, H: 3}}}, } { - for name, pack := range map[string]func([]panel.Panel){"pack": PackMissing, "compact": Compact} { + for name, pack := range map[string]func([]query.Panel){"pack": PackMissing, "compact": Compact} { t.Run(tc.name+"/"+name, func(t *testing.T) { panels := slices.Clone(tc.panels) pack(panels) @@ -37,7 +37,7 @@ func TestPackedRowBandsSnapOnlyFreeNewPanels(t *testing.T) { if needsPack(panels) { t.Fatal("packed panels overlap or have unusable grids") } - before := make([]panel.Grid, len(panels)) + before := make([]query.Grid, len(panels)) for i, p := range panels { before[i] = *p.Grid } @@ -53,8 +53,8 @@ func TestPackedRowBandsSnapOnlyFreeNewPanels(t *testing.T) { } func TestServiceMapDefaultLayoutLarge(t *testing.T) { - for _, pack := range []func([]panel.Panel){PackMissing} { - panels := []panel.Panel{{ID: "map", Viz: "service_map", Width: 12}} + for _, pack := range []func([]query.Panel){PackMissing} { + panels := []query.Panel{{ID: "map", Viz: "service_map", Width: 12}} pack(panels) if panels[0].Grid.H != 10 { t.Fatalf("service map rows=%d", panels[0].Grid.H) @@ -65,7 +65,7 @@ func TestServiceMapDefaultLayoutLarge(t *testing.T) { func TestStatHeightMinimumAndGaugeBand(t *testing.T) { for _, height := range []string{"", "s", "m", "l"} { t.Run(height, func(t *testing.T) { - panels := []panel.Panel{{Viz: "stat", Width: 3, Height: height}, {Viz: "gauge", Width: 3, Height: "s"}} + panels := []query.Panel{{Viz: "stat", Width: 3, Height: height}, {Viz: "gauge", Width: 3, Height: "s"}} PackMissing(panels) want := 4 if height == "m" { @@ -86,18 +86,18 @@ func TestStatHeightMinimumAndGaugeBand(t *testing.T) { func TestPackedRowBandsFillOnlyFreeColumns(t *testing.T) { for _, tc := range []struct { name string - panels []panel.Panel - want []panel.Grid + panels []query.Panel + want []query.Grid }{ - {"three stats", []panel.Panel{{Viz: "stat", Width: 3, Height: "s"}, {Viz: "stat", Width: 3, Height: "s"}, {Viz: "stat", Width: 3, Height: "s"}}, []panel.Grid{{X: 0, W: 4, H: 4}, {X: 4, W: 4, H: 4}, {X: 8, W: 4, H: 4}}}, - {"text and series", []panel.Panel{{Viz: "text", Width: 4, Height: "s"}, {Viz: "timeseries", Width: 6, Height: "m"}}, []panel.Grid{{X: 0, W: 5, H: 6}, {X: 5, W: 7, H: 6}}}, - {"leftmost gets remainder", []panel.Panel{{Width: 3, Height: "s"}, {Width: 3, Height: "s"}, {Width: 2, Height: "s"}}, []panel.Grid{{X: 0, W: 5, H: 3}, {X: 5, W: 4, H: 3}, {X: 9, W: 3, H: 3}}}, - {"authored right", []panel.Panel{{Width: 3, Height: "s"}, {Grid: &panel.Grid{X: 9, W: 2, H: 3}}}, []panel.Grid{{X: 0, W: 3, H: 3}, {X: 9, W: 2, H: 3}}}, - {"authored between", []panel.Panel{{Width: 3, Height: "s"}, {Grid: &panel.Grid{X: 3, W: 3, H: 3}}, {Width: 3, Height: "s"}}, []panel.Grid{{X: 0, W: 3, H: 3}, {X: 3, W: 3, H: 3}, {X: 6, W: 3, H: 3}}}, - {"right occupied lower down", []panel.Panel{{Width: 6, Height: "l"}, {Width: 3, Height: "s"}, {Width: 6, Height: "m"}}, []panel.Grid{{X: 0, W: 6, H: 10}, {X: 6, W: 3, H: 3}, {X: 6, Y: 3, W: 6, H: 6}}}, - {"authored only", []panel.Panel{{Viz: "stat", Grid: &panel.Grid{X: 2, W: 3, H: 3}}, {Grid: &panel.Grid{X: 5, W: 4, H: 3}}}, []panel.Grid{{X: 2, W: 3, H: 3}, {X: 5, W: 4, H: 3}}}, + {"three stats", []query.Panel{{Viz: "stat", Width: 3, Height: "s"}, {Viz: "stat", Width: 3, Height: "s"}, {Viz: "stat", Width: 3, Height: "s"}}, []query.Grid{{X: 0, W: 4, H: 4}, {X: 4, W: 4, H: 4}, {X: 8, W: 4, H: 4}}}, + {"text and series", []query.Panel{{Viz: "text", Width: 4, Height: "s"}, {Viz: "timeseries", Width: 6, Height: "m"}}, []query.Grid{{X: 0, W: 5, H: 6}, {X: 5, W: 7, H: 6}}}, + {"leftmost gets remainder", []query.Panel{{Width: 3, Height: "s"}, {Width: 3, Height: "s"}, {Width: 2, Height: "s"}}, []query.Grid{{X: 0, W: 5, H: 3}, {X: 5, W: 4, H: 3}, {X: 9, W: 3, H: 3}}}, + {"authored right", []query.Panel{{Width: 3, Height: "s"}, {Grid: &query.Grid{X: 9, W: 2, H: 3}}}, []query.Grid{{X: 0, W: 3, H: 3}, {X: 9, W: 2, H: 3}}}, + {"authored between", []query.Panel{{Width: 3, Height: "s"}, {Grid: &query.Grid{X: 3, W: 3, H: 3}}, {Width: 3, Height: "s"}}, []query.Grid{{X: 0, W: 3, H: 3}, {X: 3, W: 3, H: 3}, {X: 6, W: 3, H: 3}}}, + {"right occupied lower down", []query.Panel{{Width: 6, Height: "l"}, {Width: 3, Height: "s"}, {Width: 6, Height: "m"}}, []query.Grid{{X: 0, W: 6, H: 10}, {X: 6, W: 3, H: 3}, {X: 6, Y: 3, W: 6, H: 6}}}, + {"authored only", []query.Panel{{Viz: "stat", Grid: &query.Grid{X: 2, W: 3, H: 3}}, {Grid: &query.Grid{X: 5, W: 4, H: 3}}}, []query.Grid{{X: 2, W: 3, H: 3}, {X: 5, W: 4, H: 3}}}, } { - for name, pack := range map[string]func([]panel.Panel){"pack": PackMissing, "compact": Compact} { + for name, pack := range map[string]func([]query.Panel){"pack": PackMissing, "compact": Compact} { t.Run(tc.name+"/"+name, func(t *testing.T) { panels := slices.Clone(tc.panels) // Each runner gets its own authored grid pointers. @@ -128,14 +128,14 @@ func TestPackedRowBandsFillOnlyFreeColumns(t *testing.T) { } func TestPackFillsGapsWithoutStretching(t *testing.T) { - panels := []panel.Panel{ + panels := []query.Panel{ {ID: "a", Width: 3, Height: "s"}, {ID: "chart", Width: 9, Height: "m"}, {ID: "b", Width: 3, Height: "s"}, {ID: "table", Width: 12, Height: "m"}, } PackMissing(panels) - want := map[string]panel.Grid{ + want := map[string]query.Grid{ "a": {X: 0, Y: 0, W: 3, H: 3}, "chart": {X: 3, Y: 0, W: 9, H: 6}, "b": {X: 0, Y: 3, W: 3, H: 3}, @@ -156,12 +156,12 @@ func TestPackFillsGapsWithoutStretching(t *testing.T) { } func TestNeedsPackRejectsHugeOrOverflowingGrids(t *testing.T) { - for name, g := range map[string]panel.Grid{ + for name, g := range map[string]query.Grid{ "overflow": {X: math.MaxInt64 - 1, W: 3, H: 3}, "far row": {Y: 1000000, W: 3, H: 3}, "tall": {W: 3, H: 1000000}, } { - if !needsPack([]panel.Panel{{ID: "a", Grid: &g}}) { + if !needsPack([]query.Panel{{ID: "a", Grid: &g}}) { t.Errorf("%s not detected", name) } } diff --git a/internal/dashboard/resource_inventory_test.go b/internal/dashboard/resource_inventory_test.go index a58c2ef5..e183810f 100644 --- a/internal/dashboard/resource_inventory_test.go +++ b/internal/dashboard/resource_inventory_test.go @@ -13,13 +13,13 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) -func assertResourceFrame(t *testing.T, name string, frame *panel.Frame) { +func assertResourceFrame(t *testing.T, name string, frame *query.Frame) { t.Helper() got, err := json.MarshalIndent(frame, "", " ") if err != nil { @@ -41,8 +41,8 @@ func assertResourceFrame(t *testing.T, name string, frame *panel.Frame) { } } -func resourcePanels() []panel.Panel { - var panels []panel.Panel +func resourcePanels() []query.Panel { + var panels []query.Panel for _, p := range DefaultSpec().Panels { if p.ID == "versions" || p.ID == "check_states" { panels = append(panels, p) @@ -51,13 +51,13 @@ func resourcePanels() []panel.Panel { return panels } -func executeResourcePanel(t *testing.T, e *panel.Executor, p panel.Panel, start, end time.Time) panel.Result { +func executeResourcePanel(t *testing.T, e *query.Executor, p query.Panel, start, end time.Time) query.Result { t.Helper() - results, err := e.Run(t.Context(), panel.RunRequest{Dashboard: panel.Dashboard{Name: "Resource inventory", Time: panel.Time{From: &start, To: &end}, Panels: []panel.Panel{p}}}) + results, err := e.Run(t.Context(), query.RunRequest{Dashboard: query.Dashboard{Name: "Resource inventory", Time: query.Time{From: &start, To: &end}, Panels: []query.Panel{p}}}) if err != nil { t.Fatal(err) } - if len(results) != 1 || results[0].Status != panel.StatusOK || results[0].Frame == nil { + if len(results) != 1 || results[0].Status != query.StatusOK || results[0].Frame == nil { t.Fatalf("%s result: %+v", p.ID, results) } return results[0] @@ -70,12 +70,12 @@ func TestDefaultResourcePanelsAcrossCacheStates(t *testing.T) { t.Fatal(err) } defer repo.Close() - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } defer d.Close() - e := panel.NewExecutor(d, 30) + e := query.NewExecutor(d, 30) start := time.Date(2026, 10, 1, 12, 0, 0, 1, time.UTC) end := start.Add(2 * time.Minute) for i := range 2 { @@ -106,7 +106,7 @@ func TestDefaultResourcePanelsAcrossCacheStates(t *testing.T) { if _, err := d.DB.Exec(`DELETE FROM read_cache_version`); err != nil { t.Fatal(err) } - if err := query.CreateCacheTables(d.DB); err != nil { + if err := engine.CreateCacheTables(d.DB); err != nil { t.Fatal(err) } } @@ -120,7 +120,7 @@ func TestDefaultResourcePanelsAcrossCacheStates(t *testing.T) { assertResourceFrame(t, p.ID, got.Frame) // A shifted SQL execution carries its own logical inventory window. shifted := p - shifted.Time = &panel.PanelTime{Shift: "1m"} + shifted.Time = &query.TimeOverride{Shift: "1m"} got = executeResourcePanel(t, e, shifted, start, end) assertResourceFrame(t, p.ID+"-shifted", got.Frame) } @@ -135,12 +135,12 @@ func TestDefaultResourceInventoryKeepsVantageNamespacesSeparate(t *testing.T) { t.Fatal(err) } defer repo.Close() - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } defer d.Close() - e := panel.NewExecutor(d, 30) + e := query.NewExecutor(d, 30) start := time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC) end := start.Add(time.Minute) b := telemetrystore.Batch{ID: "namespaces", Spans: []telemetry.Span{{Namespace: "other", ServiceName: "api", StartUnixNanos: start.UnixNano(), Resource: map[string]any{"host.name": "same-host"}}}} @@ -190,12 +190,12 @@ func TestResourceInventoryFrozenSnapshotFrames(t *testing.T) { t.Fatal(err) } defer repo.Close() - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } defer d.Close() - e := panel.NewExecutor(d, 30) + e := query.NewExecutor(d, 30) var engine string if err := d.DB.QueryRow(`SELECT version()`).Scan(&engine); err != nil { t.Fatal(err) @@ -264,7 +264,7 @@ func TestResourceInventoryFrozenSnapshotFrames(t *testing.T) { stats["inventory_rows_by_signal"] = bySignal for _, p := range resourcePanels() { var elapsed []int64 - var want *panel.Frame + var want *query.Frame for i := range 4 { r := executeResourcePanel(t, e, p, start, end) elapsed = append(elapsed, r.ElapsedMS) diff --git a/internal/dashboard/service.go b/internal/dashboard/service.go index 3de6e71b..820eaf50 100644 --- a/internal/dashboard/service.go +++ b/internal/dashboard/service.go @@ -11,7 +11,7 @@ import ( "github.com/labstack/fanout/internal/db/generated" appid "github.com/labstack/fanout/internal/id" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) var ( @@ -23,7 +23,7 @@ var ( // Validator checks a spec completely, including its filters and SQL. // *panel.Executor implements it. type Validator interface { - Validate(ctx context.Context, d *panel.Dashboard) error + Validate(ctx context.Context, d *query.Dashboard) error } type Author struct { @@ -37,7 +37,7 @@ type Record struct { Description string `json:"description"` IsDefault bool `json:"is_default"` Version int `json:"version"` - Spec panel.Dashboard `json:"spec"` + Spec query.Dashboard `json:"spec"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } @@ -45,7 +45,7 @@ type Record struct { // Mutation identifies exactly one committed save and its successful optimistic base. type Mutation struct { Record Record - Before panel.Dashboard + Before query.Dashboard BaseVersion int } @@ -106,13 +106,13 @@ func (s *Service) VersionRecord(ctx context.Context, owner, id string, version i if err != nil { return VersionRecord{}, err } - var spec panel.Dashboard + var spec query.Dashboard if err := json.Unmarshal([]byte(r.SpecJSON), &spec); err != nil { return VersionRecord{}, err } record := Record{ID: r.ID, Name: spec.Name, Description: spec.Description, IsDefault: r.IsDefault == 1, Version: int(r.Version), Spec: spec, CreatedAt: r.DashboardCreatedAt, UpdatedAt: r.VersionCreatedAt} out := VersionRecord{Dashboard: record, AuthorKind: r.AuthorKind, AuthorID: r.AuthorID, Message: r.Message, CreatedAt: r.VersionCreatedAt, Changes: []PanelChange{}, DashboardFields: []string{}} - before := panel.Dashboard{} + before := query.Dashboard{} if version > 1 { prior, err := q.GetDashboardVersionRecord(ctx, generated.GetDashboardVersionRecordParams{DashboardID: id, OwnerID: owner, Version: int64(version - 1)}) if errors.Is(err, sql.ErrNoRows) { @@ -195,19 +195,19 @@ type saveCheckKey struct{} // WithSaveCheck adds a transport-specific check of the exact spec before each // write attempt, including edits retried against a concurrent version. -func WithSaveCheck(ctx context.Context, check func(context.Context, panel.Dashboard) error) context.Context { +func WithSaveCheck(ctx context.Context, check func(context.Context, query.Dashboard) error) context.Context { return context.WithValue(ctx, saveCheckKey{}, check) } // prepare normalizes, validates and packs a spec for storage. -func (s *Service) prepare(ctx context.Context, spec *panel.Dashboard, repack bool) error { - panel.Normalize(spec) +func (s *Service) prepare(ctx context.Context, spec *query.Dashboard, repack bool) error { + query.Normalize(spec) validationCtx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() if err := s.validator.Validate(validationCtx, spec); err != nil { return err } - if check, ok := ctx.Value(saveCheckKey{}).(func(context.Context, panel.Dashboard) error); ok { + if check, ok := ctx.Value(saveCheckKey{}).(func(context.Context, query.Dashboard) error); ok { if err := check(validationCtx, *spec); err != nil { return err } @@ -223,12 +223,12 @@ func (s *Service) prepare(ctx context.Context, spec *panel.Dashboard, repack boo return nil } -func (s *Service) Create(ctx context.Context, ownerID string, spec panel.Dashboard, author Author) (Record, error) { +func (s *Service) Create(ctx context.Context, ownerID string, spec query.Dashboard, author Author) (Record, error) { mutation, err := s.CreateWithChanges(ctx, ownerID, spec, author) return mutation.Record, err } -func (s *Service) CreateWithChanges(ctx context.Context, ownerID string, spec panel.Dashboard, author Author) (Mutation, error) { +func (s *Service) CreateWithChanges(ctx context.Context, ownerID string, spec query.Dashboard, author Author) (Mutation, error) { var err error spec, err = clone(spec) if err != nil { @@ -260,7 +260,7 @@ func (s *Service) CreateWithChanges(ctx context.Context, ownerID string, spec pa return Mutation{}, err } if affected == 0 { - return Mutation{}, panel.Problems{{Path: "dashboards", Message: "at most 500 dashboards per owner; delete a dashboard before creating another"}} + return Mutation{}, query.Problems{{Path: "dashboards", Message: "at most 500 dashboards per owner; delete a dashboard before creating another"}} } if origin, ok := BuildOriginFromContext(ctx); ok { if strings.TrimSpace(origin.ThreadID) == "" || strings.TrimSpace(origin.MessageID) == "" { @@ -293,21 +293,21 @@ func (s *Service) CreateWithChanges(ctx context.Context, ownerID string, spec pa } // Replace stores a whole new spec. baseVersion 0 means "the latest". -func (s *Service) Replace(ctx context.Context, ownerID, id string, spec panel.Dashboard, baseVersion int, author Author, message string) (Record, error) { +func (s *Service) Replace(ctx context.Context, ownerID, id string, spec query.Dashboard, baseVersion int, author Author, message string) (Record, error) { mutation, err := s.ReplaceWithChanges(ctx, ownerID, id, spec, baseVersion, author, message) return mutation.Record, err } -func (s *Service) ReplaceWithChanges(ctx context.Context, ownerID, id string, spec panel.Dashboard, baseVersion int, author Author, message string) (Mutation, error) { - return s.update(ctx, ownerID, id, baseVersion, 0, author, message, func(current panel.Dashboard) (panel.Dashboard, bool, error) { +func (s *Service) ReplaceWithChanges(ctx context.Context, ownerID, id string, spec query.Dashboard, baseVersion int, author Author, message string) (Mutation, error) { + return s.update(ctx, ownerID, id, baseVersion, 0, author, message, func(current query.Dashboard) (query.Dashboard, bool, error) { replacement, err := clone(spec) if err != nil { - return panel.Dashboard{}, false, err + return query.Dashboard{}, false, err } spec := replacement // Carry coordinates by id, including browser-resized dimensions. - grids := map[string]*panel.Grid{} - prior := map[string]panel.Panel{} + grids := map[string]*query.Grid{} + prior := map[string]query.Panel{} for _, p := range current.Panels { grids[p.ID] = p.Grid prior[p.ID] = p @@ -328,7 +328,7 @@ func (s *Service) ReplaceWithChanges(ctx context.Context, ownerID, id string, sp } } if len(spec.Panels) < len(current.Panels) { - panel.Normalize(&spec) + query.Normalize(&spec) Compact(spec.Panels) } return spec, false, nil @@ -342,7 +342,7 @@ func (s *Service) Edit(ctx context.Context, ownerID, id string, ops []Operation, } func (s *Service) EditWithChanges(ctx context.Context, ownerID, id string, ops []Operation, baseVersion int, author Author, message string) (Mutation, error) { - return s.update(ctx, ownerID, id, baseVersion, 0, author, message, func(current panel.Dashboard) (panel.Dashboard, bool, error) { + return s.update(ctx, ownerID, id, baseVersion, 0, author, message, func(current query.Dashboard) (query.Dashboard, bool, error) { return Apply(current, ops) }) } @@ -369,11 +369,11 @@ func (s *Service) RestoreWithChanges(ctx context.Context, ownerID, id string, ve if err != nil { return Mutation{}, err } - var spec panel.Dashboard + var spec query.Dashboard if err := json.Unmarshal([]byte(raw), &spec); err != nil { return Mutation{}, err } - return s.update(ctx, ownerID, id, 0, version, author, fmt.Sprintf("Restored version %d", version), func(panel.Dashboard) (panel.Dashboard, bool, error) { + return s.update(ctx, ownerID, id, 0, version, author, fmt.Sprintf("Restored version %d", version), func(query.Dashboard) (query.Dashboard, bool, error) { return spec, false, nil }) } @@ -382,7 +382,7 @@ func (s *Service) RestoreWithChanges(ctx context.Context, ownerID, id string, ve // check. With baseVersion 0 a concurrent write is retried once on the newer // version; with an explicit baseVersion it fails with ErrStale instead of // overwriting what someone else saved. -func (s *Service) update(ctx context.Context, ownerID, id string, baseVersion, restoreVersion int, author Author, message string, change func(panel.Dashboard) (panel.Dashboard, bool, error)) (Mutation, error) { +func (s *Service) update(ctx context.Context, ownerID, id string, baseVersion, restoreVersion int, author Author, message string, change func(query.Dashboard) (query.Dashboard, bool, error)) (Mutation, error) { for attempt := 0; attempt < 2; attempt++ { current, err := s.get(ctx, ownerID, id) if err != nil { @@ -423,7 +423,7 @@ func (s *Service) update(ctx context.Context, ownerID, id string, baseVersion, r return Mutation{}, ErrStale } -func (s *Service) write(ctx context.Context, ownerID, id string, base int, spec panel.Dashboard, raw string, author Author, message string) (Record, bool, error) { +func (s *Service) write(ctx context.Context, ownerID, id string, base int, spec query.Dashboard, raw string, author Author, message string) (Record, bool, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { return Record{}, false, err diff --git a/internal/dashboard/service_test.go b/internal/dashboard/service_test.go index 66596cf7..cf1cbead 100644 --- a/internal/dashboard/service_test.go +++ b/internal/dashboard/service_test.go @@ -9,17 +9,17 @@ import ( "sync/atomic" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" appstore "github.com/labstack/fanout/internal/store" ) // structural validates without DuckDB; filter checks are covered in -// internal/panel and by TestDefaultSpecPassesTheFullCheck. +// internal/query and by TestDefaultSpecPassesTheFullCheck. type structural struct{} -func (structural) Validate(_ context.Context, d *panel.Dashboard) error { - panel.Normalize(d) - if problems := panel.Validate(d); len(problems) > 0 { +func (structural) Validate(_ context.Context, d *query.Dashboard) error { + query.Normalize(d) + if problems := query.Validate(d); len(problems) > 0 { return problems } return nil @@ -31,7 +31,7 @@ type blockingValidator struct { blocked atomic.Bool } -func (v *blockingValidator) Validate(ctx context.Context, d *panel.Dashboard) error { +func (v *blockingValidator) Validate(ctx context.Context, d *query.Dashboard) error { if d.Panels[0].Content == "first writer" && v.blocked.CompareAndSwap(false, true) { close(v.entered) select { @@ -149,7 +149,7 @@ func TestRestoreMutationUsesSuccessfulOptimisticBase(t *testing.T) { func TestMutationBeforeDoesNotShareNestedFields(t *testing.T) { s := newTestService(t) spec := threePanels() - spec.Panels[0].Thresholds = []panel.Threshold{{Value: 10, Status: "warn"}} + spec.Panels[0].Thresholds = []query.Threshold{{Value: 10, Status: "warn"}} created, err := s.CreateWithChanges(t.Context(), "owner", spec, agent) if err != nil { t.Fatal(err) @@ -157,7 +157,7 @@ func TestMutationBeforeDoesNotShareNestedFields(t *testing.T) { if created.BaseVersion != 0 || !created.Record.IsDefault || len(created.Before.Panels) != 0 || spec.Panels[0].Grid != nil { t.Fatalf("create=%+v input=%+v", created, spec) } - m, err := s.update(t.Context(), "owner", created.Record.ID, 1, 0, agent, "", func(d panel.Dashboard) (panel.Dashboard, bool, error) { + m, err := s.update(t.Context(), "owner", created.Record.ID, 1, 0, agent, "", func(d query.Dashboard) (query.Dashboard, bool, error) { d.Panels[0].Title = "Updated" d.Panels[0].Thresholds[0].Value = 20 d.Panels[0].Grid.X++ @@ -187,8 +187,8 @@ func newTestService(t *testing.T) *Service { return New(sqlite.DB, structural{}) } -func textSpec(name string) panel.Dashboard { - return panel.Dashboard{Name: name, Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} +func textSpec(name string) query.Dashboard { + return query.Dashboard{Name: name, Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} } var agent = Author{Kind: "agent", ID: "owner"} @@ -251,7 +251,7 @@ func TestOwnershipNamesAndValidation(t *testing.T) { } bad := textSpec("Bad") bad.Panels[0].Viz = "piechart" - var problems panel.Problems + var problems query.Problems if _, err := s.Create(t.Context(), "owner", bad, agent); !errors.As(err, &problems) { t.Fatalf("invalid spec err = %v", err) } @@ -264,8 +264,8 @@ func TestOwnershipNamesAndValidation(t *testing.T) { } } -func threePanels() panel.Dashboard { - return panel.Dashboard{Name: "Layout", Panels: []panel.Panel{ +func threePanels() query.Dashboard { + return query.Dashboard{Name: "Layout", Panels: []query.Panel{ {ID: "a", Title: "A", Viz: "text", Content: "a", Width: 6, Height: "s"}, {ID: "b", Title: "B", Viz: "text", Content: "b", Width: 6, Height: "s"}, {ID: "c", Title: "C", Viz: "text", Content: "c", Width: 12, Height: "s"}, @@ -280,17 +280,17 @@ func TestReplaceRepacksOnlyWhenLayoutChanges(t *testing.T) { } // Removing a panel leaves no hole. removed := created.Spec - removed.Panels = []panel.Panel{removed.Panels[0], removed.Panels[2]} + removed.Panels = []query.Panel{removed.Panels[0], removed.Panels[2]} rec, err := s.Replace(t.Context(), "owner", created.ID, removed, 1, agent, "") if err != nil { t.Fatal(err) } - if g := *rec.Spec.Panels[1].Grid; g != (panel.Grid{X: 0, Y: 3, W: 12, H: 3}) { + if g := *rec.Spec.Panels[1].Grid; g != (query.Grid{X: 0, Y: 3, W: 12, H: 3}) { t.Fatalf("after removal c = %+v", g) } // A width change takes effect. wide := rec.Spec - wide.Panels = append([]panel.Panel(nil), wide.Panels...) + wide.Panels = append([]query.Panel(nil), wide.Panels...) wide.Panels[0].Width = 12 rec, err = s.Replace(t.Context(), "owner", created.ID, wide, 2, agent, "") if err != nil || rec.Spec.Panels[0].Grid.W != 12 { @@ -298,10 +298,10 @@ func TestReplaceRepacksOnlyWhenLayoutChanges(t *testing.T) { } // Same ids and sizes with moved grids keep their coordinates. moved := rec.Spec - moved.Panels = append([]panel.Panel(nil), moved.Panels...) - moved.Panels[1].Grid = &panel.Grid{X: 0, Y: 8, W: 12, H: 3} + moved.Panels = append([]query.Panel(nil), moved.Panels...) + moved.Panels[1].Grid = &query.Grid{X: 0, Y: 8, W: 12, H: 3} rec, err = s.Replace(t.Context(), "owner", created.ID, moved, 3, agent, "") - if err != nil || *rec.Spec.Panels[1].Grid != (panel.Grid{X: 0, Y: 8, W: 12, H: 3}) { + if err != nil || *rec.Spec.Panels[1].Grid != (query.Grid{X: 0, Y: 8, W: 12, H: 3}) { t.Fatalf("layout save = %+v err %v", rec.Spec.Panels[1].Grid, err) } } diff --git a/internal/dashboard/write_constraints_test.go b/internal/dashboard/write_constraints_test.go index acc43f9e..f04a50fb 100644 --- a/internal/dashboard/write_constraints_test.go +++ b/internal/dashboard/write_constraints_test.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "strings" "sync" "testing" @@ -16,7 +16,7 @@ type deadlineValidator struct { seen bool } -func (v *deadlineValidator) Validate(ctx context.Context, _ *panel.Dashboard) error { +func (v *deadlineValidator) Validate(ctx context.Context, _ *query.Dashboard) error { deadline, ok := ctx.Deadline() v.seen = true if !ok || time.Until(deadline) > 20*time.Second || time.Until(deadline) < 19*time.Second { @@ -66,8 +66,8 @@ func TestRemoveAndReplacePreserveGrid(t *testing.T) { if err != nil { t.Fatal(err) } - r.Spec.Panels[0].Grid = &panel.Grid{X: 0, Y: 0, W: 8, H: 3} - r.Spec.Panels[1].Grid = &panel.Grid{X: 8, Y: 0, W: 4, H: 3} + r.Spec.Panels[0].Grid = &query.Grid{X: 0, Y: 0, W: 8, H: 3} + r.Spec.Panels[1].Grid = &query.Grid{X: 8, Y: 0, W: 4, H: 3} r, err = s.Replace(t.Context(), "owner", r.ID, r.Spec, 1, Author{Kind: "user"}, "Widen A") if err != nil { t.Fatal(err) @@ -76,7 +76,7 @@ func TestRemoveAndReplacePreserveGrid(t *testing.T) { if err != nil { t.Fatal(err) } - if *r.Spec.Panels[0].Grid != (panel.Grid{X: 0, Y: 0, W: 8, H: 3}) || *r.Spec.Panels[1].Grid != (panel.Grid{X: 0, Y: 3, W: 12, H: 3}) { + if *r.Spec.Panels[0].Grid != (query.Grid{X: 0, Y: 0, W: 8, H: 3}) || *r.Spec.Panels[1].Grid != (query.Grid{X: 0, Y: 3, W: 12, H: 3}) { t.Fatalf("removed layout=%+v %+v", r.Spec.Panels[0].Grid, r.Spec.Panels[1].Grid) } for i := range r.Spec.Panels { @@ -95,7 +95,7 @@ func TestDashboardOwnerLimit(t *testing.T) { } } _, err := s.Create(t.Context(), "owner", textSpec("overflow"), agent) - var p panel.Problems + var p query.Problems if !errors.As(err, &p) || !strings.Contains(p.Error(), "500") { t.Fatalf("limit error=%v", err) } @@ -116,7 +116,7 @@ func TestConcurrentCreatesRespectOwnerLimit(t *testing.T) { for i := range 16 { wg.Go(func() { _, err := s.Create(t.Context(), "owner", textSpec(fmt.Sprintf("last%d", i)), agent) - var p panel.Problems + var p query.Problems if err != nil && !errors.As(err, &p) { t.Errorf("create error=%v", err) } @@ -139,9 +139,9 @@ func TestConcurrentCreatesRespectOwnerLimit(t *testing.T) { func TestReplaceWithoutGridsKeepsExistingLayout(t *testing.T) { s := newTestService(t) spec := threePanels() - spec.Panels[0].Grid = &panel.Grid{X: 1, Y: 0, W: 8, H: 4} - spec.Panels[1].Grid = &panel.Grid{X: 9, Y: 0, W: 3, H: 3} - spec.Panels[2].Grid = &panel.Grid{X: 0, Y: 4, W: 12, H: 3} + spec.Panels[0].Grid = &query.Grid{X: 1, Y: 0, W: 8, H: 4} + spec.Panels[1].Grid = &query.Grid{X: 9, Y: 0, W: 3, H: 3} + spec.Panels[2].Grid = &query.Grid{X: 0, Y: 4, W: 12, H: 3} r, err := s.Create(t.Context(), "owner", spec, agent) if err != nil { t.Fatal(err) @@ -153,7 +153,7 @@ func TestReplaceWithoutGridsKeepsExistingLayout(t *testing.T) { if err != nil { t.Fatal(err) } - if *r.Spec.Panels[0].Grid != (panel.Grid{X: 1, Y: 0, W: 8, H: 4}) { + if *r.Spec.Panels[0].Grid != (query.Grid{X: 1, Y: 0, W: 8, H: 4}) { t.Fatalf("carryover grid=%+v", r.Spec.Panels[0].Grid) } } diff --git a/internal/db/generated/alerts.sql.go b/internal/db/generated/alerts.sql.go index fe935fa8..edf1a9a0 100644 --- a/internal/db/generated/alerts.sql.go +++ b/internal/db/generated/alerts.sql.go @@ -67,7 +67,7 @@ func (q *Queries) DeleteAlertsByRuleIDAndState(ctx context.Context, arg DeleteAl } const getAlert = `-- name: GetAlert :one -SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE rule_id = ? AND service = ? +SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE rule_id = ? AND service = ? ` type GetAlertParams struct { @@ -87,7 +87,7 @@ func (q *Queries) GetAlert(ctx context.Context, arg GetAlertParams) (Alert, erro &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, @@ -96,7 +96,7 @@ func (q *Queries) GetAlert(ctx context.Context, arg GetAlertParams) (Alert, erro } const listAlerts = `-- name: ListAlerts :many -SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at FROM alerts ORDER BY created_at DESC +SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at FROM alerts ORDER BY created_at DESC ` func (q *Queries) ListAlerts(ctx context.Context) ([]Alert, error) { @@ -117,7 +117,7 @@ func (q *Queries) ListAlerts(ctx context.Context) ([]Alert, error) { &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, @@ -136,7 +136,7 @@ func (q *Queries) ListAlerts(ctx context.Context) ([]Alert, error) { } const listAlertsByRuleID = `-- name: ListAlertsByRuleID :many -SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE rule_id = ? ORDER BY created_at DESC +SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE rule_id = ? ORDER BY created_at DESC ` func (q *Queries) ListAlertsByRuleID(ctx context.Context, ruleID string) ([]Alert, error) { @@ -157,7 +157,7 @@ func (q *Queries) ListAlertsByRuleID(ctx context.Context, ruleID string) ([]Aler &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, @@ -176,7 +176,7 @@ func (q *Queries) ListAlertsByRuleID(ctx context.Context, ruleID string) ([]Aler } const listAlertsByService = `-- name: ListAlertsByService :many -SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE service = ? ORDER BY created_at DESC +SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE service = ? ORDER BY created_at DESC ` func (q *Queries) ListAlertsByService(ctx context.Context, service string) ([]Alert, error) { @@ -197,7 +197,7 @@ func (q *Queries) ListAlertsByService(ctx context.Context, service string) ([]Al &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, @@ -216,7 +216,7 @@ func (q *Queries) ListAlertsByService(ctx context.Context, service string) ([]Al } const listAlertsByState = `-- name: ListAlertsByState :many -SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE state = ? ORDER BY created_at DESC +SELECT id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at FROM alerts WHERE state = ? ORDER BY created_at DESC ` func (q *Queries) ListAlertsByState(ctx context.Context, state string) ([]Alert, error) { @@ -237,7 +237,7 @@ func (q *Queries) ListAlertsByState(ctx context.Context, state string) ([]Alert, &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, @@ -288,7 +288,7 @@ func (q *Queries) UpdateDeliveryStatus(ctx context.Context, arg UpdateDeliverySt const upsertAlert = `-- name: UpsertAlert :one INSERT INTO alerts ( id, rule_id, service, state, value, fired_at, resolved_at, - repeated_at, last_eval, last_delivery_status, last_delivery_at + repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(rule_id, service) DO UPDATE SET state = excluded.state, @@ -296,10 +296,10 @@ ON CONFLICT(rule_id, service) DO UPDATE SET fired_at = excluded.fired_at, resolved_at = excluded.resolved_at, repeated_at = excluded.repeated_at, - last_eval = excluded.last_eval, + last_evaluated_at = excluded.last_evaluated_at, last_delivery_status = excluded.last_delivery_status, last_delivery_at = excluded.last_delivery_at -RETURNING id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_eval, last_delivery_status, last_delivery_at, created_at +RETURNING id, rule_id, service, state, value, fired_at, resolved_at, repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at, created_at ` type UpsertAlertParams struct { @@ -311,7 +311,7 @@ type UpsertAlertParams struct { FiredAt sql.NullString `json:"fired_at"` ResolvedAt sql.NullString `json:"resolved_at"` RepeatedAt sql.NullString `json:"repeated_at"` - LastEval sql.NullString `json:"last_eval"` + LastEvaluatedAt sql.NullString `json:"last_evaluated_at"` LastDeliveryStatus sql.NullString `json:"last_delivery_status"` LastDeliveryAt sql.NullString `json:"last_delivery_at"` } @@ -326,7 +326,7 @@ func (q *Queries) UpsertAlert(ctx context.Context, arg UpsertAlertParams) (Alert arg.FiredAt, arg.ResolvedAt, arg.RepeatedAt, - arg.LastEval, + arg.LastEvaluatedAt, arg.LastDeliveryStatus, arg.LastDeliveryAt, ) @@ -340,7 +340,7 @@ func (q *Queries) UpsertAlert(ctx context.Context, arg UpsertAlertParams) (Alert &i.FiredAt, &i.ResolvedAt, &i.RepeatedAt, - &i.LastEval, + &i.LastEvaluatedAt, &i.LastDeliveryStatus, &i.LastDeliveryAt, &i.CreatedAt, diff --git a/internal/db/generated/models.go b/internal/db/generated/models.go index f4de3145..99e91c30 100644 --- a/internal/db/generated/models.go +++ b/internal/db/generated/models.go @@ -39,7 +39,7 @@ type Alert struct { FiredAt sql.NullString `json:"fired_at"` ResolvedAt sql.NullString `json:"resolved_at"` RepeatedAt sql.NullString `json:"repeated_at"` - LastEval sql.NullString `json:"last_eval"` + LastEvaluatedAt sql.NullString `json:"last_evaluated_at"` LastDeliveryStatus sql.NullString `json:"last_delivery_status"` LastDeliveryAt sql.NullString `json:"last_delivery_at"` CreatedAt string `json:"created_at"` diff --git a/internal/db/migrations/20261030000000_alert_last_evaluated_at.sql b/internal/db/migrations/20261030000000_alert_last_evaluated_at.sql new file mode 100644 index 00000000..714a469e --- /dev/null +++ b/internal/db/migrations/20261030000000_alert_last_evaluated_at.sql @@ -0,0 +1,2 @@ +-- +goose Up +ALTER TABLE alerts RENAME COLUMN last_eval TO last_evaluated_at; diff --git a/internal/db/migrations_test.go b/internal/db/migrations_test.go index 065df77c..503e47d6 100644 --- a/internal/db/migrations_test.go +++ b/internal/db/migrations_test.go @@ -11,10 +11,11 @@ import ( // never change or remove a checksum for a migration already published. func TestMigrationChecksums(t *testing.T) { checksums := map[string]string{ - "migrations/20260930000000_initial.sql": "2f256d45df0a604c198e165af00b66f63d9f36b13e27f2898c485da524883203", - "migrations/20261004000000_dashboard_specs.sql": "11894224e7c3ef0efcacae9a6f5f8f6d4af27ddd81ed8868b96b44fb9bbf7d36", - "migrations/20261008000001_dashboard_origins.sql": "6e7e89adf6e51633da0d73b052b12eec08ae3e7dd21ca315a4ac2fecfa703501", - "migrations/20261009000000_user_profile_status.sql": "aed4c0a316a5fb67b1e60c82d45c6b3ec34a2fbb44721ef772f6b5d3df546659", + "migrations/20260930000000_initial.sql": "2f256d45df0a604c198e165af00b66f63d9f36b13e27f2898c485da524883203", + "migrations/20261004000000_dashboard_specs.sql": "11894224e7c3ef0efcacae9a6f5f8f6d4af27ddd81ed8868b96b44fb9bbf7d36", + "migrations/20261008000001_dashboard_origins.sql": "6e7e89adf6e51633da0d73b052b12eec08ae3e7dd21ca315a4ac2fecfa703501", + "migrations/20261009000000_user_profile_status.sql": "aed4c0a316a5fb67b1e60c82d45c6b3ec34a2fbb44721ef772f6b5d3df546659", + "migrations/20261030000000_alert_last_evaluated_at.sql": "577ef95a1964aebf72d8ecb9610c310910121f7bb735dbb287966525b2fb537a", } paths, err := fs.Glob(migrationsFS, "migrations/*.sql") if err != nil { diff --git a/internal/db/queries/alerts.sql b/internal/db/queries/alerts.sql index b15e17cd..430d5d56 100644 --- a/internal/db/queries/alerts.sql +++ b/internal/db/queries/alerts.sql @@ -16,7 +16,7 @@ SELECT * FROM alerts WHERE rule_id = ? ORDER BY created_at DESC; -- name: UpsertAlert :one INSERT INTO alerts ( id, rule_id, service, state, value, fired_at, resolved_at, - repeated_at, last_eval, last_delivery_status, last_delivery_at + repeated_at, last_evaluated_at, last_delivery_status, last_delivery_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(rule_id, service) DO UPDATE SET state = excluded.state, @@ -24,7 +24,7 @@ ON CONFLICT(rule_id, service) DO UPDATE SET fired_at = excluded.fired_at, resolved_at = excluded.resolved_at, repeated_at = excluded.repeated_at, - last_eval = excluded.last_eval, + last_evaluated_at = excluded.last_evaluated_at, last_delivery_status = excluded.last_delivery_status, last_delivery_at = excluded.last_delivery_at RETURNING *; diff --git a/internal/query/analytical_backlog_test.go b/internal/engine/analytical_backlog_test.go similarity index 99% rename from internal/query/analytical_backlog_test.go rename to internal/engine/analytical_backlog_test.go index 24856c72..c2d60325 100644 --- a/internal/query/analytical_backlog_test.go +++ b/internal/engine/analytical_backlog_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -8,7 +8,7 @@ import ( "time" "github.com/labstack/fanout/internal/annotations" - "github.com/labstack/fanout/internal/query/writegate" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) diff --git a/internal/query/annotation_maintenance_test.go b/internal/engine/annotation_maintenance_test.go similarity index 99% rename from internal/query/annotation_maintenance_test.go rename to internal/engine/annotation_maintenance_test.go index d08d99d5..4fae97d2 100644 --- a/internal/query/annotation_maintenance_test.go +++ b/internal/engine/annotation_maintenance_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "bytes" @@ -15,8 +15,8 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/labstack/fanout/internal/annotations" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" "github.com/prometheus/client_golang/prometheus/testutil" diff --git a/internal/query/annotations.go b/internal/engine/annotations.go similarity index 99% rename from internal/query/annotations.go rename to internal/engine/annotations.go index 736c5473..25a463ec 100644 --- a/internal/query/annotations.go +++ b/internal/engine/annotations.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -12,8 +12,8 @@ import ( "time" "github.com/labstack/fanout/internal/annotations" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/labstack/fanout/internal/telemetry" ) diff --git a/internal/query/annotations_test.go b/internal/engine/annotations_test.go similarity index 99% rename from internal/query/annotations_test.go rename to internal/engine/annotations_test.go index a40b42ce..70c157bc 100644 --- a/internal/query/annotations_test.go +++ b/internal/engine/annotations_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/attr_variant_test.go b/internal/engine/attr_variant_test.go similarity index 99% rename from internal/query/attr_variant_test.go rename to internal/engine/attr_variant_test.go index c03d2c19..85c054ea 100644 --- a/internal/query/attr_variant_test.go +++ b/internal/engine/attr_variant_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/background_admission_test.go b/internal/engine/background_admission_test.go similarity index 99% rename from internal/query/background_admission_test.go rename to internal/engine/background_admission_test.go index 4123d5f5..51d9e104 100644 --- a/internal/query/background_admission_test.go +++ b/internal/engine/background_admission_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/engine/backlog_pressure_test.go b/internal/engine/backlog_pressure_test.go new file mode 100644 index 00000000..e99056fb --- /dev/null +++ b/internal/engine/backlog_pressure_test.go @@ -0,0 +1,423 @@ +//go:build readbench + +package engine + +import ( + "context" + "errors" + "fmt" + "github.com/DATA-DOG/go-sqlmock" + "log/slog" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" + "syscall" + "testing" + "time" + + duckdb "github.com/duckdb/duckdb-go/v2" + "github.com/labstack/fanout/internal/annotations" + "github.com/labstack/fanout/internal/config" + "github.com/labstack/fanout/internal/engine/writegate" + "github.com/labstack/fanout/internal/telemetry" + telemetrystore "github.com/labstack/fanout/internal/telemetry/store" + "github.com/prometheus/client_golang/prometheus" +) + +// The deadline includes seeding. All disposable files stay in the private workspace. +func pressureBatches(t *testing.T) int { + t.Helper() + if raw := os.Getenv("FANOUT_BACKLOG_BATCHES"); raw != "" { + n, err := strconv.Atoi(raw) + if err != nil || n < 1 { + t.Fatalf("invalid FANOUT_BACKLOG_BATCHES %q", raw) + } + return n + } + return 4096 +} +func pressureDuration(t *testing.T) time.Duration { + t.Helper() + if raw := os.Getenv("FANOUT_BACKLOG_DURATION"); raw != "" { + d, err := time.ParseDuration(raw) + if err != nil || d <= 0 { + t.Fatalf("invalid FANOUT_BACKLOG_DURATION %q", raw) + } + return d + } + return 2 * time.Minute +} +func pressureBatch(batch int, base time.Time, live bool) telemetrystore.Batch { + prefix := "pressure" + if live { + prefix = "live" + } + b := telemetrystore.Batch{ID: fmt.Sprintf("%s-%06d", prefix, batch)} + for i := range 512 { + n := base.Add(-24*time.Hour + time.Duration((batch*512+i)%86400)*time.Second).UnixNano() + ingested := base.Add(time.Duration(batch) * time.Millisecond).UnixNano() + if live { + n = base.Add(-time.Second).UnixNano() + if batch%2 == 0 { + n = base.Add(-12 * time.Hour).UnixNano() + } + ingested = base.Add(time.Duration(batch+1) * time.Second).UnixNano() + } + version := "v1" + if i%2 == 0 { + version = "v2" + } + service := fmt.Sprintf("svc%d", i%6) + trace := fmt.Sprintf("%s-trace-%d-%d", prefix, batch, i/4) + b.Spans = append(b.Spans, telemetry.Span{Namespace: "pressure", ServiceName: service, TraceID: trace, SpanID: fmt.Sprintf("s%d", i), StartUnixNanos: n, EndUnixNanos: n + int64(i%1000+1)*1000000, DurationMS: float64(i%1000 + 1), Kind: "SPAN_KIND_SERVER", StatusCode: "STATUS_CODE_OK", ServiceVersion: version, IngestedAt: ingested}) + if i < 192 { + b.Logs = append(b.Logs, telemetry.Log{Namespace: "pressure", ServiceName: service, TraceID: trace, EventUnixNanos: n, TimeUnixNanos: n, IngestedAt: ingested, Body: "request complete", Severity: "INFO"}) + } + } + return b +} +func pressureError(t *testing.T, label string, started time.Time, err error) { + t.Helper() + var native *duckdb.Error + typed := errors.As(err, &native) + kind := "none" + if typed { + kind = fmt.Sprint(native.Type) + } + t.Logf("statement=%s started=%s ended=%s duration=%s error=%v native_type=%s canceled=%t deadline=%t", label, started.UTC().Format(time.RFC3339Nano), time.Now().UTC().Format(time.RFC3339Nano), time.Since(started), err, kind, errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded)) +} + +type pressureLog struct{ t *testing.T } + +func (h pressureLog) Enabled(context.Context, slog.Level) bool { return true } +func (h pressureLog) Handle(_ context.Context, r slog.Record) error { + h.t.Logf("internal_log time=%s level=%s message=%q", r.Time.UTC().Format(time.RFC3339Nano), r.Level, r.Message) + r.Attrs(func(a slog.Attr) bool { + if err, ok := a.Value.Any().(error); ok { + pressureError(h.t, "internal_log/"+r.Message, r.Time, err) + } else { + h.t.Logf("internal_attr %s=%v", a.Key, a.Value) + } + return true + }) + return nil +} +func (h pressureLog) WithAttrs([]slog.Attr) slog.Handler { return h } +func (h pressureLog) WithGroup(string) slog.Handler { return h } + +// Same /proc + ps methodology as processRSSMiB, but unsupported diagnostics +// are reported as inconclusive rather than skipping a pressure test. +var pressureRSSState struct { + sync.Mutex + blocked error +} + +func pressureRSS() (float64, error) { + pressureRSSState.Lock() + defer pressureRSSState.Unlock() + if pressureRSSState.blocked != nil { + return 0, pressureRSSState.blocked + } + if raw, err := os.ReadFile("/proc/self/statm"); err == nil { + f := strings.Fields(string(raw)) + if len(f) > 1 { + n, e := strconv.ParseFloat(f[1], 64) + return n * float64(os.Getpagesize()) / (1 << 20), e + } + } + raw, err := exec.Command("ps", "-o", "rss=", "-p", strconv.Itoa(os.Getpid())).Output() + if err != nil { + pressureRSSState.blocked = err + return 0, err + } + n, err := strconv.ParseFloat(strings.TrimSpace(string(raw)), 64) + return n / 1024, err +} +func pressureDiagnostics(ctx context.Context, t *testing.T, d *Duck, repo *telemetrystore.Repository, phase string) { + t.Helper() + stats := d.DB.Stats() + t.Logf("write_pool phase=%s stats=%+v", phase, d.writeDB.Stats()) + var usage syscall.Rusage + cpuErr := syscall.Getrusage(syscall.RUSAGE_SELF, &usage) + cpuSeconds := float64(usage.Utime.Sec+usage.Stime.Sec) + float64(usage.Utime.Usec+usage.Stime.Usec)/1e6 + t.Logf("cpu phase=%s seconds=%.6f error=%v", phase, cpuSeconds, cpuErr) + rss, rssErr := pressureRSS() + var goMem runtime.MemStats + runtime.ReadMemStats(&goMem) + t.Logf("diagnostics phase=%s platform=%s/%s cpus=%d rss_mib=%.2f rss_error=%v go_heap_bytes=%d go_total_alloc_bytes=%d read_pool=%+v", phase, runtime.GOOS, runtime.GOARCH, runtime.NumCPU(), rss, rssErr, goMem.HeapAlloc, goMem.TotalAlloc, stats) + files, err := repo.Parquet.Stats() + t.Logf("files phase=%s stats=%+v error=%v active_batches=%d rows=%d", phase, files, err, len(repo.Parquet.BatchMetadata()), repo.RowCount()) + // Never queue diagnostics behind the pressure workers. Five read slots are + // fixed for all phases; busy samples are recorded and retried between phases. + if stats.InUse >= stats.MaxOpenConnections { + t.Logf("diagnostics phase=%s sql_sample=busy", phase) + return + } + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + for _, q := range []string{ + "SELECT version(),current_setting('memory_limit'),current_setting('threads'),current_setting('temp_directory')<>''", + "SELECT tag,memory_usage_bytes,temporary_storage_bytes FROM duckdb_memory() ORDER BY tag", + "SELECT coalesce(sum(size),0) FROM duckdb_temporary_files()", + "SELECT cache_key,last_ingested_unix_nano FROM rollup_state ORDER BY cache_key", + "SELECT (SELECT count(*) FROM read_batches),(SELECT count(*) FROM version_rollup_batches),(SELECT count(*) FROM version_rollup),(SELECT count(*) FROM anomaly_log)", + } { + rows, err := d.DB.QueryContext(ctx, q) + if err != nil { + pressureError(t, "diagnostics/"+q, time.Now(), err) + continue + } + cols, err := rows.Columns() + if err != nil { + rows.Close() + t.Logf("diagnostic_columns error=%v", err) + continue + } + for rows.Next() { + v := make([]any, len(cols)) + p := make([]any, len(cols)) + for i := range v { + p[i] = &v[i] + } + if err := rows.Scan(p...); err != nil { + t.Logf("diagnostic_scan error=%v", err) + break + } + t.Logf("diagnostic phase=%s columns=%v values=%v", phase, cols, v) + } + if err := rows.Err(); err != nil { + pressureError(t, "diagnostics/rows", time.Now(), err) + } + rows.Close() + } + families, err := prometheus.DefaultGatherer.Gather() + if err != nil { + t.Logf("metrics error=%v", err) + return + } + for _, f := range families { + if f.GetName() == "fanout_write_gate_wait_seconds" || f.GetName() == "fanout_write_gate_hold_seconds" { + for _, m := range f.Metric { + t.Logf("gate phase=%s metric=%s labels=%v count=%d seconds_sum=%.6f", phase, f.GetName(), m.Label, m.GetHistogram().GetSampleCount(), m.GetHistogram().GetSampleSum()) + } + } + } +} + +func pressureDuck(ctx context.Context, t *testing.T, batches int) (*Duck, *telemetrystore.Repository, time.Time) { + t.Helper() + root, err := filepath.Abs(filepath.Join("..", "..", ".cache", "readbench")) + if err != nil { + t.Fatal(err) + } + if err := os.MkdirAll(root, 0755); err != nil { + t.Fatal(err) + } + dir, err := os.MkdirTemp(root, "pressure-") + if err != nil { + t.Fatal(err) + } + t.Logf("scratch_state=%s", dir) + base := time.Now().UTC().Truncate(time.Minute) + cfg := config.Config{DataDir: dir, RetentionDays: 30, DuckDBMemory: "4GB", DuckDBThreads: 4, DuckDBMaxConns: 5, RollupInterval: time.Second} + repo, err := telemetrystore.Open(cfg.TelemetryDir()) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if err := repo.Close(); err != nil { + t.Errorf("repository close: %v", err) + } + }) + started := time.Now() + seeded := 0 + defer func() { + if seeded != batches { + t.Logf("seed_duration=%s seed_batches=%d requested=%d seed_incomplete=true", time.Since(started), seeded, batches) + } + }() + for batch := range batches { + if err := ctx.Err(); err != nil { + t.Fatal(err) + } + if err := repo.Commit(ctx, pressureBatch(batch, base, false)); err != nil { + t.Fatal(err) + } + seeded++ + if seeded%256 == 0 { + t.Logf("seed_progress batches=%d duration=%s", seeded, time.Since(started)) + } + } + t.Logf("seed_complete duration=%s spans=%d logs=%d", time.Since(started), batches*512, batches*192) + opened := time.Now() + d, err := NewDuck(ctx, cfg, repo) + pressureError(t, "NewDuck", opened, err) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if err := d.Close(); err != nil { + t.Errorf("engine close: %v", err) + } + }) + return d, repo, base +} + +// This controls statement attribution; the panel-package combined phase is +// the authoritative reproduction. Run each batch size in a separate process. +func TestBacklogPressureRecordsConcurrentStatementFailures(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), 30*time.Minute) + defer cancel() + d, repo, base := pressureDuck(ctx, t, pressureBatches(t)) + logger := slog.Default() + slog.SetDefault(slog.New(pressureLog{t})) + defer slog.SetDefault(logger) + pressureDiagnostics(ctx, t, d, repo, "before_service_alone") + started := time.Now() + n, err := d.refreshServiceRollup(ctx) + pressureError(t, "service_rollup/solo", started, err) + t.Logf("service_solo rows=%d", n) + pressureDiagnostics(ctx, t, d, repo, "after_service_alone") + started = time.Now() + n, err = d.refreshEdgeRollup(ctx) + pressureError(t, "edge_rollup/solo", started, err) + t.Logf("edge_solo rows=%d", n) + pressureDiagnostics(ctx, t, d, repo, "after_edge_alone") + ready := make(chan struct{}) + var wg sync.WaitGroup + wg.Add(2) + go func() { defer wg.Done(); <-ready; d.RunRollups(ctx) }() + go func() { + defer wg.Done() + <-ready + for batch := range 32 { + started := time.Now() + err := repo.Commit(ctx, pressureBatch(batch, base, true)) + pressureError(t, "publication", started, err) + if err != nil { + return + } + } + }() + close(ready) + timer := time.NewTimer(pressureDuration(t)) + select { + case <-timer.C: + case <-ctx.Done(): + } + timer.Stop() + cancel() + wg.Wait() + pressureDiagnostics(t.Context(), t, d, repo, "after_loop_publication") + t.Log("outcome=diagnostic_only; query probe does not establish panel robustness") +} + +// Existing rollupOnce only labels the component, losing which of its two +// expensive statements failed. Attribution must retain the native cause. +func TestBacklogServiceFailuresIdentifyStatementAndPreserveCause(t *testing.T) { + for _, label := range []string{"service_rollup/delete", "service_rollup/insert"} { + t.Run(label, func(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatal(err) + } + defer db.Close() + cause := &duckdb.Error{Type: duckdb.ErrorTypeOutOfMemory, Msg: "Out of Memory Error: attribution fixture"} + for _, key := range []string{serviceRollupStateKey} { + mock.ExpectQuery("FROM rollup_state").WithArgs(key).WillReturnRows(sqlmock.NewRows([]string{"watermark"}).AddRow(1)) + } + mock.ExpectBegin() + mock.ExpectExec("CREATE OR REPLACE TEMP TABLE service_pass_affected").WillReturnResult(sqlmock.NewResult(0, 0)) + mock.ExpectQuery("SELECT epoch_ns").WillReturnRows(sqlmock.NewRows([]string{"lo", "hi"}).AddRow(0, 60_000_000_000)) + if label == "service_rollup/delete" { + mock.ExpectExec("DELETE FROM service_rollup").WillReturnError(cause) + } else { + mock.ExpectExec("DELETE FROM service_rollup").WillReturnResult(sqlmock.NewResult(0, 0)) + mock.ExpectExec("WITH span_agg").WillReturnError(cause) + } + mock.ExpectRollback() + d := &Duck{DB: db, writeDB: db, publicationBounds: func() (int64, int64, int64) { return 2, 2, 1 }} + _, err = d.refreshServiceRollup(t.Context()) + var native *duckdb.Error + if err == nil || !strings.Contains(err.Error(), label) || !errors.Is(err, cause) || !errors.As(err, &native) || native != cause { + t.Fatalf("statement attribution/cause lost: %v", err) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestBacklogAnnotationFailuresIdentifyStatementAndPreserveCause(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), time.Minute) + defer cancel() + _, repo, _ := pressureDuck(ctx, t, 1) + for _, label := range []string{"version_rollup/insert", "anomaly_log/bounds", "anomaly_log/insert"} { + t.Run(label, func(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatal(err) + } + defer db.Close() + cause := &duckdb.Error{Type: duckdb.ErrorTypeOutOfMemory, Msg: "Out of Memory Error: attribution fixture"} + d := &Duck{DB: db, writeDB: db, repository: repo} + if label == "version_rollup/insert" { + mock.ExpectQuery("SELECT batch_id FROM version_rollup_batches").WillReturnRows(sqlmock.NewRows([]string{"batch_id"})) + mock.ExpectBegin() + mock.ExpectExec("INSERT INTO version_rollup SELECT").WillReturnError(cause) + mock.ExpectRollback() + _, err = d.RefreshVersionRollup(ctx) + } else { + mock.ExpectBegin() + if label == "anomaly_log/bounds" { + mock.ExpectExec("CREATE TEMP TABLE annotation_bounds").WillReturnError(cause) + } else { + mock.ExpectExec("CREATE TEMP TABLE annotation_bounds").WillReturnResult(sqlmock.NewResult(0, 0)) + mock.ExpectQuery("SELECT a.namespace").WillReturnRows(sqlmock.NewRows([]string{"namespace", "service", "kind", "start", "end", "title", "severity"})) + for _, q := range []string{"CREATE TEMP TABLE annotation_updates", "CREATE TEMP TABLE annotation_candidates"} { + mock.ExpectExec(q).WillReturnResult(sqlmock.NewResult(0, 0)) + } + mock.ExpectQuery("SELECT count").WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) + mock.ExpectExec("DELETE FROM anomaly_log").WillReturnResult(sqlmock.NewResult(0, 0)) + mock.ExpectExec("INSERT INTO anomaly_log").WillReturnError(cause) + } + mock.ExpectRollback() + now := time.Now().UTC() + err = d.RecordAnomalies(ctx, []annotations.Anomaly{{Namespace: "pressure", Service: "svc0", Kind: "latency", From: now.Add(-time.Minute), To: now, Title: "Attribution", Severity: "warning"}}, now) + } + var native *duckdb.Error + if err == nil || !strings.Contains(err.Error(), label) || !errors.Is(err, cause) || !errors.As(err, &native) || native != cause { + t.Fatalf("statement attribution/cause lost: %v", err) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestBacklogAnnotationTimeoutsIdentifyWriteGateAndPreserveDeadline(t *testing.T) { + for _, label := range []string{"version_rollup/write_gate", "anomaly_log/write_gate"} { + t.Run(label, func(t *testing.T) { + d := &Duck{repository: &telemetrystore.Repository{}} + unlock := d.writeGate.Lock(writegate.RollupService) + defer unlock() + ctx, cancel := context.WithTimeout(t.Context(), 20*time.Millisecond) + defer cancel() + var err error + if label == "version_rollup/write_gate" { + _, err = d.RefreshVersionRollup(ctx) + } else { + err = d.RecordAnomalies(ctx, nil, time.Now()) + } + if err == nil || !strings.Contains(err.Error(), label) || !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("gate attribution/deadline lost: %v", err) + } + }) + } +} diff --git a/internal/query/batch_cache.go b/internal/engine/batch_cache.go similarity index 99% rename from internal/query/batch_cache.go rename to internal/engine/batch_cache.go index 9578f2fd..bebfa9f8 100644 --- a/internal/query/batch_cache.go +++ b/internal/engine/batch_cache.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -9,8 +9,8 @@ import ( "strings" "time" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" ) diff --git a/internal/query/duck.go b/internal/engine/duck.go similarity index 99% rename from internal/query/duck.go rename to internal/engine/duck.go index 18162a50..3c24b074 100644 --- a/internal/query/duck.go +++ b/internal/engine/duck.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -17,8 +17,8 @@ import ( "github.com/labstack/fanout/internal/config" engine "github.com/labstack/fanout/internal/duckdb" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" diff --git a/internal/query/duck_memory.go b/internal/engine/duck_memory.go similarity index 99% rename from internal/query/duck_memory.go rename to internal/engine/duck_memory.go index 8405924d..3baab89b 100644 --- a/internal/query/duck_memory.go +++ b/internal/engine/duck_memory.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/duck_memory_test.go b/internal/engine/duck_memory_test.go similarity index 99% rename from internal/query/duck_memory_test.go rename to internal/engine/duck_memory_test.go index c928bad3..19990e8d 100644 --- a/internal/query/duck_memory_test.go +++ b/internal/engine/duck_memory_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "bytes" diff --git a/internal/query/duck_test.go b/internal/engine/duck_test.go similarity index 99% rename from internal/query/duck_test.go rename to internal/engine/duck_test.go index 790e560c..c49c2797 100644 --- a/internal/query/duck_test.go +++ b/internal/engine/duck_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -12,8 +12,8 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/labstack/fanout/internal/config" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" "github.com/prometheus/client_golang/prometheus/testutil" diff --git a/internal/query/edge_arrival_test.go b/internal/engine/edge_arrival_test.go similarity index 99% rename from internal/query/edge_arrival_test.go rename to internal/engine/edge_arrival_test.go index 2a7cb049..ab7df308 100644 --- a/internal/query/edge_arrival_test.go +++ b/internal/engine/edge_arrival_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "encoding/json" diff --git a/internal/query/edge_backlog_test.go b/internal/engine/edge_backlog_test.go similarity index 99% rename from internal/query/edge_backlog_test.go rename to internal/engine/edge_backlog_test.go index af313136..b46dcc7f 100644 --- a/internal/query/edge_backlog_test.go +++ b/internal/engine/edge_backlog_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/edge_pass_test.go b/internal/engine/edge_pass_test.go similarity index 99% rename from internal/query/edge_pass_test.go rename to internal/engine/edge_pass_test.go index 0e3658b5..85fa88a9 100644 --- a/internal/query/edge_pass_test.go +++ b/internal/engine/edge_pass_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "testing" diff --git a/internal/query/edge_resume_test.go b/internal/engine/edge_resume_test.go similarity index 99% rename from internal/query/edge_resume_test.go rename to internal/engine/edge_resume_test.go index 7026efb5..5652b4d2 100644 --- a/internal/query/edge_resume_test.go +++ b/internal/engine/edge_resume_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "database/sql" diff --git a/internal/query/edge_rollup_plan_test.go b/internal/engine/edge_rollup_plan_test.go similarity index 99% rename from internal/query/edge_rollup_plan_test.go rename to internal/engine/edge_rollup_plan_test.go index 8a688677..39f86e4a 100644 --- a/internal/query/edge_rollup_plan_test.go +++ b/internal/engine/edge_rollup_plan_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "database/sql" diff --git a/internal/query/edge_tick_test.go b/internal/engine/edge_tick_test.go similarity index 99% rename from internal/query/edge_tick_test.go rename to internal/engine/edge_tick_test.go index f00cda87..0b7d9f65 100644 --- a/internal/query/edge_tick_test.go +++ b/internal/engine/edge_tick_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/file_snapshot.go b/internal/engine/file_snapshot.go similarity index 99% rename from internal/query/file_snapshot.go rename to internal/engine/file_snapshot.go index 45e419bd..bf213167 100644 --- a/internal/query/file_snapshot.go +++ b/internal/engine/file_snapshot.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/file_snapshot_bench_test.go b/internal/engine/file_snapshot_bench_test.go similarity index 99% rename from internal/query/file_snapshot_bench_test.go rename to internal/engine/file_snapshot_bench_test.go index 96ce6649..45effecb 100644 --- a/internal/query/file_snapshot_bench_test.go +++ b/internal/engine/file_snapshot_bench_test.go @@ -1,6 +1,6 @@ //go:build filebench -package query +package engine import ( "encoding/json" diff --git a/internal/query/file_snapshot_test.go b/internal/engine/file_snapshot_test.go similarity index 99% rename from internal/query/file_snapshot_test.go rename to internal/engine/file_snapshot_test.go index 8162d892..f0ac5839 100644 --- a/internal/query/file_snapshot_test.go +++ b/internal/engine/file_snapshot_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -10,7 +10,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query/writegate" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" diff --git a/internal/query/json_result.go b/internal/engine/json_result.go similarity index 98% rename from internal/query/json_result.go rename to internal/engine/json_result.go index 9b773032..5411b494 100644 --- a/internal/query/json_result.go +++ b/internal/engine/json_result.go @@ -1,4 +1,4 @@ -package query +package engine import ( "math" diff --git a/internal/query/log_helpers_test.go b/internal/engine/log_helpers_test.go similarity index 99% rename from internal/query/log_helpers_test.go rename to internal/engine/log_helpers_test.go index 1f134815..b9d83a8a 100644 --- a/internal/query/log_helpers_test.go +++ b/internal/engine/log_helpers_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "testing" diff --git a/internal/query/maintenance_schedule_test.go b/internal/engine/maintenance_schedule_test.go similarity index 99% rename from internal/query/maintenance_schedule_test.go rename to internal/engine/maintenance_schedule_test.go index 6d57ce11..63a5ae4a 100644 --- a/internal/query/maintenance_schedule_test.go +++ b/internal/engine/maintenance_schedule_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/panel_sql.go b/internal/engine/panel_sql.go similarity index 99% rename from internal/query/panel_sql.go rename to internal/engine/panel_sql.go index e885d528..7a4e97ac 100644 --- a/internal/query/panel_sql.go +++ b/internal/engine/panel_sql.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/panel_sql_test.go b/internal/engine/panel_sql_test.go similarity index 99% rename from internal/query/panel_sql_test.go rename to internal/engine/panel_sql_test.go index 5952b29a..a23af5f4 100644 --- a/internal/query/panel_sql_test.go +++ b/internal/engine/panel_sql_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/parquet_gate.go b/internal/engine/parquet_gate.go similarity index 97% rename from internal/query/parquet_gate.go rename to internal/engine/parquet_gate.go index 451fd881..20cc9182 100644 --- a/internal/query/parquet_gate.go +++ b/internal/engine/parquet_gate.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" @@ -127,7 +127,7 @@ func (g *parquetReadGate) RUnlock() { g.readers-- if g.readers < 0 { g.mu.Unlock() - panic("query: parquetReadGate RUnlock without RLock") + panic("engine: parquetReadGate RUnlock without RLock") } if g.readers == 0 { g.notifyLocked() @@ -179,7 +179,7 @@ func (g *parquetReadGate) Unlock() { g.mu.Lock() if !g.writer { g.mu.Unlock() - panic("query: parquetReadGate Unlock without Lock") + panic("engine: parquetReadGate Unlock without Lock") } g.writer = false g.notifyLocked() diff --git a/internal/query/parquet_gate_test.go b/internal/engine/parquet_gate_test.go similarity index 99% rename from internal/query/parquet_gate_test.go rename to internal/engine/parquet_gate_test.go index 50a08eaf..1e5dfdfd 100644 --- a/internal/query/parquet_gate_test.go +++ b/internal/engine/parquet_gate_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/querytest/tables.go b/internal/engine/querytest/tables.go similarity index 100% rename from internal/query/querytest/tables.go rename to internal/engine/querytest/tables.go diff --git a/internal/query/resource_inventory.go b/internal/engine/resource_inventory.go similarity index 99% rename from internal/query/resource_inventory.go rename to internal/engine/resource_inventory.go index f2b43455..928e3496 100644 --- a/internal/query/resource_inventory.go +++ b/internal/engine/resource_inventory.go @@ -1,4 +1,4 @@ -package query +package engine import ( "strings" diff --git a/internal/query/resource_inventory_evidence_test.go b/internal/engine/resource_inventory_evidence_test.go similarity index 99% rename from internal/query/resource_inventory_evidence_test.go rename to internal/engine/resource_inventory_evidence_test.go index a64a70eb..fd0bfd51 100644 --- a/internal/query/resource_inventory_evidence_test.go +++ b/internal/engine/resource_inventory_evidence_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "encoding/json" diff --git a/internal/query/resource_inventory_test.go b/internal/engine/resource_inventory_test.go similarity index 99% rename from internal/query/resource_inventory_test.go rename to internal/engine/resource_inventory_test.go index 0149a014..c69d5aaf 100644 --- a/internal/query/resource_inventory_test.go +++ b/internal/engine/resource_inventory_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/rollup_admission_test.go b/internal/engine/rollup_admission_test.go similarity index 99% rename from internal/query/rollup_admission_test.go rename to internal/engine/rollup_admission_test.go index e2dc9fea..b2f5b112 100644 --- a/internal/query/rollup_admission_test.go +++ b/internal/engine/rollup_admission_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/rollup_memory_test.go b/internal/engine/rollup_memory_test.go similarity index 99% rename from internal/query/rollup_memory_test.go rename to internal/engine/rollup_memory_test.go index 6cc91474..03d6e116 100644 --- a/internal/query/rollup_memory_test.go +++ b/internal/engine/rollup_memory_test.go @@ -1,6 +1,6 @@ //go:build !race -package query +package engine import ( "database/sql" diff --git a/internal/query/rollup_test.go b/internal/engine/rollup_test.go similarity index 99% rename from internal/query/rollup_test.go rename to internal/engine/rollup_test.go index 4e75ce77..3ae3c0f6 100644 --- a/internal/query/rollup_test.go +++ b/internal/engine/rollup_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/rollup_watermark_test.go b/internal/engine/rollup_watermark_test.go similarity index 99% rename from internal/query/rollup_watermark_test.go rename to internal/engine/rollup_watermark_test.go index 683bdd59..1ed07cbd 100644 --- a/internal/query/rollup_watermark_test.go +++ b/internal/engine/rollup_watermark_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "os" diff --git a/internal/query/rollup_yield_test.go b/internal/engine/rollup_yield_test.go similarity index 99% rename from internal/query/rollup_yield_test.go rename to internal/engine/rollup_yield_test.go index 6788be11..cea0d1c9 100644 --- a/internal/query/rollup_yield_test.go +++ b/internal/engine/rollup_yield_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/rowmap_float_test.go b/internal/engine/rowmap_float_test.go similarity index 99% rename from internal/query/rowmap_float_test.go rename to internal/engine/rowmap_float_test.go index fec0dac8..a0a91348 100644 --- a/internal/query/rowmap_float_test.go +++ b/internal/engine/rowmap_float_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/service_bounds_test.go b/internal/engine/service_bounds_test.go similarity index 99% rename from internal/query/service_bounds_test.go rename to internal/engine/service_bounds_test.go index 6f777a7b..ceed413a 100644 --- a/internal/query/service_bounds_test.go +++ b/internal/engine/service_bounds_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "testing" diff --git a/internal/query/sql.go b/internal/engine/sql.go similarity index 99% rename from internal/query/sql.go rename to internal/engine/sql.go index ffe9f6db..da2b3996 100644 --- a/internal/query/sql.go +++ b/internal/engine/sql.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/sql_boundary.go b/internal/engine/sql_boundary.go similarity index 99% rename from internal/query/sql_boundary.go rename to internal/engine/sql_boundary.go index 27a7e8e7..12e49f33 100644 --- a/internal/query/sql_boundary.go +++ b/internal/engine/sql_boundary.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/sql_boundary_test.go b/internal/engine/sql_boundary_test.go similarity index 99% rename from internal/query/sql_boundary_test.go rename to internal/engine/sql_boundary_test.go index fc033889..65ebfc56 100644 --- a/internal/query/sql_boundary_test.go +++ b/internal/engine/sql_boundary_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/sql_functions_test.go b/internal/engine/sql_functions_test.go similarity index 99% rename from internal/query/sql_functions_test.go rename to internal/engine/sql_functions_test.go index fc679965..df4d76f1 100644 --- a/internal/query/sql_functions_test.go +++ b/internal/engine/sql_functions_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "os" diff --git a/internal/query/sql_limit_test.go b/internal/engine/sql_limit_test.go similarity index 99% rename from internal/query/sql_limit_test.go rename to internal/engine/sql_limit_test.go index 361604d9..043e3d35 100644 --- a/internal/query/sql_limit_test.go +++ b/internal/engine/sql_limit_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/sql_qualifiers.go b/internal/engine/sql_qualifiers.go similarity index 99% rename from internal/query/sql_qualifiers.go rename to internal/engine/sql_qualifiers.go index 8e981be8..df6d7a8b 100644 --- a/internal/query/sql_qualifiers.go +++ b/internal/engine/sql_qualifiers.go @@ -1,4 +1,4 @@ -package query +package engine import "strings" diff --git a/internal/query/sql_test.go b/internal/engine/sql_test.go similarity index 99% rename from internal/query/sql_test.go rename to internal/engine/sql_test.go index 40f1a30a..396d88a2 100644 --- a/internal/query/sql_test.go +++ b/internal/engine/sql_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/stall_instrumentation_test.go b/internal/engine/stall_instrumentation_test.go similarity index 99% rename from internal/query/stall_instrumentation_test.go rename to internal/engine/stall_instrumentation_test.go index ff0e1b73..1fec1335 100644 --- a/internal/query/stall_instrumentation_test.go +++ b/internal/engine/stall_instrumentation_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/tables_test.go b/internal/engine/tables_test.go similarity index 63% rename from internal/query/tables_test.go rename to internal/engine/tables_test.go index 1b62d520..d01ce22d 100644 --- a/internal/query/tables_test.go +++ b/internal/engine/tables_test.go @@ -1,8 +1,8 @@ -package query +package engine import ( "database/sql" - "github.com/labstack/fanout/internal/query/querytest" + "github.com/labstack/fanout/internal/engine/querytest" ) func CreateTables(db *sql.DB) error { return querytest.CreateTables(db, CreateCacheTables) } diff --git a/internal/query/testdata/duckdb-functions.txt b/internal/engine/testdata/duckdb-functions.txt similarity index 100% rename from internal/query/testdata/duckdb-functions.txt rename to internal/engine/testdata/duckdb-functions.txt diff --git a/internal/query/timestamp_plan_test.go b/internal/engine/timestamp_plan_test.go similarity index 99% rename from internal/query/timestamp_plan_test.go rename to internal/engine/timestamp_plan_test.go index 26c00591..32e11fb0 100644 --- a/internal/query/timestamp_plan_test.go +++ b/internal/engine/timestamp_plan_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/variant_boundary_test.go b/internal/engine/variant_boundary_test.go similarity index 99% rename from internal/query/variant_boundary_test.go rename to internal/engine/variant_boundary_test.go index 488534e5..473c94ea 100644 --- a/internal/query/variant_boundary_test.go +++ b/internal/engine/variant_boundary_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "encoding/json" diff --git a/internal/query/variant_integration_test.go b/internal/engine/variant_integration_test.go similarity index 99% rename from internal/query/variant_integration_test.go rename to internal/engine/variant_integration_test.go index dd5233e6..51cafa7e 100644 --- a/internal/query/variant_integration_test.go +++ b/internal/engine/variant_integration_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/version_budget_test.go b/internal/engine/version_budget_test.go similarity index 99% rename from internal/query/version_budget_test.go rename to internal/engine/version_budget_test.go index 20bf4f8d..03f3aa40 100644 --- a/internal/query/version_budget_test.go +++ b/internal/engine/version_budget_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/version_gate_test.go b/internal/engine/version_gate_test.go similarity index 95% rename from internal/query/version_gate_test.go rename to internal/engine/version_gate_test.go index e9d21e93..877197ea 100644 --- a/internal/query/version_gate_test.go +++ b/internal/engine/version_gate_test.go @@ -1,11 +1,11 @@ -package query +package engine import ( "bytes" "context" "errors" + "github.com/labstack/fanout/internal/engine/writegate" "github.com/labstack/fanout/internal/metrics" - "github.com/labstack/fanout/internal/query/writegate" "github.com/prometheus/client_golang/prometheus/testutil" "log/slog" "runtime" @@ -132,7 +132,7 @@ func signalVersionGateWait(blocked chan<- struct{}, stop <-chan struct{}) { buffer := make([]byte, 1<<20) for { for stack := range strings.SplitSeq(string(buffer[:runtime.Stack(buffer, true)]), "\n\n") { - if strings.Contains(stack, "[select]") && strings.Contains(stack, frame) && strings.Contains(stack, "query.(*Duck).refreshVersionRollup") && strings.Contains(stack, "TestVersionRollupWaitHonorsCallerCancellation") { + if strings.Contains(stack, "[select]") && strings.Contains(stack, frame) && strings.Contains(stack, "engine.(*Duck).refreshVersionRollup") && strings.Contains(stack, "TestVersionRollupWaitHonorsCallerCancellation") { close(blocked) return } diff --git a/internal/query/views.go b/internal/engine/views.go similarity index 99% rename from internal/query/views.go rename to internal/engine/views.go index a088a786..8cce974e 100644 --- a/internal/query/views.go +++ b/internal/engine/views.go @@ -1,4 +1,4 @@ -package query +package engine import ( "database/sql" diff --git a/internal/query/views_schema_test.go b/internal/engine/views_schema_test.go similarity index 99% rename from internal/query/views_schema_test.go rename to internal/engine/views_schema_test.go index cfee83f8..5f9fe6c2 100644 --- a/internal/query/views_schema_test.go +++ b/internal/engine/views_schema_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/views_test.go b/internal/engine/views_test.go similarity index 99% rename from internal/query/views_test.go rename to internal/engine/views_test.go index ceeb3e6d..f438f6d3 100644 --- a/internal/query/views_test.go +++ b/internal/engine/views_test.go @@ -1,4 +1,4 @@ -package query +package engine import ( "context" diff --git a/internal/query/writegate/write_gate.go b/internal/engine/writegate/write_gate.go similarity index 100% rename from internal/query/writegate/write_gate.go rename to internal/engine/writegate/write_gate.go diff --git a/internal/query/writegate/write_gate_test.go b/internal/engine/writegate/write_gate_test.go similarity index 100% rename from internal/query/writegate/write_gate_test.go rename to internal/engine/writegate/write_gate_test.go diff --git a/internal/fanql/ast.go b/internal/fanql/ast.go index c5d6c118..b4b5fb3c 100644 --- a/internal/fanql/ast.go +++ b/internal/fanql/ast.go @@ -1,6 +1,6 @@ package fanql -import "github.com/labstack/fanout/internal/panel" +import "github.com/labstack/fanout/internal/query" type queryTree struct { Source string @@ -116,7 +116,7 @@ type fieldName struct { type fieldRef struct { Column string Key string - Type panel.FieldType + Type query.FieldType Unit string CompareAs string } @@ -148,8 +148,8 @@ type aggregation struct { At span } type measureNode struct { - Parsed panel.Measure - Info map[panel.MeasureExpr]*measureSource + Parsed query.Measure + Info map[query.MeasureExpr]*measureSource Alias string At span Filters map[string]filterExpr diff --git a/internal/fanql/bounds_test.go b/internal/fanql/bounds_test.go index e14ac40d..7929e822 100644 --- a/internal/fanql/bounds_test.go +++ b/internal/fanql/bounds_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestEachInteractiveBoundIndependently(t *testing.T) { @@ -23,7 +23,7 @@ func TestEachInteractiveBoundIndependently(t *testing.T) { {"list", "logs where k in (" + strings.Repeat("0,", 100) + "0)", "an in list is at most 100 values", true}, } { t.Run(tc.name, func(t *testing.T) { - var problems panel.Problems + var problems query.Problems if tc.compile { compiled, ps := Compile(tc.text, Options{}) if compiled != nil { @@ -54,7 +54,7 @@ func TestAstralCharactersSpanInCodePoints(t *testing.T) { t.Fatalf("second term span = %+v", got) } _, ps = parse(text+" +", "") - if len(ps) != 1 || ps[0].Message != "unexpected +" || ps[0].Span == nil || *ps[0].Span != (panel.TextSpan{Start: 26, End: 27}) { + if len(ps) != 1 || ps[0].Message != "unexpected +" || ps[0].Span == nil || *ps[0].Span != (query.TextSpan{Start: 26, End: 27}) { t.Fatalf("diagnostic after astral text = %+v", ps) } } diff --git a/internal/fanql/complete.go b/internal/fanql/complete.go index 35b44622..e440181b 100644 --- a/internal/fanql/complete.go +++ b/internal/fanql/complete.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" ) @@ -57,7 +57,7 @@ func completionPrefix(text string, cursor int, source string) (token lexToken, p } type schemaSource interface { - Schema(context.Context, panel.SchemaRequest) (*panel.Schema, error) + Schema(context.Context, query.SchemaRequest) (*query.Schema, error) } type CompleteRequest struct { @@ -86,7 +86,7 @@ type SchemaStatus struct { } type CompleteResponse struct { - Replace panel.TextSpan `json:"replace"` + Replace query.TextSpan `json:"replace"` Items []Item `json:"items"` Schema SchemaStatus `json:"schema"` } @@ -95,7 +95,7 @@ const maxCompletionItems = 50 type completionKey struct{ window, namespace string } type completionSchemaEntry struct { - schema *panel.Schema + schema *query.Schema expires time.Time failed bool } @@ -141,7 +141,7 @@ func completionWindow(window string) (string, bool) { return "24h", false } -func (c *Completer) schema(ctx context.Context, key completionKey) (*panel.Schema, bool, bool) { +func (c *Completer) schema(ctx context.Context, key completionKey) (*query.Schema, bool, bool) { c.mu.Lock() defer c.mu.Unlock() now := c.now() @@ -168,7 +168,7 @@ func (c *Completer) fetch(parent context.Context, key completionKey, done chan s defer func() { <-completionSchemaSlots }() ctx, cancel := context.WithTimeout(parent, 20*time.Second) defer cancel() - schema, err := c.source.Schema(ctx, panel.SchemaRequest{Window: key.window, Namespace: key.namespace}) + schema, err := c.source.Schema(ctx, query.SchemaRequest{Window: key.window, Namespace: key.namespace}) c.mu.Lock() defer c.mu.Unlock() now := c.now() @@ -202,7 +202,7 @@ type completionCandidates struct { req CompleteRequest token lexToken p *parser - signal panel.SignalSchema + signal query.SignalSchema source, prefix string items []completionCandidate class int @@ -215,7 +215,7 @@ func (c *Completer) Complete(ctx context.Context, req CompleteRequest) CompleteR } schema, warm, failed := c.schema(ctx, completionKey{window, req.Namespace}) token, p := completionPrefix(req.Text, req.Cursor, req.Source) - r := CompleteResponse{Replace: panel.TextSpan{Start: token.Span.Start, End: token.Span.End}, Items: []Item{}, Schema: SchemaStatus{Window: window, Sampled: true, Warm: warm, Recent: recent, Error: failed}} + r := CompleteResponse{Replace: query.TextSpan{Start: token.Span.Start, End: token.Span.End}, Items: []Item{}, Schema: SchemaStatus{Window: window, Sampled: true, Warm: warm, Recent: recent, Error: failed}} if recent { r.Schema.Notice = "keys seen in the last 24h (recent), not in the selected interval" } @@ -306,7 +306,7 @@ func (s *completionCandidates) words(kind string, words ...string) { func (s *completionCandidates) candidates(e expect) { switch e.Class { case "source": - s.words("keyword", panel.SignalNames()...) + s.words("keyword", query.SignalNames()...) case "field": s.fields(e, false, "") case "bracket_key": @@ -344,7 +344,7 @@ func (s *completionCandidates) candidates(e expect) { s.fields(e, true, "") return } - for _, spec := range panel.MeasureSpecs() { + for _, spec := range query.MeasureSpecs() { if spec.Name == e.Func && e.Arg < spec.Args { s.fields(e, spec.Numeric, "") return @@ -355,7 +355,7 @@ func (s *completionCandidates) candidates(e expect) { s.add("", "", "keyword", s.req.Viz+" panels have no bucket", 0, 0) return } - s.words("bucket", panel.BucketNames()...) + s.words("bucket", query.BucketNames()...) case "sort_key": s.sortKeys() case "integer": @@ -419,9 +419,9 @@ func (s *completionCandidates) fields(e expect, numeric bool, scope string) { } } if scope == "" { - fields, _ := panel.SignalColumns(s.source) + fields, _ := query.SignalColumns(s.source) for _, field := range fields { - if field.Type == panel.TypeMap || e.Func == "by" && field.Type != panel.TypeString { + if field.Type == query.TypeMap || e.Func == "by" && field.Type != query.TypeString { continue } name := field.Name @@ -429,7 +429,7 @@ func (s *completionCandidates) fields(e expect, numeric bool, scope string) { name = "duration" } boost := 0 - if numeric && field.Type == panel.TypeNumber { + if numeric && field.Type == query.TypeNumber { boost = 2 } s.add(name, name, "field", field.Description, 0, boost) @@ -507,9 +507,9 @@ func (s *completionCandidates) operators(field *fieldName) { s.words("operator", ">", ">=", "<", "<=", ":") return } - fields, _ := panel.SignalColumns(s.source) + fields, _ := query.SignalColumns(s.source) for _, f := range fields { - if f.Name == field.Key && f.Type == panel.TypeTime { + if f.Name == field.Key && f.Type == query.TypeTime { s.words("operator", "=", "!=", ">", ">=", "<", "<=") return } @@ -549,7 +549,7 @@ func (s *completionCandidates) values(e expect) { return } } else { - aliases := panel.FieldAliases(f.Key) + aliases := query.FieldAliases(f.Key) for _, label := range sortedCompletionKeys(aliases) { value(label, aliases[label], 0) } @@ -602,7 +602,7 @@ func sortedCompletionKeys(m map[string]string) []string { } func (s *completionCandidates) measures() { - for _, spec := range panel.MeasureSpecs() { + for _, spec := range query.MeasureSpecs() { if len(spec.Signals) > 0 && !slices.Contains(spec.Signals, s.source) { continue } @@ -628,7 +628,7 @@ func (s *completionCandidates) sortKeys() { for i := range q.Stage.Measures { m := &q.Stage.Measures[i] m.Parsed.Expr = r.measure(m.Parsed.Expr, m.Info, m.Filters) - if c, ok := m.Parsed.Expr.(panel.MeasureCall); ok { + if c, ok := m.Parsed.Expr.(query.MeasureCall); ok { m.Parsed.Func = c.Func m.Parsed.Field = c.Field } diff --git a/internal/fanql/complete_test.go b/internal/fanql/complete_test.go index 6008f190..ac061372 100644 --- a/internal/fanql/complete_test.go +++ b/internal/fanql/complete_test.go @@ -12,10 +12,10 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) -type completionSchemaFunc func(context.Context, panel.SchemaRequest) (*panel.Schema, error) +type completionSchemaFunc func(context.Context, query.SchemaRequest) (*query.Schema, error) // expectAt replaces a whole lexical token even when the cursor is in its middle. // Punctuation is consumed by the grammar: a cursor after ':' expects a value. @@ -26,7 +26,7 @@ func expectAt(text string, cursor int) (lexToken, []expect) { func TestCompleteBoundsDistinctNamespaceFetchAdmission(t *testing.T) { gate := make(chan struct{}) - source := completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { + source := completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { <-gate return completionFixtureSchema(), nil }) @@ -61,24 +61,24 @@ func TestCompleteBoundsDistinctNamespaceFetchAdmission(t *testing.T) { } } -func (f completionSchemaFunc) Schema(ctx context.Context, req panel.SchemaRequest) (*panel.Schema, error) { +func (f completionSchemaFunc) Schema(ctx context.Context, req query.SchemaRequest) (*query.Schema, error) { return f(ctx, req) } -func completionFixtureSchema() *panel.Schema { - return &panel.Schema{Signals: map[string]panel.SignalSchema{ - "logs": {Columns: []panel.ColumnSchema{ - {Field: panel.Field{Name: "severity"}, Values: []panel.Option{{Value: "ERROR"}, {Value: "INFO"}, {Value: "WARN"}}}, - {Field: panel.Field{Name: "service"}, Values: []panel.Option{{Value: "api"}, {Value: "checkout"}}}, +func completionFixtureSchema() *query.Schema { + return &query.Schema{Signals: map[string]query.SignalSchema{ + "logs": {Columns: []query.ColumnSchema{ + {Field: query.Field{Name: "severity"}, Values: []query.Option{{Value: "ERROR"}, {Value: "INFO"}, {Value: "WARN"}}}, + {Field: query.Field{Name: "service"}, Values: []query.Option{{Value: "api"}, {Value: "checkout"}}}, }}, - "spans": {Attributes: []panel.AttributeSchema{ + "spans": {Attributes: []query.AttributeSchema{ {Key: "http.target", Scope: "attributes", Type: "string", Count: 900}, {Key: "http.method", Scope: "attributes", Type: "string", Count: 500}, {Key: "user.score", Scope: "attributes", Type: "number", Count: 20}, {Key: "k8s.pod.name", Scope: "resource", Type: "string", Count: 10}, {Key: "enabled", Scope: "attributes", Type: "boolean", Count: 5}, }}, - "metrics": {Metrics: []panel.MetricSchema{{Name: "http.server.duration", Count: 100}}}, + "metrics": {Metrics: []query.MetricSchema{{Name: "http.server.duration", Count: 100}}}, }} } @@ -114,7 +114,7 @@ func waitCompletion(t *testing.T, c *Completer, req CompleteRequest, ready func( func warmCompleter(t *testing.T) *Completer { t.Helper() - c := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { + c := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { return completionFixtureSchema(), nil })) waitCompletion(t, c, completionRequest("spans "), func(r CompleteResponse) bool { return r.Schema.Warm }) @@ -173,13 +173,13 @@ func TestCompleteFixtures(t *testing.T) { text, viz string exact, includes, excludes []string first, insert, detail string - replace *panel.TextSpan + replace *query.TextSpan }{ - {text: "logs where sev¦erity:error", first: "severity", replace: &panel.TextSpan{Start: 11, End: 19}}, + {text: "logs where sev¦erity:error", first: "severity", replace: &query.TextSpan{Start: 11, End: 19}}, {text: "logs where severity:¦", includes: []string{"trace", "debug", "info", "warn", "error", "fatal", "*"}, excludes: []string{"ERROR", "INFO", "WARN"}}, {text: "logs where severity>=¦", exact: []string{"trace", "debug", "info", "warn", "error", "fatal"}}, {text: "spans where http.¦", exact: []string{"http.target", "http.method"}, insert: "http.target"}, - {text: "spans where attributes['htt¦", first: "http.target", insert: "http.target']", replace: &panel.TextSpan{Start: 24, End: 27}}, + {text: "spans where attributes['htt¦", first: "http.target", insert: "http.target']", replace: &query.TextSpan{Start: 24, End: 27}}, {text: "spans where resource[\"k8s.¦", first: "k8s.pod.name", insert: "k8s.pod.name\"]"}, {text: "logs where service in (api, ¦", exact: []string{"checkout", "api"}}, {text: "logs where ser¦", includes: []string{"service"}, detail: "free text searches body"}, @@ -214,7 +214,7 @@ func TestCompleteFixtures(t *testing.T) { t.Run(tt.text+tt.viz, func(t *testing.T) { req := completionRequest(tt.text) req.Viz = tt.viz - req.Variables = []panel.Variable{{Name: "service"}} + req.Variables = []query.Variable{{Name: "service"}} r := c.Complete(context.Background(), req) labels := completionLabels(r) if len(r.Items) > 50 || r.Schema.Window != "1h" || !r.Schema.Warm { @@ -263,7 +263,7 @@ func TestCompleteFixtures(t *testing.T) { } } r := c.Complete(context.Background(), completionRequest("spans where attributes['😀¦")) - if r.Replace != (panel.TextSpan{Start: 24, End: 25}) { + if r.Replace != (query.TextSpan{Start: 24, End: 25}) { t.Errorf("code point replace %+v", r.Replace) } page := completionRequest("ser¦") @@ -279,8 +279,8 @@ func TestCompleteRecentFlag(t *testing.T) { recent bool }{{"7d", "24h", true}, {"", "24h", true}, {"1d", "24h", false}, {"1h", "1h", false}, {"30m", "1h", false}} { t.Run(tt.window, func(t *testing.T) { - requests := make(chan panel.SchemaRequest, 1) - c := NewCompleter(completionSchemaFunc(func(_ context.Context, r panel.SchemaRequest) (*panel.Schema, error) { + requests := make(chan query.SchemaRequest, 1) + c := NewCompleter(completionSchemaFunc(func(_ context.Context, r query.SchemaRequest) (*query.Schema, error) { requests <- r return completionFixtureSchema(), nil })) @@ -303,7 +303,7 @@ func TestCompleteRecentFlag(t *testing.T) { func TestCompleteColdCacheCoalesces(t *testing.T) { gate := make(chan struct{}) var calls, active, maximum atomic.Int32 - c := NewCompleter(completionSchemaFunc(func(ctx context.Context, _ panel.SchemaRequest) (*panel.Schema, error) { + c := NewCompleter(completionSchemaFunc(func(ctx context.Context, _ query.SchemaRequest) (*query.Schema, error) { calls.Add(1) n := active.Add(1) defer active.Add(-1) @@ -346,7 +346,7 @@ func TestCompleteColdCacheCoalesces(t *testing.T) { t.Fatalf("calls %d, max active %d", calls.Load(), maximum.Load()) } var failed atomic.Int32 - bad := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { + bad := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { failed.Add(1) return nil, errors.New("unavailable") })) @@ -386,9 +386,9 @@ func TestCompleteItemsRankByPrefixThenSubstringThenCount(t *testing.T) { func TestCompleteVocabularyPrecedesSampledValues(t *testing.T) { schema := completionFixtureSchema() logs := schema.Signals["logs"] - logs.Columns[0].Values = append(logs.Columns[0].Values, panel.Option{Value: "CUSTOM", Count: 999}) + logs.Columns[0].Values = append(logs.Columns[0].Values, query.Option{Value: "CUSTOM", Count: 999}) schema.Signals["logs"] = logs - c := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { return schema, nil })) + c := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { return schema, nil })) r := waitCompletion(t, c, completionRequest("logs where severity:¦"), func(r CompleteResponse) bool { return r.Schema.Warm }) if got := completionLabels(r); len(got) < 7 || !slices.Equal(got[:7], []string{"trace", "debug", "info", "warn", "error", "fatal", "CUSTOM"}) { t.Fatalf("vocabulary before samples: %v", got) @@ -422,7 +422,7 @@ func TestCompleteServiceMetadataBoostsWithoutHiding(t *testing.T) { spans := schema.Signals["spans"] spans.Attributes[1].Services = "checkout, api" schema.Signals["spans"] = spans - c := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { return schema, nil })) + c := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { return schema, nil })) r := waitCompletion(t, c, completionRequest("spans where service:checkout http.¦"), func(r CompleteResponse) bool { return r.Schema.Warm }) if !slices.Equal(completionLabels(r), []string{"http.method", "http.target"}) { t.Fatalf("service boost: %v", completionLabels(r)) @@ -437,7 +437,7 @@ func TestCompleteSchemaConcurrencyIsProcessWide(t *testing.T) { gate := make(chan struct{}) started := make(chan struct{}, 12) var active, maximum, calls atomic.Int32 - source := completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { + source := completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { calls.Add(1) n := active.Add(1) defer active.Add(-1) @@ -488,9 +488,9 @@ func TestCompleteRecoversInvalidFiltersBeforeStage(t *testing.T) { func TestCompleteInsertedValuesPreserveLiteralMeaning(t *testing.T) { schema := completionFixtureSchema() logs := schema.Signals["logs"] - logs.Columns[1].Values = []panel.Option{{Value: "checkout api"}, {Value: "checkout:api"}, {Value: "count | limit 1"}, {Value: `say "hello"`}, {Value: "$service"}, {Value: "*"}, {Value: "500ms"}, {Value: "true"}, {Value: "api"}} + logs.Columns[1].Values = []query.Option{{Value: "checkout api"}, {Value: "checkout:api"}, {Value: "count | limit 1"}, {Value: `say "hello"`}, {Value: "$service"}, {Value: "*"}, {Value: "500ms"}, {Value: "true"}, {Value: "api"}} schema.Signals["logs"] = logs - c := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { return schema, nil })) + c := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { return schema, nil })) req := completionRequest("logs where service:¦") r := waitCompletion(t, c, req, func(r CompleteResponse) bool { return r.Schema.Warm }) for _, tt := range []struct{ label, sql string }{{"checkout api", `service = 'checkout api'`}, {"checkout:api", `service = 'checkout:api'`}, {"count | limit 1", `service = 'count | limit 1'`}, {`say "hello"`, `service = 'say "hello"'`}, {"$service", `service = '$service'`}, {"*", `service = '*'`}, {"500ms", `service = '500ms'`}, {"true", `service = 'true'`}, {"api", `service = 'api'`}} { @@ -517,9 +517,9 @@ func TestCompleteInsertedValuesPreserveLiteralMeaning(t *testing.T) { func TestCompleteInsertedAttributeFieldsPreserveScope(t *testing.T) { schema := completionFixtureSchema() spans := schema.Signals["spans"] - spans.Attributes = []panel.AttributeSchema{{Key: "resource.foo", Scope: "attributes"}, {Key: "attributes.foo", Scope: "attributes"}, {Key: "service-name", Scope: "resource"}, {Key: "owner's.name", Scope: "attributes"}, {Key: `owner"s.name`, Scope: "resource"}, {Key: "where", Scope: "resource"}, {Key: "service", Scope: "resource"}} + spans.Attributes = []query.AttributeSchema{{Key: "resource.foo", Scope: "attributes"}, {Key: "attributes.foo", Scope: "attributes"}, {Key: "service-name", Scope: "resource"}, {Key: "owner's.name", Scope: "attributes"}, {Key: `owner"s.name`, Scope: "resource"}, {Key: "where", Scope: "resource"}, {Key: "service", Scope: "resource"}} schema.Signals["spans"] = spans - c := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { return schema, nil })) + c := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { return schema, nil })) for _, tt := range []struct{ text, key, scope, label string }{ {"spans where res¦", "resource.foo", "attributes", "attributes['resource.foo']"}, {"spans where attr¦", "attributes.foo", "attributes", "attributes['attributes.foo']"}, @@ -558,7 +558,7 @@ func TestCompleteInsertedAttributeFieldsPreserveScope(t *testing.T) { } } -func applyCompletion(text string, replace panel.TextSpan, insert string) string { +func applyCompletion(text string, replace query.TextSpan, insert string) string { runes := []rune(text) return string(runes[:replace.Start]) + insert + string(runes[replace.End:]) } diff --git a/internal/fanql/corpus_test.go b/internal/fanql/corpus_test.go index 59fcb52c..692cae3d 100644 --- a/internal/fanql/corpus_test.go +++ b/internal/fanql/corpus_test.go @@ -7,7 +7,7 @@ import ( "reflect" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) // Each JSON block is an independently pinned input/output fixture. There is no @@ -15,8 +15,8 @@ import ( type corpusFixture struct { Text string `json:"text"` Viz string `json:"viz,omitempty"` - Query *panel.Query `json:"query,omitempty"` - Problems panel.Problems `json:"problems,omitempty"` + Query *query.Spec `json:"query,omitempty"` + Problems query.Problems `json:"problems,omitempty"` GateProblems bool `json:"gate_problems,omitempty"` } diff --git a/internal/fanql/diagnostic_copy_test.go b/internal/fanql/diagnostic_copy_test.go index 45a1470c..f758142a 100644 --- a/internal/fanql/diagnostic_copy_test.go +++ b/internal/fanql/diagnostic_copy_test.go @@ -1,7 +1,7 @@ package fanql import ( - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "regexp" "strings" "testing" @@ -90,7 +90,7 @@ func TestCompileKeepsProblemsFromIndependentClauses(t *testing.T) { } func TestMetricFreeTextDiagnosticUsesSchemaExample(t *testing.T) { - schema := &panel.Schema{Signals: map[string]panel.SignalSchema{"metrics": {Metrics: []panel.MetricSchema{{Name: "cpu.utilization", Count: 1}, {Name: "http.server.requests", Count: 12}}}}} + schema := &query.Schema{Signals: map[string]query.SignalSchema{"metrics": {Metrics: []query.MetricSchema{{Name: "cpu.utilization", Count: 1}, {Name: "http.server.requests", Count: 12}}}}} c, ps := Compile("metrics where timeout", Options{Schema: schema}) if c != nil || len(ps) != 1 || ps[0].Message != "free text needs a field on metrics; use name:http.server.requests" { t.Fatalf("metric example: %+v", ps) diff --git a/internal/fanql/fanql.go b/internal/fanql/fanql.go index d30c1860..27f96fc5 100644 --- a/internal/fanql/fanql.go +++ b/internal/fanql/fanql.go @@ -1,30 +1,30 @@ // Package fanql parses the text form of Fanout's structured telemetry queries. package fanql -import "github.com/labstack/fanout/internal/panel" +import "github.com/labstack/fanout/internal/query" type Options struct { - Panel *panel.Panel `json:"panel,omitempty"` + Panel *query.Panel `json:"panel,omitempty"` Source string `json:"source,omitempty"` Viz string `json:"viz,omitempty"` - Variables []panel.Variable `json:"variables,omitempty"` - Schema *panel.Schema `json:"-"` + Variables []query.Variable `json:"variables,omitempty"` + Schema *query.Schema `json:"-"` } type Compiled struct { - Query panel.Query + Query query.Spec Canonical string Notices []Notice - Compatible []panel.VizCompat + Compatible []query.VizCompat Edits []VizEdit } // Compile parses, resolves and lowers text without executing SQL. A problem // always prevents an executable query from being returned. -func Compile(text string, opts Options) (*Compiled, panel.Problems) { +func Compile(text string, opts Options) (*Compiled, query.Problems) { return compileWith(text, opts, currentVocabulary()) } -func compileWith(text string, opts Options, vocab vocabulary) (*Compiled, panel.Problems) { +func compileWith(text string, opts Options, vocab vocabulary) (*Compiled, query.Problems) { q, problems := parseWith(text, opts.Source, vocab) if len(problems) != 0 { return nil, problems diff --git a/internal/fanql/filter_exactness_test.go b/internal/fanql/filter_exactness_test.go index 0a57e346..46fc9e6c 100644 --- a/internal/fanql/filter_exactness_test.go +++ b/internal/fanql/filter_exactness_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestRawFragmentsPreservePrecedence(t *testing.T) { @@ -62,7 +62,7 @@ func TestPrintParsePrintFixtureCorpus(t *testing.T) { } func TestPrintFunctionSearchWordsBeforeGroups(t *testing.T) { - for _, name := range panel.FilterFunctionNames() { + for _, name := range query.FilterFunctionNames() { standalone, ps := Compile("logs "+name, Options{}) if len(ps) != 0 || standalone.Canonical != "logs where "+name { t.Fatalf("standalone search spelling: %+v %+v", standalone, ps) @@ -153,7 +153,7 @@ func TestSortPreservesMeasureAliasDuration(t *testing.T) { } func TestHTTPStatusVariableRangeUsesNumericCast(t *testing.T) { - c, ps := Compile(`spans where http_status_code>=$code`, Options{Variables: []panel.Variable{{Name: "code"}}}) + c, ps := Compile(`spans where http_status_code>=$code`, Options{Variables: []query.Variable{{Name: "code"}}}) if len(ps) != 0 { t.Fatal(ps) } @@ -175,7 +175,7 @@ func TestHTTPStatusVariableRangeUsesNumericCast(t *testing.T) { func TestComparedCallVariablesBindAndRespectCountIf(t *testing.T) { t.Run("bind", func(t *testing.T) { - c, ps := Compile(`logs where lower(service)=$svc`, Options{Variables: []panel.Variable{{Name: "svc"}}}) + c, ps := Compile(`logs where lower(service)=$svc`, Options{Variables: []query.Variable{{Name: "svc"}}}) if len(ps) != 0 { t.Fatal(ps) } @@ -226,9 +226,9 @@ func TestGroupByAcceptsLiteralKeys(t *testing.T) { if len(ps) != 0 || !reflect.DeepEqual(c.Query, d.Query) { t.Fatalf("round trip: %+v %+v", d, ps) } - dashboard := panel.Dashboard{Name: "keys", Panels: []panel.Panel{{ID: "keys", Title: "Keys", Viz: "table", Query: &c.Query}}} - panel.Normalize(&dashboard) - if _, ps, err := panel.Check(t.Context(), engine, &dashboard); len(ps) != 0 || err != nil { + dashboard := query.Dashboard{Name: "keys", Panels: []query.Panel{{ID: "keys", Title: "Keys", Viz: "table", Query: &c.Query}}} + query.Normalize(&dashboard) + if _, ps, err := query.Check(t.Context(), engine, &dashboard); len(ps) != 0 || err != nil { t.Fatalf("engine check for %q: %+v %v", text, ps, err) } } @@ -240,9 +240,9 @@ func TestLiteralKeyQuotesSurviveCheckedMetadata(t *testing.T) { t.Fatal(ps) } engine, _ := newTestEngine(t) - d := panel.Dashboard{Name: "Keys", Panels: []panel.Panel{{ID: "keys", Title: "Keys", Viz: "table", Query: &c.Query}}} - panel.Normalize(&d) - checked, ps, err := panel.Check(t.Context(), engine, &d) + d := query.Dashboard{Name: "Keys", Panels: []query.Panel{{ID: "keys", Title: "Keys", Viz: "table", Query: &c.Query}}} + query.Normalize(&d) + checked, ps, err := query.Check(t.Context(), engine, &d) if err != nil || len(ps) != 0 { t.Fatal(ps, err) } diff --git a/internal/fanql/format.go b/internal/fanql/format.go index b4eb0f1e..14fedc85 100644 --- a/internal/fanql/format.go +++ b/internal/fanql/format.go @@ -3,7 +3,7 @@ package fanql import ( "context" "fmt" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/sqlscan" "strconv" "strings" @@ -18,7 +18,7 @@ const ( ) type Requirement struct { - Name panel.VizRequirement `json:"name"` + Name query.VizRequirement `json:"name"` Satisfied bool `json:"satisfied"` } type Formatted struct { @@ -39,40 +39,40 @@ const ( // Format preserves each stored filter as one entry. Candidates are kept only // after a byte or engine-AST exactness check; all other filters remain raw. -func Format(ctx context.Context, p panel.Parser, stored panel.Query, opts Options) (*Formatted, panel.Problems, error) { +func Format(ctx context.Context, p query.Parser, stored query.Spec, opts Options) (*Formatted, query.Problems, error) { if opts.Panel != nil { opts.Viz = opts.Panel.Viz } - vars := map[string]panel.Variable(nil) + vars := map[string]query.Variable(nil) if opts.Variables != nil { - vars = make(map[string]panel.Variable, len(opts.Variables)) + vars = make(map[string]query.Variable, len(opts.Variables)) for _, v := range opts.Variables { vars[v.Name] = v } } // Most stored queries are valid tables. Prove shape validity there first // instead of reparsing every measure for every possible visualization. - problems, _ := panel.QueryShape(&stored, "table", vars) - if len(problems) > 0 && len(panel.CompatibleVizzes(&stored, vars)) == 0 { + problems, _ := query.Shape(&stored, "table", vars) + if len(problems) > 0 && len(query.CompatibleVizzes(&stored, vars)) == 0 { viz := opts.Viz if viz == "" { viz = "table" } - problems, _ = panel.QueryShape(&stored, viz, vars) + problems, _ = query.Shape(&stored, viz, vars) if len(problems) > 0 { return nil, presentProblems(problems), nil } } q := &queryTree{Source: stored.From} f := &Formatted{Exactness: Exact, Notices: []Notice{}, Requires: []Requirement{}} - _, requirements := panel.QueryShape(&stored, opts.Viz, vars) + _, requirements := query.Shape(&stored, opts.Viz, vars) for _, name := range requirements { satisfied := false if p := opts.Panel; p != nil { switch name { - case panel.RequiresMinMax: + case query.RequiresMinMax: satisfied = p.Min != nil && p.Max != nil && *p.Min < *p.Max - case panel.RequiresThresholds: + case query.RequiresThresholds: satisfied = len(p.Thresholds) > 0 } } @@ -89,7 +89,7 @@ func Format(ctx context.Context, p panel.Parser, stored panel.Query, opts Option if operationalFormatError(err) { return nil, nil, fmt.Errorf("format where[%d]: %w", i, err) } - return nil, panel.Problems{{Path: fmt.Sprintf("where[%d]", i), Message: err.Error()}}, nil + return nil, query.Problems{{Path: fmt.Sprintf("where[%d]", i), Message: err.Error()}}, nil } q.Where = append(q.Where, e) if t == tierNormalized { @@ -102,7 +102,7 @@ func Format(ctx context.Context, p panel.Parser, stored panel.Query, opts Option if stored.Histogram != nil { field, ok := liftFieldText(stored.From, stored.Histogram.Field) if !ok { - return nil, panel.Problems{{Path: "histogram.field", Message: "histogram field cannot be expressed in FanQL"}}, nil + return nil, query.Problems{{Path: "histogram.field", Message: "histogram field cannot be expressed in FanQL"}}, nil } q.Stage.Histogram = &field } else { @@ -112,7 +112,7 @@ func Format(ctx context.Context, p panel.Parser, stored panel.Query, opts Option if operationalFormatError(err) { return nil, nil, fmt.Errorf("format measures[%d]: %w", i, err) } - return nil, panel.Problems{{Path: fmt.Sprintf("measures[%d]", i), Message: err.Error()}}, nil + return nil, query.Problems{{Path: fmt.Sprintf("measures[%d]", i), Message: err.Error()}}, nil } q.Stage.Measures = append(q.Stage.Measures, m) if t == tierNormalized { @@ -124,7 +124,7 @@ func Format(ctx context.Context, p panel.Parser, stored panel.Query, opts Option for _, text := range stored.By { field, ok := liftFieldText(stored.From, text) if !ok { - return nil, panel.Problems{{Path: "by", Message: "grouping field cannot be expressed in FanQL"}}, nil + return nil, query.Problems{{Path: "by", Message: "grouping field cannot be expressed in FanQL"}}, nil } q.Stage.By = append(q.Stage.By, field) } diff --git a/internal/fanql/format_copy_test.go b/internal/fanql/format_copy_test.go index baf5c59f..8ca7d351 100644 --- a/internal/fanql/format_copy_test.go +++ b/internal/fanql/format_copy_test.go @@ -3,11 +3,11 @@ package fanql import ( "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestFormatGaugeExplainsNoGrouping(t *testing.T) { - query := panel.Query{From: "spans", Measures: []string{"count()"}, By: []string{"service", "operation"}, Bucket: "1m"} + query := query.Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service", "operation"}, Bucket: "1m"} _, ps, err := Format(t.Context(), nil, query, Options{Viz: "gauge"}) if err != nil { t.Fatal(err) diff --git a/internal/fanql/fuzz_test.go b/internal/fanql/fuzz_test.go index 793a6118..e9900ef4 100644 --- a/internal/fanql/fuzz_test.go +++ b/internal/fanql/fuzz_test.go @@ -9,7 +9,7 @@ import ( "testing" "unicode/utf8" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func FuzzCompileFormatCompile(f *testing.F) { @@ -29,13 +29,13 @@ func FuzzCompileFormatCompile(f *testing.F) { f.Add(text, "") } engine, _ := newTestEngine(f) - vars := []panel.Variable{{Name: "svc", Kind: "text"}, {Name: "svcs", Kind: "custom", Options: []string{"api", "worker"}, Multi: true}} + vars := []query.Variable{{Name: "svc", Kind: "text"}, {Name: "svcs", Kind: "custom", Options: []string{"api", "worker"}, Multi: true}} f.Fuzz(func(t *testing.T, text, viz string) { c, ps := Compile(text, Options{Viz: viz, Variables: vars}) if len(ps) != 0 { return } - compatible := panel.CompatibleVizzes(&c.Query, nil) + compatible := query.CompatibleVizzes(&c.Query, nil) if len(compatible) == 0 { // Filter-only metrics have no valid panel visualization. return @@ -44,10 +44,10 @@ func FuzzCompileFormatCompile(f *testing.F) { if checkViz == "" { checkViz = compatible[0].Viz } - d := panel.Dashboard{Name: "Round trip", Variables: vars, Panels: []panel.Panel{{ID: "p", Title: "p", Viz: checkViz, Query: &c.Query}}} + d := query.Dashboard{Name: "Round trip", Variables: vars, Panels: []query.Panel{{ID: "p", Title: "p", Viz: checkViz, Query: &c.Query}}} // Compile leaves raw SQL validation to the panel gate. The property // applies to executable panel queries, including raw SQL and comments. - if _, problems, err := panel.Check(t.Context(), engine, &d); err != nil { + if _, problems, err := query.Check(t.Context(), engine, &d); err != nil { t.Fatal(err) } else if len(problems) != 0 { return @@ -136,16 +136,16 @@ func TestStructuredGeneratorCoversConditionalMeasuresAndArithmetic(t *testing.T) for choice := range 16 { // Fixed bytes keep the generated filters short while varying measures. q := generatedStructuredQuery([]byte{byte(source), byte(choice), 1, 1, 1, 1, 1, 1}) - m, err := panel.ParseMeasure(q.From, q.Measures[0]) + m, err := query.ParseMeasure(q.From, q.Measures[0]) if err != nil { t.Fatal(err) } switch x := m.Expr.(type) { - case panel.MeasureCountIf: + case query.MeasureCountIf: conditional = true - case panel.MeasureBinary: + case query.MeasureBinary: arithmetic = true - if _, ok := x.L.(panel.MeasureCountIf); ok { + if _, ok := x.L.(query.MeasureCountIf); ok { conditional = true } } @@ -167,7 +167,7 @@ func TestStructuredGeneratorCoversConditionalMeasuresAndArithmetic(t *testing.T) // generatedStructuredQuery is generator B: a bounded grammar of SQL accepted // by the existing gate, independent of FanQL's own lowerer and printer. -func generatedStructuredQuery(data []byte) panel.Query { +func generatedStructuredQuery(data []byte) query.Spec { byteAt := func(i int) byte { if len(data) == 0 { return 0 @@ -188,7 +188,7 @@ func generatedStructuredQuery(data []byte) panel.Query { "count() / 2 as half", ) } - q := panel.Query{From: source, Measures: []string{measures[int(byteAt(1))%len(measures)]}} + q := query.Spec{From: source, Measures: []string{measures[int(byteAt(1))%len(measures)]}} if byteAt(2)%5 == 0 { // Every entry remains under 500 bytes; their complete text exceeds the // interactive character bound without invalidating the structured Query. @@ -240,8 +240,8 @@ func generatedStructuredQuery(data []byte) panel.Query { func FuzzFormatRoundTrip(f *testing.F) { type seed struct { - Query panel.Query `json:"query"` - Variables []panel.Variable `json:"variables,omitempty"` + Query query.Spec `json:"query"` + Variables []query.Variable `json:"variables,omitempty"` Viz string `json:"viz,omitempty"` } for _, fixture := range storedQueryFixtures(f) { @@ -278,19 +278,19 @@ func FuzzFormatRoundTrip(f *testing.F) { input = seed{Query: generatedStructuredQuery(data)} } stored := input.Query - if len(panel.CompatibleVizzes(&stored, nil)) == 0 { + if len(query.CompatibleVizzes(&stored, nil)) == 0 { return } viz := input.Viz if viz == "" { - viz = panel.CompatibleVizzes(&stored, nil)[0].Viz + viz = query.CompatibleVizzes(&stored, nil)[0].Viz } checkedQuery := stored - dashboard := panel.Dashboard{Name: "Fuzz", Variables: input.Variables, Panels: []panel.Panel{{ID: "fuzz", Title: "Fuzz", Viz: viz, Query: &checkedQuery}}} - panel.Normalize(&dashboard) + dashboard := query.Dashboard{Name: "Fuzz", Variables: input.Variables, Panels: []query.Panel{{ID: "fuzz", Title: "Fuzz", Viz: viz, Query: &checkedQuery}}} + query.Normalize(&dashboard) // JSON mutation can produce syntactically invalid SQL in a shape-valid // Query. The round-trip promise applies only to the gate's accepted input. - if _, problems, err := panel.Check(t.Context(), engine, &dashboard); err != nil { + if _, problems, err := query.Check(t.Context(), engine, &dashboard); err != nil { t.Fatal(err) } else if len(problems) != 0 { return @@ -303,15 +303,15 @@ func FuzzFormatRoundTrip(f *testing.F) { // Complete, noneditable text is never sent through public Parse. before, _ := json.Marshal(stored) raw, err := json.Marshal(struct { - Text string `json:"text"` - Editable bool `json:"editable"` - Query panel.Query `json:"query"` + Text string `json:"text"` + Editable bool `json:"editable"` + Query query.Spec `json:"query"` }{formatted.Text, false, stored}) if err != nil { t.Fatal(err) } var envelope struct { - Query panel.Query `json:"query"` + Query query.Spec `json:"query"` } if err := json.Unmarshal(raw, &envelope); err != nil { t.Fatal(err) diff --git a/internal/fanql/latency_test.go b/internal/fanql/latency_test.go index 9e47138e..b2c25d5b 100644 --- a/internal/fanql/latency_test.go +++ b/internal/fanql/latency_test.go @@ -11,11 +11,11 @@ import ( "time" "unicode/utf8" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type budgetParser struct { - panel.Parser + query.Parser parseCalls, renderCalls int } @@ -46,7 +46,7 @@ func TestLatencyBudgets(t *testing.T) { engine, _ := newTestEngine(t) parser := &budgetParser{Parser: engine} var schemaFetches atomic.Int32 - warm := NewCompleter(completionSchemaFunc(func(context.Context, panel.SchemaRequest) (*panel.Schema, error) { + warm := NewCompleter(completionSchemaFunc(func(context.Context, query.SchemaRequest) (*query.Schema, error) { schemaFetches.Add(1) return completionFixtureSchema(), nil })) @@ -147,13 +147,13 @@ func latencyFormatFixtures(t testing.TB) []storedQueryFixture { if q == nil || len(q.Where) > 16 { continue } - if problems, _ := panel.QueryShape(q, fixture.Panel.Viz, nil); len(problems) != 0 { + if problems, _ := query.Shape(q, fixture.Panel.Viz, nil); len(problems) != 0 { t.Fatalf("stored fixture %q is not shape-valid: %+v", fixture.Name, problems) } queries = append(queries, fixture) } q := generatedStructuredQuery([]byte{0}) // 16 complete stored entries. - return append(queries, storedQueryFixture{Name: "16 entries", Panel: panel.Panel{Query: &q}}) + return append(queries, storedQueryFixture{Name: "16 entries", Panel: query.Panel{Query: &q}}) } func benchmarkLatency(b *testing.B, percentile float64, metric string, run func(int)) { diff --git a/internal/fanql/lift.go b/internal/fanql/lift.go index 1e4e7669..9ee0ac55 100644 --- a/internal/fanql/lift.go +++ b/internal/fanql/lift.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/sqlscan" "github.com/labstack/fanout/internal/telemetry" ) @@ -33,7 +33,7 @@ func operationalFormatError(err error) bool { return !errors.As(err, &input) && !strings.HasPrefix(err.Error(), "SQL parsing failed:") } -func liftEntry(ctx context.Context, p panel.Parser, signal, stored string) (filterExpr, tier, error) { +func liftEntry(ctx context.Context, p query.Parser, signal, stored string) (filterExpr, tier, error) { if e := recognizeOwnLowering(signal, stored); e != nil { return e, tierExact, nil } @@ -41,7 +41,7 @@ func liftEntry(ctx context.Context, p panel.Parser, signal, stored string) (filt if err != nil { return nil, tierRaw, err } - e := liftSQLNode(signal, panel.SQLExpression(node["where_clause"])) + e := liftSQLNode(signal, query.SQLExpression(node["where_clause"])) e = reparseLiftedEntry(signal, e) if e == nil { return &rawEntry{Text: stored}, tierRaw, nil @@ -115,7 +115,7 @@ func liftFieldText(signal, text string) (fieldName, bool) { return liftSQLField(signal, node, false) } -func liftSQLField(signal string, node *panel.SQLExpr, contains bool) (fieldName, bool) { +func liftSQLField(signal string, node *query.SQLExpr, contains bool) (fieldName, bool) { if node == nil { return fieldName{}, false } @@ -141,9 +141,9 @@ func liftSQLField(signal string, node *panel.SQLExpr, contains bool) (fieldName, return fieldName{}, false } name := names[0] - cols, _ := panel.SignalColumns(signal) + cols, _ := query.SignalColumns(signal) for _, col := range cols { - if col.Name == name && col.Type != panel.TypeMap { + if col.Name == name && col.Type != query.TypeMap { return fieldName{Key: name, Single: true, Ref: &fieldRef{Column: name, Type: col.Type, Unit: col.Unit}}, true } } @@ -165,12 +165,12 @@ func liftSQLField(signal string, node *panel.SQLExpr, contains bool) (fieldName, return fieldName{}, false } column := names[0] - return fieldName{Scope: column, Key: v.Text, Bracket: true, Ref: &fieldRef{Column: column, Key: v.Text, Type: panel.TypeString, Unit: "none"}}, true + return fieldName{Scope: column, Key: v.Text, Bracket: true, Ref: &fieldRef{Column: column, Key: v.Text, Type: query.TypeString, Unit: "none"}}, true } return fieldName{}, false } -func liftSQLValue(node *panel.SQLExpr) (literalValue, bool) { +func liftSQLValue(node *query.SQLExpr) (literalValue, bool) { if node == nil { return literalValue{}, false } @@ -213,9 +213,9 @@ func spellingValue(f fieldName, v literalValue, aliases bool) literalValue { } return v } - if v.Kind == stringValue && f.Ref.Key == "" && f.Ref.Type == panel.TypeString { + if v.Kind == stringValue && f.Ref.Key == "" && f.Ref.Type == query.TypeString { if aliases { - for alias, stored := range panel.FieldAliases(f.Ref.Column) { + for alias, stored := range query.FieldAliases(f.Ref.Column) { if v.Text == stored { v.Kind = wordValue v.Text = alias @@ -245,7 +245,7 @@ func spellingValue(f fieldName, v literalValue, aliases bool) literalValue { return v } if f.Ref.Column == "type" { - if _, ok := panel.FieldAliases("type")[v.Text]; !ok { + if _, ok := query.FieldAliases("type")[v.Text]; !ok { return v } } @@ -273,7 +273,7 @@ func durationText(ms float64) string { return strconv.FormatFloat(ms, 'f', -1, 64) + "ms" } -func liftSQLNode(signal string, node *panel.SQLExpr) filterExpr { +func liftSQLNode(signal string, node *query.SQLExpr) filterExpr { if node == nil { return nil } @@ -424,7 +424,7 @@ func liftSQLNode(signal string, node *panel.SQLExpr) filterExpr { return nil } -func liftSQLCall(signal string, node *panel.SQLExpr) *filterCall { +func liftSQLCall(signal string, node *query.SQLExpr) *filterCall { if node == nil || node.Class != "FUNCTION" { return nil } @@ -447,7 +447,7 @@ func liftSQLCall(signal string, node *panel.SQLExpr) *filterCall { } return out } -func unwrapFunction(node *panel.SQLExpr, name string) (*panel.SQLExpr, bool) { +func unwrapFunction(node *query.SQLExpr, name string) (*query.SQLExpr, bool) { if node == nil || node.Class != "FUNCTION" || node.Function != name || len(node.Arguments) != 1 { return nil, false } @@ -567,16 +567,16 @@ func liftSeverityRange(in *inExpr) filterExpr { return &betweenExpr{Field: in.Field, Lo: value(first), Hi: value(last), Bands: bands} } -func liftMeasure(ctx context.Context, p panel.Parser, signal, stored string) (measureNode, tier, error) { - parsed, err := panel.ParseMeasure(signal, stored) +func liftMeasure(ctx context.Context, p query.Parser, signal, stored string) (measureNode, tier, error) { + parsed, err := query.ParseMeasure(signal, stored) if err != nil { return measureNode{}, tierRaw, formatInput("%s", err) } m := measureNode{Parsed: parsed, Alias: parsed.Alias, Filters: map[string]filterExpr{}} - var lift func(panel.MeasureExpr) error - lift = func(e panel.MeasureExpr) error { + var lift func(query.MeasureExpr) error + lift = func(e query.MeasureExpr) error { switch x := e.(type) { - case panel.MeasureCountIf: + case query.MeasureCountIf: // The count_if conjunction is intentionally stored without outer brackets. reader := &ownSQLReader{tokens: ownSQLTokens(x.Filter)} node := reader.expression(0) @@ -598,12 +598,12 @@ func liftMeasure(ctx context.Context, p panel.Parser, signal, stored string) (me filter = &rawEntry{Text: x.Filter} } m.Filters[x.Filter] = filter - case panel.MeasureBinary: + case query.MeasureBinary: if err := lift(x.L); err != nil { return err } return lift(x.R) - case panel.MeasureNeg: + case query.MeasureNeg: return lift(x.X) } return nil @@ -615,7 +615,7 @@ func liftMeasure(ctx context.Context, p panel.Parser, signal, stored string) (me if lowered == stored { return m, tierExact, nil } - again, err := panel.ParseMeasure(signal, lowered) + again, err := query.ParseMeasure(signal, lowered) if err == nil && reflect.DeepEqual(parsed.Expr, again.Expr) && parsed.Alias == again.Alias { return m, tierNormalized, nil } @@ -709,7 +709,7 @@ func (r *ownSQLReader) need(s string) { r.failed = true } } -func (r *ownSQLReader) expression(min int) *panel.SQLExpr { +func (r *ownSQLReader) expression(min int) *query.SQLExpr { left := r.predicate() for { op := r.peek() @@ -730,12 +730,12 @@ func (r *ownSQLReader) expression(min int) *panel.SQLExpr { children := left.Children left.Children = append(children, right) } else { - left = &panel.SQLExpr{Class: "CONJUNCTION", Type: kind, Children: []*panel.SQLExpr{left, right}} + left = &query.SQLExpr{Class: "CONJUNCTION", Type: kind, Children: []*query.SQLExpr{left, right}} } } return left } -func (r *ownSQLReader) predicate() *panel.SQLExpr { +func (r *ownSQLReader) predicate() *query.SQLExpr { if r.eat("NOT") { return ownOperator("OPERATOR_NOT", r.predicate()) } @@ -743,7 +743,7 @@ func (r *ownSQLReader) predicate() *panel.SQLExpr { op := r.peek() if kind := map[string]string{"=": "COMPARE_EQUAL", "!=": "COMPARE_NOTEQUAL", "<>": "COMPARE_NOTEQUAL", "<": "COMPARE_LESSTHAN", ">": "COMPARE_GREATERTHAN", "<=": "COMPARE_LESSTHANOREQUALTO", ">=": "COMPARE_GREATERTHANOREQUALTO"}[op]; kind != "" { r.pos++ - return &panel.SQLExpr{Class: "COMPARISON", Type: kind, Left: left, Right: r.atom()} + return &query.SQLExpr{Class: "COMPARISON", Type: kind, Left: left, Right: r.atom()} } if r.eat("IS") { neg := r.eat("NOT") @@ -756,7 +756,7 @@ func (r *ownSQLReader) predicate() *panel.SQLExpr { } neg := r.eat("NOT") if r.eat("IN") { - children := []*panel.SQLExpr{left} + children := []*query.SQLExpr{left} if r.eat("(") { for { children = append(children, r.atom()) @@ -778,19 +778,19 @@ func (r *ownSQLReader) predicate() *panel.SQLExpr { lo := r.atom() r.need("AND") hi := r.atom() - return &panel.SQLExpr{Class: "BETWEEN", Type: "COMPARE_BETWEEN", Input: left, Lower: lo, Upper: hi, Negated: neg} + return &query.SQLExpr{Class: "BETWEEN", Type: "COMPARE_BETWEEN", Input: left, Lower: lo, Upper: hi, Negated: neg} } op = r.peek() if op == "~~" || op == "!~~" || op == "~~*" || op == "!~~*" { r.pos++ - return ownFunction(strings.ToLower(op), []*panel.SQLExpr{left, r.atom()}) + return ownFunction(strings.ToLower(op), []*query.SQLExpr{left, r.atom()}) } if neg { r.failed = true } return left } -func (r *ownSQLReader) atom() *panel.SQLExpr { +func (r *ownSQLReader) atom() *query.SQLExpr { if r.pos >= len(r.tokens) { r.failed = true return nil @@ -805,18 +805,18 @@ func (r *ownSQLReader) atom() *panel.SQLExpr { } token := r.tokens[r.pos] r.pos++ - var node *panel.SQLExpr + var node *query.SQLExpr switch { case token.quote == '\'': node = ownConstant("STRING", token.text) case token.quote == '"': - node = &panel.SQLExpr{Class: "COLUMN_REF", Columns: []string{token.text}} + node = &query.SQLExpr{Class: "COLUMN_REF", Columns: []string{token.text}} case strings.EqualFold(token.text, "true") || strings.EqualFold(token.text, "false"): node = ownConstant("BOOLEAN", strings.ToLower(token.text)) case numberPattern.MatchString(token.text): node = ownConstant("NUMERIC", token.text) case strings.HasPrefix(token.text, "$"): - node = &panel.SQLExpr{Class: "PARAMETER", Identifier: strings.TrimPrefix(token.text, "$")} + node = &query.SQLExpr{Class: "PARAMETER", Identifier: strings.TrimPrefix(token.text, "$")} case r.eat("("): name := strings.ToLower(token.text) if name == "cast" || name == "try_cast" { @@ -829,9 +829,9 @@ func (r *ownSQLReader) atom() *panel.SQLExpr { typ := strings.ToUpper(r.tokens[r.pos].text) r.pos++ r.need(")") - node = &panel.SQLExpr{Class: "CAST", Type: "OPERATOR_CAST", Child: child, TryCast: name == "try_cast", CastType: typ} + node = &query.SQLExpr{Class: "CAST", Type: "OPERATOR_CAST", Child: child, TryCast: name == "try_cast", CastType: typ} } else { - var args []*panel.SQLExpr + var args []*query.SQLExpr if !r.eat(")") { for { args = append(args, r.expression(0)) @@ -848,7 +848,7 @@ func (r *ownSQLReader) atom() *panel.SQLExpr { } } default: - node = &panel.SQLExpr{Class: "COLUMN_REF", Columns: []string{token.text}} + node = &query.SQLExpr{Class: "COLUMN_REF", Columns: []string{token.text}} } if r.eat("[") { key := r.atom() @@ -862,16 +862,16 @@ func (r *ownSQLReader) atom() *panel.SQLExpr { } typ := strings.ToUpper(r.tokens[r.pos].text) r.pos++ - node = &panel.SQLExpr{Class: "CAST", Child: node, CastType: typ} + node = &query.SQLExpr{Class: "CAST", Child: node, CastType: typ} } return node } -func ownConstant(kind, text string) *panel.SQLExpr { - return &panel.SQLExpr{Class: "CONSTANT", LiteralKind: kind, LiteralText: text} +func ownConstant(kind, text string) *query.SQLExpr { + return &query.SQLExpr{Class: "CONSTANT", LiteralKind: kind, LiteralText: text} } -func ownOperator(kind string, children ...*panel.SQLExpr) *panel.SQLExpr { - return &panel.SQLExpr{Class: "OPERATOR", Type: kind, Children: children} +func ownOperator(kind string, children ...*query.SQLExpr) *query.SQLExpr { + return &query.SQLExpr{Class: "OPERATOR", Type: kind, Children: children} } -func ownFunction(name string, args []*panel.SQLExpr) *panel.SQLExpr { - return &panel.SQLExpr{Class: "FUNCTION", Function: name, Arguments: args} +func ownFunction(name string, args []*query.SQLExpr) *query.SQLExpr { + return &query.SQLExpr{Class: "FUNCTION", Function: name, Arguments: args} } diff --git a/internal/fanql/lift_test.go b/internal/fanql/lift_test.go index d92b2fa2..ce007880 100644 --- a/internal/fanql/lift_test.go +++ b/internal/fanql/lift_test.go @@ -8,11 +8,11 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type countingParser struct { - panel.Parser + query.Parser calls int fail bool failErr error @@ -114,7 +114,7 @@ func TestLiftStoredSQLShapes(t *testing.T) { {"spans", `service = $service AND status = 'STATUS_CODE_ERROR'`, `(service:$service status:error)`, "normalized"}, } { t.Run(tt.sql, func(t *testing.T) { - q := panel.Query{From: tt.signal, Where: []string{tt.sql}} + q := query.Spec{From: tt.signal, Where: []string{tt.sql}} f, problems, err := Format(t.Context(), d, q, Options{}) if err != nil || len(problems) != 0 { t.Fatalf("format: %+v %v", problems, err) @@ -144,7 +144,7 @@ func TestLiftStoredSQLShapes(t *testing.T) { } }) } - q := panel.Query{From: "spans", Where: []string{`attributes['a'] = 1 OR attributes['b'] = 2`, `service = 'api'`}} + q := query.Spec{From: "spans", Where: []string{`attributes['a'] = 1 OR attributes['b'] = 2`, `service = 'api'`}} f, ps, err := Format(t.Context(), d, q, Options{}) if err != nil || len(ps) > 0 || f.Text != `spans where (attributes['a']:1 or attributes['b']:2) service:api` { t.Fatalf("entry grouping: %+v %+v %v", f, ps, err) @@ -159,12 +159,12 @@ func TestLiftMeasures(t *testing.T) { {`count_distinct(attributes['user.id'])`, `count_distinct(user.id)`, "exact"}, {`quantile(duration_ms, 0.999) as q`, `quantile(duration, 0.999) as q`, "exact"}, } { - f, ps, err := Format(t.Context(), d, panel.Query{From: "spans", Measures: []string{tt.stored}}, Options{}) + f, ps, err := Format(t.Context(), d, query.Spec{From: "spans", Measures: []string{tt.stored}}, Options{}) if err != nil || len(ps) > 0 || f.Text != "spans | "+tt.want || f.Exactness != Exactness(tt.tier) { t.Fatalf("%s: %+v %+v %v", tt.stored, f, ps, err) } } - q := panel.Query{From: "spans", Measures: []string{"count()"}, Histogram: &panel.Histogram{Field: "duration_ms", Buckets: "log2"}} + q := query.Spec{From: "spans", Measures: []string{"count()"}, Histogram: &query.Histogram{Field: "duration_ms", Buckets: "log2"}} f, ps, err := Format(t.Context(), d, q, Options{}) if err != nil || len(ps) > 0 || f.Text != "spans | histogram(duration)" { t.Fatalf("histogram: %+v %+v %v", f, ps, err) @@ -175,7 +175,7 @@ func TestLiftMeasures(t *testing.T) { t.Fatalf("invalid histogram: %+v %+v %v", f, ps, err) } for _, sort := range []string{"errors", "duration_ms", "+start"} { - f, ps, err = Format(t.Context(), d, panel.Query{From: "spans", Sort: sort}, Options{Viz: "traces"}) + f, ps, err = Format(t.Context(), d, query.Spec{From: "spans", Sort: sort}, Options{Viz: "traces"}) want := sort if sort == "duration_ms" { want = "duration" @@ -191,7 +191,7 @@ func TestLiftMeasures(t *testing.T) { func TestFormatEditableFalseIsCompleteAndReasoned(t *testing.T) { d, _ := newTestEngine(t) - q := panel.Query{From: "logs"} + q := query.Spec{From: "logs"} for i := range 16 { q.Where = append(q.Where, "body = '"+strings.Repeat("x", 480)+fmt.Sprint(i)+"'") } @@ -207,7 +207,7 @@ func TestFormatEditableFalseIsCompleteAndReasoned(t *testing.T) { t.Fatalf("lost literal %d", i) } } - rawQuery := panel.Query{From: "logs"} + rawQuery := query.Spec{From: "logs"} for i := range 16 { rawQuery.Where = append(rawQuery.Where, "coalesce(body, '"+strings.Repeat("𝔘", 110)+strings.Repeat("`", 30)+fmt.Sprint(i)+"') = ''") } @@ -238,7 +238,7 @@ func TestFormatEditableFalseIsCompleteAndReasoned(t *testing.T) { func TestFormatOperationalErrorIsReturnedNotAProblem(t *testing.T) { for _, wantErr := range []error{context.DeadlineExceeded, errors.New("disk failure")} { - f, ps, err := Format(t.Context(), &countingParser{failErr: wantErr}, panel.Query{From: "logs", Where: []string{`coalesce(body, '') = ''`}}, Options{}) + f, ps, err := Format(t.Context(), &countingParser{failErr: wantErr}, query.Spec{From: "logs", Where: []string{`coalesce(body, '') = ''`}}, Options{}) if f != nil || len(ps) > 0 || !errors.Is(err, wantErr) { t.Fatalf("got %+v %+v %v", f, ps, err) } @@ -246,7 +246,7 @@ func TestFormatOperationalErrorIsReturnedNotAProblem(t *testing.T) { } type failingRenderParser struct { - panel.Parser + query.Parser err error } @@ -257,7 +257,7 @@ func (p failingRenderParser) RenderSQL(context.Context, map[string]any) (string, func TestFormatRenderOperationalErrorIsReturnedNotAProblem(t *testing.T) { d, _ := newTestEngine(t) wantErr := errors.New("engine serialization failed") - f, ps, err := Format(t.Context(), failingRenderParser{Parser: d, err: wantErr}, panel.Query{From: "spans", Where: []string{`service='api'`}}, Options{}) + f, ps, err := Format(t.Context(), failingRenderParser{Parser: d, err: wantErr}, query.Spec{From: "spans", Where: []string{`service='api'`}}, Options{}) if f != nil || len(ps) > 0 || !errors.Is(err, wantErr) { t.Fatalf("got %+v %+v %v", f, ps, err) } @@ -265,7 +265,7 @@ func TestFormatRenderOperationalErrorIsReturnedNotAProblem(t *testing.T) { func TestFormatRejectsQueryInvalidUnderEveryViz(t *testing.T) { p := &countingParser{fail: true} - f, ps, err := Format(t.Context(), p, panel.Query{From: "spans", Measures: []string{"count()"}, By: []string{"a", "b", "c", "d"}}, Options{}) + f, ps, err := Format(t.Context(), p, query.Spec{From: "spans", Measures: []string{"count()"}, By: []string{"a", "b", "c", "d"}}, Options{}) if f != nil || len(ps) == 0 || err != nil || p.calls != 0 { t.Fatalf("got %+v %+v %v calls %d", f, ps, err, p.calls) } @@ -304,11 +304,11 @@ func TestFormatOwnLoweringFilterFixturesNeedNoEngine(t *testing.T) { func TestFormatReportsIgnoredSortAndLimit(t *testing.T) { for _, tt := range []struct { viz string - q panel.Query + q query.Spec }{ - {"timeseries", panel.Query{From: "spans", Measures: []string{"count()"}, Bucket: "auto", Sort: "count", Limit: 10}}, - {"stat", panel.Query{From: "spans", Measures: []string{"count()"}, Limit: 10}}, - {"gauge", panel.Query{From: "spans", Measures: []string{"count()"}, Limit: 10}}, + {"timeseries", query.Spec{From: "spans", Measures: []string{"count()"}, Bucket: "auto", Sort: "count", Limit: 10}}, + {"stat", query.Spec{From: "spans", Measures: []string{"count()"}, Limit: 10}}, + {"gauge", query.Spec{From: "spans", Measures: []string{"count()"}, Limit: 10}}, } { f, ps, err := Format(t.Context(), &countingParser{fail: true}, tt.q, Options{Viz: tt.viz}) want := []Notice{{Path: "limit", Message: "limit does not apply to " + tt.viz + " panels; the whole window produces one value"}} @@ -389,7 +389,7 @@ func TestFormatOwnLiteralSpellingsAreFixedPoints(t *testing.T) { } func TestFormatUndeclaredContextReportsVariableNotices(t *testing.T) { - q := panel.Query{From: "spans", Where: []string{"service = $x"}} + q := query.Spec{From: "spans", Where: []string{"service = $x"}} f, ps, err := Format(t.Context(), &countingParser{fail: true}, q, Options{}) if err != nil || len(ps) != 0 || f == nil || len(f.Notices) != 1 || f.Notices[0].Path != "where[0]" || f.Notices[0].Message != "declared variables are needed to check $x" { t.Fatalf("variable context: %+v %+v %v", f, ps, err) @@ -397,7 +397,7 @@ func TestFormatUndeclaredContextReportsVariableNotices(t *testing.T) { } func TestFormatPreservesQueriesValidUnderAnotherViz(t *testing.T) { - q := panel.Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}} + q := query.Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}} f, ps, err := Format(t.Context(), &countingParser{fail: true}, q, Options{Viz: "timeseries"}) if err != nil || len(ps) != 0 || f == nil || f.Text != "spans | count() by service" { t.Fatalf("valid table query: %+v %+v %v", f, ps, err) diff --git a/internal/fanql/literal_roundtrip_test.go b/internal/fanql/literal_roundtrip_test.go index f52b6400..d822bf57 100644 --- a/internal/fanql/literal_roundtrip_test.go +++ b/internal/fanql/literal_roundtrip_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func TestCompileNestedMeasureNegation(t *testing.T) { @@ -19,7 +19,7 @@ func TestCompileNestedMeasureNegation(t *testing.T) { if len(ps) != 0 || c == nil { t.Fatalf("compile %q: %+v", text, ps) } - if _, err := panel.ParseMeasure(c.Query.From, c.Query.Measures[0]); err != nil { + if _, err := query.ParseMeasure(c.Query.From, c.Query.Measures[0]); err != nil { t.Fatalf("lowered measure %q: %v", c.Query.Measures[0], err) } again, ps := Compile(c.Canonical, Options{}) diff --git a/internal/fanql/lower.go b/internal/fanql/lower.go index 3756df0d..a535f55d 100644 --- a/internal/fanql/lower.go +++ b/internal/fanql/lower.go @@ -6,22 +6,22 @@ import ( "strconv" "strings" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) // lower is pure: it emits one SQL string per entry and keeps all stored order. -func lower(r *resolved) (panel.Query, panel.Problems) { +func lower(r *resolved) (query.Spec, query.Problems) { q := r.Query - out := panel.Query{From: q.Source} - var problems panel.Problems + out := query.Spec{From: q.Source} + var problems query.Problems for i, e := range q.Where { if i == 16 { - problems = append(problems, panel.Problem{Path: fmt.Sprintf("where[%d]", i), Message: "at most 16 filters", Span: textSpan(e.Span())}) + problems = append(problems, query.Problem{Path: fmt.Sprintf("where[%d]", i), Message: "at most 16 filters", Span: textSpan(e.Span())}) break } sql := lowerEntry(e) if len(sql) > 500 { - problems = append(problems, panel.Problem{Path: fmt.Sprintf("where[%d]", i), Message: fmt.Sprintf("this filter lowers to %d bytes; filters are at most 500", len(sql)), Span: textSpan(e.Span())}) + problems = append(problems, query.Problem{Path: fmt.Sprintf("where[%d]", i), Message: fmt.Sprintf("this filter lowers to %d bytes; filters are at most 500", len(sql)), Span: textSpan(e.Span())}) } out.Where = append(out.Where, sql) } @@ -36,7 +36,7 @@ func lower(r *resolved) (panel.Query, panel.Problems) { buckets = "explicit" } out.Measures = []string{"count()"} - out.Histogram = &panel.Histogram{Field: lowerField(*s.Histogram), Buckets: buckets} + out.Histogram = &query.Histogram{Field: lowerField(*s.Histogram), Buckets: buckets} } else { for _, m := range s.Measures { out.Measures = append(out.Measures, lowerMeasure(m)) @@ -100,13 +100,13 @@ func lowerValue(f fieldName, v literalValue) string { n, _ := durationMS(v.Text) return decimal(n) } - if f.Ref != nil && f.Ref.Type == panel.TypeTime && f.Ref.Key == "" { + if f.Ref != nil && f.Ref.Type == query.TypeTime && f.Ref.Key == "" { return sqlString(text) + "::TIMESTAMPTZ_NS" } if v.Kind == stringValue { return sqlString(text) } - if f.Ref != nil && f.Ref.Key == "" && f.Ref.Type == panel.TypeString && f.Ref.CompareAs == "" { + if f.Ref != nil && f.Ref.Key == "" && f.Ref.Type == query.TypeString && f.Ref.CompareAs == "" { return sqlString(text) } if v.Kind == numberValue { @@ -329,7 +329,7 @@ func lowerCall(c *filterCall) string { } func lowerMeasure(m measureNode) string { - text := renderMeasure(m.Parsed.Expr, 0, func(f *panel.FieldRef) string { return f.Text }, func(sql string) string { return sql }) + text := renderMeasure(m.Parsed.Expr, 0, func(f *query.FieldRef) string { return f.Text }, func(sql string) string { return sql }) if m.Alias != "" { text += " as " + m.Alias } diff --git a/internal/fanql/lower_test.go b/internal/fanql/lower_test.go index fdba2dd8..43ab6edc 100644 --- a/internal/fanql/lower_test.go +++ b/internal/fanql/lower_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) var lowerFixtures = []struct{ text, sql string }{ @@ -80,7 +80,7 @@ func TestLowerPreservesExactIntegerLiterals(t *testing.T) { if len(ps) != 0 { t.Fatal(ps) } - want := panel.Query{From: "logs", Where: []string{"attributes['id'] = " + value}} + want := query.Spec{From: "logs", Where: []string{"attributes['id'] = " + value}} if !reflect.DeepEqual(c.Query, want) { t.Fatalf("lowered %#v; want %#v", c.Query, want) } @@ -102,7 +102,7 @@ func TestLowerCountIfRawSQLComments(t *testing.T) { if want := "count_if(" + body + ") as n"; len(c.Query.Measures) != 1 || c.Query.Measures[0] != want { t.Fatalf("%q: got %#v; want %q", text, c.Query.Measures, want) } - if _, err := panel.ParseMeasure(c.Query.From, c.Query.Measures[0]); err != nil { + if _, err := query.ParseMeasure(c.Query.From, c.Query.Measures[0]); err != nil { t.Fatalf("%q: %v", text, err) } } @@ -115,7 +115,7 @@ func TestLowerPositiveFixtures(t *testing.T) { if len(ps) > 0 { t.Fatal(ps) } - want := panel.Query{From: strings.Fields(tt.text)[0], Where: []string{tt.sql}} + want := query.Spec{From: strings.Fields(tt.text)[0], Where: []string{tt.sql}} if !reflect.DeepEqual(c.Query, want) { t.Fatalf("got %#v; want %#v", c.Query, want) } @@ -123,13 +123,13 @@ func TestLowerPositiveFixtures(t *testing.T) { } for _, tt := range []struct { text string - want panel.Query + want query.Spec }{ - {`spans | histogram(duration) by service`, panel.Query{From: "spans", Measures: []string{"count()"}, Histogram: &panel.Histogram{Field: "duration_ms", Buckets: "log2"}, By: []string{"service"}}}, - {`metrics where name:x | histogram(value) every 1m`, panel.Query{From: "metrics", Where: []string{"name = 'x'"}, Measures: []string{"count()"}, Histogram: &panel.Histogram{Field: "value", Buckets: "explicit"}, Bucket: "1m"}}, - {`spans sort errors limit 50`, panel.Query{From: "spans", Sort: "errors", Limit: 50}}, - {`spans sort duration`, panel.Query{From: "spans", Sort: "duration_ms"}}, - {`logs sort +time`, panel.Query{From: "logs", Sort: "+time"}}, + {`spans | histogram(duration) by service`, query.Spec{From: "spans", Measures: []string{"count()"}, Histogram: &query.Histogram{Field: "duration_ms", Buckets: "log2"}, By: []string{"service"}}}, + {`metrics where name:x | histogram(value) every 1m`, query.Spec{From: "metrics", Where: []string{"name = 'x'"}, Measures: []string{"count()"}, Histogram: &query.Histogram{Field: "value", Buckets: "explicit"}, Bucket: "1m"}}, + {`spans sort errors limit 50`, query.Spec{From: "spans", Sort: "errors", Limit: 50}}, + {`spans sort duration`, query.Spec{From: "spans", Sort: "duration_ms"}}, + {`logs sort +time`, query.Spec{From: "logs", Sort: "+time"}}, } { c, ps := Compile(tt.text, Options{}) if len(ps) > 0 || !reflect.DeepEqual(c.Query, tt.want) { @@ -226,7 +226,7 @@ func TestLowerStructuredBounds(t *testing.T) { func TestLowerSearchBarMode(t *testing.T) { c, ps := Compile("service:api timeout", Options{Source: "logs"}) - want := panel.Query{From: "logs", Where: []string{`service = 'api'`, `contains(lower(body), lower('timeout'))`}} + want := query.Spec{From: "logs", Where: []string{`service = 'api'`, `contains(lower(body), lower('timeout'))`}} if len(ps) > 0 || !reflect.DeepEqual(c.Query, want) { t.Fatal(c, ps) } diff --git a/internal/fanql/parser.go b/internal/fanql/parser.go index 2b707b5b..2ff9209f 100644 --- a/internal/fanql/parser.go +++ b/internal/fanql/parser.go @@ -8,7 +8,7 @@ import ( "strings" "unicode" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) const ( @@ -28,12 +28,12 @@ type parser struct { clauseID int reported map[int]bool structural map[int]int - measureInfo map[panel.MeasureExpr]*measureSource + measureInfo map[query.MeasureExpr]*measureSource vocab vocabulary tokens lexTokens runes []rune i int - problems panel.Problems + problems query.Problems bounded bool nodes, depth int heights map[any]int @@ -67,7 +67,7 @@ func (p *parser) expectTerm(nested bool) { // allocation. Other panics remain visible to callers and tests. type parseBound struct{} -func parseWith(text string, source string, vocab vocabulary) (q *queryTree, problems panel.Problems) { +func parseWith(text string, source string, vocab vocabulary) (q *queryTree, problems query.Problems) { p := &parser{vocab: vocab, runes: []rune(text), bounded: true, heights: make(map[any]int)} defer func() { if v := recover(); v != nil { @@ -99,7 +99,7 @@ func parseWith(text string, source string, vocab vocabulary) (q *queryTree, prob } // parseEntry is the unbounded internal entry parser used by the lift gate. -func parseEntry(text string) (filterExpr, panel.Problems) { +func parseEntry(text string) (filterExpr, query.Problems) { p := &parser{vocab: currentVocabulary(), runes: []rune(text), tokens: lex(text), heights: make(map[any]int)} terms := p.filters(false) for p.peek().Kind != eof { @@ -162,7 +162,7 @@ func (p *parser) issue(at span, message, hint string) { return } p.reported[p.clauseID] = true - p.problems = append(p.problems, panel.Problem{Path: "text", Message: message, Hint: hint, Span: &panel.TextSpan{Start: at.Start, End: at.End}}) + p.problems = append(p.problems, query.Problem{Path: "text", Message: message, Hint: hint, Span: &query.TextSpan{Start: at.Start, End: at.End}}) } func (p *parser) report(at span, code diagnosticCode, args ...any) { p.issue(at, diagnostic(code, args...), hint(code)) @@ -196,12 +196,12 @@ func (p *parser) node(x any, children ...any) { p.bound(x.(interface{ Span() span }).Span(), diagDepthBound) } } -func (p *parser) finish() panel.Problems { +func (p *parser) finish() query.Problems { sort.SliceStable(p.problems, func(i, j int) bool { return p.problems[i].Span.Start < p.problems[j].Span.Start }) if len(p.problems) > maxProblems { at := *p.problems[maxProblems].Span p.problems = p.problems[:maxProblems] - p.problems = append(p.problems, panel.Problem{Path: "text", Message: diagnostic(diagMore), Span: &at}) + p.problems = append(p.problems, query.Problem{Path: "text", Message: diagnostic(diagMore), Span: &at}) } return p.problems } @@ -400,9 +400,9 @@ func (p *parser) filters(nested bool) []filterExpr { p.structural = map[int]int{} } p.structural[p.clauseID]++ - span := panel.TextSpan{Start: at.Start, End: at.End} + span := query.TextSpan{Start: at.Start, End: at.End} if len(p.problems) > before { - p.problems[len(p.problems)-1].FixIts = []panel.FixIt{{Label: first, Span: span, Text: first}, {Label: second, Span: span, Text: second}} + p.problems[len(p.problems)-1].FixIts = []query.FixIt{{Label: first, Span: span, Text: first}, {Label: second, Span: span, Text: second}} } } if mode == "or" && len(terms) > 1 { @@ -1149,7 +1149,7 @@ func (p *parser) parseLimit() *limitClause { func (p *parser) stage(start int) *aggregation { p.beginClause() - p.measureInfo = map[panel.MeasureExpr]*measureSource{} + p.measureInfo = map[query.MeasureExpr]*measureSource{} s := &aggregation{At: span{Start: start}} if p.completion { p.completionQuery.Stage = s @@ -1172,7 +1172,7 @@ func (p *parser) stage(start int) *aggregation { } expr := p.measureExpression(0) if expr != nil { - m := measureNode{Parsed: panel.Measure{Expr: expr}, At: p.measureSpan(expr), Info: p.measureInfo, Filters: map[string]filterExpr{}} + m := measureNode{Parsed: query.Measure{Expr: expr}, At: p.measureSpan(expr), Info: p.measureInfo, Filters: map[string]filterExpr{}} if modifiers[p.lower()] && p.eat("as") { t := p.peek() if t.Kind == tokenIdent { @@ -1186,8 +1186,8 @@ func (p *parser) stage(start int) *aggregation { if leaves == 0 { p.report(p.measureSpan(expr), diagAggregate) } - _, call := expr.(panel.MeasureCall) - _, countIf := expr.(*panel.MeasureCountIf) + _, call := expr.(query.MeasureCall) + _, countIf := expr.(*query.MeasureCountIf) if distribution && !call { p.report(p.measureSpan(expr), diagHistogram) } @@ -1199,7 +1199,7 @@ func (p *parser) stage(start int) *aggregation { p.report(p.measureSpan(expr), diagShare) } } - if call, ok := expr.(panel.MeasureCall); ok && call.Func == "histogram" { + if call, ok := expr.(query.MeasureCall); ok && call.Func == "histogram" { if s.Histogram != nil || len(s.Measures) > 0 { p.report(p.measureSpan(call), diagHistogram) } @@ -1294,15 +1294,15 @@ func (p *parser) stage(start int) *aggregation { return s } -func (p *parser) measureSpan(e panel.MeasureExpr) span { return p.measureInfo[e].at } -func (p *parser) measureExpression(minPrec int) panel.MeasureExpr { - g := panel.MeasureGrammar{ +func (p *parser) measureSpan(e query.MeasureExpr) span { return p.measureInfo[e].at } +func (p *parser) measureExpression(minPrec int) query.MeasureExpr { + g := query.MeasureGrammar{ Peek: func() string { return grammarText(p.peek()) }, Take: func() { p.take() }, Position: func() int { return p.peek().Span.Start }, CanAtom: func() bool { t := p.peek() return t.Kind == tokenNumber || t.Kind == tokenBad || t.Kind == tokenIdent && t.Text != "as" }, - Atom: func() panel.MeasureExpr { + Atom: func() query.MeasureExpr { p.expectNext(expect{Class: "measure"}) t := p.peek() if t.Kind == tokenNumber { @@ -1312,7 +1312,7 @@ func (p *parser) measureExpression(minPrec int) panel.MeasureExpr { p.report(t.Span, diagMeasure) return nil } - x := panel.MeasureConst{Value: v, Text: t.Text} + x := query.MeasureConst{Value: v, Text: t.Text} p.recordMeasure(x, t.Span) return x } @@ -1329,19 +1329,19 @@ func (p *parser) measureExpression(minPrec int) panel.MeasureExpr { } return nil }, - Node: func(e panel.MeasureExpr, start int, children ...panel.MeasureExpr) panel.MeasureExpr { + Node: func(e query.MeasureExpr, start int, children ...query.MeasureExpr) query.MeasureExpr { p.recordMeasure(e, span{start, p.previousEnd()}, children...) return e }, - Group: func(e panel.MeasureExpr, start int) { info := p.measureInfo[e]; info.at = span{start, p.previousEnd()} }, + Group: func(e query.MeasureExpr, start int) { info := p.measureInfo[e]; info.at = span{start, p.previousEnd()} }, Enter: func(start int) { p.enter(span{start, start + 1}) }, Leave: p.leave, Depth: func(int) bool { return true }, OK: func() bool { return true }, - Fail: func(code panel.MeasureSyntaxCode, op string, start int) { + Fail: func(code query.MeasureSyntaxCode, op string, start int) { at := span{start, start + len(op)} switch code { - case panel.MeasureMissingOperand: + case query.MeasureMissingOperand: p.report(at, diagMeasureSides, op) - case panel.MeasureMissingClose: + case query.MeasureMissingClose: p.report(span{start, start + 1}, diagUnclosedGroup) default: p.report(p.peek().Span, diagMeasure) @@ -1351,12 +1351,12 @@ func (p *parser) measureExpression(minPrec int) panel.MeasureExpr { } }, } - e, _ := panel.ReadMeasureExpression(g, minPrec, 0) + e, _ := query.ReadMeasureExpression(g, minPrec, 0) return e } -func (p *parser) recordMeasure(e panel.MeasureExpr, at span, children ...panel.MeasureExpr) { +func (p *parser) recordMeasure(e query.MeasureExpr, at span, children ...query.MeasureExpr) { if p.measureInfo == nil { - p.measureInfo = map[panel.MeasureExpr]*measureSource{} + p.measureInfo = map[query.MeasureExpr]*measureSource{} } p.measureInfo[e] = &measureSource{at: at} p.nodes++ @@ -1373,7 +1373,7 @@ func (p *parser) recordMeasure(e panel.MeasureExpr, at span, children ...panel.M } } -func (p *parser) measureCall() panel.MeasureExpr { +func (p *parser) measureCall() query.MeasureExpr { name := p.take() open := p.take() at := span{Start: name.Span.Start} @@ -1388,7 +1388,7 @@ func (p *parser) measureCall() panel.MeasureExpr { } p.leave() at.End = p.previousEnd() - x := &panel.MeasureCountIf{} + x := &query.MeasureCountIf{} p.recordMeasure(x, at) if filter != nil { p.heights[x] = p.heights[filter] + 1 @@ -1399,7 +1399,7 @@ func (p *parser) measureCall() panel.MeasureExpr { p.measureInfo[x].filter = filter return x } - x := panel.MeasureCall{Func: strings.ToLower(name.Text), Field: &panel.FieldRef{}} + x := query.MeasureCall{Func: strings.ToLower(name.Text), Field: &query.FieldRef{}} var args []measureArgument p.expectNext(expect{Class: "marg", Func: x.Func, Arg: 0}) for p.peek().Kind != eof && !p.is(")") && !p.is("|") { @@ -1467,17 +1467,17 @@ func (p *parser) measureCall() panel.MeasureExpr { return x } -func measureLeaves(x panel.MeasureExpr) (int, bool, bool) { +func measureLeaves(x query.MeasureExpr) (int, bool, bool) { switch x := x.(type) { - case panel.MeasureCall: + case query.MeasureCall: return 1, x.Func == "share", x.Func == "histogram" - case panel.MeasureCountIf, *panel.MeasureCountIf: + case query.MeasureCountIf, *query.MeasureCountIf: return 1, false, false - case panel.MeasureBinary: + case query.MeasureBinary: l, ls, lh := measureLeaves(x.L) r, rs, rh := measureLeaves(x.R) return l + r, ls || rs, lh || rh - case panel.MeasureNeg: + case query.MeasureNeg: return measureLeaves(x.X) } return 0, false, false @@ -1488,7 +1488,7 @@ func fieldExample(field fieldName, op string) string { return "value" } name := strings.ToLower(field.Key) - if vocabulary := panel.FieldVocabularies()[name]; len(vocabulary.Order) > 0 { + if vocabulary := query.FieldVocabularies()[name]; len(vocabulary.Order) > 0 { return vocabulary.Order[0] } switch name { @@ -1506,18 +1506,18 @@ func fieldExample(field fieldName, op string) string { case "enabled": return "true" } - var columns []panel.Field - for _, source := range panel.SignalNames() { - if cols, ok := panel.SignalColumns(source); ok { + var columns []query.Field + for _, source := range query.SignalNames() { + if cols, ok := query.SignalColumns(source); ok { columns = append(columns, cols...) } } for _, column := range columns { if column.Name == name { switch column.Type { - case panel.TypeNumber: + case query.TypeNumber: return "1000" - case panel.TypeTime: + case query.TypeTime: return `"2026-10-29T10:00:00Z"` } } @@ -1528,7 +1528,7 @@ func fieldExample(field fieldName, op string) string { func listExamples(field fieldName) string { if field.Scope == "" && !field.Bracket { name := strings.ToLower(field.Key) - if vocabulary := panel.FieldVocabularies()[name]; len(vocabulary.Order) > 1 { + if vocabulary := query.FieldVocabularies()[name]; len(vocabulary.Order) > 1 { return strings.Join(vocabulary.Order[:2], ", ") } switch name { diff --git a/internal/fanql/parser_test.go b/internal/fanql/parser_test.go index 10eb04bb..ba6cdc95 100644 --- a/internal/fanql/parser_test.go +++ b/internal/fanql/parser_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func mustParse(t *testing.T, text string) *queryTree { @@ -18,7 +18,7 @@ func mustParse(t *testing.T, text string) *queryTree { return q } -func wantProblem(t *testing.T, text, source, message, hint string) panel.Problems { +func wantProblem(t *testing.T, text, source, message, hint string) query.Problems { t.Helper() q, ps := parse(text, source) if q != nil || len(ps) == 0 { @@ -85,7 +85,7 @@ func TestParseMixedAndOrIsRejectedWithFixIts(t *testing.T) { ps := wantProblem(t, tc.text, "", "mixed and/or needs parentheses", "write "+tc.a+" or "+tc.b) p := ps[0] start := strings.Index(tc.text, tc.body) - span := panel.TextSpan{Start: start, End: start + len(tc.body)} + span := query.TextSpan{Start: start, End: start + len(tc.body)} if *p.Span != span || len(p.FixIts) != 2 || p.FixIts[0].Span != span || p.FixIts[1].Span != span || p.FixIts[0].Text != tc.a || p.FixIts[1].Text != tc.b { t.Fatal(p) } @@ -143,7 +143,7 @@ func TestParseValueClassification(t *testing.T) { func TestParseColonEndsWord(t *testing.T) { ps := wantProblem(t, "spans where http.target:/a:b", "", "unexpected : after /a", `quote the value: http.target:"/a:b"`) - if *ps[0].Span != (panel.TextSpan{Start: 12, End: 28}) { + if *ps[0].Span != (query.TextSpan{Start: 12, End: 28}) { t.Fatal(ps) } wantProblem(t, "logs where http://x:8080/y", "", "unexpected : after http", `quote the value: "http://x:8080/y"`) @@ -232,35 +232,35 @@ func TestParseCalls(t *testing.T) { func TestParseStageMeasuresAndArithmetic(t *testing.T) { q := mustParse(t, "spans | count_if(status:error) / count() * 100 as err_pct by http_route every 1m sort err_pct limit 10") m := q.Stage.Measures[0] - mul, ok := m.Parsed.Expr.(panel.MeasureBinary) + mul, ok := m.Parsed.Expr.(query.MeasureBinary) if !ok || mul.Op != '*' || m.Alias != "err_pct" { t.Fatal(m) } - div, ok := mul.L.(panel.MeasureBinary) + div, ok := mul.L.(query.MeasureBinary) if !ok || div.Op != '/' { t.Fatal(mul) } - if _, ok := div.L.(*panel.MeasureCountIf); !ok { + if _, ok := div.L.(*query.MeasureCountIf); !ok { t.Fatal(div) } - if div.R.(panel.MeasureCall).Func != "count" || mul.R.(panel.MeasureConst).Value != 100 { + if div.R.(query.MeasureCall).Func != "count" || mul.R.(query.MeasureConst).Value != 100 { t.Fatal(mul) } if q.Stage.By[0].Key != "http_route" || q.Stage.Bucket != "1m" || q.Sort.Key != "err_pct" || q.Sort.Ascending || q.Limit.N != 10 { t.Fatal(q) } - x := mustParse(t, "spans | p95(duration)-p50(duration) as spread").Stage.Measures[0].Parsed.Expr.(panel.MeasureBinary) - if x.Op != '-' || x.L.(panel.MeasureCall).Func != "p95" || x.R.(panel.MeasureCall).Func != "p50" { + x := mustParse(t, "spans | p95(duration)-p50(duration) as spread").Stage.Measures[0].Parsed.Expr.(query.MeasureBinary) + if x.Op != '-' || x.L.(query.MeasureCall).Func != "p95" || x.R.(query.MeasureCall).Func != "p50" { t.Fatal(x) } - x = mustParse(t, "spans | count() * -1 as neg").Stage.Measures[0].Parsed.Expr.(panel.MeasureBinary) - if x.R.(panel.MeasureNeg).X.(panel.MeasureConst).Value != 1 { + x = mustParse(t, "spans | count() * -1 as neg").Stage.Measures[0].Parsed.Expr.(query.MeasureBinary) + if x.R.(query.MeasureNeg).X.(query.MeasureConst).Value != 1 { t.Fatal(x) } for _, s := range []string{"count()*100 as c100", "count()/count() as one", "count() * 1e3 as k", "count() * 1.5 as x", "(count_if(duration<=500ms) + count_if(duration>500ms duration<=2s) / 2) / count() as apdex"} { mustParse(t, "spans | "+s) } - c := mustParse(t, "spans | count() * 1e3 as k").Stage.Measures[0].Parsed.Expr.(panel.MeasureBinary).R.(panel.MeasureConst) + c := mustParse(t, "spans | count() * 1e3 as k").Stage.Measures[0].Parsed.Expr.(query.MeasureBinary).R.(query.MeasureConst) if c.Value != 1000 || c.Text != "1e3" { t.Fatal(c) } @@ -282,7 +282,7 @@ func TestParseExpressionRules(t *testing.T) { if q.Stage.Histogram == nil || q.Stage.Histogram.Key != "duration" || len(q.Stage.By) != 1 { t.Fatal(q) } - x := mustParse(t, "spans | count(*)").Stage.Measures[0].Parsed.Expr.(panel.MeasureCall) + x := mustParse(t, "spans | count(*)").Stage.Measures[0].Parsed.Expr.(query.MeasureCall) if x.Func != "count" { t.Fatal(x) } @@ -371,7 +371,7 @@ func TestParseUnclosedAndUnmatched(t *testing.T) { {"spans where duration>", "duration> needs a value; e.g. duration>500ms"}, } { ps := wantProblem(t, tc.text, "", tc.message, "") - if strings.Contains(tc.text, "(a:1") && *ps[0].Span != (panel.TextSpan{Start: 12, End: 13}) { + if strings.Contains(tc.text, "(a:1") && *ps[0].Span != (query.TextSpan{Start: 12, End: 13}) { t.Fatal(ps) } } @@ -419,7 +419,7 @@ func TestParseBoundsAreEnforcedIndependently(t *testing.T) { func TestParseKeywordCaseFolding(t *testing.T) { q := mustParse(t, "SPANS WHERE Service:API | COUNT() BY service EVERY 1M SORT COUNT LIMIT 5") x := q.Where[0].(*comparison) - if q.Source != "spans" || x.Field.Key != "Service" || x.Value.Text != "API" || q.Stage.Measures[0].Parsed.Expr.(panel.MeasureCall).Func != "count" || q.Stage.Bucket != "1m" || q.Sort.Key != "count" { + if q.Source != "spans" || x.Field.Key != "Service" || x.Value.Text != "API" || q.Stage.Measures[0].Parsed.Expr.(query.MeasureCall).Func != "count" || q.Stage.Bucket != "1m" || q.Sort.Key != "count" { t.Fatal(q, x) } } @@ -460,17 +460,17 @@ func TestParseGroupingFixItsRepairLongerChains(t *testing.T) { func TestParseApdexTree(t *testing.T) { q := mustParse(t, "spans | (count_if(duration<=500ms) + count_if(duration>500ms duration<=2s) / 2) / count() as apdex") - var walk func(panel.MeasureExpr) (int, int) - walk = func(x panel.MeasureExpr) (int, int) { + var walk func(query.MeasureExpr) (int, int) + walk = func(x query.MeasureExpr) (int, int) { switch x := x.(type) { - case panel.MeasureBinary: + case query.MeasureBinary: ld, ln := walk(x.L) rd, rn := walk(x.R) return max(ld, rd) + 1, ln + rn - case panel.MeasureNeg: + case query.MeasureNeg: d, n := walk(x.X) return d + 1, n - case panel.MeasureCall, *panel.MeasureCountIf: + case query.MeasureCall, *query.MeasureCountIf: return 1, 1 default: return 1, 0 diff --git a/internal/fanql/print.go b/internal/fanql/print.go index 4481c0c5..927bf13f 100644 --- a/internal/fanql/print.go +++ b/internal/fanql/print.go @@ -5,7 +5,7 @@ import ( "strings" "unicode" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" ) @@ -250,7 +250,7 @@ func quoteSearchBeforeGroup(e filterExpr, text string) string { neg, e = true, n.X } if x, ok := e.(*textExpr); ok { - for _, name := range panel.FilterFunctionNames() { + for _, name := range query.FilterFunctionNames() { if strings.EqualFold(x.Value.Text, name) { text = quoteText(x.Value.Text) if neg { @@ -337,7 +337,7 @@ func printValue(v literalValue, f fieldName, aliases bool) string { column = "" } } - for alias, value := range panel.FieldAliases(column) { + for alias, value := range query.FieldAliases(column) { if stored == value { return alias } @@ -449,7 +449,7 @@ func printCall(x *filterCall) string { } func printMeasure(m measureNode) string { - text := renderMeasure(m.Parsed.Expr, 0, func(f *panel.FieldRef) string { + text := renderMeasure(m.Parsed.Expr, 0, func(f *query.FieldRef) string { return printField(fieldName{Key: f.Text, Ref: &fieldRef{Column: f.Column, Key: f.Key, Type: f.Type, Unit: f.Unit}}) }, func(sql string) string { e := m.Filters[sql] @@ -467,11 +467,11 @@ func printMeasure(m measureNode) string { } return text } -func renderMeasure(e panel.MeasureExpr, parent int, field func(*panel.FieldRef) string, filter func(string) string, syntax ...map[panel.MeasureExpr]*measureSource) string { +func renderMeasure(e query.MeasureExpr, parent int, field func(*query.FieldRef) string, filter func(string) string, syntax ...map[query.MeasureExpr]*measureSource) string { if len(syntax) > 0 { if info := syntax[0][e]; info != nil { switch x := e.(type) { - case panel.MeasureCall: + case query.MeasureCall: var args []string for _, a := range info.args { switch { @@ -486,7 +486,7 @@ func renderMeasure(e panel.MeasureExpr, parent int, field func(*panel.FieldRef) } } return x.Func + "(" + strings.Join(args, ", ") + ")" - case *panel.MeasureCountIf: + case *query.MeasureCountIf: body := printEntry(info.filter, false) if _, ok := info.filter.(*andExpr); ok { body = strings.TrimSuffix(strings.TrimPrefix(body, "("), ")") @@ -496,7 +496,7 @@ func renderMeasure(e panel.MeasureExpr, parent int, field func(*panel.FieldRef) } } switch x := e.(type) { - case panel.MeasureCall: + case query.MeasureCall: var args []string if x.Field != nil { args = append(args, field(x.Field)) @@ -505,16 +505,16 @@ func renderMeasure(e panel.MeasureExpr, parent int, field func(*panel.FieldRef) args = append(args, strconv.FormatFloat(x.Q, 'f', -1, 64)) } return x.Func + "(" + strings.Join(args, ", ") + ")" - case panel.MeasureCountIf: + case query.MeasureCountIf: return "count_if(" + filter(x.Filter) + ")" - case panel.MeasureConst: + case query.MeasureConst: return strconv.FormatFloat(x.Value, 'f', -1, 64) - case panel.MeasureNeg: - if _, nested := x.X.(panel.MeasureNeg); nested { + case query.MeasureNeg: + if _, nested := x.X.(query.MeasureNeg); nested { return "-(" + renderMeasure(x.X, 0, field, filter, syntax...) + ")" } return "-" + renderMeasure(x.X, 3, field, filter, syntax...) - case panel.MeasureBinary: + case query.MeasureBinary: prec := 1 if x.Op == '*' || x.Op == '/' { prec = 2 diff --git a/internal/fanql/reference.go b/internal/fanql/reference.go index 82eb94b5..efc8863f 100644 --- a/internal/fanql/reference.go +++ b/internal/fanql/reference.go @@ -5,7 +5,7 @@ import ( "slices" "strings" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" ) @@ -14,7 +14,7 @@ import ( func Reference() string { var b strings.Builder b.WriteString("# FanQL\n\nPreview: the syntax may change before GA\n\n") - b.WriteString("FanQL is the text form of a structured telemetry query. It produces the same `panel.Query` that dashboards store and the panel engine executes. Panels store the query; text is derived. Problems prevent execution; notices never block it. Each diagnostic says what happened and what to write instead, using a valid example from that field. Diagnostics use display names without internal visualization identifiers and report all independent problems in one pass, in source order. Only follow-on cascades are suppressed.\n\n") + b.WriteString("FanQL is the text form of a structured telemetry query. It produces the same `query.Spec` that dashboards store and the engine executes. Panels store the query; text is derived. Problems prevent execution; notices never block it. Each diagnostic says what happened and what to write instead, using a valid example from that field. Diagnostics use display names without internal visualization identifiers and report all independent problems in one pass, in source order. Only follow-on cascades are suppressed.\n\n") b.WriteString("## Shape and entry points\n\n`source [where] filters | measures by fields every bucket sort key limit n`\n\nExplore accepts a whole query. Logs and Traces search bars accept filters only; the page supplies source, `where` and visualization. The visualization picker accepts the query as written. Adding `| count() every auto` to make a timeseries is a visible edit. One aggregation stage is allowed; another pipe may introduce only `sort` or `limit`, and canonical text drops that pipe.\n\n") b.WriteString("## Sources and words\n\n") fmt.Fprintf(&b, "Sources: %s, recognized only as the first token. A bare source selects all rows in the chosen time range. `where` is optional; canonical text supplies it when filters exist.\n\n", referenceWords(referenceKeys(sources))) @@ -36,10 +36,10 @@ func Reference() string { } b.WriteString("\nPrefix `-` or `not` excludes a term and includes rows where its predicate is NULL. Repeated negation cancels in pairs. SQL operators retain SQL null behavior. Compound negation follows De Morgan's law. TRY_CAST failures are NULL, so `-http_status_code between 400 and 599` includes uncastable codes.\n\nWhitespace and `and` join filters. An `or` chain must occupy its whole filter list or be parenthesized: `a:1 (b:2 or c:3)` and `(a:1 b:2) or c:3` differ. This rule also applies inside groups and `count_if`. Mixing conjunction and `or` without parentheses is a problem with suggested repairs.\n\n") b.WriteString("## Fields\n\nA single identifier is a source column when one exists, otherwise an attribute key with a notice. Dotted `http.target` means `attributes['http.target']`; `resource.k8s.pod.name` means `resource['k8s.pod.name']`. Explicit `attributes.` uses the attributes map. Bracket keys are literal nonempty strings, including spaces, Unicode, punctuation and doubled quotes. Keys beginning `resource.` or `attributes.` retain brackets where needed to preserve the map.\n\nCanonical text brackets single-segment attribute keys, so new columns cannot reinterpret canonical or stored text. Map columns require a key. `duration` denotes `duration_ms` in filters, measure arguments and trace sorts. `duration_ms>500` takes a number; `duration>500ms` requires a unit. A measure alias named duration or duration_ms stays that alias in sort. Time columns accept range comparisons against quoted timestamps, not equality shorthand.\n\n") - for _, signal := range panel.SignalNames() { + for _, signal := range query.SignalNames() { fmt.Fprintf(&b, "### %s\n\n| Name | Type | Unit | Low cardinality | Description |\n|---|---|---|---|---|\n", signal) - columns, _ := panel.SignalColumns(signal) - lowCard := panel.LowCardinalityColumns(signal) + columns, _ := query.SignalColumns(signal) + lowCard := query.LowCardinalityColumns(signal) for _, column := range columns { unit, low := column.Unit, "" if unit == "" { @@ -57,7 +57,7 @@ func Reference() string { for _, vocabulary := range []struct { name string aliases map[string]string - }{{"status (spans)", panel.FieldAliases("status")}, {"kind (spans)", panel.FieldAliases("kind")}, {"type (metrics)", panel.FieldAliases("type")}, {"severity (logs)", telemetry.SeverityAliases()}} { + }{{"status (spans)", query.FieldAliases("status")}, {"kind (spans)", query.FieldAliases("kind")}, {"type (metrics)", query.FieldAliases("type")}, {"severity (logs)", telemetry.SeverityAliases()}} { fmt.Fprintf(&b, "### %s\n\n| Input | Stored |\n|---|---|\n", vocabulary.name) for _, alias := range referenceKeys(vocabulary.aliases) { fmt.Fprintf(&b, "| `%s` | `%s` |\n", alias, vocabulary.aliases[alias]) @@ -68,9 +68,9 @@ func Reference() string { b.WriteString("Every stored log severity is normalized once: a positive severity number has authority (21+ FATAL, 17+ ERROR, 13+ WARN, 9+ INFO, 5+ DEBUG, 1+ TRACE); absent/nonpositive numbers fall back to text. Invariant: no stored log row bypasses normalization. Severity ranges expand to contiguous band membership, never CASE. `severity>=warn` means WARN, ERROR, FATAL; `severity=14` for sublevels. Empty or reversed ranges are problems.\n\nOn normalized log rows, `error_rate()` counts exactly `severity>=error`. Its backend test is `upper(severity) IN ('ERROR', 'FATAL', 'CRITICAL') OR severity_number >= 17`; normalization makes legacy CRITICAL redundant. Span `error_rate()` counts `status:error`.\n\n") b.WriteString("## Literals and durations\n\n| Literal | Rule |\n|---|---|\n| String | Bare words or single/double quotes; double a quote to escape it. Quoted values are strings and bypass aliases. |\n| Number | Integers, decimals and exponents (`500`, `1.5`, `2e3`, `-3`); non-finite values are rejected. Numbers stay numeric on number columns and attributes, and stay text as typed on string columns. |\n| Boolean | Bare `true`/`false`, case-insensitive; attributes retain boolean type, string columns compare text, number columns reject them. |\n| Duration | `us`, `ms`, `s`, `m`, `h`, only on `duration`; converted to milliseconds. Examples: `500ms`, `1.5s`, `250us`, `2m`, `1h`. Negative, compound and overflowing durations are rejected. |\n| Timestamp | Quoted RFC 3339 or `YYYY-MM-DD HH:MM:SS`, optional fraction/offset; no offset means UTC. Time comparisons retain nanoseconds through TIMESTAMPTZ_NS. |\n| Existence | `k:*` is IS NOT NULL; `-k:*` is IS NULL. |\n| Free text | Case-insensitive substring of log body or span operation; explicit field required on metrics. |\n\nContains emits `contains(lower(field), lower(value))`; map values first cast to VARCHAR. SQL LIKE/ILIKE require quoted patterns; ESCAPE is not expressible, so use `~` when `%` should be literal.\n\n") b.WriteString("## Buckets\n\n") - fmt.Fprintf(&b, "%s. `auto` lets the engine choose an interval. A bucket follows `every` and belongs to an aggregate query.\n\n", referenceWords(panel.BucketNames())) + fmt.Fprintf(&b, "%s. `auto` lets the engine choose an interval. A bucket follows `every` and belongs to an aggregate query.\n\n", referenceWords(query.BucketNames())) b.WriteString("## Measures\n\nThe registry defines accepted functions and signal availability. Fields follow the filter/grouping resolution rules. Numeric attribute measures use TRY_CAST AS DOUBLE; nonnumeric values become NULL. `count(*)` canonicalizes to `count()`.\n\n| Name | Form | Signals | Unit | Semantics |\n|---|---|---|---|---|\n") - for _, m := range panel.MeasureSpecs() { + for _, m := range query.MeasureSpecs() { form := m.Name + "()" if m.Args == 1 { form = m.Name + "(f)" @@ -79,7 +79,7 @@ func Reference() string { } signals := m.Signals if len(signals) == 0 { - signals = panel.SignalNames() + signals = query.SignalNames() } unit := m.Unit if unit == "" { @@ -90,7 +90,7 @@ func Reference() string { b.WriteString("\nMetric aggregates require a standalone `name:` equality entry. Counters use per-series increases and reset handling; gauge/updown use point values; histograms use observation counts, sums and buckets; summaries use available stored aggregates. Unsupported kind/function combinations report a diagnosis instead of treating counters as gauges.\n\n`histogram(duration)` on spans uses count with log2 duration buckets; `histogram(value)` on metrics uses explicit histogram buckets. Distributions stand alone, with at most one `by` field for a histogram; `every` selects a heatmap.\n\n") b.WriteString("## Expressions and ranking\n\n`count_if(filters)` takes a FanQL filter list as one entry and compiles to checked `count(*) FILTER (WHERE ...)::DOUBLE`. Raw entries are allowed; variables are forbidden. Spans and logs support `+ - * /`, constants, unary minus and parentheses on aggregate vizzes. Metrics, distributions and log_patterns do not support arithmetic. Every expression needs at least one aggregate. Other than a single call, an expression requires `as alias`; aliases are 1–40 lowercase letters/digits/underscores and start with a letter. `share()` stands alone. Division emits `a / nullif(b, 0)`, so zero denominators yield NULL.\n\nCount-family ratios use ratio units, `* 100` makes percent, addition/subtraction retains equal units, scaling retains the measure unit, other combinations use none. Expressions are not additive. Affine transformations inherit the underlying ranking and flip direction for a negative scale. Binomial count_if/count ratios use Wilson ranking with a 20-sample floor; other expressions use value ranking with leaf/denominator support. Ineligible series follow eligible ones by support, then dimension; result metadata discloses them.\n\nApdex uses disjoint predicates: `(count_if(duration<=500ms) + count_if(duration>500ms duration<=2s) / 2) / count() as apdex`. Exactly 500 ms counts once; NULL duration counts in the population and neither numerator.\n\nEach measure allows 256 tokens, 64 nodes, depth 8 and 8 aggregates. A query allows 256 expression nodes and 24 aggregates across at most 6 measures. A count_if filter is at most 500 bytes. Whitespace is not a token. Budgets apply to structured inputs too.\n\n") b.WriteString("## Filter functions and raw entries\n\n| Function | Signature |\n|---|---|\n") - for _, name := range panel.FilterFunctionNames() { + for _, name := range query.FilterFunctionNames() { args := "field" if name == "starts_with" || name == "contains" || name == "regexp_matches" { args = "field, quoted_string" diff --git a/internal/fanql/reference_test.go b/internal/fanql/reference_test.go index 2bf91f38..aee3bb0d 100644 --- a/internal/fanql/reference_test.go +++ b/internal/fanql/reference_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" ) @@ -16,24 +16,24 @@ func TestReferenceCoversEveryRegistryEntry(t *testing.T) { t.Errorf("reference omits %q", entry) } } - for _, m := range panel.MeasureSpecs() { + for _, m := range query.MeasureSpecs() { check(m.Name) } - for _, bucket := range panel.BucketNames() { + for _, bucket := range query.BucketNames() { check(bucket) } - for _, name := range panel.FilterFunctionNames() { + for _, name := range query.FilterFunctionNames() { check(name) } - for _, signal := range panel.SignalNames() { - columns, _ := panel.SignalColumns(signal) + for _, signal := range query.SignalNames() { + columns, _ := query.SignalColumns(signal) for _, column := range columns { if !strings.Contains(ref, "| `"+column.Name+"` | `"+string(column.Type)+"` |") { t.Errorf("missing %s column %s with type", signal, column.Name) } } } - for _, table := range []map[string]string{panel.FieldAliases("status"), panel.FieldAliases("kind"), panel.FieldAliases("type"), telemetry.SeverityAliases()} { + for _, table := range []map[string]string{query.FieldAliases("status"), query.FieldAliases("kind"), query.FieldAliases("type"), telemetry.SeverityAliases()} { for alias, stored := range table { check(alias) check(stored) diff --git a/internal/fanql/registry_growth_test.go b/internal/fanql/registry_growth_test.go index 961917d9..e3957c2d 100644 --- a/internal/fanql/registry_growth_test.go +++ b/internal/fanql/registry_growth_test.go @@ -6,7 +6,7 @@ import ( "slices" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type registryMeaning struct { @@ -55,9 +55,9 @@ func TestRegistryGrowth(t *testing.T) { ) baseline := registrySnapshot(fixtures, vocab) columns, measures, functions, bucketNames := vocab.columns, vocab.measures, vocab.functions, vocab.buckets - vocab.measures = func() []panel.MeasureSpec { + vocab.measures = func() []query.MeasureSpec { out := measures() - out = append(out, panel.MeasureSpec{Name: "p42", Args: 1, Numeric: true, Quantile: .42, Signals: []string{"spans", "logs"}}) + out = append(out, query.MeasureSpec{Name: "p42", Args: 1, Numeric: true, Quantile: .42, Signals: []string{"spans", "logs"}}) return out } vocab.functions = func() []string { return append(functions(), "ltrim") } @@ -83,10 +83,10 @@ func TestRegistryGrowth(t *testing.T) { t.Fatalf("synthetic registry hook didn't reach %q: %+v", text, ps) } } - vocab.columns = func(source string) ([]panel.Field, bool) { + vocab.columns = func(source string) ([]query.Field, bool) { out, ok := columns(source) if source == "spans" { - out = append(out, panel.Field{Name: "value", Type: panel.TypeNumber, Unit: "none"}) + out = append(out, query.Field{Name: "value", Type: query.TypeNumber, Unit: "none"}) } return out, ok } diff --git a/internal/fanql/resolve.go b/internal/fanql/resolve.go index c895d870..02614d5d 100644 --- a/internal/fanql/resolve.go +++ b/internal/fanql/resolve.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/sqlscan" "github.com/labstack/fanout/internal/suggest" "github.com/labstack/fanout/internal/telemetry" @@ -17,12 +17,12 @@ import ( type Notice struct { Path string `json:"path"` Message string `json:"message"` - Span *panel.TextSpan `json:"span,omitempty"` + Span *query.TextSpan `json:"span,omitempty"` } type resolved struct { Query *queryTree - Compatible []panel.VizCompat + Compatible []query.VizCompat Edits []VizEdit Notices []Notice } @@ -34,29 +34,29 @@ type VizEdit struct { // Vocabulary dependencies are snapshots supplied per compilation, so prospective // catalog changes can be tested without mutating process-wide state. type vocabulary struct { - columns func(string) ([]panel.Field, bool) - measures func() []panel.MeasureSpec + columns func(string) ([]query.Field, bool) + measures func() []query.MeasureSpec functions func() []string buckets func() []string } func currentVocabulary() vocabulary { - return vocabulary{panel.SignalColumns, panel.MeasureSpecs, panel.FilterFunctionNames, panel.BucketNames} + return vocabulary{query.SignalColumns, query.MeasureSpecs, query.FilterFunctionNames, query.BucketNames} } type resolver struct { opts Options vocab vocabulary out *resolved - problems panel.Problems + problems query.Problems countIf bool path string } -func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, panel.Problems) { - r := &resolver{opts: opts, vocab: vocab, out: &resolved{Query: q, Notices: []Notice{}, Compatible: []panel.VizCompat{}, Edits: []VizEdit{}}} +func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, query.Problems) { + r := &resolver{opts: opts, vocab: vocab, out: &resolved{Query: q, Notices: []Notice{}, Compatible: []query.VizCompat{}, Edits: []VizEdit{}}} if q == nil { - return nil, panel.Problems{{Path: "text", Message: "a query is required"}} + return nil, query.Problems{{Path: "text", Message: "a query is required"}} } for i, e := range q.Where { r.path = fmt.Sprintf("where[%d]", i) @@ -78,9 +78,9 @@ func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, panel before := len(r.problems) expr := r.measure(m.Parsed.Expr, m.Info, m.Filters) if len(r.problems) == before { - parsed, message, hint := panel.MeasureFromExpr(q.Source, expr, m.Alias, r.vocab.measures()) + parsed, message, hint := query.MeasureFromExpr(q.Source, expr, m.Alias, r.vocab.measures()) if message != "" { - r.problems = append(r.problems, panel.Problem{Path: r.path, Message: message, Hint: hint, Span: textSpan(m.At)}) + r.problems = append(r.problems, query.Problem{Path: r.path, Message: message, Hint: hint, Span: textSpan(m.At)}) } else { m.Parsed = parsed } @@ -99,24 +99,24 @@ func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, panel if len(r.problems) == 0 { pq, ps := lower(r.out) r.problems = append(r.problems, ps...) - vars := map[string]panel.Variable(nil) + vars := map[string]query.Variable(nil) if opts.Variables != nil { - vars = map[string]panel.Variable{} + vars = map[string]query.Variable{} for _, v := range opts.Variables { vars[v.Name] = v } } if opts.Viz != "" && len(ps) == 0 { - ps, _ = panel.QueryShape(&pq, opts.Viz, vars, preparedMeasures(q)) + ps, _ = query.Shape(&pq, opts.Viz, vars, preparedMeasures(q)) for _, p := range ps { p.Span = textSpan(queryPathSpan(q, p.Path)) r.problems = append(r.problems, p) } } - r.out.Compatible = panel.CompatibleVizzes(&pq, vars, preparedMeasures(q)) + r.out.Compatible = query.CompatibleVizzes(&pq, vars, preparedMeasures(q)) if pq.Bucket == "" && q.Stage != nil && q.Stage.Histogram == nil { pq.Bucket = "auto" - if ps, _ := panel.QueryShape(&pq, "timeseries", vars, preparedMeasures(q)); len(ps) == 0 { + if ps, _ := query.Shape(&pq, "timeseries", vars, preparedMeasures(q)); len(ps) == 0 { edit := *q stage := *q.Stage stage.Bucket = "auto" @@ -130,7 +130,7 @@ func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, panel }) r.problems = presentProblems(r.problems) if len(r.problems) > maxProblems { - r.problems = append(r.problems[:maxProblems], panel.Problem{Path: "text", Message: message(diagMore), Span: r.problems[maxProblems].Span}) + r.problems = append(r.problems[:maxProblems], query.Problem{Path: "text", Message: message(diagMore), Span: r.problems[maxProblems].Span}) } if len(r.problems) > 0 { return nil, r.problems @@ -138,9 +138,9 @@ func resolveWith(q *queryTree, opts Options, vocab vocabulary) (*resolved, panel return r.out, nil } -func textSpan(s span) *panel.TextSpan { return &panel.TextSpan{Start: s.Start, End: s.End} } +func textSpan(s span) *query.TextSpan { return &query.TextSpan{Start: s.Start, End: s.End} } func (r *resolver) issue(at span, message string) { - r.problems = append(r.problems, panel.Problem{Path: r.path, Message: message, Span: textSpan(at)}) + r.problems = append(r.problems, query.Problem{Path: r.path, Message: message, Span: textSpan(at)}) } func (r *resolver) notice(at span, message string) { r.out.Notices = append(r.out.Notices, Notice{Path: r.path, Message: message, Span: textSpan(at)}) @@ -165,7 +165,7 @@ func (r *resolver) field(f *fieldName) { if scope == "" && !f.Bracket && !strings.Contains(key, ".") { for _, c := range columns { if strings.EqualFold(key, c.Name) { - if c.Type == panel.TypeMap { + if c.Type == query.TypeMap { r.issue(f.At, c.Name+" is a map; use "+c.Name+"['key']") } f.Ref = &fieldRef{Column: c.Name, Type: c.Type, Unit: c.Unit} @@ -179,7 +179,7 @@ func (r *resolver) field(f *fieldName) { if !f.Bracket && !identifierPath.MatchString(key) { r.issue(f.At, fmt.Sprintf("%q needs brackets", key)) } - f.Ref = &fieldRef{Column: scope, Key: key, Type: panel.TypeString, Unit: "none"} + f.Ref = &fieldRef{Column: scope, Key: key, Type: query.TypeString, Unit: "none"} if f.Scope == "" && !f.Bracket && !strings.Contains(key, ".") { message := fmt.Sprintf("%q is not a %s column; reading attributes['%s']", key, r.out.Query.Source, key) for _, m := range r.vocab.measures() { @@ -250,7 +250,7 @@ func (r *resolver) expr(e filterExpr) { if r.out.Query.Source == "metrics" { name := "http.server.duration" if r.opts.Schema != nil { - var selected *panel.MetricSchema + var selected *query.MetricSchema for _, metric := range r.opts.Schema.Signals["metrics"].Metrics { if metric.Name != "" && (selected == nil || metric.Count > selected.Count || metric.Count == selected.Count && metric.Name < selected.Name) { copy := metric @@ -318,7 +318,7 @@ func (r *resolver) value(f *fieldName, v *literalValue, op string, multi bool) { r.issue(v.At, "duration needs a unit; e.g. duration>500ms") return } - if ref.Type == panel.TypeTime && ref.Key == "" { + if ref.Type == query.TypeTime && ref.Key == "" { if !isRange(op) { r.issue(f.At, fmt.Sprintf("%q is a time column; compare it with > or <", ref.Column)) } else if v.Kind != stringValue || !timestamp(v.Text) { @@ -326,7 +326,7 @@ func (r *resolver) value(f *fieldName, v *literalValue, op string, multi bool) { } return } - if ref.Type == panel.TypeNumber && ref.Key == "" && v.Kind != numberValue { + if ref.Type == query.TypeNumber && ref.Key == "" && v.Kind != numberValue { r.issue(v.At, ref.Column+" needs a number") return } @@ -336,7 +336,7 @@ func (r *resolver) value(f *fieldName, v *literalValue, op string, multi bool) { if v.Kind != wordValue || !(op == ":" || op == "=" || op == "!=" || op == "<>" || op == "in") || ref.Key != "" { return } - vocabulary := panel.FieldVocabularies()[ref.Column] + vocabulary := query.FieldVocabularies()[ref.Column] table := vocabulary.Aliases if vocabulary.Signal != r.out.Query.Source { table = nil @@ -492,7 +492,7 @@ func (r *resolver) call(c *filterCall) { } } -func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*measureSource, filters map[string]filterExpr) panel.MeasureExpr { +func (r *resolver) measure(e query.MeasureExpr, infos map[query.MeasureExpr]*measureSource, filters map[string]filterExpr) query.MeasureExpr { info := infos[e] if info == nil { return e @@ -500,12 +500,12 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea at := info.at args := info.args value := e - if conditional, ok := e.(*panel.MeasureCountIf); ok { + if conditional, ok := e.(*query.MeasureCountIf); ok { value = *conditional } switch x := value.(type) { - case panel.MeasureCall: - var spec *panel.MeasureSpec + case query.MeasureCall: + var spec *query.MeasureSpec for _, s := range r.vocab.measures() { if s.Name == x.Func { s := s @@ -533,7 +533,7 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea a := &args[i] if a.Field != nil { r.field(a.Field) - if spec.Numeric && a.Field.Ref.Key == "" && a.Field.Ref.Type != panel.TypeNumber { + if spec.Numeric && a.Field.Ref.Key == "" && a.Field.Ref.Type != query.TypeNumber { r.issue(a.At, fmt.Sprintf("%s needs a numeric field; %s is %s", x.Func, a.Field.Key, a.Field.Ref.Type)) } } @@ -541,7 +541,7 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea x.Field = nil if len(args) > 0 && args[0].Field != nil { f := args[0].Field - x.Field = &panel.FieldRef{Text: lowerField(*f), Column: f.Ref.Column, Key: f.Ref.Key, Type: f.Ref.Type, Unit: f.Ref.Unit} + x.Field = &query.FieldRef{Text: lowerField(*f), Column: f.Ref.Column, Key: f.Ref.Key, Type: f.Ref.Type, Unit: f.Ref.Unit} } x.Q = spec.Quantile if x.Func == "quantile" && len(args) > 1 && args[1].Number != nil { @@ -551,7 +551,7 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea r.issue(at, "quantile q must be a number between 0 and 1") } return x - case panel.MeasureCountIf: + case query.MeasureCountIf: if r.out.Query.Source == "metrics" { r.issue(at, "measure arithmetic is not available for metrics") return e @@ -562,7 +562,7 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea x.Filter = lowerCountFilter(info.filter) filters[x.Filter] = info.filter return x - case panel.MeasureBinary: + case query.MeasureBinary: if r.out.Query.Source == "metrics" { r.issue(at, "measure arithmetic is not available for metrics") return e @@ -570,7 +570,7 @@ func (r *resolver) measure(e panel.MeasureExpr, infos map[panel.MeasureExpr]*mea x.L = r.measure(x.L, infos, filters) x.R = r.measure(x.R, infos, filters) return x - case panel.MeasureNeg: + case query.MeasureNeg: if r.out.Query.Source == "metrics" { r.issue(at, "measure arithmetic is not available for metrics") return e @@ -586,15 +586,15 @@ func measureAlias(m measureNode, all []measureNode) string { return m.Alias } name := m.Parsed.Func - if c, ok := m.Parsed.Expr.(panel.MeasureCall); ok { + if c, ok := m.Parsed.Expr.(query.MeasureCall); ok { name = c.Func } - if _, ok := m.Parsed.Expr.(*panel.MeasureCountIf); ok { + if _, ok := m.Parsed.Expr.(*query.MeasureCountIf); ok { name = "count_if" } n := 0 for _, v := range all { - if c, ok := v.Parsed.Expr.(panel.MeasureCall); ok && c.Func == name && v.Alias == "" { + if c, ok := v.Parsed.Expr.(query.MeasureCall); ok && c.Func == name && v.Alias == "" { n++ } } @@ -615,8 +615,8 @@ func measureAlias(m measureNode, all []measureNode) string { } return name } -func preparedMeasures(q *queryTree) []panel.Measure { - out := []panel.Measure{} +func preparedMeasures(q *queryTree) []query.Measure { + out := []query.Measure{} if q.Stage != nil && q.Stage.Histogram == nil { for _, m := range q.Stage.Measures { out = append(out, m.Parsed) @@ -668,7 +668,7 @@ func (r *resolver) sort() { r.notice(s.At, "sort errors also filters to error spans; new queries: write status:error … sort duration") } } - stored := panel.Query{} + stored := query.Spec{} if q.Stage != nil { stored.Bucket = q.Stage.Bucket } @@ -716,7 +716,7 @@ func queryPathSpan(q *queryTree, path string) span { func aliasChoices(field string, aliases map[string]string) string { keys := sortedCompletionKeys(aliases) // Preserve the documented order for diagnostic suggestions. - if order := panel.FieldVocabularies()[field].Order; len(order) == len(keys) { + if order := query.FieldVocabularies()[field].Order; len(order) == len(keys) { keys = order } var choices []string @@ -729,7 +729,7 @@ func aliasChoices(field string, aliases map[string]string) string { return strings.Join(choices[:len(choices)-1], ", ") + " or " + choices[len(choices)-1] } -func ignoredClauseNotices(q panel.Query, viz string) []Notice { +func ignoredClauseNotices(q query.Spec, viz string) []Notice { notices := []Notice{} bucketed := q.Bucket != "" && slices.Contains([]string{"timeseries", "heatmap", "state_timeline"}, viz) if bucketed && q.Sort != "" { @@ -744,7 +744,7 @@ func ignoredClauseNotices(q panel.Query, viz string) []Notice { return notices } -func presentProblems(problems panel.Problems) panel.Problems { +func presentProblems(problems query.Problems) query.Problems { for i := range problems { problems[i].Message = diagnosticVizNames(problems[i].Message) problems[i].Hint = diagnosticVizNames(problems[i].Hint) diff --git a/internal/fanql/resolve_test.go b/internal/fanql/resolve_test.go index 4b50f9e1..5f0f15ea 100644 --- a/internal/fanql/resolve_test.go +++ b/internal/fanql/resolve_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) -func resolvedText(t *testing.T, text string, opts Options) (*resolved, panel.Problems) { +func resolvedText(t *testing.T, text string, opts Options) (*resolved, query.Problems) { t.Helper() q, ps := parse(text, "") if len(ps) != 0 { @@ -20,14 +20,14 @@ func resolvedText(t *testing.T, text string, opts Options) (*resolved, panel.Pro func TestResolveSingleSegmentFieldIsColumnOrAttribute(t *testing.T) { for _, tt := range []struct { text, column, key string - typ panel.FieldType + typ query.FieldType notice string }{ - {"spans where value>-3", "attributes", "value", panel.TypeString, `"value" is not a spans column; reading attributes['value']`}, - {"metrics where value>-3", "value", "", panel.TypeNumber, ""}, - {"metrics where rate:x", "attributes", "rate", panel.TypeString, `"rate" is a measure, not a metrics column; reading attributes['rate']`}, - {"spans where Service:api", "service", "", panel.TypeString, ""}, - {"spans where servce:api", "attributes", "servce", panel.TypeString, "did you mean service?"}, + {"spans where value>-3", "attributes", "value", query.TypeString, `"value" is not a spans column; reading attributes['value']`}, + {"metrics where value>-3", "value", "", query.TypeNumber, ""}, + {"metrics where rate:x", "attributes", "rate", query.TypeString, `"rate" is a measure, not a metrics column; reading attributes['rate']`}, + {"spans where Service:api", "service", "", query.TypeString, ""}, + {"spans where servce:api", "attributes", "servce", query.TypeString, "did you mean service?"}, } { t.Run(tt.text, func(t *testing.T) { r, ps := resolvedText(t, tt.text, Options{}) @@ -100,7 +100,7 @@ func TestResolveVocabularies(t *testing.T) { if got := r.Query.Where[0].(*inExpr).Values; got[0].Stored != "STATUS_CODE_ERROR" || got[1].Stored != "STATUS_CODE_OK" { t.Fatal(got) } - schema := &panel.Schema{Signals: map[string]panel.SignalSchema{"logs": {Columns: []panel.ColumnSchema{{Field: panel.Field{Name: "severity"}, Values: []panel.Option{{Value: "ERROR"}, {Value: "INFO"}}}}}}} + schema := &query.Schema{Signals: map[string]query.SignalSchema{"logs": {Columns: []query.ColumnSchema{{Field: query.Field{Name: "severity"}, Values: []query.Option{{Value: "ERROR"}, {Value: "INFO"}}}}}}} r, ps = resolvedText(t, "logs where severity:custom", Options{Schema: schema}) if len(ps) > 0 || r.Query.Where[0].(*comparison).Value.Stored != "CUSTOM" || len(r.Notices) != 1 || r.Notices[0].Message != "not a standard level; stored levels in this window: ERROR, INFO" { t.Fatal(r, ps) @@ -262,7 +262,7 @@ func TestResolveSortKeys(t *testing.T) { } func TestResolveVariables(t *testing.T) { - opts := Options{Variables: []panel.Variable{{Name: "service", Kind: "query"}, {Name: "svcs", Kind: "query", Multi: true}}} + opts := Options{Variables: []query.Variable{{Name: "service", Kind: "query"}, {Name: "svcs", Kind: "query", Multi: true}}} for _, tt := range []struct{ text, want string }{{"service:$region", "service, svcs"}, {"service:$svcs", "$svcs holds several values; use service in $svcs"}} { _, ps := resolvedText(t, "spans where "+tt.text, opts) if len(ps) == 0 || !strings.Contains(ps[0].Message, tt.want) { diff --git a/internal/fanql/roundtrip_test.go b/internal/fanql/roundtrip_test.go index edfbd865..f02bc426 100644 --- a/internal/fanql/roundtrip_test.go +++ b/internal/fanql/roundtrip_test.go @@ -15,13 +15,13 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) type storedQueryFixture struct { Name string - Panel panel.Panel - Variables []panel.Variable + Panel query.Panel + Variables []query.Variable } // Read the actual product fixtures, so additions to any dashboard automatically @@ -29,12 +29,12 @@ type storedQueryFixture struct { func storedQueryFixtures(t testing.TB) []storedQueryFixture { t.Helper() var out []storedQueryFixture - add := func(name string, p panel.Panel, vars []panel.Variable) { + add := func(name string, p query.Panel, vars []query.Variable) { if p.Query == nil { return } - d := panel.Dashboard{Name: name, Variables: vars, Panels: []panel.Panel{p}} - panel.Normalize(&d) + d := query.Dashboard{Name: name, Variables: vars, Panels: []query.Panel{p}} + query.Normalize(&d) out = append(out, storedQueryFixture{Name: name, Panel: d.Panels[0], Variables: d.Variables}) } d := dashboard.DefaultSpec() @@ -49,8 +49,8 @@ func storedQueryFixtures(t testing.TB) []storedQueryFixture { if err := json.Unmarshal(raw, &root); err != nil { t.Fatal(err) } - var walk func(any, string, []panel.Variable) - walk = func(v any, path string, vars []panel.Variable) { + var walk func(any, string, []query.Variable) + walk = func(v any, path string, vars []query.Variable) { switch x := v.(type) { case map[string]any: if value, ok := x["variables"]; ok { @@ -61,7 +61,7 @@ func storedQueryFixtures(t testing.TB) []storedQueryFixture { } if _, ok := x["query"]; ok { b, _ := json.Marshal(x) - var p panel.Panel + var p query.Panel if err := json.Unmarshal(b, &p); err != nil { t.Fatal(err) } @@ -94,7 +94,7 @@ func storedQueryFixtures(t testing.TB) []storedQueryFixture { if err != nil { t.Fatal(err) } - var d panel.Dashboard + var d query.Dashboard if err := json.Unmarshal([]byte(text), &d); err != nil { t.Fatal(err) } @@ -109,7 +109,7 @@ func storedQueryFixtures(t testing.TB) []storedQueryFixture { return out } -func canonicalSQL(t testing.TB, p panel.Parser, signal, filter string) string { +func canonicalSQL(t testing.TB, p query.Parser, signal, filter string) string { t.Helper() n, err := p.ParseSQL(context.Background(), "SELECT 1 FROM "+signal+" WHERE ("+filter+")") if err != nil { @@ -122,23 +122,23 @@ func canonicalSQL(t testing.TB, p panel.Parser, signal, filter string) string { return s } -func measureMeaning(t testing.TB, p panel.Parser, signal string, expr panel.MeasureExpr) any { +func measureMeaning(t testing.TB, p query.Parser, signal string, expr query.MeasureExpr) any { t.Helper() switch x := expr.(type) { - case panel.MeasureCall: + case query.MeasureCall: if x.Field != nil { f := *x.Field f.Text = "" x.Field = &f } return x - case panel.MeasureCountIf: + case query.MeasureCountIf: return canonicalSQL(t, p, signal, x.Filter) - case panel.MeasureConst: + case query.MeasureConst: return x.Value - case panel.MeasureNeg: + case query.MeasureNeg: return []any{"neg", measureMeaning(t, p, signal, x.X)} - case panel.MeasureBinary: + case query.MeasureBinary: return []any{x.Op, measureMeaning(t, p, signal, x.L), measureMeaning(t, p, signal, x.R)} default: t.Fatalf("unknown measure expression %T", expr) @@ -146,7 +146,7 @@ func measureMeaning(t testing.TB, p panel.Parser, signal string, expr panel.Meas } } -func assertQueryTier(t testing.TB, p panel.Parser, stored, lowered panel.Query, tier Exactness) { +func assertQueryTier(t testing.TB, p query.Parser, stored, lowered query.Spec, tier Exactness) { t.Helper() if len(stored.Where) != len(lowered.Where) { t.Fatalf("entry boundaries changed: %+v -> %+v", stored, lowered) @@ -174,11 +174,11 @@ func assertQueryTier(t testing.TB, p panel.Parser, stored, lowered panel.Query, t.Fatal("measure count changed") } for i, text := range stored.Measures { - a, err := panel.ParseMeasure(stored.From, text) + a, err := query.ParseMeasure(stored.From, text) if err != nil { t.Fatal(err) } - b, err := panel.ParseMeasure(lowered.From, lowered.Measures[i]) + b, err := query.ParseMeasure(lowered.From, lowered.Measures[i]) if err != nil { t.Fatal(err) } @@ -205,7 +205,7 @@ func TestRoundTripCorpusFixedPoint(t *testing.T) { f, ps, err := Format(t.Context(), p, c.Query, Options{Viz: fixture.Viz}) // Compile can parse filter-only metrics without a viz. There is no // metrics row viz, so these are outside Format's valid-query contract. - if len(panel.CompatibleVizzes(&c.Query, nil)) == 0 { + if len(query.CompatibleVizzes(&c.Query, nil)) == 0 { if f != nil || len(ps) == 0 || err != nil { t.Fatalf("invalid shape %q: %+v %+v %v", fixture.Text, f, ps, err) } @@ -252,14 +252,14 @@ func TestRoundTripStoredDashboards(t *testing.T) { t.Fatalf("%q: %+v", f.Text, ps) } assertQueryTier(t, engine, stored, c.Query, f.Exactness) - d := panel.Dashboard{Version: 1, Name: "round trip", Variables: fixture.Variables, Panels: []panel.Panel{p}} - panel.Normalize(&d) - _, before, err := panel.Check(t.Context(), engine, &d) + d := query.Dashboard{Version: 1, Name: "round trip", Variables: fixture.Variables, Panels: []query.Panel{p}} + query.Normalize(&d) + _, before, err := query.Check(t.Context(), engine, &d) if err != nil { t.Fatal(err) } d.Panels[0].Query = &c.Query - _, after, err := panel.Check(t.Context(), engine, &d) + _, after, err := query.Check(t.Context(), engine, &d) if err != nil { t.Fatal(err) } @@ -271,17 +271,17 @@ func TestRoundTripStoredDashboards(t *testing.T) { } func ownQueryText(r *rand.Rand, i int) string { - signal := panel.SignalNames()[r.Intn(3)] - columns, _ := panel.SignalColumns(signal) - var fields []panel.Field + signal := query.SignalNames()[r.Intn(3)] + columns, _ := query.SignalColumns(signal) + var fields []query.Field for _, f := range columns { - if f.Type == panel.TypeNumber || f.Type == panel.TypeString { + if f.Type == query.TypeNumber || f.Type == query.TypeString { fields = append(fields, f) } } f := fields[r.Intn(len(fields))] value := `"api*$'𝔘"` - if f.Type == panel.TypeNumber { + if f.Type == query.TypeNumber { value = strconv.Itoa(r.Intn(1000) - 100) } filter := f.Name + ":" + value @@ -309,8 +309,8 @@ func ownQueryText(r *rand.Rand, i int) string { } return signal + " where " + filter + " | histogram(" + field + ") by service" } - var measures []panel.MeasureSpec - for _, m := range panel.MeasureSpecs() { + var measures []query.MeasureSpec + for _, m := range query.MeasureSpecs() { if m.Name == "count_if" { continue } @@ -349,7 +349,7 @@ func containsString(values []string, value string) bool { func TestRoundTripProperties(t *testing.T) { engine, _ := newTestEngine(t) r := rand.New(rand.NewSource(20261029)) - vars := []panel.Variable{{Name: "svc", Kind: "text"}, {Name: "svcs", Kind: "custom", Options: []string{"api", "worker"}, Multi: true}} + vars := []query.Variable{{Name: "svc", Kind: "text"}, {Name: "svcs", Kind: "custom", Options: []string{"api", "worker"}, Multi: true}} for i := range 500 { text := ownQueryText(r, i) c, ps := Compile(text, Options{Variables: vars}) @@ -388,15 +388,15 @@ func TestRoundTripProperties(t *testing.T) { t.Fatal(ps) } assertQueryTier(t, engine, stored, lowered.Query, formatted.Exactness) - p := panel.Panel{ID: "p", Title: "p", Viz: "table", Query: &stored} - d := panel.Dashboard{Name: "property", Panels: []panel.Panel{p}} - panel.Normalize(&d) - _, before, err := panel.Check(t.Context(), engine, &d) + p := query.Panel{ID: "p", Title: "p", Viz: "table", Query: &stored} + d := query.Dashboard{Name: "property", Panels: []query.Panel{p}} + query.Normalize(&d) + _, before, err := query.Check(t.Context(), engine, &d) if err != nil { t.Fatal(err) } d.Panels[0].Query = &lowered.Query - _, after, err := panel.Check(t.Context(), engine, &d) + _, after, err := query.Check(t.Context(), engine, &d) if err != nil { t.Fatal(err) } @@ -409,7 +409,7 @@ func TestRoundTripProperties(t *testing.T) { func TestEntryBoundaryShapesDiffer(t *testing.T) { engine, _ := newTestEngine(t) - queries := []panel.Query{{From: "spans", Where: []string{`attributes['a'] = 1`, `attributes['b'] = 2`}}, {From: "spans", Where: []string{`attributes['a'] = 1 AND attributes['b'] = 2`}}} + queries := []query.Spec{{From: "spans", Where: []string{`attributes['a'] = 1`, `attributes['b'] = 2`}}, {From: "spans", Where: []string{`attributes['a'] = 1 AND attributes['b'] = 2`}}} texts := []string{} for _, q := range queries { f, ps, err := Format(t.Context(), engine, q, Options{}) @@ -429,7 +429,7 @@ func TestEntryBoundaryShapesDiffer(t *testing.T) { } func TestEditableFalsePreservationThroughEnvelope(t *testing.T) { - q := panel.Query{From: "logs"} + q := query.Spec{From: "logs"} for i := range 16 { q.Where = append(q.Where, "body = '"+strings.Repeat("x", 480)+strconv.Itoa(i)+"'") } @@ -439,13 +439,13 @@ func TestEditableFalsePreservationThroughEnvelope(t *testing.T) { t.Fatalf("oversized format: %+v %+v %v; engine calls=%d", f, ps, err, p.calls) } type envelope struct { - Text string `json:"text"` - Editable bool `json:"editable"` - Query panel.Query `json:"query"` - Viz string `json:"viz"` - Time panel.Time `json:"time"` + Text string `json:"text"` + Editable bool `json:"editable"` + Query query.Spec `json:"query"` + Viz string `json:"viz"` + Time query.Time `json:"time"` } - original := envelope{Text: f.Text, Query: q, Viz: "logs", Time: panel.Time{Range: "1h"}} + original := envelope{Text: f.Text, Query: q, Viz: "logs", Time: query.Time{Range: "1h"}} raw, err := json.Marshal(original) if err != nil { t.Fatal(err) diff --git a/internal/fanql/semantics_test.go b/internal/fanql/semantics_test.go index 4ad7d737..ea4b5410 100644 --- a/internal/fanql/semantics_test.go +++ b/internal/fanql/semantics_test.go @@ -11,8 +11,8 @@ import ( "time" "github.com/labstack/fanout/internal/config" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/ingest" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -33,27 +33,27 @@ func semanticSpan(namespace string, index int, attributes map[string]any) teleme } } -func semanticRun(t *testing.T, executor *panel.Executor, q panel.Query, variables []panel.Variable, vars map[string]panel.Value) panel.Result { +func semanticRun(t *testing.T, executor *query.Executor, q query.Spec, variables []query.Variable, vars map[string]query.Value) query.Result { return semanticRunViz(t, executor, q, "table", variables, vars) } -func semanticRunViz(t *testing.T, executor *panel.Executor, q panel.Query, viz string, variables []panel.Variable, vars map[string]panel.Value) panel.Result { +func semanticRunViz(t *testing.T, executor *query.Executor, q query.Spec, viz string, variables []query.Variable, vars map[string]query.Value) query.Result { t.Helper() end := semanticStart.Add(time.Hour) - results, err := executor.Run(t.Context(), panel.RunRequest{ - Dashboard: panel.Dashboard{Name: "Semantics", Time: panel.Time{From: &semanticStart, To: &end}, Variables: variables, - Panels: []panel.Panel{{ID: "semantic", Title: "Semantics", Viz: viz, Query: &q}}}, Vars: vars, + results, err := executor.Run(t.Context(), query.RunRequest{ + Dashboard: query.Dashboard{Name: "Semantics", Time: query.Time{From: &semanticStart, To: &end}, Variables: variables, + Panels: []query.Panel{{ID: "semantic", Title: "Semantics", Viz: viz, Query: &q}}}, Vars: vars, }) if err != nil { t.Fatal(err) } - if len(results) != 1 || results[0].Status == panel.StatusError || results[0].Frame == nil { + if len(results) != 1 || results[0].Status == query.StatusError || results[0].Frame == nil { t.Fatalf("query %+v: %+v", q, results) } return results[0] } -func semanticValue(t *testing.T, result panel.Result, name string) float64 { +func semanticValue(t *testing.T, result query.Result, name string) float64 { t.Helper() for i, column := range result.Frame.Columns { if column.Name == name { @@ -74,7 +74,7 @@ func semanticValue(t *testing.T, result panel.Result, name string) float64 { return 0 } -func semanticCompile(t *testing.T, text string, variables []panel.Variable) panel.Query { +func semanticCompile(t *testing.T, text string, variables []query.Variable) query.Spec { t.Helper() c, problems := Compile(text, Options{Viz: "table", Variables: variables}) if len(problems) != 0 { @@ -103,7 +103,7 @@ func TestTruthTable(t *testing.T) { if err := repo.Commit(t.Context(), telemetrystore.Batch{ID: "truth-table", Spans: spans}); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(d, 30) + executor := query.NewExecutor(d, 30) cases := []struct { namespace, filter string want int @@ -129,7 +129,7 @@ func TestTruthTable(t *testing.T) { }) } t.Run("stored SQL negative stays SQL", func(t *testing.T) { - q := panel.Query{From: "spans", Where: []string{"namespace = 'values'", "NOT (attributes['k'] = 'v')"}, Measures: []string{"count()"}} + q := query.Spec{From: "spans", Where: []string{"namespace = 'values'", "NOT (attributes['k'] = 'v')"}, Measures: []string{"count()"}} f, problems, err := Format(t.Context(), d, q, Options{Viz: "table"}) if err != nil || len(problems) != 0 { t.Fatalf("format: %+v %v", problems, err) @@ -143,9 +143,9 @@ func TestTruthTable(t *testing.T) { } }) t.Run("numeric variable uses literal ordering", func(t *testing.T) { - variables := []panel.Variable{{Name: "code", Kind: "text"}} + variables := []query.Variable{{Name: "code", Kind: "text"}} q := semanticCompile(t, "spans where namespace:http http_status_code>=$code | count()", variables) - result := semanticRun(t, executor, q, variables, map[string]panel.Value{"code": {Values: []string{"500"}}}) + result := semanticRun(t, executor, q, variables, map[string]query.Value{"code": {Values: []string{"500"}}}) if got := semanticValue(t, result, "count"); got != 0 { t.Fatalf("string variable matched %v, want 0", got) } @@ -195,8 +195,8 @@ func TestVariablesUnderAllPerConstruct(t *testing.T) { if err := repo.Commit(t.Context(), telemetrystore.Batch{ID: "all-constructs", Spans: spans}); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(d, 30) - variables := []panel.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true}} + executor := query.NewExecutor(d, 30) + variables := []query.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true}} for _, tc := range []struct { filter string entries, remaining, rows int @@ -213,7 +213,7 @@ func TestVariablesUnderAllPerConstruct(t *testing.T) { if len(q.Where) != tc.entries { t.Fatalf("authored entries %d, want %d", len(q.Where), tc.entries) } - result := semanticRun(t, executor, q, variables, map[string]panel.Value{"service": {All: true}}) + result := semanticRun(t, executor, q, variables, map[string]query.Value{"service": {All: true}}) if got := semanticValue(t, result, "count"); got != float64(tc.rows) { t.Fatalf("got %v, want %d", got, tc.rows) } @@ -276,7 +276,7 @@ func TestSeverityBandsEndToEnd(t *testing.T) { if !reflect.DeepEqual(submitter.bands, wantBands) { t.Fatalf("ingress bands %v, want %v", submitter.bands, wantBands) } - executor := panel.NewExecutor(d, 30) + executor := query.NewExecutor(d, 30) for _, tc := range []struct { filter string want int @@ -300,20 +300,20 @@ func TestSeverityBandsEndToEnd(t *testing.T) { var semanticVariables = regexp.MustCompile(`\$([A-Za-z_][A-Za-z_0-9]*)`) -func semanticCheckQuery(t *testing.T, d *query.Duck, q panel.Query) { +func semanticCheckQuery(t *testing.T, d *engine.Duck, q query.Spec) { t.Helper() - var variables []panel.Variable + var variables []query.Variable seen := map[string]bool{} for _, match := range semanticVariables.FindAllStringSubmatch(strings.Join(q.Where, " "), -1) { name := match[1] if !seen[name] { - variables = append(variables, panel.Variable{Name: name, Kind: "text"}) + variables = append(variables, query.Variable{Name: name, Kind: "text"}) seen[name] = true } } - dashboard := panel.Dashboard{Name: "Binding", Variables: variables, Panels: []panel.Panel{{ID: "binding", Title: "Binding", Viz: "table", Query: &q}}} - panel.Normalize(&dashboard) - if _, problems, err := panel.Check(t.Context(), d, &dashboard); err != nil || len(problems) != 0 { + dashboard := query.Dashboard{Name: "Binding", Variables: variables, Panels: []query.Panel{{ID: "binding", Title: "Binding", Viz: "table", Query: &q}}} + query.Normalize(&dashboard) + if _, problems, err := query.Check(t.Context(), d, &dashboard); err != nil || len(problems) != 0 { t.Fatalf("query %+v: %+v %v", q, problems, err) } } @@ -332,7 +332,7 @@ func TestEngineBindingOfEveryLoweredShape(t *testing.T) { } seen[key] = true t.Run(fixture.Query.From+"/"+entry, func(t *testing.T) { - semanticCheckQuery(t, d, panel.Query{From: fixture.Query.From, Where: []string{entry}, Measures: []string{"count()"}}) + semanticCheckQuery(t, d, query.Spec{From: fixture.Query.From, Where: []string{entry}, Measures: []string{"count()"}}) }) } for _, measure := range fixture.Query.Measures { @@ -345,7 +345,7 @@ func TestEngineBindingOfEveryLoweredShape(t *testing.T) { } seen[key] = true t.Run(fixture.Query.From+"/"+measure, func(t *testing.T) { - semanticCheckQuery(t, d, panel.Query{From: fixture.Query.From, Measures: []string{measure}}) + semanticCheckQuery(t, d, query.Spec{From: fixture.Query.From, Measures: []string{measure}}) }) } } @@ -423,9 +423,9 @@ func TestWorkloadsEndToEnd(t *testing.T) { if err := repo.Commit(t.Context(), batch); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(d, 30) - variables := []panel.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true}} - vars := map[string]panel.Value{"service": {Values: []string{"checkout"}}} + executor := query.NewExecutor(d, 30) + variables := []query.Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", IncludeAll: true}} + vars := map[string]query.Value{"service": {Values: []string{"checkout"}}} vizzes := []string{"timeseries", "traces", "table", "table", "stat", "histogram", "table", "table", "logs", "log_patterns", "timeseries", "table"} cases := make([]struct{ text, viz string }, 0, len(glanceExamples)+10) for i, text := range glanceExamples { @@ -449,13 +449,13 @@ func TestWorkloadsEndToEnd(t *testing.T) { if len(problems) != 0 { t.Fatalf("compile: %+v", problems) } - dashboard := panel.Dashboard{Name: "V1 workload", Variables: variables, Panels: []panel.Panel{{ID: "workload", Title: "Workload", Viz: tc.viz, Query: &c.Query}}} - panel.Normalize(&dashboard) - if _, problems, err := panel.Check(t.Context(), d, &dashboard); len(problems) != 0 || err != nil { + dashboard := query.Dashboard{Name: "V1 workload", Variables: variables, Panels: []query.Panel{{ID: "workload", Title: "Workload", Viz: tc.viz, Query: &c.Query}}} + query.Normalize(&dashboard) + if _, problems, err := query.Check(t.Context(), d, &dashboard); len(problems) != 0 || err != nil { t.Fatalf("check: %+v %v", problems, err) } result := semanticRunViz(t, executor, c.Query, tc.viz, variables, vars) - if result.Status != panel.StatusOK || result.Frame.Rows == 0 { + if result.Status != query.StatusOK || result.Frame.Rows == 0 { t.Fatalf("workload returned no matching data: %+v", result) } if strings.Contains(tc.text, "name:queue.lag") && semanticValue(t, result, "last") != 2 { diff --git a/internal/fanql/testhelpers_test.go b/internal/fanql/testhelpers_test.go index a443c5ad..398353e6 100644 --- a/internal/fanql/testhelpers_test.go +++ b/internal/fanql/testhelpers_test.go @@ -5,19 +5,19 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) -func newTestEngine(t testing.TB) (*query.Duck, *telemetrystore.Repository) { +func newTestEngine(t testing.TB) (*engine.Duck, *telemetrystore.Repository) { t.Helper() cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 4, RollupInterval: time.Hour} repo, err := telemetrystore.Open(cfg.TelemetryDir()) if err != nil { t.Fatal(err) } - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -27,11 +27,11 @@ func newTestEngine(t testing.TB) (*query.Duck, *telemetrystore.Repository) { // Parse returns no query whenever a problem is present. source is empty for a // whole query, or the page-supplied source for a search-bar filter. -func parse(text string, source string) (*queryTree, panel.Problems) { +func parse(text string, source string) (*queryTree, query.Problems) { return parseWith(text, source, currentVocabulary()) } // Resolve annotates fields and values in place, retaining entry boundaries. -func resolve(q *queryTree, opts Options) (*resolved, panel.Problems) { +func resolve(q *queryTree, opts Options) (*resolved, query.Problems) { return resolveWith(q, opts, currentVocabulary()) } diff --git a/internal/fanql/words.go b/internal/fanql/words.go index 4cf2e973..487124a8 100644 --- a/internal/fanql/words.go +++ b/internal/fanql/words.go @@ -2,7 +2,7 @@ package fanql import ( "fmt" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "strings" ) @@ -233,7 +233,7 @@ func message(code diagnosticCode) string { case diagByFirst: return "by needs measures first; write | count() by service" case diagBucket: - return "unknown bucket %q; use auto or one of " + strings.Join(panel.BucketNames()[1:], ", ") + return "unknown bucket %q; use auto or one of " + strings.Join(query.BucketNames()[1:], ", ") case diagByMax: return "at most 3 grouping fields" case diagHistogramBy: diff --git a/internal/intelligence/annotations_test.go b/internal/intelligence/annotations_test.go index e3208823..9bb3f948 100644 --- a/internal/intelligence/annotations_test.go +++ b/internal/intelligence/annotations_test.go @@ -4,8 +4,8 @@ import ( "context" "github.com/labstack/fanout/internal/annotations" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" - "github.com/labstack/fanout/internal/query/writegate" + "github.com/labstack/fanout/internal/engine" + "github.com/labstack/fanout/internal/engine/writegate" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" "testing" "time" @@ -18,7 +18,7 @@ func TestDetectorPublishesWhilePersistenceBlocked(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -43,7 +43,7 @@ func TestDetectorPublishesWhilePersistenceBlocked(t *testing.T) { } func TestDetectorCoalescesPendingPersistence(t *testing.T) { - d := NewDetector(&query.Duck{}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{}, DefaultDetectorConfig()) ctx, cancel := context.WithCancel(t.Context()) defer cancel() entered := make(chan time.Time, 3) @@ -109,7 +109,7 @@ func TestDetectorAnnotationMapping(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -136,7 +136,7 @@ func TestDetectorAnnotationMapping(t *testing.T) { } func TestDetectorWritesFailedFindingsWithTheNextBatch(t *testing.T) { - d := NewDetector(&query.Duck{}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{}, DefaultDetectorConfig()) ctx, cancel := context.WithCancel(t.Context()) defer cancel() calls := make(chan []annotations.Anomaly, 2) @@ -173,7 +173,7 @@ func TestDetectorWritesFailedFindingsWithTheNextBatch(t *testing.T) { } func TestDetectorKeepsDisplacedPendingIncidentAndItsInterval(t *testing.T) { - d := NewDetector(&query.Duck{}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{}, DefaultDetectorConfig()) ctx, cancel := context.WithCancel(t.Context()) entered := make(chan annotationBatch, 3) release := make(chan struct{}) @@ -215,7 +215,7 @@ func TestDetectorKeepsDisplacedPendingIncidentAndItsInterval(t *testing.T) { } func TestDetectorBoundsPendingFindings(t *testing.T) { - d := NewDetector(&query.Duck{}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{}, DefaultDetectorConfig()) now := time.Now().UTC() for _, count := range []int{maxCarriedAnomalies + 1, 1} { findings := make([]Anomaly, count) diff --git a/internal/intelligence/detector.go b/internal/intelligence/detector.go index 60a244be..62620f1b 100644 --- a/internal/intelligence/detector.go +++ b/internal/intelligence/detector.go @@ -1,6 +1,6 @@ // Package intelligence derives anomalies and log patterns from telemetry. // -// Public log-pattern SQL goes through internal/query's validator, which +// Public log-pattern SQL goes through internal/engine's validator, which // rejects "--" outright. A SQL comment in one of these statements therefore // fails the query at runtime, on a background goroutine, as a logged error // nobody is watching -- that is how latency detection stopped reporting for @@ -20,12 +20,12 @@ import ( "time" "github.com/labstack/fanout/internal/annotations" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) // Detector runs intelligence detection on observability data type Detector struct { - duck *query.Duck + duck *engine.Duck config DetectorConfig mu sync.RWMutex snapshot *Snapshot @@ -47,7 +47,7 @@ type annotationBatch struct { } // NewDetector creates a new intelligence detector -func NewDetector(duck *query.Duck, config DetectorConfig) *Detector { +func NewDetector(duck *engine.Duck, config DetectorConfig) *Detector { return &Detector{ duck: duck, config: config, @@ -666,7 +666,7 @@ func (d *Detector) detectLogPatterns(ctx context.Context, start, end time.Time) LIMIT 50 `, startNano, endNano, scope) - resp := d.duck.ExecuteSQL(ctx, query.SQLRequest{Query: sql}) + resp := d.duck.ExecuteSQL(ctx, engine.SQLRequest{Query: sql}) if resp.Error != "" { return nil, fmt.Errorf("pattern detection: %s", resp.Error) } diff --git a/internal/intelligence/detector_recovery_test.go b/internal/intelligence/detector_recovery_test.go index 65e3925c..0583e2e5 100644 --- a/internal/intelligence/detector_recovery_test.go +++ b/internal/intelligence/detector_recovery_test.go @@ -12,8 +12,8 @@ import ( "github.com/duckdb/duckdb-go/v2" "github.com/labstack/fanout/internal/annotations" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" - "github.com/labstack/fanout/internal/query/writegate" + "github.com/labstack/fanout/internal/engine" + "github.com/labstack/fanout/internal/engine/writegate" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -76,13 +76,13 @@ func TestDetectorRetriesFailedQueriesAtUnchangedWatermark(t *testing.T) { connector := &detectorFailureConnector{Connector: native} db := sql.OpenDB(connector) defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } createDetectorLogs(t, db) end := time.Now().UTC().Truncate(time.Minute).Add(-2 * time.Hour) seedDetectorRecoveryRollup(t, db, end) - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) if withPrevious { d.publishSnapshot(Snapshot{GeneratedAt: time.Now().Add(-time.Minute), evaluatedThrough: end.Add(-time.Minute), HealthScore: 85}) <-d.annotationBatches @@ -128,7 +128,7 @@ func TestDetectorRetriesPersistenceAtUnchangedWatermark(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -219,13 +219,13 @@ func TestDetectorRetriesPatternFailureWithoutPublishingHealthySnapshot(t *testin connector := &detectorFailureConnector{Connector: native} db := sql.OpenDB(connector) defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } createDetectorLogs(t, db) end := time.Now().UTC().Truncate(time.Minute).Add(-time.Hour) seedDetectorRecoveryRollup(t, db, end) - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) if withPrevious { d.runCheck(t.Context()) <-d.annotationBatches @@ -264,13 +264,13 @@ func TestDetectorKeepsUnpublishedFindingsWhenWatermarkAdvances(t *testing.T) { connector := &detectorFailureConnector{Connector: native, fail: "AS occurrence_count"} db := sql.OpenDB(connector) defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } createDetectorLogs(t, db) end := time.Now().UTC().Truncate(time.Minute).Add(-time.Hour) seedDetectorRecoveryRollup(t, db, end) - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) for range 2 { d.runCheck(t.Context()) } @@ -318,7 +318,7 @@ func TestDetectorKeepsUnpublishedFindingsWhenWatermarkAdvances(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } diff --git a/internal/intelligence/effect_size_test.go b/internal/intelligence/effect_size_test.go index 25deb8a9..3fa65689 100644 --- a/internal/intelligence/effect_size_test.go +++ b/internal/intelligence/effect_size_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) func TestLatencyAnomaliesRequireStatisticalAndPracticalSignificance(t *testing.T) { @@ -47,7 +47,7 @@ func TestLatencyAnomaliesRequireStatisticalAndPracticalSignificance(t *testing.T } } } - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) anomalies, err := d.detectLatencyAnomalies(t.Context(), start, end) if err != nil { t.Fatal(err) @@ -104,7 +104,7 @@ func TestVolumeAnomaliesRequireStatisticalAndPracticalSignificance(t *testing.T) } } } - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) anomalies, err := d.detectVolumeAnomalies(t.Context(), start, end) if err != nil { t.Fatal(err) diff --git a/internal/intelligence/parquet_test.go b/internal/intelligence/parquet_test.go index cac52263..2be4f67b 100644 --- a/internal/intelligence/parquet_test.go +++ b/internal/intelligence/parquet_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -23,7 +23,7 @@ func TestDetectorsReadNativeParquetTimestamps(t *testing.T) { t.Fatal(err) } defer repository.Close() - duck, err := query.NewDuck(ctx, cfg, repository) + duck, err := engine.NewDuck(ctx, cfg, repository) if err != nil { t.Fatal(err) } diff --git a/internal/intelligence/pattern_recovery_test.go b/internal/intelligence/pattern_recovery_test.go index 8bd66139..bf1ff4ae 100644 --- a/internal/intelligence/pattern_recovery_test.go +++ b/internal/intelligence/pattern_recovery_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -31,7 +31,7 @@ func TestLogPatternsIncludeObservedTimeAndExactEventBounds(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -79,7 +79,7 @@ func TestDetectorRefreshesPatternsAtStalledAndZeroWatermarks(t *testing.T) { t.Fatal(err) } defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } createDetectorLogs(t, db) @@ -87,7 +87,7 @@ func TestDetectorRefreshesPatternsAtStalledAndZeroWatermarks(t *testing.T) { if completed { seedDetectorRecoveryRollup(t, db, end) } - d := NewDetector(&query.Duck{DB: db}, DefaultDetectorConfig()) + d := NewDetector(&engine.Duck{DB: db}, DefaultDetectorConfig()) d.runCheck(t.Context()) previous := d.LatestSnapshot() if previous == nil || len(previous.Patterns) != 0 { diff --git a/internal/intelligence/rollup_detector_test.go b/internal/intelligence/rollup_detector_test.go index 8bed02d8..e3a89c75 100644 --- a/internal/intelligence/rollup_detector_test.go +++ b/internal/intelligence/rollup_detector_test.go @@ -8,7 +8,7 @@ import ( "github.com/labstack/fanout/internal/annotations" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -18,7 +18,7 @@ func TestServiceDetectorsWeightMinutesBySpanCount(t *testing.T) { t.Fatal(err) } defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } start := time.Date(2026, 10, 1, 12, 15, 0, 0, time.UTC) @@ -79,7 +79,7 @@ func TestDetectorsStopBeforeTheServiceWatermarkMinute(t *testing.T) { t.Fatal(err) } defer db.Close() - if err := query.CreateCacheTables(db); err != nil { + if err := engine.CreateCacheTables(db); err != nil { t.Fatal(err) } createDetectorLogs(t, db) @@ -95,7 +95,7 @@ func TestDetectorsStopBeforeTheServiceWatermarkMinute(t *testing.T) { } cfg := DefaultDetectorConfig() cfg.LookbackWindow = 5 * time.Minute - detector := NewDetector(&query.Duck{DB: db}, cfg) + detector := NewDetector(&engine.Duck{DB: db}, cfg) snapshot, err := detector.GenerateSnapshot(t.Context()) if err != nil { t.Fatal(err) @@ -119,7 +119,7 @@ func TestDetectorPersistsEvaluatedWindowWhilePatternsRefresh(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } diff --git a/internal/intelligence/sql_comments_test.go b/internal/intelligence/sql_comments_test.go index b1f475d8..834c2a1a 100644 --- a/internal/intelligence/sql_comments_test.go +++ b/internal/intelligence/sql_comments_test.go @@ -8,7 +8,7 @@ import ( ) // Every statement this package issues goes through a validator that rejects -// SQL comments outright (internal/query/sql.go: "SQL comments (--) are not +// SQL comments outright (internal/engine/sql.go: "SQL comments (--) are not // allowed"). A "--" inside a query string therefore fails at runtime, on a // background goroutine, as a logged error nobody is watching -- the anomaly // detector silently stopped reporting latency for half an hour that way. @@ -47,7 +47,7 @@ func TestNoSQLCommentsInQueryStrings(t *testing.T) { // DuckDB's FLOAT is single precision, so the driver returns float32 and the // `row["x"].(float64)` every caller here writes fails -- silently yielding 0.0. -// internal/query now widens float32 on the way out, which disarms the trap, but +// internal/engine now widens float32 on the way out, which disarms the trap, but // a rate or a count has no business being single precision in the first place // and the next reader should not have to know about the widening to trust it. func TestNoFloatCastsInQueryStrings(t *testing.T) { diff --git a/internal/mcp/committed_panic_test.go b/internal/mcp/committed_panic_test.go index 96046bb5..ca0733f2 100644 --- a/internal/mcp/committed_panic_test.go +++ b/internal/mcp/committed_panic_test.go @@ -10,13 +10,13 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/modelcontextprotocol/go-sdk/mcp" ) type panicValidator struct{ armed atomic.Bool } -func (v *panicValidator) Validate(ctx context.Context, d *panel.Dashboard) error { +func (v *panicValidator) Validate(ctx context.Context, d *query.Dashboard) error { if v.armed.Load() { panic("private panic detail") } @@ -46,7 +46,7 @@ func TestMCPPanicDistinguishesCommittedSave(t *testing.T) { } panicValidation.armed.Store(true) if commit { - s.panels = receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { panic("private panic detail") }} + s.panels = receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { panic("private panic detail") }} } var logs bytes.Buffer old := slog.Default() diff --git a/internal/mcp/concurrent_receipts_test.go b/internal/mcp/concurrent_receipts_test.go index 99cff584..916f0ad5 100644 --- a/internal/mcp/concurrent_receipts_test.go +++ b/internal/mcp/concurrent_receipts_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" ) @@ -38,17 +38,17 @@ func TestConcurrentFileBackedSaveReceiptsNameOnlyTheirOwnEdit(t *testing.T) { t.Run(fmt.Sprint("explicit=", explicit), func(t *testing.T) { s := newConcurrentFileServer(t) const n = 6 - spec := panel.Dashboard{Name: "Race"} + spec := query.Dashboard{Name: "Race"} for i := 0; i < n; i++ { - spec.Panels = append(spec.Panels, panel.Panel{ID: fmt.Sprintf("p%d", i), Title: fmt.Sprintf("P%d", i), Viz: "text", Content: "base", Width: 12}) + spec.Panels = append(spec.Panels, query.Panel{ID: fmt.Sprintf("p%d", i), Title: fmt.Sprintf("P%d", i), Viz: "text", Content: "base", Width: 12}) } var mu sync.Mutex - checkedSpecs := map[string]panel.Dashboard{} // content signature -> spec checked - s.panels = receiptExecutor{run: func(_ context.Context, req panel.RunRequest) ([]panel.Result, error) { - out := make([]panel.Result, 0, len(req.Dashboard.Panels)) + checkedSpecs := map[string]query.Dashboard{} // content signature -> spec checked + s.panels = receiptExecutor{run: func(_ context.Context, req query.RunRequest) ([]query.Result, error) { + out := make([]query.Result, 0, len(req.Dashboard.Panels)) sig := "" for _, p := range req.Dashboard.Panels { - out = append(out, panel.Result{ID: p.ID, Status: "ok"}) + out = append(out, query.Result{ID: p.ID, Status: "ok"}) sig += p.Content + "," } mu.Lock() diff --git a/internal/mcp/dashboards.go b/internal/mcp/dashboards.go index 30c6786d..06ed3288 100644 --- a/internal/mcp/dashboards.go +++ b/internal/mcp/dashboards.go @@ -10,7 +10,7 @@ import ( "time" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -20,12 +20,12 @@ type DashboardIDInput struct { } type DashboardCreateInput struct { - Dashboard panel.Dashboard `json:"dashboard" jsonschema:"Complete v1 dashboard spec"` + Dashboard query.Dashboard `json:"dashboard" jsonschema:"Complete v1 dashboard spec"` } type DashboardReplaceInput struct { ID string `json:"id" jsonschema:"Dashboard ID"` - Dashboard panel.Dashboard `json:"dashboard" jsonschema:"Complete replacement spec; omitted panels are removed"` + Dashboard query.Dashboard `json:"dashboard" jsonschema:"Complete replacement spec; omitted panels are removed"` BaseVersion int `json:"base_version,omitempty" jsonschema:"Version you read; the call fails if someone saved since"` Message string `json:"message,omitempty" jsonschema:"One line describing the change, shown in history"` } @@ -66,7 +66,7 @@ type dashboardOutput struct { Warnings []string `json:"warnings,omitempty"` Receipt *dashboardReceipt `json:"receipt,omitempty"` Error *toolerror.Error `json:"error,omitempty"` - Problems panel.Problems `json:"problems,omitempty"` + Problems query.Problems `json:"problems,omitempty"` } type savedPanelCheck struct { @@ -254,7 +254,7 @@ func (s *Server) dashboardEdit(ctx context.Context, req *mcp.CallToolRequest, in return s.saved(ctx, "Updated", record) } -func (s *Server) checkDashboardPanels(ctx context.Context, spec panel.Dashboard) error { +func (s *Server) checkDashboardPanels(ctx context.Context, spec query.Dashboard) error { telemetry := false for _, p := range spec.Panels { telemetry = telemetry || p.Viz != "text" @@ -265,15 +265,15 @@ func (s *Server) checkDashboardPanels(ctx context.Context, spec panel.Dashboard) if s.panels == nil { return errors.New("panels are unavailable") } - results, err := s.panels.Run(ctx, panel.RunRequest{Dashboard: spec}) + results, err := s.panels.Run(ctx, query.RunRequest{Dashboard: spec}) if err != nil { return err } - byID := make(map[string]panel.Result, len(results)) + byID := make(map[string]query.Result, len(results)) for _, r := range results { byID[r.ID] = r } - var problems panel.Problems + var problems query.Problems for i, p := range spec.Panels { if p.Viz == "text" { continue @@ -281,17 +281,17 @@ func (s *Server) checkDashboardPanels(ctx context.Context, spec panel.Dashboard) r, exists := byID[p.ID] // Execution status records data presence before the shared batch budget // truncates frames, which can remove every row from a populated panel. - if exists && r.Status == panel.StatusOK { + if exists && r.Status == query.StatusOK { continue } - diagnosis := panel.PresentDiagnosis(r.Diagnosis) + diagnosis := query.PresentDiagnosis(r.Diagnosis) if diagnosis == "" { - diagnosis = panel.PresentMessage(r.Error) + diagnosis = query.PresentMessage(r.Error) } if diagnosis == "" { diagnosis = "Preview returned no rows." } - problems = append(problems, panel.DiagnosisProblem(fmt.Sprintf("panels[%d]", i), fmt.Sprintf("%s: %s", p.Title, diagnosis), "Replace or drop this panel; dashboards contain only panels that return data.")) + problems = append(problems, query.DiagnosisProblem(fmt.Sprintf("panels[%d]", i), fmt.Sprintf("%s: %s", p.Title, diagnosis), "Replace or drop this panel; dashboards contain only panels that return data.")) } if len(problems) > 0 { return problems @@ -348,18 +348,18 @@ func (s *Server) saved(ctx context.Context, verb string, mutation dashboard.Muta check.Reason = "panels are unavailable" } else { checkCtx, cancel := context.WithTimeout(ctx, saveCheckBudget) - results, err := s.panels.Run(checkCtx, panel.RunRequest{Dashboard: record.Spec}) + results, err := s.panels.Run(checkCtx, query.RunRequest{Dashboard: record.Spec}) if err == nil { err = checkCtx.Err() } cancel() if err != nil { - check.Reason = panel.PresentError(err, panel.ReadError) + check.Reason = query.PresentError(err, query.ReadError) if errors.Is(err, context.DeadlineExceeded) { check.Reason = fmt.Sprintf("the check took longer than %d seconds", int(saveCheckBudget/time.Second)) } } else { - byID := map[string][]panel.Result{} + byID := map[string][]query.Result{} expected := map[string]bool{} for _, p := range record.Spec.Panels { expected[p.ID] = true @@ -378,24 +378,24 @@ func (s *Server) saved(ctx context.Context, verb string, mutation dashboard.Muta continue } r := matches[0] - if r.Status != panel.StatusOK && r.Status != panel.StatusEmpty && r.Status != panel.StatusError { + if r.Status != query.StatusOK && r.Status != query.StatusEmpty && r.Status != query.StatusError { complete = false continue } - c := savedPanelCheck{ID: r.ID, Status: r.Status, Diagnosis: panel.PresentDiagnosis(r.Diagnosis), ElapsedMS: &r.ElapsedMS} + c := savedPanelCheck{ID: r.ID, Status: r.Status, Diagnosis: query.PresentDiagnosis(r.Diagnosis), ElapsedMS: &r.ElapsedMS} if r.Frame != nil { c.Rows = r.Frame.Rows - } else if r.Status == panel.StatusOK && p.Viz == "text" && strings.TrimSpace(p.Content) != "" { + } else if r.Status == query.StatusOK && p.Viz == "text" && strings.TrimSpace(p.Content) != "" { c.Rows = 1 } if r.Error != "" { - c.Error = panel.PresentMessage(r.Error) + c.Error = query.PresentMessage(r.Error) } check.Panels[i] = c switch r.Status { - case panel.StatusEmpty: + case query.StatusEmpty: out.Warnings = append(out.Warnings, fmt.Sprintf("%s is empty: %s", r.ID, c.Diagnosis)) - case panel.StatusError: + case query.StatusError: out.Warnings = append(out.Warnings, fmt.Sprintf("%s failed: %s", r.ID, c.Error)) } } @@ -448,13 +448,13 @@ func dashboardOwner(req *mcp.CallToolRequest) (string, error) { } func dashboardToolError(err error) (*mcp.CallToolResult, dashboardOutput, error) { - var problems panel.Problems + var problems query.Problems code, message := "", "" switch { case errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded): return nil, dashboardOutput{}, safePanelToolError(err) case errors.As(err, &problems): - problems = panel.PresentProblems(problems) + problems = query.PresentProblems(problems) code, message = "invalid_spec", problems.Error() case errors.Is(err, dashboard.ErrVersionNotFound): code, message = dashboard.VersionNotFoundCode, err.Error() diff --git a/internal/mcp/dashboards_tools_test.go b/internal/mcp/dashboards_tools_test.go index 59897d61..a92f39ac 100644 --- a/internal/mcp/dashboards_tools_test.go +++ b/internal/mcp/dashboards_tools_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" mcpgoauth "github.com/modelcontextprotocol/go-sdk/auth" "github.com/modelcontextprotocol/go-sdk/mcp" @@ -16,7 +16,7 @@ import ( type cancelValidator struct{} -func (cancelValidator) Validate(ctx context.Context, _ *panel.Dashboard) error { return ctx.Err() } +func (cancelValidator) Validate(ctx context.Context, _ *query.Dashboard) error { return ctx.Err() } func newToolServer(t *testing.T, validator dashboard.Validator, panels panelExecutor) *Server { t.Helper() @@ -39,8 +39,8 @@ func requestFor(owner string) *mcp.CallToolRequest { return &mcp.CallToolRequest{Params: &mcp.CallToolParamsRaw{Meta: mcp.Meta{dashboard.OwnerMetaKey: owner}}} } -func textDashboard(name string) panel.Dashboard { - return panel.Dashboard{Name: name, Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} +func textDashboard(name string) query.Dashboard { + return query.Dashboard{Name: name, Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} } func TestCreateDashboardAcceptsTheDocumentedShape(t *testing.T) { @@ -112,7 +112,7 @@ func TestStaleBaseVersionIsReportedAndMatchingOneSucceeds(t *testing.T) { func TestInvalidSpecsReturnProblemsWithPaths(t *testing.T) { s := newPanelServer(t) ctx := t.Context() - bad := panel.Dashboard{Name: "Bad", Panels: []panel.Panel{{ID: "typo", Title: "Typo", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"p95(duraton_ms)"}}}}} + bad := query.Dashboard{Name: "Bad", Panels: []query.Panel{{ID: "typo", Title: "Typo", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"p95(duraton_ms)"}}}}} result, out, err := s.dashboardCreate(ctx, requestFor("owner"), DashboardCreateInput{Dashboard: bad}) if err != nil || !result.IsError || out.Error == nil || out.Error.Code != "invalid_spec" || !strings.Contains(out.Error.Message, "panels[0]") { t.Fatalf("create = %+v %v", out, err) @@ -163,7 +163,7 @@ func TestOtherOwnersDashboardIsNotFound(t *testing.T) { func TestSaveRejectsPanelsItCannotPreview(t *testing.T) { panels := newPanelServer(t).panels s := newToolServer(t, structural{}, panels) - spec := panel.Dashboard{Name: "Unchecked", Panels: []panel.Panel{{ID: "requests", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Where: []string{"service = = 'x'"}, Measures: []string{"count()"}}}}} + spec := query.Dashboard{Name: "Unchecked", Panels: []query.Panel{{ID: "requests", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Where: []string{"service = = 'x'"}, Measures: []string{"count()"}}}}} result, out, err := s.dashboardCreate(t.Context(), requestFor("owner"), DashboardCreateInput{Dashboard: spec}) if err != nil || !result.IsError || out.Error == nil || out.Error.Code != "invalid_spec" || out.Dashboard != nil || out.Receipt != nil { t.Fatalf("save=%+v err=%v", out, err) diff --git a/internal/mcp/error_contract_test.go b/internal/mcp/error_contract_test.go index a6f0bed6..6c8687f8 100644 --- a/internal/mcp/error_contract_test.go +++ b/internal/mcp/error_contract_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -52,7 +52,7 @@ func TestUnknownToolsKeepJSONRPCFailures(t *testing.T) { type dashboardValidationFailure struct{ err error } -func (v *dashboardValidationFailure) Validate(ctx context.Context, spec *panel.Dashboard) error { +func (v *dashboardValidationFailure) Validate(ctx context.Context, spec *query.Dashboard) error { if v.err != nil { return v.err } @@ -70,7 +70,7 @@ func TestDashboardValidationProblemsUseInvalidSpecThroughMiddleware(t *testing.T if _, err := s.dashboards.Replace(t.Context(), "owner", created.ID, spec, 1, agentAuthor("owner"), ""); err != nil { t.Fatal(err) } - problems := panel.Problems{{Path: "panels[0].query.sort", Message: "Binder Error: Unknown sort column missing", Hint: "Choose a known column"}, {Path: "name", Message: "Name required"}} + problems := query.Problems{{Path: "panels[0].query.sort", Message: "Binder Error: Unknown sort column missing", Hint: "Choose a known column"}, {Path: "name", Message: "Name required"}} v.err = problems session := connectTestClient(t, s, nil) for _, tc := range []struct { @@ -90,7 +90,7 @@ func TestDashboardValidationProblemsUseInvalidSpecThroughMiddleware(t *testing.T for _, content := range []any{json.RawMessage(result.Content[0].(*mcp.TextContent).Text), result.StructuredContent} { raw, err := json.Marshal(content) var failure dashboardOutput - if err != nil || json.Unmarshal(raw, &failure) != nil || failure.Error == nil || failure.Error.Code != "invalid_spec" || failure.Error.Message != panel.PresentProblems(problems).Error() || !reflect.DeepEqual(failure.Problems, panel.PresentProblems(problems)) { + if err != nil || json.Unmarshal(raw, &failure) != nil || failure.Error == nil || failure.Error.Code != "invalid_spec" || failure.Error.Message != query.PresentProblems(problems).Error() || !reflect.DeepEqual(failure.Problems, query.PresentProblems(problems)) { t.Fatalf("failure=%s err=%v", raw, err) } } @@ -116,7 +116,7 @@ func TestOtherDashboardFailuresKeepTheirCodesThroughMiddleware(t *testing.T) { {"replace_dashboard", "dashboard_version_conflict", "the dashboard changed since you read it; open it again and reapply the change", DashboardReplaceInput{ID: created.ID, Dashboard: spec, BaseVersion: 2}, nil}, {"edit_dashboard", "dashboard_version_conflict", "the dashboard changed since you read it; open it again and reapply the change", DashboardEditInput{ID: created.ID, BaseVersion: 2, Operations: []dashboard.Operation{{Op: "rename", Name: "Renamed"}}}, nil}, {"edit_dashboard", "tool_failed", "dashboard not found", DashboardEditInput{ID: "missing", Operations: []dashboard.Operation{{Op: "rename", Name: "Renamed"}}}, nil}, - {"create_dashboard", "tool_failed", panel.ReadFailure, DashboardCreateInput{Dashboard: textDashboard("Unavailable")}, errors.New("open /srv/private/control.sqlite: failed")}, + {"create_dashboard", "tool_failed", query.ReadFailure, DashboardCreateInput{Dashboard: textDashboard("Unavailable")}, errors.New("open /srv/private/control.sqlite: failed")}, } { t.Run(tc.message, func(t *testing.T) { v.err = tc.cause diff --git a/internal/mcp/fanql_test.go b/internal/mcp/fanql_test.go index b86a6d08..41119d39 100644 --- a/internal/mcp/fanql_test.go +++ b/internal/mcp/fanql_test.go @@ -8,20 +8,20 @@ import ( "testing" "github.com/labstack/fanout/internal/fanql" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "github.com/modelcontextprotocol/go-sdk/mcp" ) func TestQueryTelemetryAcceptsFanQLText(t *testing.T) { s := panelServerFixture(t, true) - p := panel.Panel{ID: "t", Title: "t", Viz: "table"} + p := query.Panel{ID: "t", Title: "t", Viz: "table"} input := QueryTelemetryInput{Panel: p, Text: "spans where status:error | count() by service"} _, got, err := s.queryTelemetry(t.Context(), nil, input) if err != nil { t.Fatal(err) } - want := &panel.Query{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}, Measures: []string{"count()"}, By: []string{"service"}} + want := &query.Spec{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}, Measures: []string{"count()"}, By: []string{"service"}} if !reflect.DeepEqual(got.Dashboard.Panels[0].Query, want) { t.Fatalf("query: %+v", got.Dashboard.Panels[0].Query) } @@ -43,7 +43,7 @@ type fanqlRunCounter struct { calls int } -func (e *fanqlRunCounter) Run(ctx context.Context, req panel.RunRequest) ([]panel.Result, error) { +func (e *fanqlRunCounter) Run(ctx context.Context, req query.RunRequest) ([]query.Result, error) { e.calls++ return e.panelExecutor.Run(ctx, req) } @@ -72,7 +72,7 @@ func checkFanQLToolFailure(t *testing.T, input QueryTelemetryInput, code, messag } func TestQueryTelemetryRejectsTextWithQueryOrSQL(t *testing.T) { - for _, p := range []panel.Panel{{Query: &panel.Query{From: "spans"}}, {SQL: "SELECT 1"}} { + for _, p := range []query.Panel{{Query: &query.Spec{From: "spans"}}, {SQL: "SELECT 1"}} { checkFanQLToolFailure(t, QueryTelemetryInput{Panel: p, Text: "spans"}, "invalid_input", "text cannot be combined with panel.query or panel.sql") } } @@ -153,7 +153,7 @@ func TestQueryTelemetryDescriptionPrefersStructuredInput(t *testing.T) { func TestQueryTelemetryFanQLMetadataAndStructuredProblems(t *testing.T) { s := panelServerFixture(t, true) - _, out, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: panel.Panel{ID: "t", Title: "t", Viz: "table"}, Text: "spans where status:error | count() by service"}) + _, out, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: query.Panel{ID: "t", Title: "t", Viz: "table"}, Text: "spans where status:error | count() by service"}) if err != nil { t.Fatal(err) } @@ -164,7 +164,7 @@ func TestQueryTelemetryFanQLMetadataAndStructuredProblems(t *testing.T) { raw, _ := json.Marshal(failed) var failure struct { Error toolerror.Error `json:"error"` - Problems panel.Problems `json:"problems"` + Problems query.Problems `json:"problems"` } if err != nil || result == nil || !result.IsError || json.Unmarshal(raw, &failure) != nil || failure.Error.Code != "invalid_fanql" || len(failure.Problems) != 1 || failure.Problems[0].Span == nil || len(failure.Problems[0].FixIts) != 2 { t.Fatalf("structured failure: %v", err) @@ -198,7 +198,7 @@ func TestQueryTelemetryFanQLProblemsStayStructuredThroughMiddleware(t *testing.T raw, _ := json.Marshal(content) var body struct { Error toolerror.Error `json:"error"` - Problems panel.Problems `json:"problems"` + Problems query.Problems `json:"problems"` } if json.Unmarshal(raw, &body) != nil || body.Error.Code != "invalid_fanql" || len(body.Problems) != 1 || body.Problems[0].Span == nil || len(body.Problems[0].FixIts) != 2 { t.Fatalf("structured failure: %s", raw) diff --git a/internal/mcp/fragment_budget_test.go b/internal/mcp/fragment_budget_test.go index 6b1894d4..1c1a593d 100644 --- a/internal/mcp/fragment_budget_test.go +++ b/internal/mcp/fragment_budget_test.go @@ -10,15 +10,15 @@ import ( "testing" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" sdk "github.com/modelcontextprotocol/go-sdk/mcp" ) func nonuniformFragment(values []any) PanelFragment { - return PanelFragment{Dashboard: fragmentPreset("logs", "", "", "", "", 100), Results: []panel.Result{ - {ID: "volume", Status: "ok", Frame: &panel.Frame{Columns: []panel.Column{{Name: "count", Type: "number", Role: "measure"}}, Values: [][]any{{1, 2, 3}}, Rows: 3}}, - {ID: "events", Status: "ok", Frame: &panel.Frame{Columns: []panel.Column{{Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{values}, Rows: len(values)}}, + return PanelFragment{Dashboard: fragmentPreset("logs", "", "", "", "", 100), Results: []query.Result{ + {ID: "volume", Status: "ok", Frame: &query.Frame{Columns: []query.Column{{Name: "count", Type: "number", Role: "measure"}}, Values: [][]any{{1, 2, 3}}, Rows: 3}}, + {ID: "events", Status: "ok", Frame: &query.Frame{Columns: []query.Column{{Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{values}, Rows: len(values)}}, }} } func TestHeadHeavyRowsKeepSmallPanelAndMaximalPrefix(t *testing.T) { diff --git a/internal/mcp/fragment_contract_test.go b/internal/mcp/fragment_contract_test.go index 461c01bf..0da93402 100644 --- a/internal/mcp/fragment_contract_test.go +++ b/internal/mcp/fragment_contract_test.go @@ -15,7 +15,7 @@ import ( "time" "unicode/utf8" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" sdk "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -64,7 +64,7 @@ func TestLimitCheckOnlyAppliesToRegisteredLimitInputs(t *testing.T) { func TestEscapedPayloadAndIntegerPrecision(t *testing.T) { f := PanelFragment{Dashboard: fragmentPreset("trace", "", "", "", "", 50)} for i := range 40 { - f.Results = append(f.Results, panel.Result{ID: fmt.Sprint(i), Status: panel.StatusError, SQL: strings.Repeat("\x00", 10000), Error: strings.Repeat("\x00", 10000), Diagnosis: strings.Repeat("\x00", 10000), Frame: &panel.Frame{Columns: []panel.Column{}, Values: [][]any{}, Note: strings.Repeat("\x00", 10000)}}) + f.Results = append(f.Results, query.Result{ID: fmt.Sprint(i), Status: query.StatusError, SQL: strings.Repeat("\x00", 10000), Error: strings.Repeat("\x00", 10000), Diagnosis: strings.Repeat("\x00", 10000), Frame: &query.Frame{Columns: []query.Column{}, Values: [][]any{}, Note: strings.Repeat("\x00", 10000)}}) } got := boundedTestFragment(t, f) raw, err := json.Marshal(got) @@ -72,7 +72,7 @@ func TestEscapedPayloadAndIntegerPrecision(t *testing.T) { t.Fatalf("escaped payload=%d err=%v", len(raw), err) } n := int64(9007199254740993) - f.Results = []panel.Result{{ID: "traces", Status: panel.StatusOK, Frame: &panel.Frame{Columns: []panel.Column{{Name: "count", Type: "number", Role: "measure"}}, Values: [][]any{{n}}, Rows: 1}}} + f.Results = []query.Result{{ID: "traces", Status: query.StatusOK, Frame: &query.Frame{Columns: []query.Column{{Name: "count", Type: "number", Role: "measure"}}, Values: [][]any{{n}}, Rows: 1}}} got = boundedTestFragment(t, f) if fmt.Sprint(got.Results[0].Frame.Values[0][0]) != fmt.Sprint(n) { t.Fatal("integer precision lost") @@ -80,8 +80,8 @@ func TestEscapedPayloadAndIntegerPrecision(t *testing.T) { } func TestSummaryReadableCells(t *testing.T) { - result := panel.Result{ID: "latency", Status: panel.StatusOK, Frame: &panel.Frame{Rows: 7, Columns: []panel.Column{{Name: "time", Type: "time", Role: "time"}, {Name: "p95", Type: "number", Role: "measure", Unit: "ms"}, {Name: "absent", Type: "string"}}, Values: [][]any{{int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000)}, {42, 42, 42, 42, 42, 42, 42}, {nil, nil, nil, nil, nil, nil, nil}}}} - text := fragmentSummary(PanelFragment{Results: []panel.Result{result}}) + result := query.Result{ID: "latency", Status: query.StatusOK, Frame: &query.Frame{Rows: 7, Columns: []query.Column{{Name: "time", Type: "time", Role: "time"}, {Name: "p95", Type: "number", Role: "measure", Unit: "ms"}, {Name: "absent", Type: "string"}}, Values: [][]any{{int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000), int64(1791486900000)}, {42, 42, 42, 42, 42, 42, 42}, {nil, nil, nil, nil, nil, nil, nil}}}} + text := fragmentSummary(PanelFragment{Results: []query.Result{result}}) if !strings.Contains(text, time.UnixMilli(1791486900000).UTC().Format(time.RFC3339)) || !strings.Contains(text, "42 ms") || strings.Contains(text, "absent=") { t.Fatalf("unreadable summary: %s", text) } @@ -89,14 +89,14 @@ func TestSummaryReadableCells(t *testing.T) { t.Fatalf("sample count: %s", text) } result.Frame.Truncated = true - if !strings.Contains(fragmentSummary(PanelFragment{Results: []panel.Result{result}}), "truncated=true") { + if !strings.Contains(fragmentSummary(PanelFragment{Results: []query.Result{result}}), "truncated=true") { t.Fatal("missing true truncation") } } func TestSummaryKeepsEverySupportedUnit(t *testing.T) { for unit, want := range map[string]string{"ns": "42 ns", "per_minute": "42/min", "ratio": "42×"} { - if got := summaryCell(panel.Column{Type: "number", Unit: unit}, 42); got != want { + if got := summaryCell(query.Column{Type: "number", Unit: unit}, 42); got != want { t.Fatalf("%s: %s, want %s", unit, got, want) } } @@ -126,7 +126,7 @@ func TestPresetsHaveTitlesAndSearchLimit(t *testing.T) { } func TestEncodingFailureCancellationAndMetadata(t *testing.T) { - f := PanelFragment{Dashboard: fragmentPreset("overview", "", "", "", "", 50), Results: []panel.Result{{ID: "health", Status: panel.StatusOK, Frame: &panel.Frame{Columns: []panel.Column{}, Values: [][]any{}, Totals: []any{math.NaN()}}}}} + f := PanelFragment{Dashboard: fragmentPreset("overview", "", "", "", "", 50), Results: []query.Result{{ID: "health", Status: query.StatusOK, Frame: &query.Frame{Columns: []query.Column{}, Values: [][]any{}, Totals: []any{math.NaN()}}}}} if _, err := boundFragment(t.Context(), f); err == nil { t.Fatal("encoding error swallowed") } @@ -147,7 +147,7 @@ func TestEncodingFailureCancellationAndMetadata(t *testing.T) { } func TestTopologyEdgesAndOverviewTraceSummary(t *testing.T) { f := PanelFragment{Dashboard: fragmentPreset("topology", "", "", "", "", 50)} - frame := &panel.Frame{Columns: []panel.Column{{Name: "kind"}, {Name: "caller"}, {Name: "callee"}, {Name: "error_rate", Type: "number", Unit: "percent"}, {Name: "calls", Type: "number", Unit: "count"}}, Values: make([][]any, 5)} + frame := &query.Frame{Columns: []query.Column{{Name: "kind"}, {Name: "caller"}, {Name: "callee"}, {Name: "error_rate", Type: "number", Unit: "percent"}, {Name: "calls", Type: "number", Unit: "count"}}, Values: make([][]any, 5)} for i := range 20 { for c, v := range []any{"node", fmt.Sprint(i), nil, nil, nil} { frame.Values[c] = append(frame.Values[c], v) @@ -160,12 +160,12 @@ func TestTopologyEdgesAndOverviewTraceSummary(t *testing.T) { } frame.Rows++ } - f.Results = []panel.Result{{ID: "services", Status: panel.StatusOK, Frame: frame}} + f.Results = []query.Result{{ID: "services", Status: query.StatusOK, Frame: frame}} text := fragmentSummary(f) if strings.Count(text, "caller=") != 10 || strings.Index(text, "edge_09") > strings.Index(text, "edge_10") { t.Fatalf("edges not ranked/sample bounded: %s", text) } - frame.Health = &panel.HealthFrame{Health: "unhealthy", Counts: observability.HealthCounts{Healthy: 2, Degraded: 3, Unhealthy: 4}} + frame.Health = &query.HealthFrame{Health: "unhealthy", Counts: observability.HealthCounts{Healthy: 2, Degraded: 3, Unhealthy: 4}} f.Trace = &observability.Result[observability.TraceDetail]{Data: observability.TraceDetail{TraceID: "trace", DurationMS: 42, SpanCount: 7, HasError: true, Spans: []observability.TraceSpan{{Operation: "GET cart", DurationMS: 42, Status: "STATUS_CODE_ERROR", Start: time.Date(2026, 10, 7, 19, 0, 0, 0, time.UTC)}}}} text = fragmentSummary(f) for _, part := range []string{"healthy=2 degraded=3 unhealthy=4", "root=GET cart", "duration=42 ms", "status=Error spans=7", "slowest:", "erroring:"} { @@ -259,7 +259,7 @@ func TestToolDocsDescribeFragmentInputs(t *testing.T) { func TestInputBudgetReportsActualBytes(t *testing.T) { s := newPanelServer(t) - _, _, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: panel.Panel{ID: "text", Title: "Text", Viz: "text", Content: strings.Repeat("x", 140000)}}) + _, _, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: query.Panel{ID: "text", Title: "Text", Viz: "text", Content: strings.Repeat("x", 140000)}}) if err == nil || !strings.Contains(err.Error(), "limit 131072 bytes, actual 140") { t.Fatalf("input budget error=%v", err) } @@ -273,7 +273,7 @@ func BenchmarkBoundFragmentLarge(b *testing.B) { for row := range values { values[row] = body } - fragment.Results = append(fragment.Results, panel.Result{ID: fmt.Sprintf("logs_%d", i), Status: panel.StatusOK, Frame: &panel.Frame{Columns: []panel.Column{{Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{values}, Rows: len(values)}}) + fragment.Results = append(fragment.Results, query.Result{ID: fmt.Sprintf("logs_%d", i), Status: query.StatusOK, Frame: &query.Frame{Columns: []query.Column{{Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{values}, Rows: len(values)}}) } b.ReportAllocs() b.ResetTimer() diff --git a/internal/mcp/fragment_identity_test.go b/internal/mcp/fragment_identity_test.go index a0845eb7..75e572a3 100644 --- a/internal/mcp/fragment_identity_test.go +++ b/internal/mcp/fragment_identity_test.go @@ -1,12 +1,12 @@ package mcp import ( - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "testing" ) func TestFragmentIdentityIncludesRelativeWindowAndVars(t *testing.T) { - f := PanelFragment{Dashboard: panel.Dashboard{Name: "Map", Time: panel.Time{Range: "1h"}, Panels: []panel.Panel{{ID: "a", Title: "A", Viz: "service_map", Query: &panel.Query{From: "spans"}}}}, Results: []panel.Result{{ID: "a", FromMS: 1, ToMS: 2}}} + f := PanelFragment{Dashboard: query.Dashboard{Name: "Map", Time: query.Time{Range: "1h"}, Panels: []query.Panel{{ID: "a", Title: "A", Viz: "service_map", Query: &query.Spec{From: "spans"}}}}, Results: []query.Result{{ID: "a", FromMS: 1, ToMS: 2}}} original := fragmentIdentity(f) f.Dashboard.Name = "Another title" f.Dashboard.Panels[0].ID = "b" @@ -19,14 +19,14 @@ func TestFragmentIdentityIncludesRelativeWindowAndVars(t *testing.T) { t.Fatal("different captured windows deduped") } f.Results[0].FromMS = 1 - f.Vars = map[string]panel.Value{"service": panel.Value{Values: []string{"checkout"}}} + f.Vars = map[string]query.Value{"service": query.Value{Values: []string{"checkout"}}} if original == fragmentIdentity(f) { t.Fatal("different vars deduped") } } func TestMapIdentityIgnoresLimitsOnlyForIdenticalCompleteProjections(t *testing.T) { - f := PanelFragment{Dashboard: panel.Dashboard{Time: panel.Time{Range: "1h"}, Panels: []panel.Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &panel.Query{From: "spans", Limit: 20}}}}, Results: []panel.Result{{ID: "map", FromMS: 1, ToMS: 2, Frame: &panel.Frame{Columns: []panel.Column{{Name: "service", Type: "string", Role: "dimension"}}, Values: [][]any{{"checkout"}}, Rows: 1}}}} + f := PanelFragment{Dashboard: query.Dashboard{Time: query.Time{Range: "1h"}, Panels: []query.Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &query.Spec{From: "spans", Limit: 20}}}}, Results: []query.Result{{ID: "map", FromMS: 1, ToMS: 2, Frame: &query.Frame{Columns: []query.Column{{Name: "service", Type: "string", Role: "dimension"}}, Values: [][]any{{"checkout"}}, Rows: 1}}}} first := fragmentIdentity(f) f.Dashboard.Panels[0].Query.Limit = 400 if first != fragmentIdentity(f) { diff --git a/internal/mcp/fragments.go b/internal/mcp/fragments.go index bd65a74e..cd22c939 100644 --- a/internal/mcp/fragments.go +++ b/internal/mcp/fragments.go @@ -16,21 +16,21 @@ import ( "github.com/google/jsonschema-go/jsonschema" "github.com/labstack/fanout/internal/fanql" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/modelcontextprotocol/go-sdk/mcp" ) type QueryTelemetryInput struct { - Panel panel.Panel `json:"panel" jsonschema:"One v1 panel to display in the answer"` + Panel query.Panel `json:"panel" jsonschema:"One v1 panel to display in the answer"` Text string `json:"text,omitempty" jsonschema:"FanQL text that becomes panel.query; prefer panel.query (structured) or panel.sql; see fanout://fanql/reference"` - Variables []panel.Variable `json:"variables,omitempty" jsonschema:"Optional v1 variable definitions used by this panel"` - Time *panel.Time `json:"time,omitempty" jsonschema:"Optional dashboard time override: exact from/to or a relative range"` - Vars map[string]panel.Value `json:"vars,omitempty" jsonschema:"Resolved variable values: strings or lists; preserves $__all and empty lists"` + Variables []query.Variable `json:"variables,omitempty" jsonschema:"Optional v1 variable definitions used by this panel"` + Time *query.Time `json:"time,omitempty" jsonschema:"Optional dashboard time override: exact from/to or a relative range"` + Vars map[string]query.Value `json:"vars,omitempty" jsonschema:"Resolved variable values: strings or lists; preserves $__all and empty lists"` } type fanqlToolFailureOutput struct { Error fanql.Failure `json:"error"` - Problems panel.Problems `json:"problems,omitempty"` + Problems query.Problems `json:"problems,omitempty"` } // QueryTelemetryOutput includes FanQL failures without changing preset fragments. @@ -38,7 +38,7 @@ type QueryTelemetryOutput struct { *PanelFragment Notices []fanql.Notice `json:"notices,omitempty"` Error *fanql.Failure `json:"error,omitempty"` - Problems panel.Problems `json:"problems,omitempty"` + Problems query.Problems `json:"problems,omitempty"` } type FragmentView struct { Kind string `json:"kind" jsonschema:"View kind: preset or query"` @@ -46,30 +46,30 @@ type FragmentView struct { } type PanelFragment struct { View FragmentView `json:"view"` - Dashboard panel.Dashboard `json:"dashboard"` - Results []panel.Result `json:"results"` - Vars map[string]panel.Value `json:"vars,omitempty"` + Dashboard query.Dashboard `json:"dashboard"` + Results []query.Result `json:"results"` + Vars map[string]query.Value `json:"vars,omitempty"` Trace *observability.Result[observability.TraceDetail] `json:"trace,omitempty"` } // The published schema deliberately has no subset selector. Raw input is // checked by middleware before the SDK decodes this type. type fragmentInput struct { - Dashboard panel.Dashboard `json:"dashboard" jsonschema:"Complete v1 dashboard specification; every panel is executed"` - Time *panel.Time `json:"time,omitempty" jsonschema:"Optional dashboard time override: exact from/to or a relative range"` - Vars map[string]panel.Value `json:"vars,omitempty" jsonschema:"Resolved variable values: strings or lists; preserves $__all and empty lists"` + Dashboard query.Dashboard `json:"dashboard" jsonschema:"Complete v1 dashboard specification; every panel is executed"` + Time *query.Time `json:"time,omitempty" jsonschema:"Optional dashboard time override: exact from/to or a relative range"` + Vars map[string]query.Value `json:"vars,omitempty" jsonschema:"Resolved variable values: strings or lists; preserves $__all and empty lists"` Widths map[string]int `json:"widths,omitempty" jsonschema:"Optional panel widths in pixels, keyed by panel ID"` Compare *bool `json:"compare,omitempty" jsonschema:"Override previous-period comparison for the complete fragment"` } type variableOptions struct { - Options map[string][]panel.Option `json:"options"` + Options map[string][]query.Option `json:"options"` } // Value's wire form is scalar/list JSON, not the fields of its Go struct. // Supply the same override to input and output schema inference. func fragmentTool[In, Out any](server *Server, tool *mcp.Tool, handler mcp.ToolHandlerFor[In, Out]) { options := &jsonschema.ForOptions{TypeSchemas: map[reflect.Type]*jsonschema.Schema{ - reflect.TypeFor[panel.Value](): {AnyOf: []*jsonschema.Schema{{Type: "string"}, {Type: "array", Items: &jsonschema.Schema{Type: "string"}}}}, + reflect.TypeFor[query.Value](): {AnyOf: []*jsonschema.Schema{{Type: "string"}, {Type: "array", Items: &jsonschema.Schema{Type: "string"}}}}, }} input, err := jsonschema.For[In](options) if err != nil { @@ -100,7 +100,7 @@ func fragmentTool[In, Out any](server *Server, tool *mcp.Tool, handler mcp.ToolH mcp.AddTool(server.mcp, tool, handler) } -func (s *Server) runFragment(ctx context.Context, req panel.RunRequest, kinds ...string) (*mcp.CallToolResult, PanelFragment, error) { +func (s *Server) runFragment(ctx context.Context, req query.RunRequest, kinds ...string) (*mcp.CallToolResult, PanelFragment, error) { out, err := s.executeFragment(ctx, req) if err != nil { return nil, PanelFragment{}, err @@ -126,25 +126,25 @@ func finishFragment(ctx context.Context, out PanelFragment, kinds ...string) (*m } func (s *Server) noDataError(ctx context.Context, out PanelFragment) error { - code, guidance, err := s.panels.EmptyGuidance(ctx, panel.RunRequest{Dashboard: out.Dashboard, Vars: out.Vars}) + code, guidance, err := s.panels.EmptyGuidance(ctx, query.RunRequest{Dashboard: out.Dashboard, Vars: out.Vars}) if err != nil { return safePanelToolError(err) } if code == "unknown_service" { - return guidanceError(code, panel.PresentDiagnosis(guidance)) + return guidanceError(code, query.PresentDiagnosis(guidance)) } - notes := []string{"No matching data.", panel.PresentDiagnosis(guidance)} + notes := []string{"No matching data.", query.PresentDiagnosis(guidance)} for i, r := range out.Results { title := r.ID if i < len(out.Dashboard.Panels) { title = out.Dashboard.Panels[i].Title } - notes = append(notes, fmt.Sprintf("%s: %s", title, panel.PresentDiagnosis(r.Diagnosis))) + notes = append(notes, fmt.Sprintf("%s: %s", title, query.PresentDiagnosis(r.Diagnosis))) } return guidanceError("no_data", strings.Join(notes, " ")) } -func (s *Server) executeFragment(ctx context.Context, req panel.RunRequest) (PanelFragment, error) { +func (s *Server) executeFragment(ctx context.Context, req query.RunRequest) (PanelFragment, error) { if s.panels == nil { return PanelFragment{}, errors.New("panels are unavailable") } @@ -154,12 +154,12 @@ func (s *Server) executeFragment(ctx context.Context, req panel.RunRequest) (Pan if err != nil { return PanelFragment{}, err } - var detached panel.RunRequest + var detached query.RunRequest if err = json.Unmarshal(raw, &detached); err != nil { return PanelFragment{}, err } req = detached - panel.Normalize(&req.Dashboard) + query.Normalize(&req.Dashboard) if req.Time != nil { req.Dashboard.Time = *req.Time req.Time = nil @@ -170,10 +170,10 @@ func (s *Server) executeFragment(ctx context.Context, req panel.RunRequest) (Pan req.Dashboard.Time.Compare = "previous_period" } } - panel.Normalize(&req.Dashboard) + query.Normalize(&req.Dashboard) // Reject oversized authored input before execution, rather than silently // changing query semantics to fit the persisted-response budget. - authored, err := json.Marshal(PanelFragment{Dashboard: req.Dashboard, Vars: req.Vars, Results: []panel.Result{}}) + authored, err := json.Marshal(PanelFragment{Dashboard: req.Dashboard, Vars: req.Vars, Results: []query.Result{}}) if err != nil { return PanelFragment{}, fmt.Errorf("encode authored fragment: %w", err) } @@ -194,28 +194,28 @@ func (s *Server) queryTelemetry(ctx context.Context, _ *mcp.CallToolRequest, inp if input.Text != "" { compiled, problems := fanql.Compile(input.Text, fanql.Options{Viz: input.Panel.Viz, Variables: input.Variables}) if len(problems) != 0 { - return fanqlToolFailure(fanql.Failure{Code: "invalid_fanql", Message: "The query has problems."}, panel.PresentProblems(problems)) + return fanqlToolFailure(fanql.Failure{Code: "invalid_fanql", Message: "The query has problems."}, query.PresentProblems(problems)) } input.Panel.Query = &compiled.Query notices = append(notices, compiled.Notices...) } - d := panel.Dashboard{Name: input.Panel.Title, Variables: input.Variables, Panels: []panel.Panel{input.Panel}} - result, out, err := s.runFragment(ctx, panel.RunRequest{Dashboard: d, Time: input.Time, Vars: input.Vars}) + d := query.Dashboard{Name: input.Panel.Title, Variables: input.Variables, Panels: []query.Panel{input.Panel}} + result, out, err := s.runFragment(ctx, query.RunRequest{Dashboard: d, Time: input.Time, Vars: input.Vars}) response := QueryTelemetryOutput{PanelFragment: &out} if err == nil && input.Text != "" { response.Notices = notices } return result, response, err } -func (s *Server) queryPanelFragment(ctx context.Context, _ *mcp.CallToolRequest, input panel.RunRequest) (*mcp.CallToolResult, PanelFragment, error) { +func (s *Server) queryPanelFragment(ctx context.Context, _ *mcp.CallToolRequest, input query.RunRequest) (*mcp.CallToolResult, PanelFragment, error) { if input.Panels != nil { return nil, PanelFragment{}, errors.New("panels is forbidden for query_panel_fragment") } return s.runFragment(ctx, input) } -func (s *Server) panelExemplars(ctx context.Context, _ *mcp.CallToolRequest, input panel.ExemplarRequest) (*mcp.CallToolResult, panel.ExemplarResponse, error) { +func (s *Server) panelExemplars(ctx context.Context, _ *mcp.CallToolRequest, input query.ExemplarRequest) (*mcp.CallToolResult, query.ExemplarResponse, error) { if s.panels == nil { - return nil, panel.ExemplarResponse{}, errors.New("panels are unavailable") + return nil, query.ExemplarResponse{}, errors.New("panels are unavailable") } out, err := s.panels.Exemplars(ctx, input) if err != nil { @@ -223,7 +223,7 @@ func (s *Server) panelExemplars(ctx context.Context, _ *mcp.CallToolRequest, inp } return summary(fmt.Sprintf("%d exemplar traces.", len(out.Traces))), out, nil } -func (s *Server) resolvePanelVariables(ctx context.Context, _ *mcp.CallToolRequest, input panel.ResolveRequest) (*mcp.CallToolResult, variableOptions, error) { +func (s *Server) resolvePanelVariables(ctx context.Context, _ *mcp.CallToolRequest, input query.ResolveRequest) (*mcp.CallToolResult, variableOptions, error) { if s.panels == nil { return nil, variableOptions{}, errors.New("panels are unavailable") } @@ -234,8 +234,8 @@ func (s *Server) resolvePanelVariables(ctx context.Context, _ *mcp.CallToolReque return summary("Panel variable options."), variableOptions{Options: options}, nil } -func fragmentPreset(kind, service, namespace, severity, search string, limit int) panel.Dashboard { - d := panel.Dashboard{Name: map[string]string{"overview": "System health", "topology": "Service dependencies", "performance": "Service performance", "logs": "Log explorer", "trace": "Trace detail"}[kind], Time: panel.Time{Range: "1h", Refresh: "off"}} +func fragmentPreset(kind, service, namespace, severity, search string, limit int) query.Dashboard { + d := query.Dashboard{Name: map[string]string{"overview": "System health", "topology": "Service dependencies", "performance": "Service performance", "logs": "Log explorer", "trace": "Trace detail"}[kind], Time: query.Time{Range: "1h", Refresh: "off"}} filters := []string{} literal := func(s string) string { return "'" + strings.ReplaceAll(s, "'", "''") + "'" } if namespace != "" { @@ -245,7 +245,7 @@ func fragmentPreset(kind, service, namespace, severity, search string, limit int filters = append(filters, "service = "+literal(service)) } add := func(id, title, viz, signal, measure, unit string, by []string, bucket string) { - q := &panel.Query{From: signal, Where: append([]string(nil), filters...), By: by, Bucket: bucket} + q := &query.Spec{From: signal, Where: append([]string(nil), filters...), By: by, Bucket: bucket} if measure != "" { q.Measures = []string{measure} } @@ -260,7 +260,7 @@ func fragmentPreset(kind, service, namespace, severity, search string, limit int if limit > 0 { q.Limit = min(cap, limit) } - d.Panels = append(d.Panels, panel.Panel{ID: id, Title: title, Viz: viz, Unit: unit, Query: q}) + d.Panels = append(d.Panels, query.Panel{ID: id, Title: title, Viz: viz, Unit: unit, Query: q}) } switch kind { case "overview": @@ -280,7 +280,7 @@ func fragmentPreset(kind, service, namespace, severity, search string, limit int add("volume", "Log volume", "timeseries", "logs", "count()", "count", []string{"severity"}, "auto") add("events", "Log events", "logs", "logs", "", "", nil, "") if search != "" { - d.Panels[len(d.Panels)-1].Options = &panel.Options{Highlight: search} + d.Panels[len(d.Panels)-1].Options = &query.Options{Highlight: search} d.Panels[0].Query.Where = append(d.Panels[0].Query.Where, "contains(lower(body),lower("+literal(search)+"))") } case "trace": @@ -449,7 +449,7 @@ func numeric(value any) float64 { } return 0 } -func summaryCell(col panel.Column, value any) string { +func summaryCell(col query.Column, value any) string { if col.Type == "time" { switch v := value.(type) { case time.Time: @@ -546,7 +546,7 @@ func boundFragment(ctx context.Context, fragment PanelFragment) (PanelFragment, r.Diagnosis = clipJSON(r.Diagnosis, 512) r.Error = clipJSON(r.Error, 512) r.AnnotationError = clipJSON(r.AnnotationError, 256) - for _, f := range []*panel.Frame{r.Frame, r.Previous} { + for _, f := range []*query.Frame{r.Frame, r.Previous} { if f != nil { f.Note = clipJSON(f.Note, 512) } @@ -578,7 +578,7 @@ func boundFragment(ctx context.Context, fragment PanelFragment) (PanelFragment, original := scope.Services choices = append(choices, collection{r.ID + "/scope", len(original), func() any { return scope.Services }, func(n int) { scope.Services = original[:n]; scope.Limited = true; r.AnnotationError = payloadLimitNote }, func() any { return r }}) } - for j, f := range []*panel.Frame{r.Frame, r.Previous} { + for j, f := range []*query.Frame{r.Frame, r.Previous} { if f == nil || f.Rows == 0 { continue } @@ -764,7 +764,7 @@ func boundFragment(ctx context.Context, fragment PanelFragment) (PanelFragment, // explicit empty/truncated frames rather than silently exceed the contract. for i := range out.Results { r := &out.Results[i] - r.Frame = &panel.Frame{Columns: []panel.Column{}, Values: [][]any{}, Truncated: true, Note: payloadLimitNote} + r.Frame = &query.Frame{Columns: []query.Column{}, Values: [][]any{}, Truncated: true, Note: payloadLimitNote} r.Previous = nil r.AnnotationScope = nil } @@ -783,7 +783,7 @@ func boundFragment(ctx context.Context, fragment PanelFragment) (PanelFragment, return out, nil } -func fanqlToolFailure(problem fanql.Failure, problems panel.Problems) (*mcp.CallToolResult, QueryTelemetryOutput, error) { +func fanqlToolFailure(problem fanql.Failure, problems query.Problems) (*mcp.CallToolResult, QueryTelemetryOutput, error) { result := summary(problem.Message) result.IsError = true return result, QueryTelemetryOutput{Error: &problem, Problems: problems}, nil diff --git a/internal/mcp/fragments_test.go b/internal/mcp/fragments_test.go index 5db7a5cb..5d88c4a7 100644 --- a/internal/mcp/fragments_test.go +++ b/internal/mcp/fragments_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/modelcontextprotocol/go-sdk/mcp" "reflect" "strings" @@ -15,8 +15,8 @@ import ( func TestQueryTelemetryReturnsExecutableFragment(t *testing.T) { s, _, _, from, to := serviceInputFixture(t) - p := panel.Panel{ID: "latency", Title: "Latency", Viz: "timeseries", Query: &panel.Query{From: "spans", Measures: []string{"p95(duration_ms)"}, Bucket: "auto"}} - _, got, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: p, Time: &panel.Time{From: &from, To: &to}}) + p := query.Panel{ID: "latency", Title: "Latency", Viz: "timeseries", Query: &query.Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, Bucket: "auto"}} + _, got, err := s.queryTelemetry(t.Context(), nil, QueryTelemetryInput{Panel: p, Time: &query.Time{From: &from, To: &to}}) if err != nil { t.Fatal(err) } @@ -37,7 +37,7 @@ func TestQueryTelemetryReturnsExecutableFragment(t *testing.T) { if _, ok := decoded["dashboard"]; !ok { t.Fatal("missing spec") } - if got.Results[0].Status == panel.StatusEmpty && got.Results[0].Diagnosis == "" { + if got.Results[0].Status == query.StatusEmpty && got.Results[0].Diagnosis == "" { t.Fatal("unexplained empty") } } @@ -57,16 +57,16 @@ func TestFragmentPresetsUseSingleUnitPanels(t *testing.T) { } } s := panelServerFixture(t, true) - results, err := s.panels.Run(t.Context(), panel.RunRequest{Dashboard: d}) + results, err := s.panels.Run(t.Context(), query.RunRequest{Dashboard: d}) if err != nil { t.Fatalf("%s: %v", name, err) } positive := false for _, r := range results { - if r.Status == panel.StatusOK && r.Frame != nil && r.Frame.Rows > 0 { + if r.Status == query.StatusOK && r.Frame != nil && r.Frame.Rows > 0 { positive = true } - if r.Status != panel.StatusOK && !(r.Status == panel.StatusEmpty && r.Diagnosis != "") { + if r.Status != query.StatusOK && !(r.Status == query.StatusEmpty && r.Diagnosis != "") { t.Fatalf("%s panel %s: status=%s diagnosis=%q error=%q", name, r.ID, r.Status, r.Diagnosis, r.Error) } } @@ -77,12 +77,12 @@ func TestFragmentPresetsUseSingleUnitPanels(t *testing.T) { } func largeLogsFragment() PanelFragment { d := fragmentPreset("logs", "checkout", "shop", "ERROR", "", 100) - f := &panel.Frame{Columns: []panel.Column{{Name: "service", Type: "string", Role: "dimension"}, {Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{{}, {}}, Rows: 1000} + f := &query.Frame{Columns: []query.Column{{Name: "service", Type: "string", Role: "dimension"}, {Name: "body", Type: "string", Role: "dimension"}}, Values: [][]any{{}, {}}, Rows: 1000} for i := 0; i < f.Rows; i++ { f.Values[0] = append(f.Values[0], "checkout") f.Values[1] = append(f.Values[1], strings.Repeat("x", 2000)) } - return PanelFragment{Dashboard: d, Results: []panel.Result{{ID: "volume", Status: panel.StatusEmpty, Diagnosis: "No volume buckets in fixture"}, {ID: "events", Status: panel.StatusOK, Frame: f}}} + return PanelFragment{Dashboard: d, Results: []query.Result{{ID: "volume", Status: query.StatusEmpty, Diagnosis: "No volume buckets in fixture"}, {ID: "events", Status: query.StatusOK, Frame: f}}} } func TestFragmentSummaryBoundedLogsFixture(t *testing.T) { f := largeLogsFragment() @@ -122,17 +122,17 @@ func TestFragmentPayloadCapLogsFixture(t *testing.T) { } func TestFragmentSummaryBoundedWideUnicode(t *testing.T) { - var results []panel.Result + var results []query.Result for i := range 40 { - f := &panel.Frame{Rows: 10} + f := &query.Frame{Rows: 10} for c := range 80 { - f.Columns = append(f.Columns, panel.Column{Name: fmt.Sprintf("value_%d", c)}) + f.Columns = append(f.Columns, query.Column{Name: fmt.Sprintf("value_%d", c)}) f.Values = append(f.Values, make([]any, 10)) for row := range 10 { f.Values[c][row] = strings.Repeat("界", 1000) } } - results = append(results, panel.Result{ID: fmt.Sprintf("panel_%d", i), Status: panel.StatusOK, Frame: f, SQL: "DO NOT EXPOSE SQL", Diagnosis: "diagnosis"}) + results = append(results, query.Result{ID: fmt.Sprintf("panel_%d", i), Status: query.StatusOK, Frame: f, SQL: "DO NOT EXPOSE SQL", Diagnosis: "diagnosis"}) } got := fragmentSummary(PanelFragment{Results: results}) if len(got) > 16*1024 || !utf8.ValidString(got) || got != fragmentSummary(PanelFragment{Results: results}) || strings.Contains(got, "DO NOT EXPOSE SQL") { @@ -147,7 +147,7 @@ func TestFragmentSummaryBoundedWideUnicode(t *testing.T) { func TestFragmentPayloadLargestPreviousTrendsAndTrace(t *testing.T) { original := largeLogsFragment() - original.Results[0].Frame = &panel.Frame{Columns: []panel.Column{{Name: "count"}}, Values: [][]any{{1}}, Rows: 1} + original.Results[0].Frame = &query.Frame{Columns: []query.Column{{Name: "count"}}, Values: [][]any{{1}}, Rows: 1} original.Results[1].Previous = original.Results[1].Frame original.Results[1].Frame.Trends = map[string][][]any{"body": make([][]any, 1000)} for i := range 1000 { @@ -162,7 +162,7 @@ func TestFragmentPayloadLargestPreviousTrendsAndTrace(t *testing.T) { if testFragmentBytes(t, got) > fragmentPayloadLimit || got.Results[0].Frame.Rows != 1 { t.Fatal("cap or largest selection") } - for _, f := range []*panel.Frame{got.Results[1].Frame, got.Results[1].Previous} { + for _, f := range []*query.Frame{got.Results[1].Frame, got.Results[1].Previous} { if !f.Truncated || f.Note == "" { t.Fatal("missing visible truncation") } @@ -186,15 +186,15 @@ func TestFragmentPayloadLargestPreviousTrendsAndTrace(t *testing.T) { } func TestFragmentPayloadFixedMetadataAndSmallUnchanged(t *testing.T) { - small := PanelFragment{Dashboard: fragmentPreset("trace", "", "", "", "", 50), Results: []panel.Result{{ID: "traces", Status: panel.StatusEmpty, Diagnosis: "No traces"}}} + small := PanelFragment{Dashboard: fragmentPreset("trace", "", "", "", "", 50), Results: []query.Result{{ID: "traces", Status: query.StatusEmpty, Diagnosis: "No traces"}}} if !reflect.DeepEqual(boundedTestFragment(t, small), small) { t.Fatal("small payload changed") } var f PanelFragment for i := range 40 { id := fmt.Sprintf("p%d", i) - f.Dashboard.Panels = append(f.Dashboard.Panels, panel.Panel{ID: id, Title: id, Viz: "text", Content: "Text"}) - f.Results = append(f.Results, panel.Result{ID: id, Status: panel.StatusError, SQL: strings.Repeat("sql", 100000), Error: strings.Repeat("error", 100000), Diagnosis: strings.Repeat("diagnosis", 100000), Frame: &panel.Frame{Columns: []panel.Column{}, Values: [][]any{}, Note: strings.Repeat("note", 100000)}}) + f.Dashboard.Panels = append(f.Dashboard.Panels, query.Panel{ID: id, Title: id, Viz: "text", Content: "Text"}) + f.Results = append(f.Results, query.Result{ID: id, Status: query.StatusError, SQL: strings.Repeat("sql", 100000), Error: strings.Repeat("error", 100000), Diagnosis: strings.Repeat("diagnosis", 100000), Frame: &query.Frame{Columns: []query.Column{}, Values: [][]any{}, Note: strings.Repeat("note", 100000)}}) } got := boundedTestFragment(t, f) if testFragmentBytes(t, got) > fragmentPayloadLimit { @@ -206,7 +206,7 @@ func TestFragmentVarsRoundTripAndAppHelpers(t *testing.T) { s := newPanelServer(t) session := connectTestClient(t, s, &mcp.ClientCapabilities{Extensions: map[string]any{mcpUIExtension: map[string]any{"mimeTypes": []string{mcpAppMIME}}}}) vars := map[string]any{"all": "$__all", "scalar": "checkout", "empty": []string{}, "multi": []string{"checkout", "payment"}} - d := panel.Dashboard{Name: "Variables", Panels: []panel.Panel{{ID: "text", Title: "Text", Viz: "text", Content: "Text"}}, Variables: []panel.Variable{{Name: "all", Kind: "custom", Options: []string{"checkout"}, IncludeAll: true}, {Name: "scalar", Kind: "text"}, {Name: "empty", Kind: "custom", Options: []string{"checkout"}, Multi: true}, {Name: "multi", Kind: "custom", Options: []string{"checkout", "payment"}, Multi: true}}} + d := query.Dashboard{Name: "Variables", Panels: []query.Panel{{ID: "text", Title: "Text", Viz: "text", Content: "Text"}}, Variables: []query.Variable{{Name: "all", Kind: "custom", Options: []string{"checkout"}, IncludeAll: true}, {Name: "scalar", Kind: "text"}, {Name: "empty", Kind: "custom", Options: []string{"checkout"}, Multi: true}, {Name: "multi", Kind: "custom", Options: []string{"checkout", "payment"}, Multi: true}}} got, err := session.CallTool(t.Context(), &mcp.CallToolParams{Name: "query_panel_fragment", Arguments: map[string]any{"dashboard": d, "vars": vars}}) if err != nil || got.IsError { t.Fatalf("call=%+v %v", got, err) @@ -258,7 +258,7 @@ func TestFragmentPresetsExecutedSummariesAndOperationScope(t *testing.T) { t.Fatal("summary cap") } for _, r := range f.Results { - if r.Status == panel.StatusError { + if r.Status == query.StatusError { t.Fatalf("%s: %+v", name, r) } if r.ID == "operations" { @@ -319,11 +319,11 @@ func TestFragmentTraceCapturedWindowAndSelectedID(t *testing.T) { func TestFragmentPayloadCapFixedWideFramesAndScopes(t *testing.T) { f := PanelFragment{Dashboard: fragmentPreset("trace", "", "", "", "", 50)} for i := range 40 { - r := panel.Result{ID: fmt.Sprintf("p%d", i), Status: panel.StatusOK, Frame: &panel.Frame{Rows: 1}, AnnotationScope: &panel.AnnotationMatch{}} + r := query.Result{ID: fmt.Sprintf("p%d", i), Status: query.StatusOK, Frame: &query.Frame{Rows: 1}, AnnotationScope: &query.AnnotationMatch{}} for range 300 { - r.Frame.Columns = append(r.Frame.Columns, panel.Column{Name: strings.Repeat("label", 50), Type: "string", Role: "dimension"}) + r.Frame.Columns = append(r.Frame.Columns, query.Column{Name: strings.Repeat("label", 50), Type: "string", Role: "dimension"}) r.Frame.Values = append(r.Frame.Values, []any{"v"}) - r.AnnotationScope.Services = append(r.AnnotationScope.Services, panel.AnnotationService{Namespace: "shop", Service: strings.Repeat("service", 100)}) + r.AnnotationScope.Services = append(r.AnnotationScope.Services, query.AnnotationService{Namespace: "shop", Service: strings.Repeat("service", 100)}) } f.Results = append(f.Results, r) } @@ -360,7 +360,7 @@ func TestFragmentNamedToolsMCPSeededContract(t *testing.T) { for _, name := range []string{"get_observability_overview", "get_service_topology", "get_service_performance", "search_logs", "inspect_trace", "query_telemetry"} { args := map[string]any{"namespace": "shop"} if name == "query_telemetry" { - args = map[string]any{"panel": panel.Panel{ID: "custom", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}} + args = map[string]any{"panel": query.Panel{ID: "custom", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}} } if name == "inspect_trace" { args["trace_id"] = "trace-1" @@ -379,7 +379,7 @@ func TestFragmentNamedToolsMCPSeededContract(t *testing.T) { } positive := false for i, r := range f.Results { - if f.Dashboard.Panels[i].ID != r.ID || r.Status == panel.StatusError || r.Status == panel.StatusEmpty && r.Diagnosis == "" { + if f.Dashboard.Panels[i].ID != r.ID || r.Status == query.StatusError || r.Status == query.StatusEmpty && r.Diagnosis == "" { t.Fatalf("%s: %+v", name, r) } if r.Frame != nil && r.Frame.Rows > 0 { @@ -401,7 +401,7 @@ func TestFragmentNamedToolsMCPSeededContract(t *testing.T) { func TestQueryTelemetryDoesNotMutateAuthoredInput(t *testing.T) { s := panelServerFixture(t, true) - input := QueryTelemetryInput{Panel: panel.Panel{ID: "latency", Title: "Latency", Viz: "timeseries", Query: &panel.Query{From: "spans", Measures: []string{"p95(duration_ms)"}}}} + input := QueryTelemetryInput{Panel: query.Panel{ID: "latency", Title: "Latency", Viz: "timeseries", Query: &query.Spec{From: "spans", Measures: []string{"p95(duration_ms)"}}}} before, _ := json.Marshal(input) _, _, err := s.queryTelemetry(t.Context(), nil, input) if err != nil { diff --git a/internal/mcp/history_test.go b/internal/mcp/history_test.go index 0aa04c26..5ca3ccd5 100644 --- a/internal/mcp/history_test.go +++ b/internal/mcp/history_test.go @@ -11,7 +11,7 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" mcpgoauth "github.com/modelcontextprotocol/go-sdk/auth" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -23,7 +23,7 @@ type restoreConflictValidator struct { release chan struct{} } -func (v *restoreConflictValidator) Validate(ctx context.Context, d *panel.Dashboard) error { +func (v *restoreConflictValidator) Validate(ctx context.Context, d *query.Dashboard) error { if v.armed.Load() && d.Panels[0].Content == "hello" { attempt := int(v.attempt.Add(1)) if attempt <= 2 { @@ -124,7 +124,7 @@ func TestRestoreLosesTwoContestedBasesWithoutReceipt(t *testing.T) { func TestDashboardHistoryToolsAppendRestoreVersion(t *testing.T) { s := newPanelServer(t) - _, created, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: panel.Dashboard{Name: "History", Panels: []panel.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "first"}}}}) + _, created, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: query.Dashboard{Name: "History", Panels: []query.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "first"}}}}) if err != nil { t.Fatal(err) } @@ -150,7 +150,7 @@ func TestDashboardHistoryToolsAppendRestoreVersion(t *testing.T) { } func TestDashboardRestoreReceiptUsesLatestCommittedBase(t *testing.T) { - s := newToolServer(t, structural{}, panel.NewExecutor(nil, 30)) + s := newToolServer(t, structural{}, query.NewExecutor(nil, 30)) _, created, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: textDashboard("History")}) if err != nil { t.Fatal(err) diff --git a/internal/mcp/http_cancellation_test.go b/internal/mcp/http_cancellation_test.go index 79f8892f..abc21a04 100644 --- a/internal/mcp/http_cancellation_test.go +++ b/internal/mcp/http_cancellation_test.go @@ -11,7 +11,7 @@ import ( duckdb "github.com/duckdb/duckdb-go/v2" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/queryrows" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -19,8 +19,8 @@ import ( ) type disconnectQueryEngine struct { - panel.Engine - duck *query.Duck + query.Engine + duck *engine.Duck started chan struct{} stopped chan disconnectResult release chan struct{} @@ -67,7 +67,7 @@ func TestHTTPDisconnectCancelsPanelDuckDBQuery(t *testing.T) { t.Fatal(err) } defer repo.Close() - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -86,7 +86,7 @@ func TestHTTPDisconnectCancelsPanelDuckDBQuery(t *testing.T) { if err != nil { t.Fatal(err) } - server := NewWithIntelligence(nil, nil, panel.NewExecutor(engine, 30), nil, "test") + server := NewWithIntelligence(nil, nil, query.NewExecutor(engine, 30), nil, "test") httpServer := httptest.NewServer(server.HTTPHandler()) defer httpServer.Close() defer close(engine.release) diff --git a/internal/mcp/no_data_test.go b/internal/mcp/no_data_test.go index b2d04d62..5f0c4a20 100644 --- a/internal/mcp/no_data_test.go +++ b/internal/mcp/no_data_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -22,11 +22,11 @@ func TestAllEmptyFragmentsReturnGuidanceWithoutViews(t *testing.T) { }{ {"get_service_performance", map[string]any{"service": "collector"}, []string{"collector", "spans=0, logs=0, metrics=1"}}, {"search_logs", map[string]any{"service": "logger", "severity": "ERROR"}, []string{"INFO (1)", "spans=0, logs=1, metrics=0"}}, - {"query_telemetry", map[string]any{"panel": panel.Panel{ID: "p", Title: "Collector latency", Viz: "stat", Query: &panel.Query{From: "spans", Where: []string{"namespace = 'shop' AND service = 'collector'"}, Measures: []string{"p95(duration_ms)"}}}}, []string{"Collector latency", "metrics=1"}}, + {"query_telemetry", map[string]any{"panel": query.Panel{ID: "p", Title: "Collector latency", Viz: "stat", Query: &query.Spec{From: "spans", Where: []string{"namespace = 'shop' AND service = 'collector'"}, Measures: []string{"p95(duration_ms)"}}}}, []string{"Collector latency", "metrics=1"}}, } { t.Run(tc.name, func(t *testing.T) { if tc.name == "query_telemetry" { - tc.args["time"] = panel.Time{From: &from, To: &to} + tc.args["time"] = query.Time{From: &from, To: &to} } else { tc.args["from"], tc.args["to"], tc.args["namespace"] = from, to, "shop" } @@ -47,9 +47,9 @@ func TestAllEmptyFragmentsReturnGuidanceWithoutViews(t *testing.T) { } // A mixed fragment remains a view, retaining its empty panel's diagnosis. d := fragmentPreset("performance", "checkout", "shop", "", "", 0) - d.Time = panel.Time{From: &from, To: &to} + d.Time = query.Time{From: &from, To: &to} d.Panels[3].Query.Where = append(d.Panels[3].Query.Where, "operation = 'absent'") - result, out, err := s.runFragment(t.Context(), panel.RunRequest{Dashboard: d}) + result, out, err := s.runFragment(t.Context(), query.RunRequest{Dashboard: d}) if err != nil || result.IsError || len(out.Results) != 4 || out.Results[0].Status != "ok" || out.Results[3].Status != "empty" { t.Fatalf("partial=%+v err=%v", out, err) } @@ -73,9 +73,9 @@ func TestEmptyStorePresetsReturnNoData(t *testing.T) { func TestDashboardMutationsRejectEmptyPanelsBeforeWriting(t *testing.T) { s, _, _, from, to := serviceInputFixture(t) s = newToolServer(t, structural{}, s.panels) - spec := panel.Dashboard{Name: "Checked", Time: panel.Time{From: &from, To: &to}, Panels: []panel.Panel{ + spec := query.Dashboard{Name: "Checked", Time: query.Time{From: &from, To: &to}, Panels: []query.Panel{ {ID: "note", Title: "Notes", Viz: "text", Content: "Context"}, - {ID: "requests", Title: "Collector requests", Viz: "stat", Query: &panel.Query{From: "spans", Where: []string{"service = 'collector'"}, Measures: []string{"count()"}}}, + {ID: "requests", Title: "Collector requests", Viz: "stat", Query: &query.Spec{From: "spans", Where: []string{"service = 'collector'"}, Measures: []string{"count()"}}}, }} result, out, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: spec}) if err != nil || !result.IsError || out.Error == nil || out.Error.Code != "invalid_spec" || out.Dashboard != nil || !strings.Contains(out.Error.Message, "panels[1]") || !strings.Contains(out.Error.Message, "Collector requests") || !strings.Contains(out.Error.Message, "Values seen") { @@ -153,8 +153,8 @@ func TestEmptyGuidanceOmitsUnrepresentableNamespaceScopes(t *testing.T) { {predicate, "service = '" + service + "'"}, {"(" + predicate + ") AND service = '" + service + "'"}, } { - d := panel.Dashboard{Name: "Scoped", Time: panel.Time{From: &from, To: &to}, Panels: []panel.Panel{{ID: "logs", Title: "Logs", Viz: "logs", Query: &panel.Query{From: "logs", Where: where}}}} - code, note, err := s.panels.EmptyGuidance(t.Context(), panel.RunRequest{Dashboard: d}) + d := query.Dashboard{Name: "Scoped", Time: query.Time{From: &from, To: &to}, Panels: []query.Panel{{ID: "logs", Title: "Logs", Viz: "logs", Query: &query.Spec{From: "logs", Where: where}}}} + code, note, err := s.panels.EmptyGuidance(t.Context(), query.RunRequest{Dashboard: d}) if err != nil || code != "no_data" || note != "" { t.Fatalf("unsafe scope produced service guidance: code=%q note=%q err=%v", code, note, err) } @@ -166,20 +166,20 @@ func TestEmptyGuidanceOmitsUnrepresentableNamespaceScopes(t *testing.T) { func TestDashboardSaveAcceptsBatchCellBudgetTruncation(t *testing.T) { s := panelServerFixture(t, true) - d := panel.Dashboard{Name: "Budget"} + d := query.Dashboard{Name: "Budget"} // TestBatchCellBudget's forty six-column tables exhaust the shared // 200,000-cell budget. A third span input brings this fixture to the // same 1,000-row per-frame cap before batch truncation. for i := range 40 { - d.Panels = append(d.Panels, panel.Panel{ID: fmt.Sprintf("p%d", i), Title: "wide", Viz: "table", SQL: "SELECT a.span_id, a.service, a.operation, a.http_route, a.status, a.duration_ms FROM spans a, spans b, spans c WHERE $__window(a.start_time)"}) + d.Panels = append(d.Panels, query.Panel{ID: fmt.Sprintf("p%d", i), Title: "wide", Viz: "table", SQL: "SELECT a.span_id, a.service, a.operation, a.http_route, a.status, a.duration_ms FROM spans a, spans b, spans c WHERE $__window(a.start_time)"}) } - results, err := s.panels.Run(t.Context(), panel.RunRequest{Dashboard: d}) + results, err := s.panels.Run(t.Context(), query.RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) } truncatedToZero := false for _, r := range results { - if r.Status != panel.StatusOK || r.Frame == nil { + if r.Status != query.StatusOK || r.Frame == nil { t.Fatalf("populated fixture failed: %+v", r) } truncatedToZero = truncatedToZero || (r.Frame.Truncated && r.Frame.Rows == 0) diff --git a/internal/mcp/panel_examples_test.go b/internal/mcp/panel_examples_test.go index f65286b2..5565230a 100644 --- a/internal/mcp/panel_examples_test.go +++ b/internal/mcp/panel_examples_test.go @@ -10,15 +10,15 @@ import ( "unicode/utf8" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) func TestSQLTimestampRuleAppearsOnceInAgentGuidance(t *testing.T) { - field, ok := reflect.TypeOf(panel.Panel{}).FieldByName("SQL") - if !ok || strings.Count(field.Tag.Get("jsonschema"), panel.SQLTimestampGuide) != 1 { + field, ok := reflect.TypeOf(query.Panel{}).FieldByName("SQL") + if !ok || strings.Count(field.Tag.Get("jsonschema"), query.SQLTimestampGuide) != 1 { t.Fatalf("SQL field guidance=%s", field.Tag.Get("jsonschema")) } docs, err := DescribeTools(t.Context()) @@ -30,7 +30,7 @@ func TestSQLTimestampRuleAppearsOnceInAgentGuidance(t *testing.T) { for _, doc := range docs { if doc.Name == name { found = true - if strings.Count(doc.Description, panel.SQLTimestampGuide) != 1 { + if strings.Count(doc.Description, query.SQLTimestampGuide) != 1 { t.Fatalf("%s must state the timestamp rule once", name) } } @@ -45,7 +45,7 @@ func TestExamplesAndPreviewCoverNewTypes(t *testing.T) { s := newPanelServer(t) coverage := map[string]int{} for example, text := range []string{investigationExample, paymentExample, metricExample} { - var d panel.Dashboard + var d query.Dashboard if err := json.Unmarshal([]byte(text), &d); err != nil { t.Fatal(err) } @@ -232,7 +232,7 @@ func TestMetricGuidanceIsConciseAndExamplesValidate(t *testing.T) { } } s := newPanelServer(t) - var d panel.Dashboard + var d query.Dashboard if err := json.Unmarshal([]byte(metricExample), &d); err != nil { t.Fatal(err) } @@ -289,19 +289,19 @@ func TestMetricExamplesExecuteWithObservations(t *testing.T) { if err := repo.Commit(t.Context(), telemetrystore.Batch{ID: "metric-examples", Metrics: metrics}); err != nil { t.Fatal(err) } - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = duck.Close() }) - executor := panel.NewExecutor(duck, 30) - var d panel.Dashboard + executor := query.NewExecutor(duck, 30) + var d query.Dashboard if err := json.Unmarshal([]byte(metricExample), &d); err != nil { t.Fatal(err) } end := at.Add(time.Minute) - d.Time = panel.Time{From: &at, To: &end} - results, err := executor.Run(t.Context(), panel.RunRequest{Dashboard: d}) + d.Time = query.Time{From: &at, To: &end} + results, err := executor.Run(t.Context(), query.RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) } @@ -310,7 +310,7 @@ func TestMetricExamplesExecuteWithObservations(t *testing.T) { } for i, want := range []float64{1, 0.95} { r := results[i] - if r.Status != panel.StatusOK || r.Frame == nil || r.Frame.Rows != 1 { + if r.Status != query.StatusOK || r.Frame == nil || r.Frame.Rows != 1 { t.Fatalf("%s: %+v", r.ID, r) } found := false @@ -332,7 +332,7 @@ func TestMetricExamplesExecuteWithObservations(t *testing.T) { func TestResourceInventoryExampleExecutesThroughPanelTools(t *testing.T) { now := time.Now().UTC() s := panelServerFixtureAt(t, true, now) - var d panel.Dashboard + var d query.Dashboard if err := json.Unmarshal([]byte(resourceInventoryExample), &d); err != nil { t.Fatal(err) } diff --git a/internal/mcp/panels.go b/internal/mcp/panels.go index e96930bd..baa69725 100644 --- a/internal/mcp/panels.go +++ b/internal/mcp/panels.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -19,9 +19,9 @@ type SchemaInput struct { } type PreviewInput struct { - Panels []panel.Panel `json:"panels" jsonschema:"Panels to check and run, in the same format as dashboard panels"` - Variables []panel.Variable `json:"variables,omitempty" jsonschema:"Variables the panels reference"` - Time *panel.Time `json:"time,omitempty" jsonschema:"Time range; default the last hour"` + Panels []query.Panel `json:"panels" jsonschema:"Panels to check and run, in the same format as dashboard panels"` + Variables []query.Variable `json:"variables,omitempty" jsonschema:"Variables the panels reference"` + Time *query.Time `json:"time,omitempty" jsonschema:"Time range; default the last hour"` Vars map[string]string `json:"vars,omitempty" jsonschema:"Variable values to preview with; $__all selects All"` } @@ -34,30 +34,30 @@ type PanelPreview struct { Interval string `json:"interval,omitempty"` Diagnosis string `json:"diagnosis,omitempty"` Error string `json:"error,omitempty"` - Problems []panel.Problem `json:"problems,omitempty"` + Problems []query.Problem `json:"problems,omitempty"` ElapsedMS *int64 `json:"elapsed_ms,omitempty" jsonschema:"Execution duration in milliseconds; omitted for invalid or not_run panels"` } type PreviewOutput struct { ElapsedMS int64 `json:"elapsed_ms"` Panels []PanelPreview `json:"panels"` - Problems []panel.Problem `json:"problems,omitempty"` + Problems []query.Problem `json:"problems,omitempty"` } -const baseSpecGuide = `A dashboard is {name, description, time:{range}, variables, panels}. Each panel: {id (lowercase), title, viz, width 1-12, query or sql}. viz: stat or gauge (one measure; gauge needs min and max), timeseries (bucket auto, at most one by), bar (one or two by), table (up to three by), text (content in Markdown), heatmap (bucket auto, no by), histogram (at most one by), scatter (exactly two measures in x then y order, one item dimension and an optional colour dimension), state_timeline (one measure, one item dimension, bucket auto and thresholds required). Rollup panel types are service_map (dependency graph) and health (overview metrics, error trend and health distribution). They require query.from=spans, no measures, by, bucket or sort, and only namespace/service equality filters with a literal or single-value variable; explicit casts and values with surrounding whitespace are rejected. Reads default to 400 services/edges and are capped at 400 even when query.limit is larger. Service scope applies before the limit; map nodes carry p95_ms and edges carry average_ms; error_rate is percent. Row panel types are logs, log_patterns and traces. Logs and traces take no measures, by or bucket. Patterns use count() by body_template. Patterns group only by body_template. Severity is the most frequent severity, ties choose the higher severity. Service is the most frequent service, ties choose ascending service name. Both describe the scoped, redacted events, not extra grouping dimensions. Each pattern returns dominant severity, top service, count and a dense trend, computed in the same bounded query after redaction and scoped filters. Redaction applies before filtering, grouping, display and drill-down. Row panels cannot use SQL. "erroring" means slowest erroring traces: filter to erroring traces, then rank by root duration. Trace candidate ranking is approximate when filters exclude the root span, as with exemplars. Categorical charts use fixed-order colour slots. Categorical options.top defaults to 6, maximum 6. Structured panels: the server computes Other; series are chosen worst-first by confidence (Wilson lower bound for error rates; at least 20 samples for latency); the rest fold into Other (N). Count, rate, sum and share rank largest first. Error rates require at least 20 requests for eligible Wilson ranking (z=1.96). Percentiles, quantile, avg, max and min require at least 20 non-null numeric samples for eligible value ranking and use better (explicit or inferred). Ineligible series follow eligible ones by sample count descending. Ties use sample count descending, then name ascending. SQL panels: series past six are left out, with a note. state_timeline defaults to 8 rows, maximum 20; other noncategorical panels use the same limits. Scatter supports options.x_scale and options.y_scale (log or linear), with distinct x_unit for x and unit for y, each inferred independently when omitted. Rows returned use the count unit. State timelines preserve null and absent buckets as unknown and keep the top items without merging them into Other. Scatter requires a structured query. SQL state_timeline requires timestamp time, a string item, one numeric measure and optional string state; its interval is one minute and thresholds are required. Items rank by volume (row count) for top N. Previous-period comparison is not drawn for scatter or state_timeline. Distribution panels use a structured query with one count() measure and histogram: {field: duration_ms, buckets: log2} for spans or {field: value, buckets: explicit} for metrics. Negative span durations clamp to [0,1); +Inf goes to overflow; NaN is excluded because it is not a measurement. Metric histograms use stored temporality and shared per-series increases; resets contribute current counts. Delta histograms sum observation weights. query: {from: spans|logs|metrics, where: [filter expressions], measures: [fn(field) as alias], by: [fields], bucket, sort, limit}. Measures: count(), rate() per second, error_rate() percent, share() percent, avg/min/max/sum(field), last(value) for metrics, p50/p75/p90/p95/p99(field), quantile(field, 0.999), count_distinct(field). Spans and logs aggregate panels also support count_if(SQL filter) and + - * / with constants and parentheses; arithmetic requires as alias and at least one aggregate, variables are not allowed inside count_if, share() stands alone, and division by zero returns null. Measures are bounded to 256 tokens, 64 nodes, depth 8 and 8 aggregates each, and 256 nodes and 24 aggregates together. Metrics do not support arithmetic. Fields are columns from get_telemetry_schema or attributes['key'] / resource['key'] with the key written literally. Filters are SQL boolean expressions: service = $service, kind = 'SPAN_KIND_SERVER', status = 'STATUS_CODE_ERROR', http_route IN $routes, attributes['http.response.status_code']::INTEGER >= 500. Variables: {name, kind: query|custom|constant|text, from, field, default, include_all}; $__all selects All and removes filters that use the variable. sql: one SELECT over spans, logs, metrics, service_rollup, edge_rollup or resource_inventory that filters time with $__window(column).` + " " + panel.SQLTimestampGuide + ` Use values exactly as get_telemetry_schema lists them. Example panel: {"id":"latency","title":"Checkout latency","viz":"timeseries","width":8,"query":{"from":"spans","where":["service = 'checkout'","kind = 'SPAN_KIND_SERVER'"],"measures":["p50(duration_ms)","p95(duration_ms)","p99(duration_ms)"],"bucket":"auto"},"unit":"ms","thresholds":[{"value":1500,"status":"bad"}]}.` + " " + metricMeasureGuide + " " + resourceInventoryGuide +const baseSpecGuide = `A dashboard is {name, description, time:{range}, variables, panels}. Each panel: {id (lowercase), title, viz, width 1-12, query or sql}. viz: stat or gauge (one measure; gauge needs min and max), timeseries (bucket auto, at most one by), bar (one or two by), table (up to three by), text (content in Markdown), heatmap (bucket auto, no by), histogram (at most one by), scatter (exactly two measures in x then y order, one item dimension and an optional colour dimension), state_timeline (one measure, one item dimension, bucket auto and thresholds required). Rollup panel types are service_map (dependency graph) and health (overview metrics, error trend and health distribution). They require query.from=spans, no measures, by, bucket or sort, and only namespace/service equality filters with a literal or single-value variable; explicit casts and values with surrounding whitespace are rejected. Reads default to 400 services/edges and are capped at 400 even when query.limit is larger. Service scope applies before the limit; map nodes carry p95_ms and edges carry average_ms; error_rate is percent. Row panel types are logs, log_patterns and traces. Logs and traces take no measures, by or bucket. Patterns use count() by body_template. Patterns group only by body_template. Severity is the most frequent severity, ties choose the higher severity. Service is the most frequent service, ties choose ascending service name. Both describe the scoped, redacted events, not extra grouping dimensions. Each pattern returns dominant severity, top service, count and a dense trend, computed in the same bounded query after redaction and scoped filters. Redaction applies before filtering, grouping, display and drill-down. Row panels cannot use SQL. "erroring" means slowest erroring traces: filter to erroring traces, then rank by root duration. Trace candidate ranking is approximate when filters exclude the root span, as with exemplars. Categorical charts use fixed-order colour slots. Categorical options.top defaults to 6, maximum 6. Structured panels: the server computes Other; series are chosen worst-first by confidence (Wilson lower bound for error rates; at least 20 samples for latency); the rest fold into Other (N). Count, rate, sum and share rank largest first. Error rates require at least 20 requests for eligible Wilson ranking (z=1.96). Percentiles, quantile, avg, max and min require at least 20 non-null numeric samples for eligible value ranking and use better (explicit or inferred). Ineligible series follow eligible ones by sample count descending. Ties use sample count descending, then name ascending. SQL panels: series past six are left out, with a note. state_timeline defaults to 8 rows, maximum 20; other noncategorical panels use the same limits. Scatter supports options.x_scale and options.y_scale (log or linear), with distinct x_unit for x and unit for y, each inferred independently when omitted. Rows returned use the count unit. State timelines preserve null and absent buckets as unknown and keep the top items without merging them into Other. Scatter requires a structured query. SQL state_timeline requires timestamp time, a string item, one numeric measure and optional string state; its interval is one minute and thresholds are required. Items rank by volume (row count) for top N. Previous-period comparison is not drawn for scatter or state_timeline. Distribution panels use a structured query with one count() measure and histogram: {field: duration_ms, buckets: log2} for spans or {field: value, buckets: explicit} for metrics. Negative span durations clamp to [0,1); +Inf goes to overflow; NaN is excluded because it is not a measurement. Metric histograms use stored temporality and shared per-series increases; resets contribute current counts. Delta histograms sum observation weights. query: {from: spans|logs|metrics, where: [filter expressions], measures: [fn(field) as alias], by: [fields], bucket, sort, limit}. Measures: count(), rate() per second, error_rate() percent, share() percent, avg/min/max/sum(field), last(value) for metrics, p50/p75/p90/p95/p99(field), quantile(field, 0.999), count_distinct(field). Spans and logs aggregate panels also support count_if(SQL filter) and + - * / with constants and parentheses; arithmetic requires as alias and at least one aggregate, variables are not allowed inside count_if, share() stands alone, and division by zero returns null. Measures are bounded to 256 tokens, 64 nodes, depth 8 and 8 aggregates each, and 256 nodes and 24 aggregates together. Metrics do not support arithmetic. Fields are columns from get_telemetry_schema or attributes['key'] / resource['key'] with the key written literally. Filters are SQL boolean expressions: service = $service, kind = 'SPAN_KIND_SERVER', status = 'STATUS_CODE_ERROR', http_route IN $routes, attributes['http.response.status_code']::INTEGER >= 500. Variables: {name, kind: query|custom|constant|text, from, field, default, include_all}; $__all selects All and removes filters that use the variable. sql: one SELECT over spans, logs, metrics, service_rollup, edge_rollup or resource_inventory that filters time with $__window(column).` + " " + query.SQLTimestampGuide + ` Use values exactly as get_telemetry_schema lists them. Example panel: {"id":"latency","title":"Checkout latency","viz":"timeseries","width":8,"query":{"from":"spans","where":["service = 'checkout'","kind = 'SPAN_KIND_SERVER'"],"measures":["p50(duration_ms)","p95(duration_ms)","p99(duration_ms)"],"bucket":"auto"},"unit":"ms","thresholds":[{"value":1500,"status":"bad"}]}.` + " " + metricMeasureGuide + " " + resourceInventoryGuide func (s *Server) registerPanelTools() { readOnly := &mcp.ToolAnnotations{ReadOnlyHint: true, OpenWorldHint: boolPtr(false)} fragmentTool(s, &mcp.Tool{Name: "query_telemetry", Title: "Telemetry panel", Description: "Display one v1 panel in chat as an executable dashboard fragment. Use get_telemetry_schema to discover fields; see create_dashboard for the spec guide. The authored spec plus vars must fit 128 KiB (131072 serialized JSON bytes); larger inputs are rejected with their actual size. Agents: write panel.query (structured JSON) first, or panel.sql for complex work; text accepts FanQL: source [where] filters | measures by fields every bucket sort key limit n. Examples: spans where status:error | count() by service; logs where severity>=warn | count() by service every 1m. See fanout://fanql/reference for fields, operators and variables.", Annotations: readOnly, Meta: appToolMeta(panelsAppURI)}, s.queryTelemetry) fragmentTool(s, &mcp.Tool{Name: "query_panel_fragment", Title: "Refresh telemetry panels", Description: "Run every panel in a dashboard fragment; panel subsets are forbidden.", Annotations: readOnly, Meta: appHelperMeta()}, func(ctx context.Context, req *mcp.CallToolRequest, input fragmentInput) (*mcp.CallToolResult, PanelFragment, error) { - return s.queryPanelFragment(ctx, req, panel.RunRequest{Dashboard: input.Dashboard, Time: input.Time, Vars: input.Vars, Widths: input.Widths, Compare: input.Compare}) + return s.queryPanelFragment(ctx, req, query.RunRequest{Dashboard: input.Dashboard, Time: input.Time, Vars: input.Vars, Widths: input.Widths, Compare: input.Compare}) }) fragmentTool(s, &mcp.Tool{Name: "list_panel_exemplars", Title: "Panel exemplars", Description: "Find bounded traces for a panel selection.", Annotations: readOnly, Meta: appHelperMeta()}, s.panelExemplars) fragmentTool(s, &mcp.Tool{Name: "resolve_panel_variables", Title: "Panel variable options", Description: "Resolve variable options within a dashboard fragment window.", Annotations: readOnly, Meta: appHelperMeta()}, s.resolvePanelVariables) mcp.AddTool(s.mcp, &mcp.Tool{ Name: "get_telemetry_schema", Title: "Telemetry schema", - Description: "List the signals, columns with their common values, attribute keys seen per service, metric names, services, measure functions, units and SQL-only relations in sql_relations. Read this before drafting panels so filters use values that exist. " + panel.SQLTimestampGuide + " See create_dashboard for the spec guide.", + Description: "List the signals, columns with their common values, attribute keys seen per service, metric names, services, measure functions, units and SQL-only relations in sql_relations. Read this before drafting panels so filters use values that exist. " + query.SQLTimestampGuide + " See create_dashboard for the spec guide.", Annotations: readOnly, }, s.telemetrySchema) mcp.AddTool(s.mcp, &mcp.Tool{ @@ -67,13 +67,13 @@ func (s *Server) registerPanelTools() { }, s.previewPanels) } -func (s *Server) telemetrySchema(ctx context.Context, _ *mcp.CallToolRequest, input SchemaInput) (*mcp.CallToolResult, *panel.Schema, error) { +func (s *Server) telemetrySchema(ctx context.Context, _ *mcp.CallToolRequest, input SchemaInput) (*mcp.CallToolResult, *query.Schema, error) { if s.panels == nil { return nil, nil, errors.New("panels are unavailable") } ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - schema, err := s.panels.Schema(ctx, panel.SchemaRequest{Window: input.Window, Namespace: input.Namespace}) + schema, err := s.panels.Schema(ctx, query.SchemaRequest{Window: input.Window, Namespace: input.Namespace}) if err != nil { return nil, nil, safePanelToolError(err) } @@ -90,16 +90,16 @@ func (s *Server) previewPanels(ctx context.Context, _ *mcp.CallToolRequest, inpu if s.panels == nil { return nil, PreviewOutput{}, errors.New("panels are unavailable") } - d := panel.Dashboard{Name: "Preview", Variables: input.Variables, Panels: input.Panels} + d := query.Dashboard{Name: "Preview", Variables: input.Variables, Panels: input.Panels} if input.Time != nil { d.Time = *input.Time } - vars := map[string]panel.Value{} + vars := map[string]query.Value{} for name, value := range input.Vars { - if value == panel.AllValue { - vars[name] = panel.Value{All: true} + if value == query.AllValue { + vars[name] = query.Value{All: true} } else { - vars[name] = panel.Value{Values: []string{value}} + vars[name] = query.Value{Values: []string{value}} } } out := PreviewOutput{Panels: make([]PanelPreview, len(input.Panels))} @@ -107,11 +107,11 @@ func (s *Server) previewPanels(ctx context.Context, _ *mcp.CallToolRequest, inpu out.Panels[i] = PanelPreview{ID: p.ID, Status: "not_run"} } start := time.Now() - results, err := s.panels.Run(ctx, panel.RunRequest{Dashboard: d, Vars: vars}) + results, err := s.panels.Run(ctx, query.RunRequest{Dashboard: d, Vars: vars}) out.ElapsedMS = time.Since(start).Milliseconds() - var problems panel.Problems + var problems query.Problems if errors.As(err, &problems) { - for _, problem := range panel.PresentProblems(problems) { + for _, problem := range query.PresentProblems(problems) { if m := panelPath.FindStringSubmatch(problem.Path); m != nil { i, _ := strconv.Atoi(m[1]) if i < len(out.Panels) { @@ -128,7 +128,7 @@ func (s *Server) previewPanels(ctx context.Context, _ *mcp.CallToolRequest, inpu return nil, PreviewOutput{}, safePanelToolError(err) } for i, r := range results { - preview := PanelPreview{ElapsedMS: &r.ElapsedMS, ID: r.ID, Status: r.Status, Interval: r.Interval, Diagnosis: panel.PresentDiagnosis(r.Diagnosis), Error: panel.PresentMessage(r.Error)} + preview := PanelPreview{ElapsedMS: &r.ElapsedMS, ID: r.ID, Status: r.Status, Interval: r.Interval, Diagnosis: query.PresentDiagnosis(r.Diagnosis), Error: query.PresentMessage(r.Error)} if r.Frame != nil { preview.Rows = r.Frame.Rows for _, c := range r.Frame.Columns { @@ -174,5 +174,5 @@ func previewSummary(out PreviewOutput) string { } func safePanelToolError(err error) error { - return panel.PresentedError(err, panel.ReadError) + return query.PresentedError(err, query.ReadError) } diff --git a/internal/mcp/panels_test.go b/internal/mcp/panels_test.go index 04cff0a2..3a158526 100644 --- a/internal/mcp/panels_test.go +++ b/internal/mcp/panels_test.go @@ -9,8 +9,8 @@ import ( "github.com/labstack/fanout/internal/config" "github.com/labstack/fanout/internal/dashboard" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" appstore "github.com/labstack/fanout/internal/store" "github.com/labstack/fanout/internal/telemetry" @@ -20,10 +20,10 @@ import ( func TestPreviewReportsTotalAndExecutedPanelTimings(t *testing.T) { s := newPanelServer(t) - s.panels = receiptExecutor{panelExecutor: s.panels, run: func(_ context.Context, req panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: req.Dashboard.Panels[0].ID, Status: "ok", ElapsedMS: 37}}, nil + s.panels = receiptExecutor{panelExecutor: s.panels, run: func(_ context.Context, req query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: req.Dashboard.Panels[0].ID, Status: "ok", ElapsedMS: 37}}, nil }} - _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "hello"}}}) + _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{{ID: "note", Title: "Note", Viz: "text", Content: "hello"}}}) if err != nil || out.ElapsedMS < 0 || len(out.Panels) != 1 || (out.Panels[0].ElapsedMS == nil || *out.Panels[0].ElapsedMS != 37) || out.Panels[0].Status != "ok" { t.Fatalf("out=%+v err=%v", out, err) } @@ -44,7 +44,7 @@ func panelServerFixtureAt(t *testing.T, seed bool, now time.Time) *Server { if err != nil { t.Fatal(err) } - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -79,7 +79,7 @@ func panelServerFixtureAt(t *testing.T, seed bool, now time.Time) *Server { t.Fatal(err) } } - executor := panel.NewExecutor(duck, 30) + executor := query.NewExecutor(duck, 30) executor.SetRollupReader(observability.New(duck, duck, 30)) if seed { server := NewWithIntelligence(observability.New(duck, duck, 30), dashboard.New(sqlite.DB, executor), executor, nil, "test") @@ -95,9 +95,9 @@ func ownerRequest() *mcp.CallToolRequest { func TestPreviewPanelsReportsEachPanel(t *testing.T) { s := newPanelServer(t) - _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{ - {ID: "requests", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}, - {ID: "typo", Title: "Typo", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"p95(duraton_ms)"}}}, + _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{ + {ID: "requests", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}, + {ID: "typo", Title: "Typo", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"p95(duraton_ms)"}}}, }}) if err != nil { t.Fatal(err) @@ -111,7 +111,7 @@ func TestPreviewPanelsReportsEachPanel(t *testing.T) { if out.ElapsedMS < 0 || out.Panels[0].ElapsedMS != nil || out.Panels[1].ElapsedMS != nil { t.Fatalf("invalid/not_run timing = %+v", out) } - _, out, err = s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{{ID: "requests", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}}}) + _, out, err = s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{{ID: "requests", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}}}) if err != nil || out.Panels[0].Status != "empty" || out.Panels[0].Diagnosis == "" { t.Fatalf("empty store preview = %+v %v", out.Panels, err) } @@ -119,9 +119,9 @@ func TestPreviewPanelsReportsEachPanel(t *testing.T) { func TestCreateAndEditDashboardTools(t *testing.T) { s := panelServerFixture(t, true) - spec := panel.Dashboard{Name: "Checkout", Panels: []panel.Panel{ + spec := query.Dashboard{Name: "Checkout", Panels: []query.Panel{ {ID: "notes", Title: "Notes", Viz: "text", Content: "Money path."}, - {ID: "requests", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}, + {ID: "requests", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}, }} result, out, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: spec}) if err != nil { diff --git a/internal/mcp/pattern_context_guide_test.go b/internal/mcp/pattern_context_guide_test.go index 4f1aa8ef..ae9a4fd8 100644 --- a/internal/mcp/pattern_context_guide_test.go +++ b/internal/mcp/pattern_context_guide_test.go @@ -1,7 +1,7 @@ package mcp import ( - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "reflect" "strings" "testing" @@ -24,7 +24,7 @@ func TestPreviewPatternContextGuide(t *testing.T) { t.Errorf("guide missing %q", term) } } - field, _ := reflect.TypeFor[panel.Panel]().FieldByName("Viz") + field, _ := reflect.TypeFor[query.Panel]().FieldByName("Viz") if !strings.Contains(field.Tag.Get("jsonschema"), "dominant severity") { t.Error("spec description omits log pattern context") } diff --git a/internal/mcp/performance_operations_test.go b/internal/mcp/performance_operations_test.go index 8d042f2a..db8a5092 100644 --- a/internal/mcp/performance_operations_test.go +++ b/internal/mcp/performance_operations_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -20,7 +20,7 @@ func TestPerformanceSlowOperationsAcrossProtocols(t *testing.T) { t.Fatal(err) } t.Cleanup(func() { _ = repo.Close() }) - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -60,7 +60,7 @@ func TestPerformanceSlowOperationsAcrossProtocols(t *testing.T) { if err := repo.Commit(t.Context(), telemetrystore.Batch{ID: "operations", Spans: spans}); err != nil { t.Fatal(err) } - s := &Server{panels: panel.NewExecutor(duck, 30)} + s := &Server{panels: query.NewExecutor(duck, 30)} for _, tc := range cases { t.Run(tc.protocol, func(t *testing.T) { for _, limit := range []int{0, 1} { @@ -85,7 +85,7 @@ func TestPerformanceSlowOperationsAcrossProtocols(t *testing.T) { if limit > 0 { wantOperations, wantP95 = wantOperations[:limit], wantP95[:limit] } - if r.ID != "operations" || r.Status != panel.StatusOK || r.Frame == nil || r.Frame.Rows != len(wantOperations) { + if r.ID != "operations" || r.Status != query.StatusOK || r.Frame == nil || r.Frame.Rows != len(wantOperations) { t.Fatalf("operations result = %+v", r) } if len(r.Frame.Columns) != 2 || r.Frame.Columns[0].Name != "operation" || r.Frame.Columns[1].Name != "p95" || !reflect.DeepEqual(r.Frame.Values[0], wantOperations) { diff --git a/internal/mcp/presentation_test.go b/internal/mcp/presentation_test.go index 48ff6cfb..c36ef0a5 100644 --- a/internal/mcp/presentation_test.go +++ b/internal/mcp/presentation_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp" ) @@ -20,7 +20,7 @@ func TestTimestampLiteralHintSurvivesMCPPreviewAndDashboardRejection(t *testing. now := time.Date(2026, 10, 20, 18, 6, 0, 0, time.UTC) s := panelServerFixtureAt(t, true, now) from := now.Add(-time.Hour) - window := panel.Time{From: &from, To: &now} + window := query.Time{From: &from, To: &now} for _, tc := range []struct { name, predicate string invalid bool @@ -32,8 +32,8 @@ func TestTimestampLiteralHintSurvivesMCPPreviewAndDashboardRejection(t *testing. {"explicit_cast", "start_time < TIMESTAMPTZ '2026-10-20 17:36:15+00'::TIMESTAMPTZ_NS", false}, } { t.Run(tc.name, func(t *testing.T) { - p := panel.Panel{ID: "calls", Title: "Calls", Viz: "table", SQL: "SELECT count(*) AS n FROM spans WHERE $__window(start_time) AND " + tc.predicate} - _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{p}, Time: &window}) + p := query.Panel{ID: "calls", Title: "Calls", Viz: "table", SQL: "SELECT count(*) AS n FROM spans WHERE $__window(start_time) AND " + tc.predicate} + _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{p}, Time: &window}) if err != nil || len(out.Panels) != 1 { t.Fatalf("preview=%+v err=%v", out, err) } @@ -44,12 +44,12 @@ func TestTimestampLiteralHintSurvivesMCPPreviewAndDashboardRejection(t *testing. } return } - if got.Status != "invalid" || len(got.Problems) != 1 || got.Problems[0].Path != "panels[0].sql" || got.Problems[0].Hint != panel.SQLTimestampGuide { + if got.Status != "invalid" || len(got.Problems) != 1 || got.Problems[0].Path != "panels[0].sql" || got.Problems[0].Hint != query.SQLTimestampGuide { t.Fatalf("preview lost hint: %+v", got) } session := connectTestClient(t, s, nil) result, err := session.CallTool(t.Context(), &mcpsdk.CallToolParams{ - Name: "create_dashboard", Arguments: DashboardCreateInput{Dashboard: panel.Dashboard{Name: "Time literals", Time: window, Panels: []panel.Panel{p}}}, + Name: "create_dashboard", Arguments: DashboardCreateInput{Dashboard: query.Dashboard{Name: "Time literals", Time: window, Panels: []query.Panel{p}}}, Meta: mcpsdk.Meta{dashboard.OwnerMetaKey: "owner"}, }) if err != nil || !result.IsError { @@ -58,10 +58,10 @@ func TestTimestampLiteralHintSurvivesMCPPreviewAndDashboardRejection(t *testing. check := func(raw []byte) { t.Helper() var failure dashboardOutput - if err := json.Unmarshal(raw, &failure); err != nil || failure.Error == nil || failure.Error.Code != "invalid_spec" || !strings.Contains(failure.Error.Message, panel.SQLTimestampGuide) { + if err := json.Unmarshal(raw, &failure); err != nil || failure.Error == nil || failure.Error.Code != "invalid_spec" || !strings.Contains(failure.Error.Message, query.SQLTimestampGuide) { t.Fatalf("failure=%s err=%v", raw, err) } - if len(failure.Problems) != 1 || failure.Problems[0].Path != "panels[0].sql" || failure.Problems[0].Hint != panel.SQLTimestampGuide { + if len(failure.Problems) != 1 || failure.Problems[0].Path != "panels[0].sql" || failure.Problems[0].Hint != query.SQLTimestampGuide { t.Fatalf("lost problem hint: %+v", failure.Problems) } } @@ -80,7 +80,7 @@ type presentationExecutor struct { guidance string } -func (p presentationExecutor) EmptyGuidance(context.Context, panel.RunRequest) (string, string, error) { +func (p presentationExecutor) EmptyGuidance(context.Context, query.RunRequest) (string, string, error) { return "no_data", p.guidance, nil } @@ -113,8 +113,8 @@ func TestPresentationAcrossMCPPreviewsReceiptsGuidanceAndErrors(t *testing.T) { t.Errorf("lost author diagnostic: %q", got) } } - s.panels = presentationExecutor{receiptExecutor: receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: "notes", Status: "error", Error: message, Diagnosis: "No matching data."}}, nil + s.panels = presentationExecutor{receiptExecutor: receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: "notes", Status: "error", Error: message, Diagnosis: "No matching data."}}, nil }}, guidance: "No matching data."} text, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: textDashboard("Preview").Panels}) if err != nil { @@ -128,13 +128,13 @@ func TestPresentationAcrossMCPPreviewsReceiptsGuidanceAndErrors(t *testing.T) { t.Fatal(err) } check(saved) - guidance := s.noDataError(t.Context(), PanelFragment{Dashboard: textDashboard("Empty"), Results: []panel.Result{{ID: "notes", Diagnosis: "No matching data."}}}) + guidance := s.noDataError(t.Context(), PanelFragment{Dashboard: textDashboard("Empty"), Results: []query.Result{{ID: "notes", Diagnosis: "No matching data."}}}) if guidance == nil { t.Fatal("missing no_data guidance") } check(guidance.Error()) - s.panels = receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return nil, panel.Problems{{Path: "panels[0].sql", Message: message, Hint: message}} + s.panels = receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return nil, query.Problems{{Path: "panels[0].sql", Message: message, Hint: message}} }} text, out, err = s.previewPanels(t.Context(), nil, PreviewInput{Panels: textDashboard("Invalid").Panels}) if err != nil { @@ -149,7 +149,7 @@ func TestPresentationAcrossMCPPreviewsReceiptsGuidanceAndErrors(t *testing.T) { } cause := errors.New(message) got := safePanelToolError(cause) - if !errors.Is(got, cause) || got.Error() != panel.ReadFailure { + if !errors.Is(got, cause) || got.Error() != query.ReadFailure { t.Fatalf("operational error: %v", got) } // Exercise actual MCP middleware and both error content paths. @@ -169,7 +169,7 @@ func TestPresentationAcrossMCPPreviewsReceiptsGuidanceAndErrors(t *testing.T) { func TestStructuredFilterRuntimeDiagnosticReachesPreview(t *testing.T) { s := panelServerFixture(t, true) - _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &panel.Query{From: "spans", Measures: []string{"count()"}, Where: []string{"CAST(service AS INTEGER) > 0"}}}}}) + _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &query.Spec{From: "spans", Measures: []string{"count()"}, Where: []string{"CAST(service AS INTEGER) > 0"}}}}}) if err != nil { t.Fatal(err) } @@ -185,14 +185,14 @@ func TestProductDiagnosesSurvivePublicationBoundaries(t *testing.T) { const routeDiagnosis = "No spans match this combination of filters in this time range. Without HTTP route /api/cart, 120 match the remaining filters. Values seen: /cart (60), /quote (60)." for _, diagnosis := range []string{routeDiagnosis, "No logs for body /srv/checkout/a.parquet or value 'IO Error: DuckDB'."} { s := newToolServer(t, structural{}, nil) - s.panels = presentationExecutor{receiptExecutor: receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: "notes", Status: "empty", Diagnosis: diagnosis}}, nil + s.panels = presentationExecutor{receiptExecutor: receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: "notes", Status: "empty", Diagnosis: diagnosis}}, nil }}, guidance: diagnosis} _, out, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: textDashboard("Preview").Panels}) if err != nil || out.Panels[0].Diagnosis != diagnosis { t.Fatalf("preview: %+v %v", out, err) } - guidance := s.noDataError(t.Context(), PanelFragment{Dashboard: textDashboard("Empty"), Results: []panel.Result{{ID: "notes", Diagnosis: diagnosis}}}) + guidance := s.noDataError(t.Context(), PanelFragment{Dashboard: textDashboard("Empty"), Results: []query.Result{{ID: "notes", Diagnosis: diagnosis}}}) if guidance == nil || !strings.Contains(guidance.Error(), diagnosis) { t.Fatalf("guidance: %v", guidance) } @@ -201,7 +201,7 @@ func TestProductDiagnosesSurvivePublicationBoundaries(t *testing.T) { t.Fatalf("receipt: %+v %v", saved, err) } spec := textDashboard("Empty telemetry") - spec.Panels[0] = panel.Panel{ID: "notes", Title: "Calls", Viz: "table", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}} + spec.Panels[0] = query.Panel{ID: "notes", Title: "Calls", Viz: "table", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}} result, rejected, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: spec}) if err != nil || !result.IsError || rejected.Error == nil || rejected.Error.Code != "invalid_spec" || !strings.Contains(rejected.Error.Message, diagnosis) { t.Fatalf("save validation lost diagnosis: %+v %v", rejected, err) @@ -212,17 +212,17 @@ func TestProductDiagnosesSurvivePublicationBoundaries(t *testing.T) { func TestNoDataRouteGuidanceSurvivesMCPMiddleware(t *testing.T) { const diagnosis = "No spans match these filters. Without HTTP route /api/cart, 120 match the remaining filters." s := newToolServer(t, structural{}, presentationExecutor{ - receiptExecutor: receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: "calls", Status: panel.StatusEmpty, Diagnosis: diagnosis}}, nil + receiptExecutor: receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: "calls", Status: query.StatusEmpty, Diagnosis: diagnosis}}, nil }}, guidance: diagnosis, }) session := connectTestClient(t, s, nil) result, err := session.CallTool(t.Context(), &mcpsdk.CallToolParams{ Name: "query_telemetry", - Arguments: map[string]any{"panel": panel.Panel{ + Arguments: map[string]any{"panel": query.Panel{ ID: "calls", Title: "Calls", Viz: "table", - Query: &panel.Query{From: "spans", Where: []string{"http_route = '/api/cart'"}}, + Query: &query.Spec{From: "spans", Where: []string{"http_route = '/api/cart'"}}, }}, }) if err != nil || !result.IsError { @@ -239,16 +239,16 @@ func TestNoDataRouteGuidanceSurvivesMCPMiddleware(t *testing.T) { func TestDashboardRejectionsPreserveRouteDiagnosesThroughMiddleware(t *testing.T) { const diagnosis = "No spans match these filters. Without HTTP route /api/orders/{id}, 120 match the remaining filters." - s := newToolServer(t, structural{}, receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: "calls", Status: panel.StatusEmpty, Diagnosis: diagnosis}}, nil + s := newToolServer(t, structural{}, receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: "calls", Status: query.StatusEmpty, Diagnosis: diagnosis}}, nil }}) _, created, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: textDashboard("Saved")}) if err != nil { t.Fatal(err) } - spec := panel.Dashboard{Name: "Rejected", Panels: []panel.Panel{{ID: "calls", Title: "Calls", Viz: "table", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}}} - want := panel.PresentProblems(panel.Problems{panel.DiagnosisProblem("panels[0]", "Calls: "+diagnosis, "Replace or drop this panel; dashboards contain only panels that return data.")}).Error() - if panel.PresentMessage(want) != panel.ReadFailure { + spec := query.Dashboard{Name: "Rejected", Panels: []query.Panel{{ID: "calls", Title: "Calls", Viz: "table", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}}} + want := query.PresentProblems(query.Problems{query.DiagnosisProblem("panels[0]", "Calls: "+diagnosis, "Replace or drop this panel; dashboards contain only panels that return data.")}).Error() + if query.PresentMessage(want) != query.ReadFailure { t.Fatal("route diagnosis no longer reproduces operational path presentation") } session := connectTestClient(t, s, nil) diff --git a/internal/mcp/receipt_quality_test.go b/internal/mcp/receipt_quality_test.go index 8d2b12b1..566880fd 100644 --- a/internal/mcp/receipt_quality_test.go +++ b/internal/mcp/receipt_quality_test.go @@ -11,12 +11,12 @@ import ( "time" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" ) func parallelTimingExecutor() receiptExecutor { - return receiptExecutor{run: func(_ context.Context, req panel.RunRequest) ([]panel.Result, error) { - results := make([]panel.Result, len(req.Dashboard.Panels)) + return receiptExecutor{run: func(_ context.Context, req query.RunRequest) ([]query.Result, error) { + results := make([]query.Result, len(req.Dashboard.Panels)) var wg sync.WaitGroup for i, p := range req.Dashboard.Panels { wg.Add(1) @@ -24,7 +24,7 @@ func parallelTimingExecutor() receiptExecutor { defer wg.Done() start := time.Now() time.Sleep(30 * time.Millisecond) - results[i] = panel.Result{ID: p.ID, Status: panel.StatusOK, ElapsedMS: time.Since(start).Milliseconds()} + results[i] = query.Result{ID: p.ID, Status: query.StatusOK, ElapsedMS: time.Since(start).Milliseconds()} }() } wg.Wait() @@ -36,7 +36,7 @@ func TestSaveAndPreviewTotalsMeasureParallelWallTime(t *testing.T) { s := newToolServer(t, structural{}, parallelTimingExecutor()) spec := textDashboard("Parallel timings") for _, id := range []string{"b", "c", "d"} { - spec.Panels = append(spec.Panels, panel.Panel{ID: id, Title: id, Viz: "text", Content: id}) + spec.Panels = append(spec.Panels, query.Panel{ID: id, Title: id, Viz: "text", Content: id}) } _, saved, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: spec}) if err != nil { @@ -76,7 +76,7 @@ func TestSaveAndPreviewTotalsMeasureParallelWallTime(t *testing.T) { func TestUnexecutedPanelRowsOmitTimingMeasurements(t *testing.T) { s := newPanelServer(t) - _, preview, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []panel.Panel{ + _, preview, err := s.previewPanels(t.Context(), nil, PreviewInput{Panels: []query.Panel{ {ID: "valid", Title: "Valid", Viz: "text", Content: "hello"}, {ID: "invalid", Title: "Invalid", Viz: "unknown"}, }}) @@ -105,8 +105,8 @@ func TestUnexecutedPanelRowsOmitTimingMeasurements(t *testing.T) { } func TestSavedPanelErrorsAreRedactedWithoutLoggingAgain(t *testing.T) { - s := newToolServer(t, structural{}, receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { - return []panel.Result{{ID: "notes", Status: panel.StatusError, Error: "cannot read /private/telemetry/file.parquet"}}, nil + s := newToolServer(t, structural{}, receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { + return []query.Result{{ID: "notes", Status: query.StatusError, Error: "cannot read /private/telemetry/file.parquet"}}, nil }}) var logs bytes.Buffer original := slog.Default() diff --git a/internal/mcp/receipts_test.go b/internal/mcp/receipts_test.go index d4a066f3..7f5c5dfe 100644 --- a/internal/mcp/receipts_test.go +++ b/internal/mcp/receipts_test.go @@ -8,16 +8,16 @@ import ( "time" "github.com/labstack/fanout/internal/dashboard" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/modelcontextprotocol/go-sdk/mcp" ) type receiptExecutor struct { panelExecutor - run func(context.Context, panel.RunRequest) ([]panel.Result, error) + run func(context.Context, query.RunRequest) ([]query.Result, error) } -func (e receiptExecutor) Run(ctx context.Context, req panel.RunRequest) ([]panel.Result, error) { +func (e receiptExecutor) Run(ctx context.Context, req query.RunRequest) ([]query.Result, error) { return e.run(ctx, req) } @@ -25,21 +25,21 @@ func TestSaveCheckFailuresAreStructuredAndDoNotRetrySave(t *testing.T) { longError := "cannot read /private/data/file: " + strings.Repeat("details; ", 100) + "final diagnostic" for _, tc := range []struct { name string - results []panel.Result + results []query.Result err error checked bool }{ {name: "missing"}, - {name: "duplicate", results: []panel.Result{{ID: "notes", Status: "ok"}, {ID: "notes", Status: "ok"}}}, - {name: "unexpected", results: []panel.Result{{ID: "other", Status: "ok"}}}, - {name: "not_run", results: []panel.Result{{ID: "notes", Status: "not_run"}}}, + {name: "duplicate", results: []query.Result{{ID: "notes", Status: "ok"}, {ID: "notes", Status: "ok"}}}, + {name: "unexpected", results: []query.Result{{ID: "other", Status: "ok"}}}, + {name: "not_run", results: []query.Result{{ID: "notes", Status: "not_run"}}}, {name: "engine", err: errors.New("cannot open /private/data/telemetry.parquet")}, {name: "timeout", err: context.DeadlineExceeded}, - {name: "failing_panel", results: []panel.Result{{ID: "notes", Status: "error", Error: longError, ElapsedMS: 17}}, checked: true}, + {name: "failing_panel", results: []query.Result{{ID: "notes", Status: "error", Error: longError, ElapsedMS: 17}}, checked: true}, } { t.Run(tc.name, func(t *testing.T) { s := newToolServer(t, structural{}, nil) - s.panels = receiptExecutor{run: func(ctx context.Context, _ panel.RunRequest) ([]panel.Result, error) { + s.panels = receiptExecutor{run: func(ctx context.Context, _ query.RunRequest) ([]query.Result, error) { deadline, ok := ctx.Deadline() if !ok || time.Until(deadline) > saveCheckBudget { t.Error("missing eight-second budget") @@ -63,7 +63,7 @@ func TestSaveCheckFailuresAreStructuredAndDoNotRetrySave(t *testing.T) { if tc.name == "failing_panel" && (check.Panels[0].Status != "error" || *check.Panels[0].ElapsedMS != 17 || len(out.Warnings) != 1) { t.Fatal(out) } - if tc.name == "failing_panel" && (check.Panels[0].Error != panel.ReadFailure || strings.Contains(result.Content[0].(*mcp.TextContent).Text, "final diagnostic")) { + if tc.name == "failing_panel" && (check.Panels[0].Error != query.ReadFailure || strings.Contains(result.Content[0].(*mcp.TextContent).Text, "final diagnostic")) { t.Fatal("receipt lost the complete sanitized diagnostic") } versions, err := s.dashboards.Versions(t.Context(), "owner", out.Dashboard.ID) @@ -85,15 +85,15 @@ func TestSaveCheckMatchesEverySavedIDRatherThanResultOrder(t *testing.T) { for _, duplicate := range []bool{false, true} { t.Run(map[bool]string{false: "reordered", true: "duplicate"}[duplicate], func(t *testing.T) { s := newToolServer(t, structural{}, nil) - s.panels = receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { + s.panels = receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { id := "notes" if duplicate { id = "b" } - return []panel.Result{{ID: "b", Status: "empty", Diagnosis: "No spans match.", ElapsedMS: 19}, {ID: id, Status: "ok", ElapsedMS: 31}}, nil + return []query.Result{{ID: "b", Status: "empty", Diagnosis: "No spans match.", ElapsedMS: 19}, {ID: id, Status: "ok", ElapsedMS: 31}}, nil }} spec := textDashboard("IDs") - spec.Panels = append(spec.Panels, panel.Panel{ID: "b", Title: "B", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}) + spec.Panels = append(spec.Panels, query.Panel{ID: "b", Title: "B", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}) mutation, err := s.dashboards.CreateWithChanges(t.Context(), "owner", spec, agentAuthor("owner")) if err != nil { t.Fatal(err) @@ -124,9 +124,9 @@ func TestSaveCheckDoesNotAcceptResultsAfterCancellation(t *testing.T) { } ctx, cancel := context.WithCancel(t.Context()) defer cancel() - s.panels = receiptExecutor{run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { + s.panels = receiptExecutor{run: func(context.Context, query.RunRequest) ([]query.Result, error) { cancel() - return []panel.Result{{ID: "notes", Status: "ok"}}, nil + return []query.Result{{ID: "notes", Status: "ok"}}, nil }} _, out, err := s.saved(ctx, "Created", mutation) if err != nil || out.Receipt.SaveCheck.Checked || out.Receipt.SaveCheck.Reason == "" || out.Dashboard.Version != 1 { @@ -168,7 +168,7 @@ func TestConcurrentSaveReceiptIdentifiesItsOwnCommittedVersion(t *testing.T) { t.Fatal(err) } entered, release := make(chan struct{}), make(chan struct{}) - s.panels = receiptExecutor{run: func(ctx context.Context, req panel.RunRequest) ([]panel.Result, error) { + s.panels = receiptExecutor{run: func(ctx context.Context, req query.RunRequest) ([]query.Result, error) { close(entered) select { case <-release: @@ -178,7 +178,7 @@ func TestConcurrentSaveReceiptIdentifiesItsOwnCommittedVersion(t *testing.T) { if req.Dashboard.Panels[0].Content != "first" { t.Error("checked a later writer's spec") } - return []panel.Result{{ID: "notes", Status: "ok", ElapsedMS: 23}}, nil + return []query.Result{{ID: "notes", Status: "ok", ElapsedMS: 23}}, nil }} type answer struct { out dashboardOutput @@ -205,7 +205,7 @@ func TestConcurrentSaveReceiptIdentifiesItsOwnCommittedVersion(t *testing.T) { func TestRemoveReceiptPacksNeighborsWithoutAuthoredChips(t *testing.T) { s := newPanelServer(t) spec := textDashboard("Packing") - spec.Panels = append(spec.Panels, panel.Panel{ID: "b", Title: "B", Viz: "text", Content: "b"}, panel.Panel{ID: "c", Title: "C", Viz: "text", Content: "c"}) + spec.Panels = append(spec.Panels, query.Panel{ID: "b", Title: "B", Viz: "text", Content: "b"}, query.Panel{ID: "c", Title: "C", Viz: "text", Content: "c"}) for i := range spec.Panels { spec.Panels[i].Width = 12 } @@ -225,9 +225,9 @@ func TestRemoveReceiptPacksNeighborsWithoutAuthoredChips(t *testing.T) { func TestSaveReceiptsCheckCommittedPanelsAndAuthoredChanges(t *testing.T) { s := newPanelServer(t) - spec := panel.Dashboard{Name: "Receipt", Panels: []panel.Panel{ + spec := query.Dashboard{Name: "Receipt", Panels: []query.Panel{ {ID: "notes", Title: "Notes", Viz: "text", Content: "Notes."}, - {ID: "requests", Title: "Requests", Viz: "stat", Query: &panel.Query{From: "spans", Measures: []string{"count()"}}}, + {ID: "requests", Title: "Requests", Viz: "stat", Query: &query.Spec{From: "spans", Measures: []string{"count()"}}}, }} result, rejected, err := s.dashboardCreate(t.Context(), ownerRequest(), DashboardCreateInput{Dashboard: spec}) if err != nil || !result.IsError || rejected.Error == nil || rejected.Error.Code != "invalid_spec" || rejected.Dashboard != nil || !strings.Contains(rejected.Error.Message, "panels[1]") || !strings.Contains(rejected.Error.Message, "Requests") || !strings.Contains(rejected.Error.Message, "No spans") { diff --git a/internal/mcp/server.go b/internal/mcp/server.go index ab08d933..4cf25f58 100644 --- a/internal/mcp/server.go +++ b/internal/mcp/server.go @@ -17,7 +17,7 @@ import ( "github.com/labstack/fanout/internal/dashboard" "github.com/labstack/fanout/internal/intelligence" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/toolerror" "github.com/modelcontextprotocol/go-sdk/jsonrpc" "github.com/modelcontextprotocol/go-sdk/mcp" @@ -91,14 +91,14 @@ type LogsInput struct { // panelExecutor keeps execution injectable while production uses the pinned engine. type panelExecutor interface { - Run(context.Context, panel.RunRequest) ([]panel.Result, error) - Validate(context.Context, *panel.Dashboard) error - Schema(context.Context, panel.SchemaRequest) (*panel.Schema, error) - Exemplars(context.Context, panel.ExemplarRequest) (panel.ExemplarResponse, error) - ResolveVariables(context.Context, panel.ResolveRequest) (map[string][]panel.Option, error) + Run(context.Context, query.RunRequest) ([]query.Result, error) + Validate(context.Context, *query.Dashboard) error + Schema(context.Context, query.SchemaRequest) (*query.Schema, error) + Exemplars(context.Context, query.ExemplarRequest) (query.ExemplarResponse, error) + ResolveVariables(context.Context, query.ResolveRequest) (map[string][]query.Option, error) ResolveWindow(time.Time, time.Time) (time.Time, time.Time, error) ServiceGuidance(context.Context, time.Time, time.Time, string, string) (string, error) - EmptyGuidance(context.Context, panel.RunRequest) (string, string, error) + EmptyGuidance(context.Context, query.RunRequest) (string, string, error) } type Server struct { @@ -111,11 +111,11 @@ type Server struct { limitTools map[string]bool } -func NewWithIntelligence(queries Observability, dashboards *dashboard.Service, panels *panel.Executor, snapshots IntelligenceSnapshots, version string) *Server { +func NewWithIntelligence(queries Observability, dashboards *dashboard.Service, panels *query.Executor, snapshots IntelligenceSnapshots, version string) *Server { return newServer(queries, dashboards, panels, snapshots, version) } -func newServer(queries Observability, dashboards *dashboard.Service, panels *panel.Executor, snapshots IntelligenceSnapshots, version string) *Server { +func newServer(queries Observability, dashboards *dashboard.Service, panels *query.Executor, snapshots IntelligenceSnapshots, version string) *Server { s := &Server{ mcp: mcp.NewServer(&mcp.Implementation{ Name: "fanout", @@ -204,12 +204,12 @@ func normalizeToolErrors(next mcp.MethodHandler) mcp.MethodHandler { switch failure := payload["error"].(type) { case *toolerror.Error: if !slices.Contains(alreadyPresented, failure.Code) { - failure.Message = panel.PresentMessage(failure.Message) + failure.Message = query.PresentMessage(failure.Message) } case map[string]any: code, _ := failure["code"].(string) if message, ok := failure["message"].(string); ok && !slices.Contains(alreadyPresented, code) { - failure["message"] = panel.PresentMessage(message) + failure["message"] = query.PresentMessage(message) } } raw, marshalErr := json.Marshal(payload) @@ -463,8 +463,8 @@ func (s *Server) presetFragment(ctx context.Context, input QueryInput, kind, ser return nil, PanelFragment{}, err } d := fragmentPreset(kind, service, input.Namespace, severity, search, input.Limit) - d.Time = panel.Time{From: &scope.Start, To: &scope.End, Refresh: "off"} - out, err := s.executeFragment(ctx, panel.RunRequest{Dashboard: d}) + d.Time = query.Time{From: &scope.Start, To: &scope.End, Refresh: "off"} + out, err := s.executeFragment(ctx, query.RunRequest{Dashboard: d}) if err != nil { return nil, PanelFragment{}, err } @@ -498,12 +498,12 @@ func (s *Server) trace(ctx context.Context, _ *mcp.CallToolRequest, input TraceI return nil, PanelFragment{}, safePanelToolError(err) } d := fragmentPreset("trace", input.Service, input.Namespace, "", "", input.Limit) - d.Time = panel.Time{From: &scope.Start, To: &scope.End, Refresh: "off"} + d.Time = query.Time{From: &scope.Start, To: &scope.End, Refresh: "off"} // A representative lookup is performed once. The list must represent that // selected trace, even when no match exists (empty id cannot show others). id := detail.Data.TraceID d.Panels[0].Query.Where = append(d.Panels[0].Query.Where, "trace_id = '"+strings.ReplaceAll(id, "'", "''")+"'") - out, err := s.executeFragment(ctx, panel.RunRequest{Dashboard: d}) + out, err := s.executeFragment(ctx, query.RunRequest{Dashboard: d}) if err != nil { return nil, PanelFragment{}, err } @@ -528,12 +528,12 @@ func (s *Server) trace(ctx context.Context, _ *mcp.CallToolRequest, input TraceI return summary(fragmentSummary(out)), out, nil } -func allResultsEmpty(results []panel.Result) bool { +func allResultsEmpty(results []query.Result) bool { if len(results) == 0 { return false } for _, result := range results { - if result.Status != panel.StatusEmpty { + if result.Status != query.StatusEmpty { return false } } diff --git a/internal/mcp/server_test.go b/internal/mcp/server_test.go index 2ac57c7c..667c7c57 100644 --- a/internal/mcp/server_test.go +++ b/internal/mcp/server_test.go @@ -10,7 +10,7 @@ import ( "github.com/labstack/fanout/internal/dashboard" "github.com/labstack/fanout/internal/intelligence" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" controlstore "github.com/labstack/fanout/internal/store" mcpgoauth "github.com/modelcontextprotocol/go-sdk/auth" "github.com/modelcontextprotocol/go-sdk/mcp" @@ -20,18 +20,18 @@ type fakeObservability struct { scope observability.Scope } -// structural validates without DuckDB; filter checks live in internal/panel. +// structural validates without DuckDB; filter checks live in internal/query. type structural struct{} -func (structural) Validate(_ context.Context, d *panel.Dashboard) error { - panel.Normalize(d) - if problems := panel.Validate(d); len(problems) > 0 { +func (structural) Validate(_ context.Context, d *query.Dashboard) error { + query.Normalize(d) + if problems := query.Validate(d); len(problems) > 0 { return problems } return nil } -func withName(d panel.Dashboard, name string) panel.Dashboard { +func withName(d query.Dashboard, name string) query.Dashboard { d.Name = name return d } @@ -56,7 +56,7 @@ func TestDashboardToolsUseAuthenticatedOwner(t *testing.T) { } server := NewWithIntelligence(&fakeObservability{}, dashboard.New(database.DB, structural{}), nil, nil, "test") req := &mcp.CallToolRequest{Params: &mcp.CallToolParamsRaw{}, Extra: &mcp.RequestExtra{TokenInfo: &mcpgoauth.TokenInfo{UserID: "owner", Scopes: []string{dashboard.OAuthScope}}}} - spec := panel.Dashboard{Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} + spec := query.Dashboard{Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} _, output, err := server.dashboardCreate(ctx, req, DashboardCreateInput{Dashboard: withName(spec, "AI overview")}) if err != nil { t.Fatal(err) @@ -95,7 +95,7 @@ func TestDashboardOwnerIgnoresSpoofedMetaWhenTokenPresent(t *testing.T) { Params: &mcp.CallToolParamsRaw{Meta: mcp.Meta{dashboard.OwnerMetaKey: "attacker"}}, Extra: &mcp.RequestExtra{TokenInfo: &mcpgoauth.TokenInfo{UserID: "owner", Scopes: []string{dashboard.OAuthScope}}}, } - spec := panel.Dashboard{Panels: []panel.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} + spec := query.Dashboard{Panels: []query.Panel{{ID: "notes", Title: "Notes", Viz: "text", Content: "hello"}}} if _, _, err := server.dashboardCreate(ctx, req, DashboardCreateInput{Dashboard: withName(spec, "Spoof check")}); err != nil { t.Fatal(err) } diff --git a/internal/mcp/service_input_test.go b/internal/mcp/service_input_test.go index c925a1e1..9c577213 100644 --- a/internal/mcp/service_input_test.go +++ b/internal/mcp/service_input_test.go @@ -11,8 +11,8 @@ import ( "unicode/utf8" "github.com/labstack/fanout/internal/config" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" "github.com/labstack/fanout/internal/query" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -20,7 +20,7 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -func serviceInputFixture(t testing.TB) (*Server, *query.Duck, *telemetrystore.Repository, time.Time, time.Time) { +func serviceInputFixture(t testing.TB) (*Server, *engine.Duck, *telemetrystore.Repository, time.Time, time.Time) { t.Helper() cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 4, RollupInterval: time.Hour} repo, err := telemetrystore.Open(cfg.TelemetryDir()) @@ -28,7 +28,7 @@ func serviceInputFixture(t testing.TB) (*Server, *query.Duck, *telemetrystore.Re t.Fatal(err) } t.Cleanup(func() { _ = repo.Close() }) - duck, err := query.NewDuck(t.Context(), cfg, repo) + duck, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -49,7 +49,7 @@ func serviceInputFixture(t testing.TB) (*Server, *query.Duck, *telemetrystore.Re if err := repo.Commit(t.Context(), batch); err != nil { t.Fatal(err) } - executor := panel.NewExecutor(duck, 30) + executor := query.NewExecutor(duck, 30) queries := observability.New(duck, duck, 30) executor.SetRollupReader(queries) s := NewWithIntelligence(queries, nil, executor, nil, "test") @@ -110,13 +110,13 @@ func TestServiceInputsKeepKnownAndIdleServices(t *testing.T) { } continue } - if err != nil || result.IsError || len(out.Results) != 4 || out.Results[3].Status != panel.StatusOK { + if err != nil || result.IsError || len(out.Results) != 4 || out.Results[3].Status != query.StatusOK { t.Fatalf("cached=%v %s: %+v %v", cached, service, out, err) } } } result, out, err := s.logs(t.Context(), nil, LogsInput{Service: "logger", Namespace: "shop", From: &from, To: &to}) - if err != nil || result.IsError || len(out.Results) == 0 || out.Results[0].Status != panel.StatusOK { + if err != nil || result.IsError || len(out.Results) == 0 || out.Results[0].Status != query.StatusOK { t.Fatalf("log-only service lost: %+v %+v %v", result, out, err) } result, out, err = s.trace(t.Context(), nil, TraceInput{Service: "checkout", Namespace: "shop", From: &from, To: &to}) @@ -135,7 +135,7 @@ func (e *serviceGuidanceSpy) ServiceGuidance(ctx context.Context, start, end tim return e.panelExecutor.ServiceGuidance(ctx, start, end, namespace, service) } -func (e *serviceGuidanceSpy) EmptyGuidance(ctx context.Context, req panel.RunRequest) (string, string, error) { +func (e *serviceGuidanceSpy) EmptyGuidance(ctx context.Context, req query.RunRequest) (string, string, error) { for _, p := range req.Dashboard.Panels { if p.Query != nil { for _, f := range p.Query.Where { @@ -194,23 +194,23 @@ func TestServiceInputsValidateOnlyAfterAllResultsEmpty(t *testing.T) { unknown bool empty bool }{ - {name: "unknown", service: "missing", statuses: []string{panel.StatusEmpty, panel.StatusEmpty}, lookups: 1, unknown: true, empty: true}, - {name: "known empty", service: "idle", statuses: []string{panel.StatusEmpty, panel.StatusEmpty}, lookups: 1, empty: true}, - {name: "no service", statuses: []string{panel.StatusEmpty, panel.StatusEmpty}, empty: true}, - {name: "one populated", service: "missing", statuses: []string{panel.StatusEmpty, panel.StatusOK}}, - {name: "panel error", service: "missing", statuses: []string{panel.StatusEmpty, panel.StatusError}}, + {name: "unknown", service: "missing", statuses: []string{query.StatusEmpty, query.StatusEmpty}, lookups: 1, unknown: true, empty: true}, + {name: "known empty", service: "idle", statuses: []string{query.StatusEmpty, query.StatusEmpty}, lookups: 1, empty: true}, + {name: "no service", statuses: []string{query.StatusEmpty, query.StatusEmpty}, empty: true}, + {name: "one populated", service: "missing", statuses: []string{query.StatusEmpty, query.StatusOK}}, + {name: "panel error", service: "missing", statuses: []string{query.StatusEmpty, query.StatusError}}, {name: "execution error", service: "missing", runErr: errors.New("execution failed")}, } { t.Run(tc.name, func(t *testing.T) { ran := false - spy := &serviceGuidanceSpy{panelExecutor: receiptExecutor{panelExecutor: executor, run: func(context.Context, panel.RunRequest) ([]panel.Result, error) { + spy := &serviceGuidanceSpy{panelExecutor: receiptExecutor{panelExecutor: executor, run: func(context.Context, query.RunRequest) ([]query.Result, error) { ran = true if spyCalls := s.panels.(*serviceGuidanceSpy).calls; spyCalls != 0 { t.Errorf("membership ran before preset: %d lookups", spyCalls) } - var results []panel.Result + var results []query.Result for i, status := range tc.statuses { - results = append(results, panel.Result{ID: fmt.Sprint(i), Status: status}) + results = append(results, query.Result{ID: fmt.Sprint(i), Status: status}) } return results, tc.runErr }}} @@ -247,7 +247,7 @@ func TestServiceGuidanceBoundsOversizedName(t *testing.T) { func TestServiceInputsClampWindowBeforeValidation(t *testing.T) { s, duck, repo, _, to := serviceInputFixture(t) - executor := panel.NewExecutor(duck, 7) + executor := query.NewExecutor(duck, 7) queries := observability.New(duck, duck, 7) executor.SetRollupReader(queries) s.panels, s.queries = executor, queries @@ -406,7 +406,7 @@ func BenchmarkServiceInput(b *testing.B) { b.Fatal(err) } d := fragmentPreset("performance", "checkout", "shop", "", "", 0) - d.Time = panel.Time{From: &from, To: &to, Refresh: "off"} + d.Time = query.Time{From: &from, To: &to, Refresh: "off"} for _, name := range []string{"rollup_check", "inventory_check", "unknown_guidance", "preset_baseline", "preset_lazy"} { b.Run(name, func(b *testing.B) { for b.Loop() { @@ -419,7 +419,7 @@ func BenchmarkServiceInput(b *testing.B) { case "unknown_guidance": _, err = s.panels.ServiceGuidance(b.Context(), from, to, "shop", "kafka") case "preset_baseline": - _, _, err = s.runFragment(b.Context(), panel.RunRequest{Dashboard: d}, "preset") + _, _, err = s.runFragment(b.Context(), query.RunRequest{Dashboard: d}, "preset") case "preset_lazy": _, _, err = s.performance(b.Context(), nil, PerformanceInput{Service: "checkout", Namespace: "shop", From: &from, To: &to}) } @@ -460,7 +460,7 @@ func BenchmarkServiceInputRetainedBatches(b *testing.B) { b.Run(name, func(b *testing.B) { for b.Loop() { b.StopTimer() - duck, err := query.NewDuck(b.Context(), cfg, repo) + duck, err := engine.NewDuck(b.Context(), cfg, repo) if err != nil { b.Fatal(err) } @@ -468,7 +468,7 @@ func BenchmarkServiceInputRetainedBatches(b *testing.B) { if err := duck.DB.QueryRow(`SELECT count(*) FROM read_batches`).Scan(&cached); err != nil || cached != 0 { b.Fatalf("expected cold batch cache: %d %v", cached, err) } - executor := panel.NewExecutor(duck, 7) + executor := query.NewExecutor(duck, 7) queries := observability.New(duck, duck, 7) executor.SetRollupReader(queries) s := NewWithIntelligence(queries, nil, executor, nil, "test") @@ -477,7 +477,7 @@ func BenchmarkServiceInputRetainedBatches(b *testing.B) { service = "kafka" } d := fragmentPreset("performance", service, "shop", "", "", 0) - d.Time = panel.Time{From: &from, To: &to, Refresh: "off"} + d.Time = query.Time{From: &from, To: &to, Refresh: "off"} var out PanelFragment var message string b.StartTimer() @@ -487,7 +487,7 @@ func BenchmarkServiceInputRetainedBatches(b *testing.B) { case "cold_unknown_guidance": message, err = executor.ServiceGuidance(b.Context(), from, to, "shop", "kafka") case "cold_preset_baseline", "cold_unknown_baseline": - _, out, err = s.runFragment(b.Context(), panel.RunRequest{Dashboard: d}, "preset") + _, out, err = s.runFragment(b.Context(), query.RunRequest{Dashboard: d}, "preset") case "cold_preset_lazy", "cold_unknown_lazy": _, out, err = s.performance(b.Context(), nil, PerformanceInput{Service: service, Namespace: "shop", From: &from, To: &to}) } @@ -511,9 +511,9 @@ func BenchmarkServiceInputRetainedBatches(b *testing.B) { b.Fatalf("expected four panel results: %+v", out.Results) } for _, result := range out.Results { - want := panel.StatusOK + want := query.StatusOK if name == "cold_unknown_baseline" { - want = panel.StatusEmpty + want = query.StatusEmpty } if result.Status != want { b.Fatalf("preset failed: %+v", result) diff --git a/internal/mcp/tool_errors_test.go b/internal/mcp/tool_errors_test.go index cd72f885..d3581d7d 100644 --- a/internal/mcp/tool_errors_test.go +++ b/internal/mcp/tool_errors_test.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" "github.com/labstack/fanout/internal/observability" - "github.com/labstack/fanout/internal/panel" + "github.com/labstack/fanout/internal/query" "strings" "testing" "time" @@ -25,14 +25,14 @@ func (p pathErrorObservability) Trace(context.Context, observability.Scope, stri func TestMCPRedactsEnginePaths(t *testing.T) { s := NewWithIntelligence(pathErrorObservability{}, nil, nil, nil, "test") _, _, err := s.trace(t.Context(), nil, TraceInput{}) - if err == nil || strings.Contains(err.Error(), "/srv/") || err.Error() != panel.ReadFailure { + if err == nil || strings.Contains(err.Error(), "/srv/") || err.Error() != query.ReadFailure { t.Fatalf("MCP error=%v", err) } } type boundedWriteValidator struct{ t *testing.T } -func (v boundedWriteValidator) Validate(ctx context.Context, _ *panel.Dashboard) error { +func (v boundedWriteValidator) Validate(ctx context.Context, _ *query.Dashboard) error { d, ok := ctx.Deadline() if !ok || time.Until(d) > 20*time.Second { v.t.Errorf("unbounded MCP write: %v %v", d, ok) diff --git a/internal/observability/batch_reads_bench_test.go b/internal/observability/batch_reads_bench_test.go index 79bf60f7..99b246d3 100644 --- a/internal/observability/batch_reads_bench_test.go +++ b/internal/observability/batch_reads_bench_test.go @@ -13,7 +13,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -58,7 +58,7 @@ func TestCompletedReadBenchmark(t *testing.T) { t.Fatal(err) } } - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } diff --git a/internal/observability/batch_reads_test.go b/internal/observability/batch_reads_test.go index dd56fa0b..8d813d9a 100644 --- a/internal/observability/batch_reads_test.go +++ b/internal/observability/batch_reads_test.go @@ -7,26 +7,26 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) -func newCompletedReadTest(t *testing.T) (*query.Duck, *telemetrystore.Repository, *Service) { +func newCompletedReadTest(t *testing.T) (*engine.Duck, *telemetrystore.Repository, *Service) { t.Helper() cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 2, RollupInterval: time.Hour} repo, err := telemetrystore.Open(cfg.TelemetryDir()) if err != nil { t.Fatal(err) } - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = d.Close(); _ = repo.Close() }) return d, repo, New(d, d, 30) } -func warmCompletedReads(t *testing.T, d *query.Duck, want int) { +func warmCompletedReads(t *testing.T, d *engine.Duck, want int) { t.Helper() for attempt := 0; attempt <= want; attempt++ { if _, err := d.RefreshReadCaches(t.Context()); err != nil { diff --git a/internal/observability/dependencies_test.go b/internal/observability/dependencies_test.go index 5d9a0cd4..c374e517 100644 --- a/internal/observability/dependencies_test.go +++ b/internal/observability/dependencies_test.go @@ -4,12 +4,12 @@ import ( "context" "database/sql" "errors" - "github.com/labstack/fanout/internal/query/querytest" + "github.com/labstack/fanout/internal/engine/querytest" "reflect" "testing" "time" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/queryrows" ) @@ -19,10 +19,10 @@ func TestDependenciesKeyedTraversalIsBoundedAndScoped(t *testing.T) { t.Fatal(err) } t.Cleanup(func() { _ = db.Close() }) - if err := querytest.CreateTables(db, query.CreateCacheTables); err != nil { + if err := querytest.CreateTables(db, engine.CreateCacheTables); err != nil { t.Fatal(err) } - if err := query.CreateViews(db); err != nil { + if err := engine.CreateViews(db); err != nil { t.Fatal(err) } start := time.Date(2026, 9, 30, 12, 0, 0, 0, time.UTC) diff --git a/internal/panel/backlog_pressure_test.go b/internal/panel/backlog_pressure_test.go deleted file mode 100644 index 9d627ee6..00000000 --- a/internal/panel/backlog_pressure_test.go +++ /dev/null @@ -1,646 +0,0 @@ -//go:build readbench - -package panel - -import ( - "context" - "errors" - "fmt" - "log/slog" - "os" - "os/exec" - "path/filepath" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "syscall" - "testing" - "time" - - duckdb "github.com/duckdb/duckdb-go/v2" - "github.com/labstack/fanout/internal/annotations" - "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" - "github.com/labstack/fanout/internal/queryrows" - "github.com/labstack/fanout/internal/telemetry" - telemetrystore "github.com/labstack/fanout/internal/telemetry/store" - "github.com/prometheus/client_golang/prometheus" -) - -// The deadline includes seeding. All disposable files stay in the private workspace. -func pressureBatches(t *testing.T) int { - t.Helper() - if raw := os.Getenv("FANOUT_BACKLOG_BATCHES"); raw != "" { - n, err := strconv.Atoi(raw) - if err != nil || n < 1 { - t.Fatalf("invalid FANOUT_BACKLOG_BATCHES %q", raw) - } - return n - } - return 4096 -} -func pressureDuration(t *testing.T) time.Duration { - t.Helper() - if raw := os.Getenv("FANOUT_BACKLOG_DURATION"); raw != "" { - d, err := time.ParseDuration(raw) - if err != nil || d <= 0 { - t.Fatalf("invalid FANOUT_BACKLOG_DURATION %q", raw) - } - return d - } - return 2 * time.Minute -} -func pressureBatch(batch int, base time.Time, live bool) telemetrystore.Batch { - prefix := "pressure" - if live { - prefix = "live" - } - b := telemetrystore.Batch{ID: fmt.Sprintf("%s-%06d", prefix, batch)} - for i := range 512 { - n := base.Add(-24*time.Hour + time.Duration((batch*512+i)%86400)*time.Second).UnixNano() - ingested := base.Add(time.Duration(batch) * time.Millisecond).UnixNano() - if live { - n = base.Add(-time.Second).UnixNano() - if batch%2 == 0 { - n = base.Add(-12 * time.Hour).UnixNano() - } - ingested = base.Add(time.Duration(batch+1) * time.Second).UnixNano() - } - version := "v1" - if i%2 == 0 { - version = "v2" - } - service := fmt.Sprintf("svc%d", i%6) - trace := fmt.Sprintf("%s-trace-%d-%d", prefix, batch, i/4) - b.Spans = append(b.Spans, telemetry.Span{Namespace: "pressure", ServiceName: service, TraceID: trace, SpanID: fmt.Sprintf("s%d", i), StartUnixNanos: n, EndUnixNanos: n + int64(i%1000+1)*1000000, DurationMS: float64(i%1000 + 1), Kind: "SPAN_KIND_SERVER", StatusCode: "STATUS_CODE_OK", ServiceVersion: version, IngestedAt: ingested}) - if i < 192 { - b.Logs = append(b.Logs, telemetry.Log{Namespace: "pressure", ServiceName: service, TraceID: trace, EventUnixNanos: n, TimeUnixNanos: n, IngestedAt: ingested, Body: "request complete", Severity: "INFO"}) - } - } - return b -} -func pressureError(t *testing.T, label string, started time.Time, err error) { - t.Helper() - var native *duckdb.Error - typed := errors.As(err, &native) - kind := "none" - if typed { - kind = fmt.Sprint(native.Type) - } - t.Logf("statement=%s started=%s ended=%s duration=%s error=%v native_type=%s canceled=%t deadline=%t", label, started.UTC().Format(time.RFC3339Nano), time.Now().UTC().Format(time.RFC3339Nano), time.Since(started), err, kind, errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded)) -} - -type pressureLog struct{ t *testing.T } - -func (h pressureLog) Enabled(context.Context, slog.Level) bool { return true } -func (h pressureLog) Handle(_ context.Context, r slog.Record) error { - h.t.Logf("internal_log time=%s level=%s message=%q", r.Time.UTC().Format(time.RFC3339Nano), r.Level, r.Message) - r.Attrs(func(a slog.Attr) bool { - if err, ok := a.Value.Any().(error); ok { - pressureError(h.t, "internal_log/"+r.Message, r.Time, err) - } else { - h.t.Logf("internal_attr %s=%v", a.Key, a.Value) - } - return true - }) - return nil -} -func (h pressureLog) WithAttrs([]slog.Attr) slog.Handler { return h } -func (h pressureLog) WithGroup(string) slog.Handler { return h } - -// Same /proc + ps methodology as processRSSMiB, but unsupported diagnostics -// are reported as inconclusive rather than skipping a pressure test. -var pressureRSSState struct { - sync.Mutex - blocked error -} - -func pressureRSS() (float64, error) { - pressureRSSState.Lock() - defer pressureRSSState.Unlock() - if pressureRSSState.blocked != nil { - return 0, pressureRSSState.blocked - } - if raw, err := os.ReadFile("/proc/self/statm"); err == nil { - f := strings.Fields(string(raw)) - if len(f) > 1 { - n, e := strconv.ParseFloat(f[1], 64) - return n * float64(os.Getpagesize()) / (1 << 20), e - } - } - raw, err := exec.Command("ps", "-o", "rss=", "-p", strconv.Itoa(os.Getpid())).Output() - if err != nil { - pressureRSSState.blocked = err - return 0, err - } - n, err := strconv.ParseFloat(strings.TrimSpace(string(raw)), 64) - return n / 1024, err -} -func pressureDiagnostics(ctx context.Context, t *testing.T, d *query.Duck, repo *telemetrystore.Repository, phase string) { - t.Helper() - stats := d.DB.Stats() - var usage syscall.Rusage - cpuErr := syscall.Getrusage(syscall.RUSAGE_SELF, &usage) - cpuSeconds := float64(usage.Utime.Sec+usage.Stime.Sec) + float64(usage.Utime.Usec+usage.Stime.Usec)/1e6 - t.Logf("cpu phase=%s seconds=%.6f error=%v", phase, cpuSeconds, cpuErr) - rss, rssErr := pressureRSS() - var goMem runtime.MemStats - runtime.ReadMemStats(&goMem) - t.Logf("diagnostics phase=%s platform=%s/%s cpus=%d rss_mib=%.2f rss_error=%v go_heap_bytes=%d go_total_alloc_bytes=%d read_pool=%+v", phase, runtime.GOOS, runtime.GOARCH, runtime.NumCPU(), rss, rssErr, goMem.HeapAlloc, goMem.TotalAlloc, stats) - files, err := repo.Parquet.Stats() - t.Logf("files phase=%s stats=%+v error=%v active_batches=%d rows=%d", phase, files, err, len(repo.Parquet.BatchMetadata()), repo.RowCount()) - // Never queue diagnostics behind the pressure workers. Five read slots are - // fixed for all phases; busy samples are recorded and retried between phases. - if stats.InUse >= stats.MaxOpenConnections { - t.Logf("diagnostics phase=%s sql_sample=busy", phase) - return - } - ctx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - for _, q := range []string{ - "SELECT version(),current_setting('memory_limit'),current_setting('threads'),current_setting('temp_directory')<>''", - "SELECT tag,memory_usage_bytes,temporary_storage_bytes FROM duckdb_memory() ORDER BY tag", - "SELECT coalesce(sum(size),0) FROM duckdb_temporary_files()", - "SELECT cache_key,last_ingested_unix_nano FROM rollup_state ORDER BY cache_key", - "SELECT (SELECT count(*) FROM read_batches),(SELECT count(*) FROM version_rollup_batches),(SELECT count(*) FROM version_rollup),(SELECT count(*) FROM anomaly_log)", - } { - rows, err := d.DB.QueryContext(ctx, q) - if err != nil { - pressureError(t, "diagnostics/"+q, time.Now(), err) - continue - } - cols, err := rows.Columns() - if err != nil { - rows.Close() - t.Logf("diagnostic_columns error=%v", err) - continue - } - for rows.Next() { - v := make([]any, len(cols)) - p := make([]any, len(cols)) - for i := range v { - p[i] = &v[i] - } - if err := rows.Scan(p...); err != nil { - t.Logf("diagnostic_scan error=%v", err) - break - } - t.Logf("diagnostic phase=%s columns=%v values=%v", phase, cols, v) - } - if err := rows.Err(); err != nil { - pressureError(t, "diagnostics/rows", time.Now(), err) - } - rows.Close() - } - families, err := prometheus.DefaultGatherer.Gather() - if err != nil { - t.Logf("metrics error=%v", err) - return - } - for _, f := range families { - if f.GetName() == "fanout_write_gate_wait_seconds" || f.GetName() == "fanout_write_gate_hold_seconds" { - for _, m := range f.Metric { - t.Logf("gate phase=%s metric=%s labels=%v count=%d seconds_sum=%.6f", phase, f.GetName(), m.Label, m.GetHistogram().GetSampleCount(), m.GetHistogram().GetSampleSum()) - } - } - } -} - -func pressurePanelSeed(ctx context.Context, t *testing.T, batches int) (*query.Duck, *telemetrystore.Repository, time.Time) { - t.Helper() - root, err := filepath.Abs(filepath.Join("..", "..", ".cache", "readbench")) - if err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(root, 0755); err != nil { - t.Fatal(err) - } - dir, err := os.MkdirTemp(root, "pressure-") - if err != nil { - t.Fatal(err) - } - t.Logf("scratch_state=%s", dir) - base := time.Now().UTC().Truncate(time.Minute) - cfg := config.Config{DataDir: dir, RetentionDays: 30, DuckDBMemory: "4GB", DuckDBThreads: 4, DuckDBMaxConns: 5, RollupInterval: time.Second} - repo, err := telemetrystore.Open(cfg.TelemetryDir()) - if err != nil { - t.Fatal(err) - } - t.Cleanup(func() { - if err := repo.Close(); err != nil { - t.Errorf("repository close: %v", err) - } - }) - started := time.Now() - seeded := 0 - defer func() { - if seeded != batches { - t.Logf("seed_duration=%s seed_batches=%d requested=%d seed_incomplete=true", time.Since(started), seeded, batches) - } - }() - for batch := range batches { - if err := ctx.Err(); err != nil { - t.Fatal(err) - } - if err := repo.Commit(ctx, pressureBatch(batch, base, false)); err != nil { - t.Fatal(err) - } - seeded++ - if seeded%256 == 0 { - t.Logf("seed_progress batches=%d duration=%s", seeded, time.Since(started)) - } - } - t.Logf("seed_complete duration=%s spans=%d logs=%d", time.Since(started), batches*512, batches*192) - opened := time.Now() - d, err := query.NewDuck(ctx, cfg, repo) - pressureError(t, "NewDuck", opened, err) - if err != nil { - t.Fatal(err) - } - t.Cleanup(func() { - if err := d.Close(); err != nil { - t.Errorf("engine close: %v", err) - } - }) - return d, repo, base -} - -func pressurePanelDuck(ctx context.Context, t *testing.T, batches int) (*query.Duck, *telemetrystore.Repository, time.Time, time.Time) { - d, repo, base := pressurePanelSeed(ctx, t, batches) - return d, repo, base.Add(-24 * time.Hour), base -} -func pressureSpec(start, end time.Time) Dashboard { - return Dashboard{Name: "Backlog pressure", Time: Time{From: &start, To: &end}, Panels: []Panel{ - {ID: "table", Title: "Service counts", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, - {ID: "count", Title: "Span count", Viz: "stat", Query: &Query{From: "spans", Measures: []string{"count()"}}}, - {ID: "p95", Title: "Latency", Viz: "table", Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}}}, - {ID: "logs", Title: "Log count", Viz: "stat", Query: &Query{From: "logs", Measures: []string{"count()"}}}, - }} -} - -// Diagnostic runs precede the behavior regression so the actual failure, not -// an assumed batch count, selects its frozen workload. -func TestBacklogPressureMeasuresWindowedConcurrency(t *testing.T) { runPanelPressure(t, false) } -func TestPanelsRemainUsableDuringBacklog(t *testing.T) { runPanelPressure(t, true) } -func runPanelPressure(t *testing.T, assertUsable bool) { - ctx, cancel := context.WithTimeout(t.Context(), 30*time.Minute) - defer cancel() - batches := pressureBatches(t) - d, repo, start, end := pressurePanelDuck(ctx, t, batches) - logger := slog.Default() - slog.SetDefault(slog.New(pressureLog{t})) - defer slog.SetDefault(logger) - spec := pressureSpec(start, end) - observed := pressurePanelEngine{Duck: d, record: func(c context.Context, stage, q string, started time.Time, err error) { - pressureError(t, "panel_sql/"+stage, started, err) - t.Logf("failed_sql stage=%s sql=%q ctx_error=%v", stage, q, c.Err()) - }} - executor := NewExecutor(observed, 30) - pressureDiagnostics(ctx, t, d, repo, "before_panels_alone") - var failed, requests, published, versions, anomalies, anomalyDropped atomic.Int64 - run := func(c context.Context, phase string, worker int) []Result { - started := time.Now() - results, err := executor.Run(c, RunRequest{Dashboard: spec}) - requests.Add(1) - pressureError(t, fmt.Sprintf("executor/%s/%d", phase, worker), started, err) - if err != nil { - failed.Add(1) - } - for _, r := range results { - t.Logf("panel phase=%s worker=%d id=%s status=%s elapsed_ms=%d error=%q", phase, worker, r.ID, r.Status, r.ElapsedMS, r.Error) - if r.Status == StatusError { - failed.Add(1) - } - } - return results - } - // Four concurrent dashboard requests retain the executor's production - // fanout. When internal reads occupy the fifth slot, diagnostics defer - // their SQL samples until the workers have joined. - worker := func(c context.Context, phase string, id int) { - for c.Err() == nil { - started := time.Now() - results, err := executor.Run(c, RunRequest{Dashboard: spec}) - requests.Add(1) - pressureError(t, fmt.Sprintf("executor/%s/%d", phase, id), started, err) - if err != nil && c.Err() == nil { - failed.Add(1) - } - for _, r := range results { - t.Logf("panel phase=%s worker=%d id=%s status=%s elapsed_ms=%d error=%q sql=%q", phase, id, r.ID, r.Status, r.ElapsedMS, r.Error, r.SQL) - if r.Status == StatusError && c.Err() == nil { - failed.Add(1) - } - } - select { - case <-c.Done(): - return - case <-time.After(time.Second): - } - } - } - solo, stopSolo := context.WithTimeout(ctx, 30*time.Second) - var soloWG sync.WaitGroup - soloReady := make(chan struct{}) - for i := range 4 { - soloWG.Add(1) - go func() { defer soloWG.Done(); <-soloReady; worker(solo, "alone", i) }() - } - close(soloReady) - soloWG.Wait() - stopSolo() - pressureDiagnostics(ctx, t, d, repo, "after_panels_alone") - workloadStarted := time.Now() - work, stopWork := context.WithTimeout(ctx, pressureDuration(t)) - defer stopWork() - loop, stopLoop := context.WithCancel(ctx) - loopDone := make(chan struct{}) - ready := make(chan struct{}) - var wg sync.WaitGroup - go func() { <-ready; defer close(loopDone); d.RunRollups(loop) }() - for i := range 4 { - wg.Add(1) - go func() { defer wg.Done(); <-ready; worker(work, "combined", i) }() - } - wg.Add(1) - go func() { - defer wg.Done() - <-ready - for batch := range 32 { - if work.Err() != nil { - return - } - started := time.Now() - err := repo.Commit(work, pressureBatch(batch, end, true)) - pressureError(t, "publication/combined", started, err) - if err != nil { - failed.Add(1) - return - } - published.Add(1) - select { - case <-work.Done(): - return - case <-time.After(pressureDuration(t) / 32): - } - } - }() - wg.Add(1) - go func() { - defer wg.Done() - <-ready - for work.Err() == nil { - started := time.Now() - n, err := d.RefreshVersionRollup(work) - pressureError(t, "version_rollup/combined", started, err) - versions.Add(n) - if err != nil && work.Err() == nil { - failed.Add(1) - } - select { - case <-work.Done(): - return - case <-time.After(time.Second): - } - } - }() - wg.Add(1) - go func() { - defer wg.Done() - <-ready - for work.Err() == nil { - started := time.Now() - err := d.RecordAnomalies(work, []annotations.Anomaly{{Namespace: "pressure", Service: "svc0", Kind: "latency", From: end.Add(-time.Minute), To: end, Title: "Pressure probe", Severity: "warning"}}, end) - pressureError(t, "anomaly_log/combined", started, err) - // The detector writes a batch that misses the write gate with its - // next batch, so admission timeouts here are delays, counted - // separately. Any other anomaly error fails. - switch { - case err == nil: - anomalies.Add(1) - case work.Err() != nil: - case errors.Is(err, context.DeadlineExceeded) && strings.Contains(err.Error(), "anomaly_log/write_gate"): - anomalyDropped.Add(1) - default: - failed.Add(1) - } - select { - case <-work.Done(): - return - case <-time.After(time.Second): - } - } - }() - // RSS sampling does not consume an engine connection. SQL diagnostics are - // sampled only when a slot is available, and again after workers join. - wg.Add(1) - var peakRSS float64 - go func() { - defer wg.Done() - <-ready - ticker := time.NewTicker(5 * time.Second) - defer ticker.Stop() - for { - rss, err := pressureRSS() - peakRSS = max(peakRSS, rss) - t.Logf("rss_sample mib=%.2f error=%v read_pool=%+v", rss, err, d.DB.Stats()) - select { - case <-work.Done(): - return - case <-ticker.C: - pressureDiagnostics(work, t, d, repo, "combined") - } - } - }() - close(ready) - wg.Wait() - stopWork() - t.Logf("workload_duration=%s requests=%d published=%d version_batches=%d anomaly_writes=%d failures=%d peak_rss_mib=%.2f", time.Since(workloadStarted), requests.Load(), published.Load(), versions.Load(), anomalies.Load(), failed.Load(), peakRSS) - pressureDiagnostics(ctx, t, d, repo, "after_workers") - var visibleVersions, visibleAnomalies int64 - progressCtx, stopProgress := context.WithTimeout(ctx, 5*time.Second) - progressErr := d.DB.QueryRowContext(progressCtx, "SELECT (SELECT count(*) FROM version_rollup),(SELECT count(*) FROM anomaly_log)").Scan(&visibleVersions, &visibleAnomalies) - stopProgress() - t.Logf("pressure_progress visible_versions=%d visible_anomalies=%d error=%v", visibleVersions, visibleAnomalies, progressErr) - // The drain remains finite, with RunRollups still running. Marker equality - // uses active immutable batch IDs because compaction may retire inputs. - drainStarted := time.Now() - drain, stopDrain := context.WithTimeout(ctx, 3*time.Minute) - drained := false - for drain.Err() == nil { - active := repo.Parquet.BatchMetadata() - var cached, marked int64 - err := d.DB.QueryRowContext(drain, "SELECT (SELECT count(*) FROM read_batches),(SELECT count(*) FROM version_rollup_batches)").Scan(&cached, &marked) - t.Logf("drain active=%d cached=%d version_marked=%d error=%v", len(active), cached, marked, err) - if err == nil && cached == int64(len(active)) && marked == int64(len(active)) { - var behind int - err = d.DB.QueryRowContext(drain, "SELECT count(*) FROM rollup_state WHERE cache_key='service_rollup_v3' AND last_ingested_unix_nano >= ?", end.Add(time.Duration(published.Load())*time.Second).UnixNano()).Scan(&behind) - if err == nil && behind == 1 { - drained = true - break - } - } - select { - case <-drain.Done(): - case <-time.After(time.Second): - } - } - stopDrain() - stopLoop() - <-loopDone - pressureDiagnostics(ctx, t, d, repo, "after_drain") - finalResults := run(ctx, "after_drain", 0) - exactCtx, stopExact := context.WithTimeout(ctx, 30*time.Second) - defer stopExact() - var spanCount, logCount, rolledSpans, rolledLogs int64 - err := d.DB.QueryRowContext(exactCtx, "SELECT coalesce(sum(spans),0),coalesce(sum(log_count),0) FROM service_rollup WHERE namespace='pressure'").Scan(&rolledSpans, &rolledLogs) - pressureError(t, "service_rollup/exact_counts", time.Now(), err) - for _, b := range repo.Parquet.BatchMetadata() { - spanCount += int64(b.Spans) - logCount += int64(b.Logs) - } - expectedSpans := int64(batches)*512 + published.Load()*512 - expectedLogs := int64(batches)*192 + published.Load()*192 - t.Logf("outcome drained=%t drain_duration=%s failures=%d expected_spans=%d active_spans=%d rolled_spans=%d expected_logs=%d active_logs=%d rolled_logs=%d versions_processed=%d anomaly_writes=%d", drained, time.Since(drainStarted), failed.Load(), expectedSpans, spanCount, rolledSpans, expectedLogs, logCount, rolledLogs, versions.Load(), anomalies.Load()) - rawExact := true - for _, r := range finalResults { - if r.ID != "count" && r.ID != "logs" { - continue - } - expected := expectedSpans - if r.ID == "logs" { - expected = expectedLogs - } - if !pressureExactCount(t, r, expected) { - rawExact = false - } - } - if len(finalResults) != len(spec.Panels) { - rawExact = false - } - t.Logf("anomaly_admission_dropped=%d", anomalyDropped.Load()) - if assertUsable { - if failed.Load() > 0 { - t.Errorf("panel/publication/version/anomaly failures=%d", failed.Load()) - } - if anomalies.Load() == 0 { - t.Error("no anomaly write succeeded under backlog") - } - if !drained || !rawExact || err != nil || spanCount != expectedSpans || logCount != expectedLogs || rolledSpans != expectedSpans || rolledLogs != expectedLogs { - t.Error("backlog did not drain with exact counts") - } - if progressErr != nil || visibleVersions == 0 || visibleAnomalies == 0 { - t.Error("no bounded version/anomaly progress during pressure") - } - } else { - t.Log("outcome=diagnostic; a finite run without a defect is INCONCLUSIVE, not a robustness PASS") - } -} - -func pressureExactCount(t *testing.T, r Result, expected int64) bool { - t.Helper() - if r.Status != StatusOK || r.Frame == nil || len(r.Frame.Totals) != len(r.Frame.Columns) { - t.Logf("raw_exact id=%s invalid_frame=true", r.ID) - return false - } - for i, c := range r.Frame.Columns { - if c.Role != "measure" || c.Name != "count" { - continue - } - value, err := strconv.ParseFloat(fmt.Sprint(r.Frame.Totals[i]), 64) - t.Logf("raw_exact id=%s count=%v expected=%d error=%v", r.ID, r.Frame.Totals[i], expected, err) - return err == nil && value == float64(expected) - } - t.Logf("raw_exact id=%s missing_count_measure=true", r.ID) - return false -} -func TestBacklogCountsReadWholeWindowMeasureTotals(t *testing.T) { - ctx, cancel := context.WithTimeout(t.Context(), time.Minute) - defer cancel() - d, _, start, end := pressurePanelDuck(ctx, t, 1) - results, err := NewExecutor(d, 30).Run(ctx, RunRequest{Dashboard: pressureSpec(start, end)}) - if err != nil { - t.Fatal(err) - } - checked := 0 - for _, r := range results { - if r.ID == "count" { - checked++ - if !pressureExactCount(t, r, 512) { - t.Fatal("incorrect span total") - } - } - if r.ID == "logs" { - checked++ - if !pressureExactCount(t, r, 192) { - t.Fatal("incorrect log total") - } - } - } - if checked != 2 { - t.Fatalf("missing count results: %v", results) - } -} - -// The proxy preserves the native engine and window context. It observes the -// actual failing SQL, including a stat's separate whole-window total query. -type pressurePanelEngine struct { - *query.Duck - record func(context.Context, string, string, time.Time, error) -} - -func (e pressurePanelEngine) QueryContext(ctx context.Context, q string, args ...any) (queryrows.Rows, error) { - started := time.Now() - rows, err := e.Duck.QueryContext(ctx, q, args...) - if err != nil { - e.record(ctx, "query", q, started, err) - return rows, err - } - return &pressurePanelRows{Rows: rows, ctx: ctx, q: q, started: started, record: e.record}, nil -} -func TestBacklogPanelErrorsIdentifyActualSQLAndKeepNativeCause(t *testing.T) { - ctx, cancel := context.WithTimeout(t.Context(), time.Minute) - defer cancel() - d, _, start, end := pressurePanelDuck(ctx, t, 1) - q := "SELECT missing_pressure_column FROM spans WHERE start_time>=?::TIMESTAMP_NS::TIMESTAMPTZ_NS AND start_time= ?", end.Add(time.Duration(published.Load())*time.Second).UnixNano()).Scan(&behind) + if err == nil && behind == 1 { + drained = true + break + } + } + select { + case <-drain.Done(): + case <-time.After(time.Second): + } + } + stopDrain() + stopLoop() + <-loopDone + pressureDiagnostics(ctx, t, d, repo, "after_drain") + finalResults := run(ctx, "after_drain", 0) + exactCtx, stopExact := context.WithTimeout(ctx, 30*time.Second) + defer stopExact() + var spanCount, logCount, rolledSpans, rolledLogs int64 + err := d.DB.QueryRowContext(exactCtx, "SELECT coalesce(sum(spans),0),coalesce(sum(log_count),0) FROM service_rollup WHERE namespace='pressure'").Scan(&rolledSpans, &rolledLogs) + pressureError(t, "service_rollup/exact_counts", time.Now(), err) + for _, b := range repo.Parquet.BatchMetadata() { + spanCount += int64(b.Spans) + logCount += int64(b.Logs) + } + expectedSpans := int64(batches)*512 + published.Load()*512 + expectedLogs := int64(batches)*192 + published.Load()*192 + t.Logf("outcome drained=%t drain_duration=%s failures=%d expected_spans=%d active_spans=%d rolled_spans=%d expected_logs=%d active_logs=%d rolled_logs=%d versions_processed=%d anomaly_writes=%d", drained, time.Since(drainStarted), failed.Load(), expectedSpans, spanCount, rolledSpans, expectedLogs, logCount, rolledLogs, versions.Load(), anomalies.Load()) + rawExact := true + for _, r := range finalResults { + if r.ID != "count" && r.ID != "logs" { + continue + } + expected := expectedSpans + if r.ID == "logs" { + expected = expectedLogs + } + if !pressureExactCount(t, r, expected) { + rawExact = false + } + } + if len(finalResults) != len(spec.Panels) { + rawExact = false + } + t.Logf("anomaly_admission_dropped=%d", anomalyDropped.Load()) + if assertUsable { + if failed.Load() > 0 { + t.Errorf("panel/publication/version/anomaly failures=%d", failed.Load()) + } + if anomalies.Load() == 0 { + t.Error("no anomaly write succeeded under backlog") + } + if !drained || !rawExact || err != nil || spanCount != expectedSpans || logCount != expectedLogs || rolledSpans != expectedSpans || rolledLogs != expectedLogs { + t.Error("backlog did not drain with exact counts") + } + if progressErr != nil || visibleVersions == 0 || visibleAnomalies == 0 { + t.Error("no bounded version/anomaly progress during pressure") + } + } else { + t.Log("outcome=diagnostic; a finite run without a defect is INCONCLUSIVE, not a robustness PASS") } } -func TestBacklogAnnotationFailuresIdentifyStatementAndPreserveCause(t *testing.T) { +func pressureExactCount(t *testing.T, r Result, expected int64) bool { + t.Helper() + if r.Status != StatusOK || r.Frame == nil || len(r.Frame.Totals) != len(r.Frame.Columns) { + t.Logf("raw_exact id=%s invalid_frame=true", r.ID) + return false + } + for i, c := range r.Frame.Columns { + if c.Role != "measure" || c.Name != "count" { + continue + } + value, err := strconv.ParseFloat(fmt.Sprint(r.Frame.Totals[i]), 64) + t.Logf("raw_exact id=%s count=%v expected=%d error=%v", r.ID, r.Frame.Totals[i], expected, err) + return err == nil && value == float64(expected) + } + t.Logf("raw_exact id=%s missing_count_measure=true", r.ID) + return false +} +func TestBacklogCountsReadWholeWindowMeasureTotals(t *testing.T) { ctx, cancel := context.WithTimeout(t.Context(), time.Minute) defer cancel() - _, repo, _ := pressureDuck(ctx, t, 1) - for _, label := range []string{"version_rollup/insert", "anomaly_log/bounds", "anomaly_log/insert"} { - t.Run(label, func(t *testing.T) { - db, mock, err := sqlmock.New() - if err != nil { - t.Fatal(err) - } - defer db.Close() - cause := &duckdb.Error{Type: duckdb.ErrorTypeOutOfMemory, Msg: "Out of Memory Error: attribution fixture"} - d := &Duck{DB: db, writeDB: db, repository: repo} - if label == "version_rollup/insert" { - mock.ExpectQuery("SELECT batch_id FROM version_rollup_batches").WillReturnRows(sqlmock.NewRows([]string{"batch_id"})) - mock.ExpectBegin() - mock.ExpectExec("INSERT INTO version_rollup SELECT").WillReturnError(cause) - mock.ExpectRollback() - _, err = d.RefreshVersionRollup(ctx) - } else { - mock.ExpectBegin() - if label == "anomaly_log/bounds" { - mock.ExpectExec("CREATE TEMP TABLE annotation_bounds").WillReturnError(cause) - } else { - mock.ExpectExec("CREATE TEMP TABLE annotation_bounds").WillReturnResult(sqlmock.NewResult(0, 0)) - mock.ExpectQuery("SELECT a.namespace").WillReturnRows(sqlmock.NewRows([]string{"namespace", "service", "kind", "start", "end", "title", "severity"})) - for _, q := range []string{"CREATE TEMP TABLE annotation_updates", "CREATE TEMP TABLE annotation_candidates"} { - mock.ExpectExec(q).WillReturnResult(sqlmock.NewResult(0, 0)) - } - mock.ExpectQuery("SELECT count").WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) - mock.ExpectExec("DELETE FROM anomaly_log").WillReturnResult(sqlmock.NewResult(0, 0)) - mock.ExpectExec("INSERT INTO anomaly_log").WillReturnError(cause) - } - mock.ExpectRollback() - now := time.Now().UTC() - err = d.RecordAnomalies(ctx, []annotations.Anomaly{{Namespace: "pressure", Service: "svc0", Kind: "latency", From: now.Add(-time.Minute), To: now, Title: "Attribution", Severity: "warning"}}, now) - } - var native *duckdb.Error - if err == nil || !strings.Contains(err.Error(), label) || !errors.Is(err, cause) || !errors.As(err, &native) || native != cause { - t.Fatalf("statement attribution/cause lost: %v", err) + d, _, start, end := pressurePanelDuck(ctx, t, 1) + results, err := NewExecutor(d, 30).Run(ctx, RunRequest{Dashboard: pressureSpec(start, end)}) + if err != nil { + t.Fatal(err) + } + checked := 0 + for _, r := range results { + if r.ID == "count" { + checked++ + if !pressureExactCount(t, r, 512) { + t.Fatal("incorrect span total") } - if err := mock.ExpectationsWereMet(); err != nil { - t.Fatal(err) + } + if r.ID == "logs" { + checked++ + if !pressureExactCount(t, r, 192) { + t.Fatal("incorrect log total") } - }) + } + } + if checked != 2 { + t.Fatalf("missing count results: %v", results) } } -func TestBacklogAnnotationTimeoutsIdentifyWriteGateAndPreserveDeadline(t *testing.T) { - for _, label := range []string{"version_rollup/write_gate", "anomaly_log/write_gate"} { - t.Run(label, func(t *testing.T) { - d := &Duck{repository: &telemetrystore.Repository{}} - unlock := d.writeGate.Lock(writegate.RollupService) - defer unlock() - ctx, cancel := context.WithTimeout(t.Context(), 20*time.Millisecond) - defer cancel() - var err error - if label == "version_rollup/write_gate" { - _, err = d.RefreshVersionRollup(ctx) - } else { - err = d.RecordAnomalies(ctx, nil, time.Now()) - } - if err == nil || !strings.Contains(err.Error(), label) || !errors.Is(err, context.DeadlineExceeded) { - t.Fatalf("gate attribution/deadline lost: %v", err) - } - }) +// The proxy preserves the native engine and window context. It observes the +// actual failing SQL, including a stat's separate whole-window total engine. +type pressurePanelEngine struct { + *engine.Duck + record func(context.Context, string, string, time.Time, error) +} + +func (e pressurePanelEngine) QueryContext(ctx context.Context, q string, args ...any) (queryrows.Rows, error) { + started := time.Now() + rows, err := e.Duck.QueryContext(ctx, q, args...) + if err != nil { + e.record(ctx, "query", q, started, err) + return rows, err } + return &pressurePanelRows{Rows: rows, ctx: ctx, q: q, started: started, record: e.record}, nil +} +func TestBacklogPanelErrorsIdentifyActualSQLAndKeepNativeCause(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), time.Minute) + defer cancel() + d, _, start, end := pressurePanelDuck(ctx, t, 1) + q := "SELECT missing_pressure_column FROM spans WHERE start_time>=?::TIMESTAMP_NS::TIMESTAMPTZ_NS AND start_time CAST($service AS VARCHAR)") spec.Panels = append(spec.Panels, - Panel{ID: "unbindable", Title: "Unbindable", Viz: "stat", Query: &Query{From: "spans", Measures: []string{"count()"}, Where: []string{ + Panel{ID: "unbindable", Title: "Unbindable", Viz: "stat", Query: &Spec{From: "spans", Measures: []string{"count()"}, Where: []string{ "duration_ms > CAST($service AS VARCHAR)", "start_time > 5", "duration_ms > $service", diff --git a/internal/panel/compile.go b/internal/query/compile.go similarity index 99% rename from internal/panel/compile.go rename to internal/query/compile.go index 2bf13e6e..25c3bc55 100644 --- a/internal/panel/compile.go +++ b/internal/query/compile.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" diff --git a/internal/panel/compile_expr_test.go b/internal/query/compile_expr_test.go similarity index 99% rename from internal/panel/compile_expr_test.go rename to internal/query/compile_expr_test.go index 8d005f59..6372c574 100644 --- a/internal/panel/compile_expr_test.go +++ b/internal/query/compile_expr_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/compile_test.go b/internal/query/compile_test.go similarity index 91% rename from internal/panel/compile_test.go rename to internal/query/compile_test.go index 8bd89c19..14131cd0 100644 --- a/internal/panel/compile_test.go +++ b/internal/query/compile_test.go @@ -1,9 +1,9 @@ -package panel +package query import ( "math" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" "reflect" @@ -34,7 +34,7 @@ func filter(expr string, params ...string) Filter { } func TestCompileTimeseriesBindsVariables(t *testing.T) { - p := &Panel{ID: "latency", Viz: "timeseries", Query: &Query{From: "spans", Bucket: "1m"}} + p := &Panel{ID: "latency", Viz: "timeseries", Query: &Spec{From: "spans", Bucket: "1m"}} scope := Scope{Start: compileStart, End: compileEnd, Interval: time.Minute, Vars: map[string]Value{"service": {Values: []string{"x'); DROP TABLE spans; --"}}}} got, err := compileQuery(p, measuresOf(t, "spans", "p50(duration_ms)", "p95(duration_ms)"), []Filter{filter("(service = CAST($service AS VARCHAR))", "service"), filter("(kind = 'SPAN_KIND_SERVER')")}, scope) if err != nil { @@ -57,7 +57,7 @@ func TestCompileTimeseriesBindsVariables(t *testing.T) { } func TestCompileGroupedSeriesFoldsIntoOther(t *testing.T) { - p := &Panel{ID: "rps", Viz: "timeseries", Options: &Options{Top: 3}, Query: &Query{From: "spans", By: []string{"service"}, Bucket: "5m"}} + p := &Panel{ID: "rps", Viz: "timeseries", Options: &Options{Top: 3}, Query: &Spec{From: "spans", By: []string{"service"}, Bucket: "5m"}} got, err := compileQuery(p, measuresOf(t, "spans", "rate()"), nil, Scope{Start: compileStart, End: compileEnd, Interval: 5 * time.Minute}) if err != nil { t.Fatal(err) @@ -71,7 +71,7 @@ func TestCompileGroupedSeriesFoldsIntoOther(t *testing.T) { } func TestCompileTableDropsAllAndSorts(t *testing.T) { - p := &Panel{ID: "routes", Viz: "table", Query: &Query{From: "spans", By: []string{"attributes['http.route']"}, Sort: "count", Limit: 5}} + p := &Panel{ID: "routes", Viz: "table", Query: &Spec{From: "spans", By: []string{"attributes['http.route']"}, Sort: "count", Limit: 5}} scope := Scope{Start: compileStart, End: compileEnd, Vars: map[string]Value{"service": {All: true}}} got, err := compileQuery(p, measuresOf(t, "spans", "error_rate()", "count()"), []Filter{filter("(service = CAST($service AS VARCHAR))", "service")}, scope) if err != nil { @@ -88,7 +88,7 @@ func TestCompileTableDropsAllAndSorts(t *testing.T) { } func TestCompileMultiValueAndEmptySelection(t *testing.T) { - p := &Panel{ID: "n", Viz: "stat", Query: &Query{From: "spans"}} + p := &Panel{ID: "n", Viz: "stat", Query: &Spec{From: "spans"}} in := Filter{Expr: "(http_route IN (CAST($routes AS VARCHAR)))", Source: "http_route IN $routes", Params: []string{"routes"}, InParams: map[string]bool{"routes": true}} got, err := compileQuery(p, measuresOf(t, "spans", "count()"), []Filter{in}, Scope{Start: compileStart, End: compileEnd, Vars: map[string]Value{"routes": {Values: []string{"/a", "/b"}}}}) if err != nil { @@ -105,7 +105,7 @@ func TestCompileMultiValueAndEmptySelection(t *testing.T) { } func TestCompileShareAndLogs(t *testing.T) { - p := &Panel{ID: "sev", Viz: "timeseries", Query: &Query{From: "logs", By: []string{"severity"}, Bucket: "1m"}} + p := &Panel{ID: "sev", Viz: "timeseries", Query: &Spec{From: "logs", By: []string{"severity"}, Bucket: "1m"}} got, err := compileQuery(p, measuresOf(t, "logs", "share()"), nil, Scope{Start: compileStart, End: compileEnd, Interval: time.Minute}) if err != nil { t.Fatal(err) @@ -118,7 +118,7 @@ func TestCompileShareAndLogs(t *testing.T) { } } -func runCompiled(t *testing.T, d *query.Duck, c Compiled, start, end time.Time) [][]any { +func runCompiled(t *testing.T, d *engine.Duck, c Compiled, start, end time.Time) [][]any { t.Helper() ctx := queryrows.WithWindow(t.Context(), queryrows.Window{Start: start, End: end}) rows, err := d.QueryContext(ctx, c.SQL, c.Args...) @@ -156,7 +156,7 @@ func TestCompiledQueriesRunOnTheEngine(t *testing.T) { commit(t, repo, shopSpans(), logs) end := fixtureStart.Add(time.Hour) - p := &Panel{ID: "rps", Viz: "timeseries", Options: &Options{Top: 3}, Query: &Query{From: "spans", By: []string{"service"}, Bucket: "5m"}} + p := &Panel{ID: "rps", Viz: "timeseries", Options: &Options{Top: 3}, Query: &Spec{From: "spans", By: []string{"service"}, Bucket: "5m"}} c, err := compileQuery(p, measuresOf(t, "spans", "rate()"), nil, Scope{Start: fixtureStart, End: end, Interval: 5 * time.Minute}) if err != nil { t.Fatal(err) @@ -168,7 +168,7 @@ func TestCompiledQueriesRunOnTheEngine(t *testing.T) { svc := filter("(service = CAST($service AS VARCHAR))", "service") vars := map[string]Value{"service": {Values: []string{"checkout"}}} - p = &Panel{ID: "lat", Viz: "timeseries", Query: &Query{From: "spans", Bucket: "5m"}} + p = &Panel{ID: "lat", Viz: "timeseries", Query: &Spec{From: "spans", Bucket: "5m"}} c, err = compileQuery(p, measuresOf(t, "spans", "p95(duration_ms)"), []Filter{svc}, Scope{Start: fixtureStart, End: end, Interval: 5 * time.Minute, Vars: vars}) if err != nil { t.Fatal(err) @@ -177,7 +177,7 @@ func TestCompiledQueriesRunOnTheEngine(t *testing.T) { t.Fatalf("p95 series: %d rows", len(rows)) } - p = &Panel{ID: "sev", Viz: "timeseries", Query: &Query{From: "logs", By: []string{"severity"}, Bucket: "1m"}} + p = &Panel{ID: "sev", Viz: "timeseries", Query: &Spec{From: "logs", By: []string{"severity"}, Bucket: "1m"}} c, err = compileQuery(p, measuresOf(t, "logs", "share()"), nil, Scope{Start: fixtureStart, End: end, Interval: time.Minute}) if err != nil { t.Fatal(err) @@ -195,7 +195,7 @@ func TestCompiledQueriesRunOnTheEngine(t *testing.T) { } } - p = &Panel{ID: "n", Viz: "stat", Query: &Query{From: "spans"}} + p = &Panel{ID: "n", Viz: "stat", Query: &Spec{From: "spans"}} c, err = compileQuery(p, measuresOf(t, "spans", "count()"), []Filter{svc}, Scope{Start: fixtureStart, End: end, Vars: vars}) if err != nil { t.Fatal(err) diff --git a/internal/panel/confidence_ranking_test.go b/internal/query/confidence_ranking_test.go similarity index 96% rename from internal/panel/confidence_ranking_test.go rename to internal/query/confidence_ranking_test.go index 87527ec8..c0b34ff6 100644 --- a/internal/panel/confidence_ranking_test.go +++ b/internal/query/confidence_ranking_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -91,7 +91,7 @@ func TestConfidenceRankingEngine(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { before := counter.queries - d := Dashboard{Name: "Confidence", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Better: tc.better, Options: &Options{Top: tc.top}, Query: &Query{From: "spans", Measures: []string{tc.measure}, By: []string{"service"}, Where: []string{tc.where}, Bucket: "1m"}}}} + d := Dashboard{Name: "Confidence", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Better: tc.better, Options: &Options{Top: tc.top}, Query: &Spec{From: "spans", Measures: []string{tc.measure}, By: []string{"service"}, Where: []string{tc.where}, Bucket: "1m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || len(got) != 1 || got[0].Status != StatusOK || got[0].Frame == nil { t.Fatalf("run: %+v %v", got, err) diff --git a/internal/panel/deploy_split.go b/internal/query/deploy_split.go similarity index 99% rename from internal/panel/deploy_split.go rename to internal/query/deploy_split.go index 9b1286ed..2f73113a 100644 --- a/internal/panel/deploy_split.go +++ b/internal/query/deploy_split.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/deploy_split_test.go b/internal/query/deploy_split_test.go similarity index 98% rename from internal/panel/deploy_split_test.go rename to internal/query/deploy_split_test.go index 9a63fec5..79db4e34 100644 --- a/internal/panel/deploy_split_test.go +++ b/internal/query/deploy_split_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -58,7 +58,7 @@ func TestDeploySplitUsesEffectiveWindowAndRates(t *testing.T) { t.Fatalf("rate used full window: %v", f.Values) } } - d.Panels[0].Time = &PanelTime{Range: "15m"} + d.Panels[0].Time = &TimeOverride{Range: "15m"} got, err = e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame.Note == "" || len(got[0].Frame.Columns) != 2 { t.Fatalf("no deploy: %+v %v", got, err) @@ -117,7 +117,7 @@ func TestDeploySplitLatestDeployAndBoundaries(t *testing.T) { t.Fatalf("wrong subwindow count: %+v", f) } } - d.Panels[0].Time = &PanelTime{Range: "15m"} + d.Panels[0].Time = &TimeOverride{Range: "15m"} got, err = e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame == nil || got[0].Frame.Note != "No deploy in this panel's time range; showing the whole window." { t.Fatalf("boundary deploy should remain unsplit: %+v %v", got, err) diff --git a/internal/panel/diagnose.go b/internal/query/diagnose.go similarity index 99% rename from internal/panel/diagnose.go rename to internal/query/diagnose.go index 0c3d3ff2..9e280ea2 100644 --- a/internal/panel/diagnose.go +++ b/internal/query/diagnose.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/diagnose_regression_test.go b/internal/query/diagnose_regression_test.go similarity index 92% rename from internal/panel/diagnose_regression_test.go rename to internal/query/diagnose_regression_test.go index 24e670e0..ec17a99b 100644 --- a/internal/panel/diagnose_regression_test.go +++ b/internal/query/diagnose_regression_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -19,7 +19,7 @@ func TestDiagnosisHighlightOnlyWhenActiveFiltersMatch(t *testing.T) { e.now = func() time.Time { return fixtureStart.Add(time.Hour) } for _, viz := range []string{"logs", "log_patterns"} { t.Run(viz, func(t *testing.T) { - p := Panel{ID: "logs", Title: "Logs", Viz: viz, Options: &Options{Highlight: "error"}, Query: &Query{From: "logs", Where: []string{"service = 'missing'"}}} + p := Panel{ID: "logs", Title: "Logs", Viz: viz, Options: &Options{Highlight: "error"}, Query: &Spec{From: "logs", Where: []string{"service = 'missing'"}}} if viz == "log_patterns" { p.Query.Measures = []string{"count()"} p.Query.By = []string{"body_template"} @@ -57,7 +57,7 @@ func TestDiagnosisNamesOnlyEmptyingRouteFilter(t *testing.T) { e.now = func() time.Time { return fixtureStart.Add(time.Hour) } d := shopDashboard() // The causal filter is deliberately beyond the old six-filter cutoff. - d.Panels = []Panel{{ID: "empty", Title: "Empty", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: []string{ + d.Panels = []Panel{{ID: "empty", Title: "Empty", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: []string{ "service = $service", "kind = 'SPAN_KIND_SERVER'", "http_method = 'GET'", "duration_ms > 0", "status <> 'unknown'", "namespace = 'shop'", "http_route <> ''", }}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) @@ -85,7 +85,7 @@ func TestDiagnosisReportsCombinationWhenEachFilterMatchesAlone(t *testing.T) { service, kind := "service = 'checkout'", "kind = 'SPAN_KIND_CONSUMER'" d := Dashboard{Name: "Diagnosis", Time: Time{Range: "1h"}} for i, where := range [][]string{{service}, {kind}, {service, kind}} { - d.Panels = append(d.Panels, Panel{ID: fmt.Sprintf("p%d", i), Title: "Spans", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: where}}) + d.Panels = append(d.Panels, Panel{ID: fmt.Sprintf("p%d", i), Title: "Spans", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: where}}) } results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -109,7 +109,7 @@ func TestDiagnosisChoosesMostSelectiveQualifyingFilter(t *testing.T) { d := shopDashboard() // Removing service recovers 60 frontend rows; removing route recovers // 120 checkout rows, so route is the more selective conflicting filter. - d.Panels = []Panel{{ID: "empty", Title: "Empty", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: []string{"service = $service", "http_route = '/api/cart'"}}}} + d.Panels = []Panel{{ID: "empty", Title: "Empty", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: []string{"service = $service", "http_route = '/api/cart'"}}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -132,7 +132,7 @@ func TestDiagnosisSkipsFailingFilterRerun(t *testing.T) { e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } d := Dashboard{Name: "Diagnosis", Time: Time{Range: "1h"}, Panels: []Panel{{ - ID: "empty", Title: "Empty", Viz: "table", Query: &Query{ + ID: "empty", Title: "Empty", Viz: "table", Query: &Spec{ From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Where: []string{"service = 'checkout'", "CAST(http_status_code AS BIGINT) > 100", "http_route = '/missing'"}, }, @@ -167,7 +167,7 @@ func TestDiagnosisBoundsReruns(t *testing.T) { for i := range 16 { where = append(where, fmt.Sprintf("duration_ms > %d", 1000000+i)) } - p := &Panel{ID: "empty", Title: "Empty", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, Where: where}} + p := &Panel{ID: "empty", Title: "Empty", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, Where: where}} d := shopDashboard() d.Panels = []Panel{*p} Normalize(&d) diff --git a/internal/panel/distribution.go b/internal/query/distribution.go similarity index 99% rename from internal/panel/distribution.go rename to internal/query/distribution.go index 91ca46df..359cebe7 100644 --- a/internal/panel/distribution.go +++ b/internal/query/distribution.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/distribution_test.go b/internal/query/distribution_test.go similarity index 85% rename from internal/panel/distribution_test.go rename to internal/query/distribution_test.go index f4a1e53d..3edd1ccb 100644 --- a/internal/panel/distribution_test.go +++ b/internal/query/distribution_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -16,7 +16,7 @@ import ( func TestDistributionCounts(t *testing.T) { e := newFixtureExecutor(t) d := shopDashboard() - d.Panels = []Panel{{ID: "h", Title: "Latency distribution", Viz: "histogram", Query: &Query{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}} + d.Panels = []Panel{{ID: "h", Title: "Latency distribution", Viz: "histogram", Query: &Spec{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -41,7 +41,7 @@ func TestDistributionCounts(t *testing.T) { e = NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } d.Variables = nil - d.Panels[0].Query = &Query{From: "metrics", Where: []string{"name = 'latency'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} + d.Panels[0].Query = &Spec{From: "metrics", Where: []string{"name = 'latency'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} got, err = e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -67,7 +67,7 @@ func TestMetricHistogramTemporality(t *testing.T) { } e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Hist", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Unit: "ms", Query: &Query{From: "metrics", Where: []string{"name = 'latency'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} + d := Dashboard{Name: "Hist", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Unit: "ms", Query: &Spec{From: "metrics", Where: []string{"name = 'latency'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} for _, temporality := range []string{"cumulative", "delta"} { if temporality == "delta" { engine, repo = newTestEngine(t) @@ -122,7 +122,7 @@ func TestDistributionBudget(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(24 * time.Hour) } - d := Dashboard{Name: "Heat", Time: Time{Range: "24h"}, Panels: []Panel{{ID: "heat", Title: "Heat", Viz: "heatmap", Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "1m", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} + d := Dashboard{Name: "Heat", Time: Time{Range: "24h"}, Panels: []Panel{{ID: "heat", Title: "Heat", Viz: "heatmap", Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "1m", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -176,12 +176,12 @@ func TestDistributionValidation(t *testing.T) { p Panel want Problem }{ - {Panel{ID: "h", Title: "H", Viz: "heatmap", Query: &Query{From: "spans", Measures: []string{"count()"}}}, Problem{Path: "panels[0].query.histogram", Message: "distribution panels require a histogram", Hint: "spans: duration_ms/log2; metrics: value/explicit"}}, - {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.measures", Message: "distribution counts require count()", Hint: "use count() as the observation weight"}}, - {Panel{ID: "h", Title: "H", Viz: "heatmap", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.by", Message: "heatmap panels take no group by", Hint: ""}}, - {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service", "name"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.by", Message: "histogram panels group by at most 1 field(s)", Hint: ""}}, - {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "explicit"}}}, Problem{Path: "panels[0].query.histogram", Message: "use spans duration_ms/log2 or metrics value/explicit", Hint: ""}}, - {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "log2"}}}, Problem{Path: "panels[0].query.histogram", Message: "use spans duration_ms/log2 or metrics value/explicit", Hint: ""}}, + {Panel{ID: "h", Title: "H", Viz: "heatmap", Query: &Spec{From: "spans", Measures: []string{"count()"}}}, Problem{Path: "panels[0].query.histogram", Message: "distribution panels require a histogram", Hint: "spans: duration_ms/log2; metrics: value/explicit"}}, + {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.measures", Message: "distribution counts require count()", Hint: "use count() as the observation weight"}}, + {Panel{ID: "h", Title: "H", Viz: "heatmap", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.by", Message: "heatmap panels take no group by", Hint: ""}}, + {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service", "name"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, Problem{Path: "panels[0].query.by", Message: "histogram panels group by at most 1 field(s)", Hint: ""}}, + {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "explicit"}}}, Problem{Path: "panels[0].query.histogram", Message: "use spans duration_ms/log2 or metrics value/explicit", Hint: ""}}, + {Panel{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "log2"}}}, Problem{Path: "panels[0].query.histogram", Message: "use spans duration_ms/log2 or metrics value/explicit", Hint: ""}}, {Panel{ID: "h", Title: "H", Viz: "heatmap", SQL: "SELECT count(*) FROM spans"}, Problem{Path: "panels[0].query", Message: "distribution panels require a structured query", Hint: ""}}, {Panel{ID: "h", Title: "H", Viz: "histogram", SQL: "SELECT count(*) FROM spans"}, Problem{Path: "panels[0].query", Message: "distribution panels require a structured query", Hint: ""}}, } @@ -215,7 +215,7 @@ func TestDistributionMalformedHistogram(t *testing.T) { } e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} + d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != "ok" || got[0].Frame == nil { t.Fatalf("malformed histogram: %+v %v", got, err) @@ -247,7 +247,7 @@ func TestDistributionSpanBoundaries(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} + d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != "ok" || got[0].Frame == nil { t.Fatalf("span histogram: %+v %v", got, err) @@ -273,7 +273,7 @@ func TestDistributionSpanOther(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Options: &Options{Top: 1}, Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} + d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Options: &Options{Top: 1}, Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != "ok" || got[0].Frame == nil { t.Fatalf("split histogram: %+v %v", got, err) @@ -308,7 +308,7 @@ func TestMetricHistogramHeatmap(t *testing.T) { } e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Heat", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "heatmap", Unit: "ms", Query: &Query{From: "metrics", Measures: []string{"count()"}, Bucket: "5m", Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} + d := Dashboard{Name: "Heat", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "heatmap", Unit: "ms", Query: &Spec{From: "metrics", Measures: []string{"count()"}, Bucket: "5m", Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} for _, temporality := range []string{"cumulative", "delta"} { if temporality == "delta" { engine, repo = newTestEngine(t) @@ -376,7 +376,7 @@ func TestMetricHistogramSeriesIdentity(t *testing.T) { } e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Query{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} + d := Dashboard{Name: "Hist", Panels: []Panel{{ID: "h", Title: "H", Viz: "histogram", Query: &Spec{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != "ok" { t.Fatalf("identity: %+v %v", got, err) @@ -467,7 +467,7 @@ func TestMetricDistributionMixedKinds(t *testing.T) { t.Fatalf("rows=%d err=%v", rows, err) } for _, viz := range []string{"histogram", "heatmap"} { - q := &Query{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} + q := &Spec{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} if viz == "heatmap" { q.Bucket = "1m" } @@ -491,7 +491,7 @@ func TestMetricDistributionOtherCountsContributingSeries(t *testing.T) { insertMetrics(t, db, metricHistogram(fixtureStart.Add(-time.Minute), "[10]", "[10,0]", 10, 100, series)) insertMetrics(t, db, metricHistogram(fixtureStart, "[10]", fmt.Sprintf("[%d,0]", 10+increase), int64(10+increase), float64(100+increase), series)) } - q := &Query{From: "metrics", By: []string{"attributes['series']"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} + q := &Spec{From: "metrics", By: []string{"attributes['series']"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} r := runMetricPanel(t, e, Panel{Viz: "histogram", Options: &Options{Top: 5}, Query: q}, fixtureStart.Add(-time.Minute), fixtureStart.Add(time.Nanosecond)) if !reflect.DeepEqual(metricValues(t, r, "series"), []any{"Other (2)", "s0", "s1", "s2", "s3", "s4"}) || !reflect.DeepEqual(metricValues(t, r, "count"), []any{7.0, 9.0, 8.0, 7.0, 6.0, 5.0}) { diff --git a/internal/panel/drill_logs_test.go b/internal/query/drill_logs_test.go similarity index 90% rename from internal/panel/drill_logs_test.go rename to internal/query/drill_logs_test.go index b56b1077..b95cd2c0 100644 --- a/internal/panel/drill_logs_test.go +++ b/internal/query/drill_logs_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" @@ -14,7 +14,7 @@ func TestDrillLogsKeepCheckedSelection(t *testing.T) { commit(t, repo, nil, []telemetry.Log{{ServiceName: "checkout", Severity: "ERROR", Body: "failed", TimeUnixNanos: at, EventUnixNanos: at, IngestedAt: at}, {ServiceName: "frontend", Severity: "INFO", Body: "ok", TimeUnixNanos: at, EventUnixNanos: at, IngestedAt: at}}) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "levels", Title: "Levels", Viz: "bar", Query: &Query{From: "logs", Where: []string{"service = 'checkout'"}, Measures: []string{"count()"}, By: []string{"severity"}}}}} + d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "levels", Title: "Levels", Viz: "bar", Query: &Spec{From: "logs", Where: []string{"service = 'checkout'"}, Measures: []string{"count()"}, By: []string{"severity"}}}}} req := ExemplarRequest{Dashboard: d, PanelID: "levels", Kind: "logs", From: fixtureStart, To: fixtureStart.Add(time.Minute), Dimensions: map[string]string{"severity": "ERROR"}} got, err := e.Exemplars(t.Context(), req) if err != nil { @@ -44,7 +44,7 @@ func TestExemplarCapturedWindowDoesNotMove(t *testing.T) { e := newFixtureExecutor(t) from, to := fixtureStart, fixtureStart.Add(time.Hour) d := shopDashboard() - d.Panels[2].Time = &PanelTime{Shift: "1h"} + d.Panels[2].Time = &TimeOverride{Shift: "1h"} req := ExemplarRequest{Dashboard: d, PanelID: "by_route", Time: &Time{From: &from, To: &to, Refresh: "off"}, From: from, To: to} e.now = func() time.Time { return fixtureStart.Add(10 * time.Hour) } got, err := e.Exemplars(t.Context(), req) @@ -63,7 +63,7 @@ func TestDrillLogsCapAndSource(t *testing.T) { commit(t, repo, nil, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "levels", Title: "Levels", Viz: "bar", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"severity"}}}}} + d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "levels", Title: "Levels", Viz: "bar", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"severity"}}}}} req := ExemplarRequest{Dashboard: d, PanelID: "levels", Kind: "logs", From: fixtureStart, To: fixtureStart.Add(time.Minute), Dimensions: map[string]string{"severity": "ERROR"}} got, err := e.Exemplars(t.Context(), req) if err != nil || got.Logs == nil || got.Logs.Rows != 200 || !got.Logs.Truncated || len(got.Traces) != 0 { diff --git a/internal/panel/errors.go b/internal/query/errors.go similarity index 99% rename from internal/panel/errors.go rename to internal/query/errors.go index 523c9d41..e8203207 100644 --- a/internal/panel/errors.go +++ b/internal/query/errors.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" diff --git a/internal/panel/errors_test.go b/internal/query/errors_test.go similarity index 98% rename from internal/panel/errors_test.go rename to internal/query/errors_test.go index 4b4c3aa5..21940cd2 100644 --- a/internal/panel/errors_test.go +++ b/internal/query/errors_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -115,7 +115,7 @@ func TestNativePanelSQLFailuresHaveSafePreciseDiagnostics(t *testing.T) { func TestStructuredFilterRuntimeFailureKeepsAuthorDiagnostic(t *testing.T) { e := newFixtureExecutor(t) - d := Dashboard{Name: "Calls", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, Where: []string{"CAST(service AS INTEGER) > 0"}}}}} + d := Dashboard{Name: "Calls", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, Where: []string{"CAST(service AS INTEGER) > 0"}}}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) diff --git a/internal/panel/exec.go b/internal/query/exec.go similarity index 98% rename from internal/panel/exec.go rename to internal/query/exec.go index 2b7b6389..b6bed63a 100644 --- a/internal/panel/exec.go +++ b/internal/query/exec.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -16,7 +16,7 @@ import ( "golang.org/x/sync/errgroup" ) -// Engine is the query engine the executor runs on. *query.Duck implements it; +// Engine is the query engine the executor runs on. *engine.Duck implements it; // QueryContext binds the Parquet snapshot for the window in the context. type Engine interface { Parser @@ -225,8 +225,8 @@ func (e *Executor) Run(ctx context.Context, req RunRequest) ([]Result, error) { // BatchDeadlineError is shared by HTTP and MCP batch callers. const BatchDeadlineError = "Not run: the dashboard ran out of time. Narrow the time range or split the dashboard." -// QueryTimeoutError describes the executor's per-panel time limit. -const QueryTimeoutError = "The query took longer than 10 seconds. Narrow the time range or add filters." +// TimeoutError describes the executor's per-panel time limit. +const TimeoutError = "The query took longer than 10 seconds. Narrow the time range or add filters." // Allocate the response budget in panel order, independently of completion // order, so concurrent refreshes retain the same portion of their frames. @@ -573,7 +573,7 @@ func failed(res Result, err error, stopped error) Result { } switch { case ownTimeout && errors.Is(err, context.DeadlineExceeded): - res.Error = QueryTimeoutError + res.Error = TimeoutError res.Retryable = true default: res.Error = errorMessage(err, executionErrorKind(err)) diff --git a/internal/panel/exec_logging_test.go b/internal/query/exec_logging_test.go similarity index 97% rename from internal/panel/exec_logging_test.go rename to internal/query/exec_logging_test.go index 3580d928..5d3cdc88 100644 --- a/internal/panel/exec_logging_test.go +++ b/internal/query/exec_logging_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "bytes" @@ -65,7 +65,7 @@ func TestRunCallerCancellationDoesNotLogPanelError(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { e := newFixtureExecutor(t) - d := Dashboard{Name: "Cancellation", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}}}}} + d := Dashboard{Name: "Cancellation", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}}}}} if err := e.Validate(t.Context(), &d); err != nil { t.Fatal(err) } diff --git a/internal/panel/exec_test.go b/internal/query/exec_test.go similarity index 89% rename from internal/panel/exec_test.go rename to internal/query/exec_test.go index cbb7235e..2cc6cfad 100644 --- a/internal/panel/exec_test.go +++ b/internal/query/exec_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -17,9 +17,9 @@ func TestRunResolvesOneInstantForAllPanelWindows(t *testing.T) { return fixtureStart.Add(time.Hour).Add(time.Duration(calls.Add(1)-1) * 27 * time.Millisecond) } d := Dashboard{Name: "Shared window", Time: Time{Range: "1h"}, Panels: []Panel{ - {ID: "current", Title: "Current", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, - {ID: "other", Title: "Other", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, - {ID: "prior", Title: "Prior", Viz: "timeseries", Time: &PanelTime{Shift: "1d"}, Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, + {ID: "current", Title: "Current", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, + {ID: "other", Title: "Other", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, + {ID: "prior", Title: "Prior", Viz: "timeseries", Time: &TimeOverride{Shift: "1d"}, Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "5m"}}, }} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -64,9 +64,9 @@ func shopDashboard() Dashboard { {Name: "route", Kind: "query", From: "spans", Field: "http_route", Where: []string{"service = $service"}, IncludeAll: true, Default: AllValue}, }, Panels: []Panel{ - {ID: "latency", Title: "Latency", Viz: "timeseries", Query: &Query{From: "spans", Where: []string{"service = $service", "http_route = $route"}, Measures: []string{"p95(duration_ms)"}, Bucket: "5m"}}, - {ID: "requests", Title: "Requests", Viz: "stat", Query: &Query{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}}}, - {ID: "by_route", Title: "By route", Viz: "bar", Query: &Query{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}, By: []string{"http_route"}}}, + {ID: "latency", Title: "Latency", Viz: "timeseries", Query: &Spec{From: "spans", Where: []string{"service = $service", "http_route = $route"}, Measures: []string{"p95(duration_ms)"}, Bucket: "5m"}}, + {ID: "requests", Title: "Requests", Viz: "stat", Query: &Spec{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}}}, + {ID: "by_route", Title: "By route", Viz: "bar", Query: &Spec{From: "spans", Where: []string{"service = $service"}, Measures: []string{"count()"}, By: []string{"http_route"}}}, {ID: "services", Title: "Services", Viz: "table", SQL: "SELECT service, count(*) AS n FROM spans WHERE $__window(start_time) GROUP BY 1 ORDER BY 2 DESC"}, {ID: "notes", Title: "Notes", Viz: "text", Content: "Checkout is the money path."}, }, @@ -139,7 +139,7 @@ func TestRunComparesWithThePreviousPeriod(t *testing.T) { func TestRunExplainsEmptyPanels(t *testing.T) { e := newFixtureExecutor(t) d := shopDashboard() - d.Panels = []Panel{{ID: "nope", Title: "Nope", Viz: "bar", Query: &Query{From: "spans", Where: []string{"service = $service", "http_route = '/nope'"}, Measures: []string{"count()"}, By: []string{"http_route"}}}} + d.Panels = []Panel{{ID: "nope", Title: "Nope", Viz: "bar", Query: &Spec{From: "spans", Where: []string{"service = $service", "http_route = '/nope'"}, Measures: []string{"count()"}, By: []string{"http_route"}}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -153,7 +153,7 @@ func TestRunExplainsEmptyPanels(t *testing.T) { func TestRunIsolatesPanelErrors(t *testing.T) { e := newFixtureExecutor(t) d := shopDashboard() - d.Panels = append(d.Panels, Panel{ID: "broken", Title: "Broken", Viz: "stat", Query: &Query{From: "spans", Where: []string{"service::INTEGER > 1"}, Measures: []string{"count()"}}}) + d.Panels = append(d.Panels, Panel{ID: "broken", Title: "Broken", Viz: "stat", Query: &Spec{From: "spans", Where: []string{"service::INTEGER > 1"}, Measures: []string{"count()"}}}) results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) diff --git a/internal/panel/execution_limits_test.go b/internal/query/execution_limits_test.go similarity index 98% rename from internal/panel/execution_limits_test.go rename to internal/query/execution_limits_test.go index 8159d59d..800de06d 100644 --- a/internal/panel/execution_limits_test.go +++ b/internal/query/execution_limits_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "bytes" @@ -36,7 +36,7 @@ func TestBatchDeadlineKeepsCompletedPanels(t *testing.T) { e.parallel = 1 d := Dashboard{Name: "Deadline", Panels: []Panel{{ID: "fast", Title: "Fast", Viz: "text", Content: "done"}}} for _, id := range []string{"slow", "queued"} { - d.Panels = append(d.Panels, Panel{ID: id, Title: id, Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}}}) + d.Panels = append(d.Panels, Panel{ID: id, Title: id, Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}}}) } results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || len(results) != 3 { @@ -260,7 +260,7 @@ func TestNormalizeBetter(t *testing.T) { {"p95(duration_ms)", "", "lower"}, {"error_rate()", "", "lower"}, {"count()", "status = 'STATUS_CODE_ERROR'", "lower"}, {"count()", "status != 'STATUS_CODE_ERROR'", "higher"}, {"count()", "NOT (status = 'STATUS_CODE_ERROR')", "higher"}, {"rate()", "", "higher"}, {"count()", "", "higher"}, {"count_distinct(service)", "", ""}, } { - d := Dashboard{Panels: []Panel{{Viz: "stat", Query: &Query{From: "spans", Measures: []string{tc.measure}}}}} + d := Dashboard{Panels: []Panel{{Viz: "stat", Query: &Spec{From: "spans", Measures: []string{tc.measure}}}}} if tc.filter != "" { d.Panels[0].Query.Where = []string{tc.filter} } diff --git a/internal/panel/exemplar_bounds_test.go b/internal/query/exemplar_bounds_test.go similarity index 94% rename from internal/panel/exemplar_bounds_test.go rename to internal/query/exemplar_bounds_test.go index 7b9e8990..c98aeb0b 100644 --- a/internal/panel/exemplar_bounds_test.go +++ b/internal/query/exemplar_bounds_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" ) @@ -24,7 +24,7 @@ func (e exemplarProbeEngine) QueryContext(ctx context.Context, text string, args } func exemplarDashboard(from string) Dashboard { - return Dashboard{Name: "Selection", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "bar", Query: &Query{From: from, Measures: []string{"count()"}, By: []string{"service"}}}}} + return Dashboard{Name: "Selection", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "bar", Query: &Spec{From: from, Measures: []string{"count()"}, By: []string{"service"}}}}} } func exemplarRequest(d Dashboard) ExemplarRequest { @@ -61,14 +61,14 @@ func TestExemplarDeadlineAndCancel(t *testing.T) { } func TestExemplarSafeErrors(t *testing.T) { - engine, _ := newTestEngine(t) - failure := fmt.Errorf("read '/private/telemetry/batch/logs.parquet': %w", query.ErrParquetReadWait) - probe := exemplarProbeEngine{Engine: engine, query: func(context.Context, string, ...any) (queryrows.Rows, error) { return nil, failure }} + duck, _ := newTestEngine(t) + failure := fmt.Errorf("read '/private/telemetry/batch/logs.parquet': %w", engine.ErrParquetReadWait) + probe := exemplarProbeEngine{Engine: duck, query: func(context.Context, string, ...any) (queryrows.Rows, error) { return nil, failure }} e := NewExecutor(probe, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } _, err := e.Exemplars(t.Context(), exemplarRequest(exemplarDashboard("spans"))) err = PresentedError(err, ReadError) - if !errors.Is(err, query.ErrParquetReadWait) || strings.Contains(err.Error(), "/private/telemetry") || err.Error() != ReadFailure { + if !errors.Is(err, engine.ErrParquetReadWait) || strings.Contains(err.Error(), "/private/telemetry") || err.Error() != ReadFailure { t.Fatalf("lost safe error chain: %v", err) } } @@ -256,7 +256,7 @@ func TestExemplarCandidateCapAndSlowest(t *testing.T) { if err != nil || len(got.Traces) != 20 || !got.Truncated || got.Traces[0].DurationMS != 1005 { t.Fatalf("slowest: %+v %v", got, err) } - p := Panel{Query: &Query{From: "spans"}} + p := Panel{Query: &Spec{From: "spans"}} where, args, _ := selectionWhere(&p, nil, Scope{Start: fixtureStart, End: fixtureStart.Add(time.Hour)}, nil, nil) args = append(args, fixtureStart, fixtureStart.Add(time.Hour)) rows, err := engine.QueryContext(t.Context(), checkedTraceSQL("spans", where, 2000, "duration_ms DESC,trace_id,namespace", "start_time::TIMESTAMP_NS"), args...) diff --git a/internal/panel/exemplars.go b/internal/query/exemplars.go similarity index 99% rename from internal/panel/exemplars.go rename to internal/query/exemplars.go index fca438b2..fd6451ac 100644 --- a/internal/panel/exemplars.go +++ b/internal/query/exemplars.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/exemplars_test.go b/internal/query/exemplars_test.go similarity index 93% rename from internal/panel/exemplars_test.go rename to internal/query/exemplars_test.go index e9ad38b6..39c8c674 100644 --- a/internal/panel/exemplars_test.go +++ b/internal/query/exemplars_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" @@ -52,7 +52,7 @@ func TestExemplarsRejectForgedDimensions(t *testing.T) { } } func TestExemplarBucketValidation(t *testing.T) { - p := &Panel{Query: &Query{From: "spans", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}} + p := &Panel{Query: &Spec{From: "spans", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}} scope := Scope{Start: fixtureStart, End: fixtureStart.Add(time.Hour)} bad := math.NaN() upper := 1.0 @@ -79,7 +79,7 @@ func TestExemplarsLogsCandidateUsesRedactedBody(t *testing.T) { commit(t, repo, spans, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Log lineage", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "bar", Query: &Query{From: "logs", Where: []string{"body LIKE '%failed%'"}, Measures: []string{"count()"}, By: []string{"severity"}}}}} + d := Dashboard{Name: "Log lineage", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "bar", Query: &Spec{From: "logs", Where: []string{"body LIKE '%failed%'"}, Measures: []string{"count()"}, By: []string{"severity"}}}}} req := ExemplarRequest{Dashboard: d, PanelID: "p", From: fixtureStart, To: fixtureStart.Add(time.Minute)} got, err := e.Exemplars(t.Context(), req) if err != nil || len(got.Traces) != 1 || got.Traces[0].TraceID != "log-trace" { diff --git a/internal/panel/export.go b/internal/query/export.go similarity index 99% rename from internal/panel/export.go rename to internal/query/export.go index 76be5dd1..1099679d 100644 --- a/internal/panel/export.go +++ b/internal/query/export.go @@ -1,4 +1,4 @@ -package panel +package query import ( "slices" diff --git a/internal/panel/export_test.go b/internal/query/export_test.go similarity index 99% rename from internal/panel/export_test.go rename to internal/query/export_test.go index 3e2a6c73..6f336a98 100644 --- a/internal/panel/export_test.go +++ b/internal/query/export_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "reflect" diff --git a/internal/panel/filter.go b/internal/query/filter.go similarity index 99% rename from internal/panel/filter.go rename to internal/query/filter.go index 2000c465..677ea1ae 100644 --- a/internal/panel/filter.go +++ b/internal/query/filter.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/filter_test.go b/internal/query/filter_test.go similarity index 99% rename from internal/panel/filter_test.go rename to internal/query/filter_test.go index ab8a0bec..41f79ff3 100644 --- a/internal/panel/filter_test.go +++ b/internal/query/filter_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "strings" diff --git a/internal/panel/frame.go b/internal/query/frame.go similarity index 99% rename from internal/panel/frame.go rename to internal/query/frame.go index 55d30c59..ec9612f4 100644 --- a/internal/panel/frame.go +++ b/internal/query/frame.go @@ -1,4 +1,4 @@ -package panel +package query import ( "database/sql" diff --git a/internal/panel/frame_semantics_test.go b/internal/query/frame_semantics_test.go similarity index 95% rename from internal/panel/frame_semantics_test.go rename to internal/query/frame_semantics_test.go index 03b83e8e..f5e412e0 100644 --- a/internal/panel/frame_semantics_test.go +++ b/internal/query/frame_semantics_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "bytes" @@ -28,7 +28,7 @@ func TestSeriesKeepsNewestBucket(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(duck, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Series", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "series", Title: "Series", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "30s"}, Options: &Options{Top: 6}}}} + d := Dashboard{Name: "Series", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "series", Title: "Series", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "30s"}, Options: &Options{Top: 6}}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -103,7 +103,7 @@ func TestErrorCountDirections(t *testing.T) { "spans": {"status = 'STATUS_CODE_ERROR'", "status IN ('STATUS_CODE_ERROR')"}, } { for _, filter := range filters { - p := Panel{Query: &Query{From: signal, Measures: []string{"count()"}, Where: []string{filter}}} + p := Panel{Query: &Spec{From: signal, Measures: []string{"count()"}, Where: []string{filter}}} if got := inferBetter(&p); got != "lower" { t.Errorf("%s: %s direction=%q", signal, filter, got) } diff --git a/internal/panel/heat_density_test.go b/internal/query/heat_density_test.go similarity index 78% rename from internal/panel/heat_density_test.go rename to internal/query/heat_density_test.go index 8db776af..1acbf396 100644 --- a/internal/panel/heat_density_test.go +++ b/internal/query/heat_density_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "strings" @@ -9,9 +9,9 @@ import ( func TestWidthAwareCellBuckets(t *testing.T) { e := newFixtureExecutor(t) d := Dashboard{Name: "Density", Time: Time{Range: "24h"}, Panels: []Panel{ - {ID: "heat", Title: "Heat", Viz: "heatmap", Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "auto", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, - {ID: "state", Title: "State", Viz: "state_timeline", Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto"}}, - {ID: "line", Title: "Line", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"count()"}, Bucket: "auto"}}, + {ID: "heat", Title: "Heat", Viz: "heatmap", Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "auto", Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, + {ID: "state", Title: "State", Viz: "state_timeline", Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto"}}, + {ID: "line", Title: "Line", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"count()"}, Bucket: "auto"}}, }} fixed := d.Panels[0] fixed.ID = "fixed" diff --git a/internal/panel/interaction_test.go b/internal/query/interaction_test.go similarity index 79% rename from internal/panel/interaction_test.go rename to internal/query/interaction_test.go index 0d69ccca..570d7c1f 100644 --- a/internal/panel/interaction_test.go +++ b/internal/query/interaction_test.go @@ -1,15 +1,15 @@ -package panel +package query import ( "testing" "time" ) -func TestPanelTimeWindow(t *testing.T) { +func TestTimeOverrideWindow(t *testing.T) { e := newFixtureExecutor(t) d := shopDashboard() d.Panels = d.Panels[:1] - d.Panels[0].Time = &PanelTime{Range: "15m"} + d.Panels[0].Time = &TimeOverride{Range: "15m"} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -17,7 +17,7 @@ func TestPanelTimeWindow(t *testing.T) { if got[0].FromMS != fixtureStart.Add(45*time.Minute).UnixMilli() || got[0].ToMS != fixtureStart.Add(time.Hour).UnixMilli() { t.Fatalf("window: %+v", got[0]) } - d.Panels[0].Time = &PanelTime{Shift: "1h"} + d.Panels[0].Time = &TimeOverride{Shift: "1h"} got, err = e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) diff --git a/internal/panel/items.go b/internal/query/items.go similarity index 99% rename from internal/panel/items.go rename to internal/query/items.go index 0e611d59..bc11d017 100644 --- a/internal/panel/items.go +++ b/internal/query/items.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/items_test.go b/internal/query/items_test.go similarity index 80% rename from internal/panel/items_test.go rename to internal/query/items_test.go index a66d17f5..7b918b00 100644 --- a/internal/panel/items_test.go +++ b/internal/query/items_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -16,8 +16,8 @@ func TestItemsExecute(t *testing.T) { e := newFixtureExecutor(t) d := shopDashboard() d.Panels = []Panel{ - {ID: "scatter", Title: "Mean and tail latency", Viz: "scatter", Query: &Query{From: "spans", Measures: []string{"avg(duration_ms)", "p95(duration_ms)"}, By: []string{"http_route", "service"}}, Options: &Options{XScale: "log", YScale: "linear"}}, - {ID: "states", Title: "Latency states", Viz: "state_timeline", Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "5m"}, Thresholds: []Threshold{{Value: 500, Status: "bad"}}}, + {ID: "scatter", Title: "Mean and tail latency", Viz: "scatter", Query: &Spec{From: "spans", Measures: []string{"avg(duration_ms)", "p95(duration_ms)"}, By: []string{"http_route", "service"}}, Options: &Options{XScale: "log", YScale: "linear"}}, + {ID: "states", Title: "Latency states", Viz: "state_timeline", Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "5m"}, Thresholds: []Threshold{{Value: 500, Status: "bad"}}}, } got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -42,7 +42,7 @@ func TestTimelineBudget(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(24 * time.Hour) } - d := Dashboard{Name: "States", Time: Time{Range: "24h"}, Panels: []Panel{{ID: "states", Title: "States", Viz: "state_timeline", Options: &Options{Top: 6}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "1m"}}}} + d := Dashboard{Name: "States", Time: Time{Range: "24h"}, Panels: []Panel{{ID: "states", Title: "States", Viz: "state_timeline", Options: &Options{Top: 6}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "1m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -79,7 +79,7 @@ func TestTimelineBudget(t *testing.T) { } func TestItemsValidation(t *testing.T) { - mixed := Panel{ID: "s", Title: "S", Viz: "scatter", XUnit: "count", Unit: "ms", Query: &Query{From: "spans", Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"service"}}} + mixed := Panel{ID: "s", Title: "S", Viz: "scatter", XUnit: "count", Unit: "ms", Query: &Spec{From: "spans", Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"service"}}} d := Dashboard{Name: "Mixed", Panels: []Panel{mixed}} Normalize(&d) if got := Validate(&d); len(got) != 0 { @@ -89,9 +89,9 @@ func TestItemsValidation(t *testing.T) { panel Panel want Problem }{ - {Panel{ID: "s", Title: "S", Viz: "state_timeline", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].thresholds", Message: "state_timeline requires thresholds", Hint: "set a warn or bad boundary for the selected measure"}}, - {Panel{ID: "s", Title: "S", Viz: "scatter", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].query.measures", Message: "scatter requires exactly two measures", Hint: "select x and y measures in that order"}}, - {Panel{ID: "s", Title: "S", Viz: "bar", XUnit: "count", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].x_unit", Message: "x_unit applies only to scatter", Hint: "remove x_unit or use scatter"}}, + {Panel{ID: "s", Title: "S", Viz: "state_timeline", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].thresholds", Message: "state_timeline requires thresholds", Hint: "set a warn or bad boundary for the selected measure"}}, + {Panel{ID: "s", Title: "S", Viz: "scatter", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].query.measures", Message: "scatter requires exactly two measures", Hint: "select x and y measures in that order"}}, + {Panel{ID: "s", Title: "S", Viz: "bar", XUnit: "count", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, Problem{Path: "panels[0].x_unit", Message: "x_unit applies only to scatter", Hint: "remove x_unit or use scatter"}}, } unknown := mixed unknown.XUnit = "rows" @@ -110,7 +110,7 @@ func TestItemsValidation(t *testing.T) { } func TestTimelineSharePartitionsByBucket(t *testing.T) { e := newFixtureExecutor(t) - d := Dashboard{Name: "Share", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 50, Status: "warn"}}, Query: &Query{From: "spans", Measures: []string{"share()"}, By: []string{"service"}, Bucket: "5m"}}}} + d := Dashboard{Name: "Share", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 50, Status: "warn"}}, Query: &Spec{From: "spans", Measures: []string{"share()"}, By: []string{"service"}, Bucket: "5m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame == nil { t.Fatalf("share: %+v %v", got, err) @@ -142,7 +142,7 @@ func TestTimelineShareBeforeTopN(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Share", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 50, Status: "warn"}}, Query: &Query{From: "spans", Measures: []string{"share()"}, By: []string{"service"}, Bucket: "5m"}}}} + d := Dashboard{Name: "Share", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 50, Status: "warn"}}, Query: &Spec{From: "spans", Measures: []string{"share()"}, By: []string{"service"}, Bucket: "5m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("share: %+v %v", got, err) @@ -184,7 +184,7 @@ func TestItemsUnitNormalization(t *testing.T) { {"explicit_units", "count", "count", "count", "count"}, } { t.Run(tc.name, func(t *testing.T) { - d := Dashboard{Name: "Units", Panels: []Panel{{ID: "s", Title: "S", Viz: "scatter", XUnit: tc.x, Unit: tc.y, Query: &Query{From: "logs", Measures: []string{"avg(severity_number)", "max(severity_number)"}, By: []string{"service"}}}}} + d := Dashboard{Name: "Units", Panels: []Panel{{ID: "s", Title: "S", Viz: "scatter", XUnit: tc.x, Unit: tc.y, Query: &Spec{From: "logs", Measures: []string{"avg(severity_number)", "max(severity_number)"}, By: []string{"service"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("scatter: %+v %v", got, err) @@ -197,7 +197,7 @@ func TestItemsUnitNormalization(t *testing.T) { } for _, unit := range []string{"", "none", "count"} { t.Run("timeline/"+unit, func(t *testing.T) { - d := Dashboard{Name: "Units", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Unit: unit, Thresholds: []Threshold{{Value: 10, Status: "warn"}}, Query: &Query{From: "logs", Measures: []string{"avg(severity_number)"}, By: []string{"service"}, Bucket: "5m"}}}} + d := Dashboard{Name: "Units", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Unit: unit, Thresholds: []Threshold{{Value: 10, Status: "warn"}}, Query: &Spec{From: "logs", Measures: []string{"avg(severity_number)"}, By: []string{"service"}, Bucket: "5m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("timeline: %+v %v", got, err) @@ -220,7 +220,7 @@ func TestItemsScatterAxisUnits(t *testing.T) { {"both_overrides", "none", "ns", "none", "ns"}, } { t.Run(tc.name, func(t *testing.T) { - d := Dashboard{Name: "Axes", Panels: []Panel{{ID: "s", Title: "S", Viz: "scatter", XUnit: tc.x, Unit: tc.y, Query: &Query{From: "spans", Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"service"}}}}} + d := Dashboard{Name: "Axes", Panels: []Panel{{ID: "s", Title: "S", Viz: "scatter", XUnit: tc.x, Unit: tc.y, Query: &Spec{From: "spans", Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"service"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("scatter: %+v %v", got, err) @@ -239,10 +239,10 @@ func TestItemsOptionsValidation(t *testing.T) { panel Panel paths []string }{ - {"invalid_scales", Panel{Viz: "scatter", Options: &Options{XScale: "sqrt", YScale: "sqrt"}, Query: &Query{From: "spans", Measures: []string{"count()", "rate()"}, By: []string{"service"}}}, []string{"options.x_scale", "options.y_scale"}}, - {"bar_scales", Panel{Viz: "bar", Options: &Options{XScale: "log", YScale: "linear"}, Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, []string{"options.x_scale", "options.y_scale"}}, + {"invalid_scales", Panel{Viz: "scatter", Options: &Options{XScale: "sqrt", YScale: "sqrt"}, Query: &Spec{From: "spans", Measures: []string{"count()", "rate()"}, By: []string{"service"}}}, []string{"options.x_scale", "options.y_scale"}}, + {"bar_scales", Panel{Viz: "bar", Options: &Options{XScale: "log", YScale: "linear"}, Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, []string{"options.x_scale", "options.y_scale"}}, {"text_axes", Panel{Viz: "text", Content: "Notes", XUnit: "count", Options: &Options{XScale: "log", YScale: "linear"}}, []string{"x_unit", "options.x_scale", "options.y_scale"}}, - {"timeline_style_and_sort", Panel{Viz: "state_timeline", Options: &Options{Style: "stacked"}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Sort: "p95"}}, []string{"options.style", "query.sort"}}, + {"timeline_style_and_sort", Panel{Viz: "state_timeline", Options: &Options{Style: "stacked"}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Sort: "p95"}}, []string{"options.style", "query.sort"}}, {"sql_scatter", Panel{Viz: "scatter", SQL: "SELECT service, count(*) FROM spans WHERE $__window(start_time) GROUP BY 1"}, []string{"query"}}, } { t.Run(tc.name, func(t *testing.T) { @@ -268,7 +268,7 @@ func TestItemsLogsUseRedactedSource(t *testing.T) { for _, viz := range []string{"scatter", "state_timeline"} { for _, field := range []string{"body", "body_template"} { t.Run(viz+"/"+field, func(t *testing.T) { - p := Panel{ID: "p", Title: "P", Viz: viz, Query: &Query{From: "logs", Measures: []string{"count()", "rate()"}, By: []string{field}}} + p := Panel{ID: "p", Title: "P", Viz: viz, Query: &Spec{From: "logs", Measures: []string{"count()", "rate()"}, By: []string{field}}} if viz == "state_timeline" { p.Query.Measures = []string{"count()"} p.Query.Bucket = "5m" @@ -299,7 +299,7 @@ func TestTimelinePreservesUnknownBuckets(t *testing.T) { commit(t, repo, []telemetry.Span{{TraceID: "t", SpanID: "s", ServiceName: "svc", StartUnixNanos: n, EndUnixNanos: n + 1000000, DurationMS: 1, IngestedAt: n}}, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Unknown", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"avg(attributes['missing'])"}, By: []string{"service"}, Bucket: "5m"}}}} + d := Dashboard{Name: "Unknown", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"avg(attributes['missing'])"}, By: []string{"service"}, Bucket: "5m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("timeline: %+v %v", got, err) @@ -312,7 +312,7 @@ func TestTimelinePreservesUnknownBuckets(t *testing.T) { func TestTimelineBudgetKeepsNewestCompleteBuckets(t *testing.T) { e := newFixtureExecutor(t) - d := Dashboard{Name: "States", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 500, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "5m"}}}} + d := Dashboard{Name: "States", Panels: []Panel{{ID: "s", Title: "S", Viz: "state_timeline", Thresholds: []Threshold{{Value: 500, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}, Bucket: "5m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("timeline: %+v %v", got, err) diff --git a/internal/panel/log_redaction_test.go b/internal/query/log_redaction_test.go similarity index 99% rename from internal/panel/log_redaction_test.go rename to internal/query/log_redaction_test.go index 3c0ffcfd..131623a1 100644 --- a/internal/panel/log_redaction_test.go +++ b/internal/query/log_redaction_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/log_source.go b/internal/query/log_source.go similarity index 97% rename from internal/panel/log_source.go rename to internal/query/log_source.go index bd8288ab..e4d31245 100644 --- a/internal/panel/log_source.go +++ b/internal/query/log_source.go @@ -1,4 +1,4 @@ -package panel +package query import "github.com/labstack/fanout/internal/observability" diff --git a/internal/panel/log_window_test.go b/internal/query/log_window_test.go similarity index 93% rename from internal/panel/log_window_test.go rename to internal/query/log_window_test.go index 9667ca8d..b6658b3c 100644 --- a/internal/panel/log_window_test.go +++ b/internal/query/log_window_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -21,7 +21,7 @@ func TestLogPanelsPreserveExactWindowRedactionLimitsAndLateBatches(t *testing.T) commit(t, repo, nil, []telemetry.Log{makeLog("shop", "checkout", fmt.Sprintf("late-%d password=secret", i), start.UnixNano()+int64(i+1))}) } executor := NewExecutor(engine, 30) - spec := Dashboard{Name: "Logs", Time: Time{From: &start, To: &end}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Query{From: "logs", Where: []string{"namespace = 'shop'", "service = 'checkout'"}, Limit: 3}}}} + spec := Dashboard{Name: "Logs", Time: Time{From: &start, To: &end}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Spec{From: "logs", Where: []string{"namespace = 'shop'", "service = 'checkout'"}, Limit: 3}}}} for _, warm := range []bool{false, true} { if warm { if _, err := engine.RefreshReadCaches(t.Context()); err != nil { @@ -74,7 +74,7 @@ func TestEndpointPanelUsesExactNanosecondBoundaries(t *testing.T) { } commit(t, repo, spans, nil) e := NewExecutor(engine, 30) - spec := Dashboard{Name: "Endpoints", Time: Time{From: &start, To: &end}, Panels: []Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'", "service = 'checkout'"}, Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"http_route"}}}}} + spec := Dashboard{Name: "Endpoints", Time: Time{From: &start, To: &end}, Panels: []Panel{{ID: "p", Title: "Calls", Viz: "table", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'", "service = 'checkout'"}, Measures: []string{"count()", "p95(duration_ms)"}, By: []string{"http_route"}}}}} for _, warm := range []bool{false, true} { if warm { if _, err := engine.RefreshReadCaches(t.Context()); err != nil { diff --git a/internal/panel/measure.go b/internal/query/measure.go similarity index 99% rename from internal/panel/measure.go rename to internal/query/measure.go index 1f3f984c..b1f5b4c7 100644 --- a/internal/panel/measure.go +++ b/internal/query/measure.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/measure_compile.go b/internal/query/measure_compile.go similarity index 99% rename from internal/panel/measure_compile.go rename to internal/query/measure_compile.go index 1650cfdc..d4fe7f2a 100644 --- a/internal/panel/measure_compile.go +++ b/internal/query/measure_compile.go @@ -1,4 +1,4 @@ -package panel +package query import ( "strconv" diff --git a/internal/panel/measure_expr_test.go b/internal/query/measure_expr_test.go similarity index 98% rename from internal/panel/measure_expr_test.go rename to internal/query/measure_expr_test.go index 079a05af..a5afb95e 100644 --- a/internal/panel/measure_expr_test.go +++ b/internal/query/measure_expr_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -188,7 +188,7 @@ func TestMeasureBudgets(t *testing.T) { } } func exprDashboard(measures ...string) Dashboard { - d := Dashboard{Name: "Expressions", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "e", Title: "E", Viz: "table", Query: &Query{From: "spans", Measures: measures}}}} + d := Dashboard{Name: "Expressions", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "e", Title: "E", Viz: "table", Query: &Spec{From: "spans", Measures: measures}}}} Normalize(&d) return d } diff --git a/internal/panel/measure_syntax.go b/internal/query/measure_syntax.go similarity index 99% rename from internal/panel/measure_syntax.go rename to internal/query/measure_syntax.go index 37fad386..abe89592 100644 --- a/internal/panel/measure_syntax.go +++ b/internal/query/measure_syntax.go @@ -1,4 +1,4 @@ -package panel +package query // MeasureSyntaxCode identifies syntax failures independently of frontend copy. type MeasureSyntaxCode uint8 diff --git a/internal/panel/measure_test.go b/internal/query/measure_test.go similarity index 99% rename from internal/panel/measure_test.go rename to internal/query/measure_test.go index a91c1977..658d8024 100644 --- a/internal/panel/measure_test.go +++ b/internal/query/measure_test.go @@ -1,4 +1,4 @@ -package panel +package query import "testing" diff --git a/internal/panel/metric_buckets.go b/internal/query/metric_buckets.go similarity index 99% rename from internal/panel/metric_buckets.go rename to internal/query/metric_buckets.go index 0abd054d..d115ff3f 100644 --- a/internal/panel/metric_buckets.go +++ b/internal/query/metric_buckets.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/metric_crosscheck_test.go b/internal/query/metric_crosscheck_test.go similarity index 99% rename from internal/panel/metric_crosscheck_test.go rename to internal/query/metric_crosscheck_test.go index 49b2ad94..4b071e60 100644 --- a/internal/panel/metric_crosscheck_test.go +++ b/internal/query/metric_crosscheck_test.go @@ -1,6 +1,6 @@ //go:build readbench -package panel +package query import ( "fmt" @@ -21,7 +21,7 @@ func metricCrosscheckDashboard(name, measure string, start, end time.Time) Dashb by = []string{"attributes['state']"} } return Dashboard{Name: "Metric cross-check", Time: Time{From: &start, To: &end}, Panels: []Panel{{ - ID: "metric", Title: "Metric", Viz: "timeseries", Query: &Query{From: "metrics", + ID: "metric", Title: "Metric", Viz: "timeseries", Query: &Spec{From: "metrics", Where: []string{"name = " + sqlString(name)}, Measures: []string{measure}, By: by, Bucket: "1m"}, }}} } diff --git a/internal/panel/metric_histogram.go b/internal/query/metric_histogram.go similarity index 99% rename from internal/panel/metric_histogram.go rename to internal/query/metric_histogram.go index cdb35dca..96c3079d 100644 --- a/internal/panel/metric_histogram.go +++ b/internal/query/metric_histogram.go @@ -1,4 +1,4 @@ -package panel +package query import "strings" diff --git a/internal/panel/metric_histogram_test.go b/internal/query/metric_histogram_test.go similarity index 99% rename from internal/panel/metric_histogram_test.go rename to internal/query/metric_histogram_test.go index 16f93e20..37578065 100644 --- a/internal/panel/metric_histogram_test.go +++ b/internal/query/metric_histogram_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -165,7 +165,7 @@ func TestHistogramOtherRecomputesQuantilesAndWeightedMean(t *testing.T) { measure, alias string want float64 }{{"p95(value)", "p95", 19.375}, {"avg(value)", "avg", 13}, {"sum(value)", "sum", 1300}} { - r := runMetricPanel(t, e, Panel{Viz: viz, Options: &Options{Top: 1}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: viz, Options: &Options{Top: 1}, Query: &Spec{ From: "metrics", Where: []string{"name='net'"}, By: by, Bucket: bucket, Measures: []string{tc.measure}, }}, fixtureStart, fixtureStart.Add(time.Minute)) diff --git a/internal/panel/metric_intervals_test.go b/internal/query/metric_intervals_test.go similarity index 98% rename from internal/panel/metric_intervals_test.go rename to internal/query/metric_intervals_test.go index dad04162..8a355cf5 100644 --- a/internal/panel/metric_intervals_test.go +++ b/internal/query/metric_intervals_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -203,7 +203,7 @@ func TestMetricCounterTotalsHoldAcrossStaggeredExportIntervals(t *testing.T) { } } } - r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, fixtureStart, fixtureStart.Add(15*time.Minute)) + r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, fixtureStart, fixtureStart.Add(15*time.Minute)) if got := r.Frame.Totals[len(r.Frame.Totals)-1]; got != 21.0 { t.Fatalf("stat=%v want 21", got) } diff --git a/internal/panel/metric_measure_bench_test.go b/internal/query/metric_measure_bench_test.go similarity index 95% rename from internal/panel/metric_measure_bench_test.go rename to internal/query/metric_measure_bench_test.go index 17621493..bffa6d91 100644 --- a/internal/panel/metric_measure_bench_test.go +++ b/internal/query/metric_measure_bench_test.go @@ -1,6 +1,6 @@ //go:build readbench -package panel +package query import ( "database/sql" @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/labstack/fanout/internal/query" - "github.com/labstack/fanout/internal/query/querytest" + "github.com/labstack/fanout/internal/engine" + "github.com/labstack/fanout/internal/engine/querytest" "github.com/labstack/fanout/internal/telemetry" ) @@ -30,7 +30,7 @@ func TestMetricMeasuresExecuteAtReviewScale(t *testing.T) { if _, err := db.Exec("SET TimeZone='UTC'"); err != nil { t.Fatal(err) } - if err := querytest.CreateTables(db, query.CreateCacheTables); err != nil { + if err := querytest.CreateTables(db, engine.CreateCacheTables); err != nil { t.Fatal(err) } if _, err := db.Exec("DROP TABLE telemetry.metrics"); err != nil { @@ -41,7 +41,7 @@ func TestMetricMeasuresExecuteAtReviewScale(t *testing.T) { t.Fatal(err) } t.Logf("engine=%s threads=%s memory_limit=%s (defaults)", version, threads, memory) - e := NewExecutor(&query.Duck{DB: db}, 30) + e := NewExecutor(&engine.Duck{DB: db}, 30) start, end := fixtureStart, fixtureStart.Add(time.Hour) e.now = func() time.Time { return end } for _, kind := range []string{"gauge", "counter", "histogram"} { @@ -89,7 +89,7 @@ func TestMetricMeasuresExecuteAtReviewScale(t *testing.T) { if _, err := db.Exec("CREATE OR REPLACE VIEW telemetry.metrics AS SELECT * FROM read_parquet(" + pattern + ",hive_partitioning=false,union_by_name=false)"); err != nil { t.Fatal(err) } - if err := query.CreateViews(db); err != nil { + if err := engine.CreateViews(db); err != nil { t.Fatal(err) } var rows, series int64 @@ -132,7 +132,7 @@ func TestMetricMeasuresExecuteAtReviewScale(t *testing.T) { } } for _, shape := range shapes { - p := Panel{ID: shape.id, Title: shape.id, Viz: shape.viz, Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: shape.measures, By: shape.by}} + p := Panel{ID: shape.id, Title: shape.id, Viz: shape.viz, Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: shape.measures, By: shape.by}} if shape.interval > 0 { p.Query.Bucket = "1m" if shape.interval == 10*time.Second { diff --git a/internal/panel/metric_measures.go b/internal/query/metric_measures.go similarity index 99% rename from internal/panel/metric_measures.go rename to internal/query/metric_measures.go index dc506270..6f506d88 100644 --- a/internal/panel/metric_measures.go +++ b/internal/query/metric_measures.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/metric_measures_test.go b/internal/query/metric_measures_test.go similarity index 92% rename from internal/panel/metric_measures_test.go rename to internal/query/metric_measures_test.go index d6fa178b..4c8a12f0 100644 --- a/internal/panel/metric_measures_test.go +++ b/internal/query/metric_measures_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "math" @@ -14,7 +14,7 @@ func runMetricMeasure(t *testing.T, e *Executor, measures []string, bucket strin if bucket != "" { viz = "timeseries" } - return runMetricPanel(t, e, Panel{Viz: viz, Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: measures, By: by, Bucket: bucket}}, start, end) + return runMetricPanel(t, e, Panel{Viz: viz, Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: measures, By: by, Bucket: bucket}}, start, end) } func TestMetricRateUsesCoveredElapsedTime(t *testing.T) { @@ -37,7 +37,7 @@ func TestMetricRateUsesCoveredElapsedTime(t *testing.T) { } } } - r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, fixtureStart, fixtureStart.Add(3*time.Minute)) + r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, fixtureStart, fixtureStart.Add(3*time.Minute)) if r.Frame.Totals[len(r.Frame.Totals)-1] != 1.0 { t.Fatalf("totals=%v", r.Frame.Totals) } @@ -218,10 +218,10 @@ func TestMetricAuxiliaryAggregatesUseSeriesRates(t *testing.T) { } start, end := fixtureStart, fixtureStart.Add(3*time.Minute) panels := []Panel{ - {ID: "stat", Title: "Rate", Viz: "stat", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, - {ID: "table", Title: "Rate", Viz: "table", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}}, Options: &Options{Columns: []ColumnFormat{{Field: "rate", Format: "sparkline"}}}}, - {ID: "items", Title: "Rates", Viz: "scatter", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate() as x", "last(value) as y"}, By: []string{"service"}}}, - {ID: "states", Title: "Rates", Viz: "state_timeline", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "1m"}, Thresholds: []Threshold{{Value: 2, Status: "bad"}}}, + {ID: "stat", Title: "Rate", Viz: "stat", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}}}, + {ID: "table", Title: "Rate", Viz: "table", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}}, Options: &Options{Columns: []ColumnFormat{{Field: "rate", Format: "sparkline"}}}}, + {ID: "items", Title: "Rates", Viz: "scatter", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate() as x", "last(value) as y"}, By: []string{"service"}}}, + {ID: "states", Title: "Rates", Viz: "state_timeline", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "1m"}, Thresholds: []Threshold{{Value: 2, Status: "bad"}}}, } compare := true results, err := e.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Metrics", Time: Time{From: &start, To: &end}, Panels: panels}, Compare: &compare}) @@ -261,7 +261,7 @@ func TestMetricRankingRecomputesOtherFromSeriesRates(t *testing.T) { m.ServiceName = p.id insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Spec{ From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "5m", }}, fixtureStart, fixtureStart.Add(2*time.Minute)) dims, rates := metricValues(t, r, "service"), metricValues(t, r, "rate") @@ -309,7 +309,7 @@ func TestMetricRankingUsesWholeWindowRatherThanBucketRates(t *testing.T) { m.ServiceName = p.service insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Spec{ From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, By: []string{"service"}, Bucket: "30s", }}, fixtureStart, fixtureStart.Add(2*time.Minute)) names := metricValues(t, r, "service") @@ -328,7 +328,7 @@ func TestMetricSeriesFiltersPreserveLiteralNamesAndAttributeKeys(t *testing.T) { m.Attributes = map[string]any{"metric_input": "metric_previous"} insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "table", Query: &Query{From: "metrics", Where: []string{ + r := runMetricPanel(t, e, Panel{Viz: "table", Query: &Spec{From: "metrics", Where: []string{ "name='metric_points'", "attributes['metric_input']='metric_previous'", }, Measures: []string{"rate()", "sum(value)"}}}, fixtureStart, fixtureStart.Add(2*time.Minute)) if !reflect.DeepEqual(metricValues(t, r, "rate"), []any{1.0}) || !reflect.DeepEqual(metricValues(t, r, "sum"), []any{60.0}) { @@ -370,7 +370,7 @@ func TestMetricOtherRecomputesSeriesMeansPercentilesAndDistinctUnion(t *testing. } } // Rank the full window, then recompute the folded measure from series. - r := runMetricPanel(t, e, Panel{Viz: "bar", Options: &Options{Top: 1}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: "bar", Options: &Options{Top: 1}, Query: &Spec{ From: "metrics", Where: []string{"name='net'"}, By: []string{"name", "service"}, Measures: []string{tc.measure + " as folded"}, }}, fixtureStart, fixtureStart.Add(time.Minute)) dims, values := metricValues(t, r, "service"), metricValues(t, r, "folded") @@ -479,7 +479,7 @@ func TestMetricTableTrendShareUsesCompleteScopeBeforeDisplayedTuples(t *testing. m.Type, m.Monotonic, m.Temporality = "gauge", false, "" insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "table", Options: &Options{Columns: []ColumnFormat{{Field: "portion", Format: "sparkline"}}}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: "table", Options: &Options{Columns: []ColumnFormat{{Field: "portion", Format: "sparkline"}}}, Query: &Spec{ From: "metrics", Where: []string{"name='net'"}, By: []string{"service"}, Measures: []string{"count()", "share() as portion", "sum(value)"}, Sort: "portion", Limit: 1, }}, fixtureStart, fixtureStart.Add(2*time.Minute)) want := 200.0 / 3.0 @@ -510,7 +510,7 @@ func TestMetricLastExpiresRestartedSeriesAtFiveMinutes(t *testing.T) { } { // Keep a three-minute stat window while its end advances past expiry. end := fixtureStart.Add(tc.end) - r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"last(value)"}}}, end.Add(-3*time.Minute), end) + r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"last(value)"}}}, end.Add(-3*time.Minute), end) if got := r.Frame.Totals[len(r.Frame.Totals)-1]; got != tc.want { t.Fatalf("end=%s last=%v want %v", tc.end, got, tc.want) } @@ -537,7 +537,7 @@ func TestMetricLastStatCountsOnlyRecentlyReportingSeries(t *testing.T) { m.Attributes = map[string]any{"series": p.id} insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"last(value)"}}}, fixtureStart, end) + r := runMetricPanel(t, e, Panel{Viz: "stat", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"last(value)"}}}, fixtureStart, end) if got := r.Frame.Totals[len(r.Frame.Totals)-1]; got != 30.0 { t.Fatalf("long window last=%v", got) } @@ -560,7 +560,7 @@ func TestMetricPointOnlyMeasuresSkipLookback(t *testing.T) { } } for _, measure := range []string{"min(value)", "max(value)", "avg(hist_sum)", "p95(hist_sum)"} { - p := Panel{Query: &Query{From: "metrics", Measures: []string{measure}}} + p := Panel{Query: &Spec{From: "metrics", Measures: []string{measure}}} scope := Scope{Start: fixtureStart, End: fixtureStart.Add(time.Minute)} if read := metricReadScope(&p, scope); !reflect.DeepEqual(read, scope) { t.Fatalf("%s read=%+v", measure, read) @@ -575,7 +575,7 @@ func TestMetricMultiDayBucketsAndTableTrendsUseEpochOrigin(t *testing.T) { m.Type, m.Monotonic, m.Temporality = "gauge", false, "" insertMetrics(t, db, m) } - p := Panel{ID: "m", Title: "Metric", Viz: "table", Query: &Query{From: "metrics", Where: []string{"name='net'"}, By: []string{"service"}, Measures: []string{"avg(value)"}}, Options: &Options{Columns: []ColumnFormat{{Field: "avg", Format: "sparkline"}}}} + p := Panel{ID: "m", Title: "Metric", Viz: "table", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, By: []string{"service"}, Measures: []string{"avg(value)"}}, Options: &Options{Columns: []ColumnFormat{{Field: "avg", Format: "sparkline"}}}} d := Dashboard{Name: "Metrics", Panels: []Panel{p}} Normalize(&d) checked, problems, err := Check(t.Context(), e.engine, &d) diff --git a/internal/panel/metric_name_test.go b/internal/query/metric_name_test.go similarity index 91% rename from internal/panel/metric_name_test.go rename to internal/query/metric_name_test.go index 769650b3..e7cd55a7 100644 --- a/internal/panel/metric_name_test.go +++ b/internal/query/metric_name_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" @@ -35,7 +35,7 @@ func TestMetricNameRuleUsesCheckedEqualities(t *testing.T) { } { t.Run(tc.label, func(t *testing.T) { d := Dashboard{Name: "Metrics", Variables: []Variable{{Name: "metric", Kind: "custom", Options: []string{"net", "cpu"}, Default: "net", IncludeAll: tc.all, Multi: tc.multi}}, - Panels: []Panel{{ID: "metric", Title: "Metric", Viz: "table", Query: &Query{From: "metrics", Where: []string{tc.where}, Measures: []string{tc.measure}, By: tc.by}}}} + Panels: []Panel{{ID: "metric", Title: "Metric", Viz: "table", Query: &Spec{From: "metrics", Where: []string{tc.where}, Measures: []string{tc.measure}, By: tc.by}}}} Normalize(&d) _, problems, err := Check(t.Context(), e.engine, &d) if err != nil { @@ -72,7 +72,7 @@ func TestMetricKindMismatchHasActionableDiagnosis(t *testing.T) { m.Monotonic = false m.Name = "system.memory.usage" insertMetrics(t, db, m) - r := runMetricPanel(t, e, Panel{Viz: "timeseries", Query: &Query{From: "metrics", Where: []string{"name='system.memory.usage'"}, Measures: []string{"rate()"}, Bucket: "1m"}}, fixtureStart, fixtureStart.Add(time.Minute)) + r := runMetricPanel(t, e, Panel{Viz: "timeseries", Query: &Spec{From: "metrics", Where: []string{"name='system.memory.usage'"}, Measures: []string{"rate()"}, Bucket: "1m"}}, fixtureStart, fixtureStart.Add(time.Minute)) want := "A rate needs a counter; system.memory.usage is an updown. Show its latest or average value instead." if r.Status != StatusEmpty || r.Diagnosis != want { t.Fatalf("diagnosis=%+v", r) @@ -92,7 +92,7 @@ func TestMetricHistogramDiagnosisSuggestsCompatibleMeasuresWithoutAliases(t *tes func TestMetricNameInsideAndHintsAtSeparateWhereEntry(t *testing.T) { e, _ := metricFixture(t) - d := Dashboard{Name: "Metrics", Panels: []Panel{{ID: "m", Title: "Metric", Viz: "table", Query: &Query{From: "metrics", Where: []string{"service='svc' AND (name='net' AND type='counter')"}, Measures: []string{"rate()"}}}}} + d := Dashboard{Name: "Metrics", Panels: []Panel{{ID: "m", Title: "Metric", Viz: "table", Query: &Spec{From: "metrics", Where: []string{"service='svc' AND (name='net' AND type='counter')"}, Measures: []string{"rate()"}}}}} Normalize(&d) _, problems, err := Check(t.Context(), e.engine, &d) if err != nil { @@ -119,7 +119,7 @@ func TestMetricNameAllGroupsDifferentMetricsSeparately(t *testing.T) { start, end := fixtureStart, fixtureStart.Add(time.Minute) d := Dashboard{Name: "Metrics", Time: Time{From: &start, To: &end}, Variables: []Variable{{ Name: "metric", Kind: "custom", Options: []string{"net", "cpu"}, IncludeAll: true, Default: AllValue, - }}, Panels: []Panel{{ID: "metrics", Title: "Metrics", Viz: "table", Query: &Query{ + }}, Panels: []Panel{{ID: "metrics", Title: "Metrics", Viz: "table", Query: &Spec{ From: "metrics", Where: []string{"name=$metric"}, Measures: []string{"sum(value)"}, By: []string{"name"}, }}}} results, err := e.Run(t.Context(), RunRequest{Dashboard: d, Vars: map[string]Value{"metric": {All: true}}}) @@ -147,7 +147,7 @@ func TestMetricTopNamesNeverCombineDifferentMetricsIntoOther(t *testing.T) { m.Type, m.Monotonic, m.Temporality = "gauge", false, "" insertMetrics(t, db, m) } - r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Query{ + r := runMetricPanel(t, e, Panel{Viz: "timeseries", Options: &Options{Top: 1}, Query: &Spec{ From: "metrics", Measures: []string{"sum(value)"}, By: []string{"name"}, Bucket: "1m", }}, fixtureStart, fixtureStart.Add(time.Minute)) names, values := metricValues(t, r, "name"), metricValues(t, r, "sum") diff --git a/internal/panel/metric_schema_test.go b/internal/query/metric_schema_test.go similarity index 99% rename from internal/panel/metric_schema_test.go rename to internal/query/metric_schema_test.go index c63f3e92..983ff49a 100644 --- a/internal/panel/metric_schema_test.go +++ b/internal/query/metric_schema_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" diff --git a/internal/panel/metric_series.go b/internal/query/metric_series.go similarity index 99% rename from internal/panel/metric_series.go rename to internal/query/metric_series.go index f85bfa1e..933de70e 100644 --- a/internal/panel/metric_series.go +++ b/internal/query/metric_series.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/metric_series_test.go b/internal/query/metric_series_test.go similarity index 95% rename from internal/panel/metric_series_test.go rename to internal/query/metric_series_test.go index df1c1d3e..4e02d589 100644 --- a/internal/panel/metric_series_test.go +++ b/internal/query/metric_series_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "bytes" @@ -185,7 +185,7 @@ func TestMetricReadScopeIncludesSeparateLookbackBatch(t *testing.T) { t.Fatal(err) } } - p := Panel{ID: "rate", Title: "Rate", Viz: "timeseries", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, Bucket: "1m"}} + p := Panel{ID: "rate", Title: "Rate", Viz: "timeseries", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"rate()"}, Bucket: "1m"}} original := Scope{Start: at, End: at.Add(2 * time.Minute), Interval: time.Minute} read := metricReadScope(&p, original) if !read.Start.Equal(at.Add(-10*time.Minute)) || !original.Start.Equal(at) { @@ -226,7 +226,7 @@ func TestHistogramPanelsShareResetIncreases(t *testing.T) { insertMetrics(t, db, m) } for _, viz := range []string{"histogram", "heatmap"} { - q := &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} + q := &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}} if viz == "heatmap" { q.Bucket = "1m" } @@ -257,7 +257,7 @@ func TestHistogramPanelsShareResetIncreases(t *testing.T) { m := metricHistogram(fixtureStart, "[10]", "[3,2]", 5, 30, "a") m.Temporality = "delta" insertMetrics(t, db, m) - h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Query{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, fixtureStart, fixtureStart.Add(time.Minute)) + h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Spec{From: "metrics", Where: []string{"name='net'"}, Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, fixtureStart, fixtureStart.Add(time.Minute)) if !reflect.DeepEqual(metricValues(t, h, "count"), []any{3.0, 2.0}) { t.Fatalf("delta counts=%+v", h.Frame) } @@ -358,7 +358,7 @@ func TestMetricHistogramRawKeepsZeroBoundsAndEmptyBoundLists(t *testing.T) { !reflect.DeepEqual(metricValues(t, r, "hi"), []any{-10.0, 0.0, 10.0, nil, nil}) { t.Fatalf("raw histogram lost bounds: %+v", r.Frame) } - h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Query{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, scope.Start, scope.End) + h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Spec{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, scope.Start, scope.End) if !reflect.DeepEqual(metricValues(t, h, "count"), []any{2.0, 3.0}) { t.Fatalf("display retained zero weights: %+v", h.Frame) } @@ -373,7 +373,7 @@ func TestMetricHistogramReadsSeparateLookbackBatch(t *testing.T) { } } e := NewExecutor(engine, 30) - p := Panel{Viz: "heatmap", Query: &Query{From: "metrics", Where: []string{"name='net'", "attributes['series']='a'"}, Measures: []string{"count()"}, Bucket: "1m", Histogram: &Histogram{Field: "value", Buckets: "explicit"}}} + p := Panel{Viz: "heatmap", Query: &Spec{From: "metrics", Where: []string{"name='net'", "attributes['series']='a'"}, Measures: []string{"count()"}, Bucket: "1m", Histogram: &Histogram{Field: "value", Buckets: "explicit"}}} r := runMetricPanel(t, e, p, fixtureStart, fixtureStart.Add(2*time.Minute)) if !reflect.DeepEqual(metricValues(t, r, "count"), []any{1.0, 2.0}) || r.FromMS != fixtureStart.UnixMilli() || r.ToMS != fixtureStart.Add(2*time.Minute).UnixMilli() { t.Fatalf("lookback or visible window: %+v", r) @@ -382,7 +382,7 @@ func TestMetricHistogramReadsSeparateLookbackBatch(t *testing.T) { func TestMetricReadScopeLeavesSQLAndOtherSignalsUnchanged(t *testing.T) { scope := Scope{Start: fixtureStart, End: fixtureStart.Add(time.Minute)} - for _, p := range []Panel{{SQL: "SELECT * FROM metrics WHERE $__window(time)"}, {Query: &Query{From: "spans"}}, {Query: &Query{From: "logs"}}} { + for _, p := range []Panel{{SQL: "SELECT * FROM metrics WHERE $__window(time)"}, {Query: &Spec{From: "spans"}}, {Query: &Spec{From: "logs"}}} { if got := metricReadScope(&p, scope); !reflect.DeepEqual(got, scope) { t.Fatalf("unexpected lookback: %+v", got) } @@ -461,7 +461,7 @@ func TestHistogramIncreaseRebinsChangedBounds(t *testing.T) { t.Fatalf("rebinned increases=%+v", r.Frame) } if tc.name == "growing_exponential_range" { - h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Query{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, scope.Start, scope.End) + h := runMetricPanel(t, e, Panel{Viz: "histogram", Query: &Spec{From: "metrics", Measures: []string{"count()"}, Histogram: &Histogram{Field: "value", Buckets: "explicit"}}}, scope.Start, scope.End) if !reflect.DeepEqual(metricValues(t, h, "count"), []any{2.0}) { t.Fatalf("growing range distribution=%+v", h.Frame) } diff --git a/internal/panel/metric_view_test.go b/internal/query/metric_view_test.go similarity index 99% rename from internal/panel/metric_view_test.go rename to internal/query/metric_view_test.go index ffa40481..aae27f3a 100644 --- a/internal/panel/metric_view_test.go +++ b/internal/query/metric_view_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/panel_bench_data_test.go b/internal/query/panel_bench_data_test.go similarity index 98% rename from internal/panel/panel_bench_data_test.go rename to internal/query/panel_bench_data_test.go index e86964a4..fd6908c4 100644 --- a/internal/panel/panel_bench_data_test.go +++ b/internal/query/panel_bench_data_test.go @@ -1,6 +1,6 @@ //go:build readbench -package panel +package query import ( "crypto/sha256" @@ -18,7 +18,7 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" "github.com/labstack/fanout/internal/queryrows" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" @@ -574,7 +574,7 @@ func panelTraceIndex(dir string) (err error) { return err } -func panelBenchEngine(tb testing.TB, data panelBenchData) (*query.Duck, config.Config) { +func panelBenchEngine(tb testing.TB, data panelBenchData) (*engine.Duck, config.Config) { tb.Helper() // Load validates authentication even though this harness never serves HTTP. // Only a dummy test auth value is supplied; storage sizing stays automatic. @@ -586,7 +586,7 @@ func panelBenchEngine(tb testing.TB, data panelBenchData) (*query.Duck, config.C if err != nil { tb.Fatal(err) } - engine, err := query.NewDuck(tb.Context(), cfg, repo) + engine, err := engine.NewDuck(tb.Context(), cfg, repo) if err != nil { repo.Close() tb.Fatal(err) @@ -599,7 +599,7 @@ func panelBenchEngine(tb testing.TB, data panelBenchData) (*query.Duck, config.C return engine, cfg } -func assertPanelReplay(t *testing.T, data panelBenchData, want int64) *query.Duck { +func assertPanelReplay(t *testing.T, data panelBenchData, want int64) *engine.Duck { t.Helper() engine, _ := panelBenchEngine(t, data) var count, distinct int64 diff --git a/internal/panel/panel_bench_test.go b/internal/query/panel_bench_test.go similarity index 97% rename from internal/panel/panel_bench_test.go rename to internal/query/panel_bench_test.go index 1a27ef8c..e84bf8f9 100644 --- a/internal/panel/panel_bench_test.go +++ b/internal/query/panel_bench_test.go @@ -1,6 +1,6 @@ //go:build readbench -package panel +package query import ( "crypto/sha256" @@ -129,7 +129,7 @@ func BenchmarkPanelQueries24Hours(b *testing.B) { b.Logf("dataset=%s", raw) dashboard := panelBenchmarkDashboard(data) shapes := append([]Panel(nil), dashboard.Panels...) - shapes = append(shapes, Panel{ID: "p95_by_service", Title: "p95 by service", Viz: "table", Query: &Query{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}}}, Panel{ID: "error_rate_window", Title: "Whole window error rate", Viz: "table", Query: &Query{From: "spans", Measures: []string{"error_rate()"}}}) + shapes = append(shapes, Panel{ID: "p95_by_service", Title: "p95 by service", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"p95(duration_ms)"}, By: []string{"service"}}}, Panel{ID: "error_rate_window", Title: "Whole window error rate", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"error_rate()"}}}) shapes = append(shapes, panelBenchmarkMetricShapes(b, panelBenchmarkMetricNames(b, engine, data))...) var failing []string for _, shape := range shapes { @@ -163,7 +163,7 @@ func panelBenchmarkDashboard(data panelBenchData) Dashboard { literal := "'" + strings.ReplaceAll(service, "'", "''") + "'" d := Dashboard{Name: "Dashboard performance", Time: Time{From: &data.Start, To: &data.End, Refresh: "off"}, Variables: []Variable{{Name: "service", Kind: "query", From: "spans", Field: "service", Default: AllValue, IncludeAll: true}}} add := func(id, viz, from string, measures, where, by []string, bucket string) { - d.Panels = append(d.Panels, Panel{ID: id, Title: id, Viz: viz, Width: 4, Height: "s", Query: &Query{From: from, Measures: measures, Where: where, By: by, Bucket: bucket}}) + d.Panels = append(d.Panels, Panel{ID: id, Title: id, Viz: viz, Width: 4, Height: "s", Query: &Spec{From: from, Measures: measures, Where: where, By: by, Bucket: bucket}}) } add("traces_all", "table", "spans", []string{"count_distinct(trace_id)"}, []string{"trace_id <> ''"}, nil, "") add("traces_checkout", "table", "spans", []string{"count_distinct(trace_id)"}, []string{"trace_id <> ''", "service = " + literal}, nil, "") @@ -202,7 +202,7 @@ func panelBenchmarkMetricShapes(tb testing.TB, names map[string]string) []Panel continue } literal := "'" + strings.ReplaceAll(name, "'", "''") + "'" - shapes = append(shapes, Panel{ID: shape.id, Title: shape.id, Viz: "timeseries", Query: &Query{From: "metrics", Measures: []string{shape.measure}, Where: []string{"type = '" + shape.kind + "'", "name = " + literal}, By: shape.by, Bucket: "auto"}}) + shapes = append(shapes, Panel{ID: shape.id, Title: shape.id, Viz: "timeseries", Query: &Spec{From: "metrics", Measures: []string{shape.measure}, Where: []string{"type = '" + shape.kind + "'", "name = " + literal}, By: shape.by, Bucket: "auto"}}) tb.Logf("metric shape=%s type=%s name=%q measure=%s", shape.id, shape.kind, name, shape.measure) } return shapes diff --git a/internal/panel/params.go b/internal/query/params.go similarity index 99% rename from internal/panel/params.go rename to internal/query/params.go index fd497885..1d09a7e8 100644 --- a/internal/panel/params.go +++ b/internal/query/params.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" diff --git a/internal/panel/params_test.go b/internal/query/params_test.go similarity index 99% rename from internal/panel/params_test.go rename to internal/query/params_test.go index 93dbbd60..26da5555 100644 --- a/internal/panel/params_test.go +++ b/internal/query/params_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/pattern_context_test.go b/internal/query/pattern_context_test.go similarity index 93% rename from internal/panel/pattern_context_test.go rename to internal/query/pattern_context_test.go index 059fb2c3..fa543f55 100644 --- a/internal/panel/pattern_context_test.go +++ b/internal/query/pattern_context_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -51,7 +51,7 @@ func TestPreviewPatternContextEngine(t *testing.T) { counter := &previewPatternCounter{Engine: engine} e := NewExecutor(counter, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Context", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "auto"}}}} + d := Dashboard{Name: "Context", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "auto"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -103,7 +103,7 @@ func TestPreviewPatternContextEngine(t *testing.T) { } func TestPatternContextIsAggregated(t *testing.T) { - p := &Panel{ID: "p", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}}} + p := &Panel{ID: "p", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}}} c, err := compileRows(p, nil, Scope{Start: compileStart, End: compileEnd, Interval: time.Minute}) if err != nil { t.Fatal(err) @@ -135,7 +135,7 @@ func TestPreviewPatternContextBudgetsEngine(t *testing.T) { e.now = func() time.Time { return fixtureStart.Add(3 * time.Hour) } d := Dashboard{Name: "Budgets", Time: Time{Range: "3h"}} for i := 0; i < 30; i++ { - d.Panels = append(d.Panels, Panel{ID: fmt.Sprintf("p%d", i), Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "10s", Limit: 80}}) + d.Panels = append(d.Panels, Panel{ID: fmt.Sprintf("p%d", i), Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "10s", Limit: 80}}) } got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { diff --git a/internal/panel/preview_patterns_test.go b/internal/query/preview_patterns_test.go similarity index 95% rename from internal/panel/preview_patterns_test.go rename to internal/query/preview_patterns_test.go index c2efa650..f1a81bad 100644 --- a/internal/panel/preview_patterns_test.go +++ b/internal/query/preview_patterns_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -24,7 +24,7 @@ func TestPreviewPatternContextEngineScoped(t *testing.T) { commit(t, repo, nil, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Scoped context", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", Where: []string{"namespace = 'shop'"}, By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "auto"}}}} + d := Dashboard{Name: "Scoped context", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", Where: []string{"namespace = 'shop'"}, By: []string{"body_template"}, Measures: []string{"count()"}, Bucket: "auto"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || len(got) != 1 || got[0].Status != StatusOK || got[0].Frame == nil { t.Fatalf("patterns: %+v %v", got, err) diff --git a/internal/panel/problems.go b/internal/query/problems.go similarity index 99% rename from internal/panel/problems.go rename to internal/query/problems.go index 07f944a9..a34d5690 100644 --- a/internal/panel/problems.go +++ b/internal/query/problems.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/problems_test.go b/internal/query/problems_test.go similarity index 98% rename from internal/panel/problems_test.go rename to internal/query/problems_test.go index 0583ec17..d8aaff28 100644 --- a/internal/panel/problems_test.go +++ b/internal/query/problems_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" diff --git a/internal/panel/ranking_expr_test.go b/internal/query/ranking_expr_test.go similarity index 99% rename from internal/panel/ranking_expr_test.go rename to internal/query/ranking_expr_test.go index 13a5247a..c63d059c 100644 --- a/internal/panel/ranking_expr_test.go +++ b/internal/query/ranking_expr_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/retryability_test.go b/internal/query/retryability_test.go similarity index 96% rename from internal/panel/retryability_test.go rename to internal/query/retryability_test.go index e7d14e4f..690bcac8 100644 --- a/internal/panel/retryability_test.go +++ b/internal/query/retryability_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -58,7 +58,7 @@ func TestQueryDeadlineIsRetryable(t *testing.T) { e := newFixtureExecutor(t) e.engine = &slowBatchEngine{Engine: e.engine} e.timeout = 5 * time.Millisecond - results, err := e.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Timeout", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}}}}}}) + results, err := e.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Timeout", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}}}}}}) if err != nil || len(results) != 1 { t.Fatalf("results=%+v err=%v", results, err) } diff --git a/internal/panel/rollup_panels.go b/internal/query/rollup_panels.go similarity index 99% rename from internal/panel/rollup_panels.go rename to internal/query/rollup_panels.go index 135acbb7..81f83d9d 100644 --- a/internal/panel/rollup_panels.go +++ b/internal/query/rollup_panels.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/rollup_panels_test.go b/internal/query/rollup_panels_test.go similarity index 89% rename from internal/panel/rollup_panels_test.go rename to internal/query/rollup_panels_test.go index 856fc347..ee8822fb 100644 --- a/internal/panel/rollup_panels_test.go +++ b/internal/query/rollup_panels_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -28,8 +28,8 @@ func TestRollupPanelsReuseServices(t *testing.T) { e.SetRollupReader(reader) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } d := Dashboard{Name: "Overview", Time: Time{Range: "1h"}, Panels: []Panel{ - {ID: "health", Title: "Health", Viz: "health", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'"}}}, - {ID: "map", Title: "Map", Viz: "service_map", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'"}}}, + {ID: "health", Title: "Health", Viz: "health", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'"}}}, + {ID: "map", Title: "Map", Viz: "service_map", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'"}}}, }} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -67,7 +67,7 @@ func TestRollupPanelsAggregateContract(t *testing.T) { e := NewExecutor(engine, 30) e.SetRollupReader(reader) e.now = func() time.Time { return at.Add(time.Hour) } - d := Dashboard{Name: "Health", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'", "'checkout' = service"}}}}} + d := Dashboard{Name: "Health", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'", "'checkout' = service"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -89,7 +89,7 @@ func TestRollupPanelsAggregateContract(t *testing.T) { func TestRollupPanelsRejectCastSemantics(t *testing.T) { e := newFixtureExecutor(t) for _, where := range []string{"CAST(service AS BOOLEAN) = CAST('true' AS BOOLEAN)", "service = CAST('checkout' AS BOOLEAN)"} { - d := Dashboard{Name: "Cast", Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Query{From: "spans", Where: []string{where}}}}} + d := Dashboard{Name: "Cast", Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Spec{From: "spans", Where: []string{where}}}}} if err := e.Validate(t.Context(), &d); err == nil { t.Fatalf("silently discarded cast in %s", where) } @@ -109,7 +109,7 @@ func TestRollupPanelsRejectNormalizedEquality(t *testing.T) { func TestRollupPanelsScopesAndSelection(t *testing.T) { e := newFixtureExecutor(t) for _, viz := range []string{"health", "service_map"} { - p := Panel{ID: "p", Title: "P", Viz: viz, Query: &Query{From: "spans"}} + p := Panel{ID: "p", Title: "P", Viz: viz, Query: &Spec{From: "spans"}} scope := Scope{Start: fixtureStart, End: fixtureStart.Add(time.Hour), Vars: map[string]Value{"s": {Values: []string{"checkout"}}}} field, value, err := rollupFilterValue(t.Context(), e.engine, Filter{Source: "$s = service"}, scope) if err != nil || field != "service" || value != "checkout" { @@ -137,7 +137,7 @@ func TestRollupPanelsScopesAndSelection(t *testing.T) { func TestRollupPanelsValidateScopeOnly(t *testing.T) { for _, viz := range []string{"health", "service_map"} { - for _, q := range []*Query{{From: "logs"}, {From: "spans", Measures: []string{"count()"}}, {From: "spans", By: []string{"service"}}, {From: "spans", Bucket: "auto"}, {From: "spans", Sort: "spans"}} { + for _, q := range []*Spec{{From: "logs"}, {From: "spans", Measures: []string{"count()"}}, {From: "spans", By: []string{"service"}}, {From: "spans", Bucket: "auto"}, {From: "spans", Sort: "spans"}} { d := Dashboard{Name: "Scope", Panels: []Panel{{ID: "p", Title: "P", Viz: viz, Query: q}}} Normalize(&d) if len(Validate(&d)) == 0 { @@ -168,7 +168,7 @@ func TestRollupPanelsApplyServiceBeforeLimit(t *testing.T) { e := NewExecutor(engine, 30) e.SetRollupReader(observability.New(engine, engine, 30)) e.now = func() time.Time { return at.Add(time.Hour) } - d := Dashboard{Name: "Quiet", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'", "service = 'quiet'"}}}, {ID: "m", Title: "M", Viz: "service_map", Query: &Query{From: "spans", Where: []string{"namespace = 'shop'", "service = 'quiet'"}}}}} + d := Dashboard{Name: "Quiet", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "h", Title: "H", Viz: "health", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'", "service = 'quiet'"}}}, {ID: "m", Title: "M", Viz: "service_map", Query: &Spec{From: "spans", Where: []string{"namespace = 'shop'", "service = 'quiet'"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -193,7 +193,7 @@ func TestRollupPanelsRejectUnrepresentableFilters(t *testing.T) { {"service = operation", "rollup equality needs a literal or variable"}, } for _, tc := range cases { - d := Dashboard{Name: "Map", Panels: []Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &Query{From: "spans", Where: []string{tc.where}}}}} + d := Dashboard{Name: "Map", Panels: []Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &Spec{From: "spans", Where: []string{tc.where}}}}} err := e.Validate(t.Context(), &d) var got Problems want := Problem{Path: "panels[0].query.where[0]", Message: tc.message, Hint: "use namespace or service equality with a literal or single-value variable"} @@ -222,7 +222,7 @@ func TestHealthPanelReadsOnlySummaryAndTrendForScopedRollups(t *testing.T) { executor := NewExecutor(engine, 30) executor.SetRollupReader(observability.New(counter, engine, 30)) executor.now = func() time.Time { return at.Add(time.Hour) } - out, err := executor.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Health", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "health", Title: "Health", Viz: "health", Query: &Query{From: "spans", Where: []string{"namespace='shop'", "service='checkout'"}}}}}}) + out, err := executor.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Health", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "health", Title: "Health", Viz: "health", Query: &Spec{From: "spans", Where: []string{"namespace='shop'", "service='checkout'"}}}}}}) if err != nil || len(out) != 1 || out[0].Status != "ok" { t.Fatalf("health panel: %+v %v", out, err) } diff --git a/internal/panel/rowpanels.go b/internal/query/rowpanels.go similarity index 99% rename from internal/panel/rowpanels.go rename to internal/query/rowpanels.go index 50e69d62..fd5e8479 100644 --- a/internal/panel/rowpanels.go +++ b/internal/query/rowpanels.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/rowpanels_test.go b/internal/query/rowpanels_test.go similarity index 94% rename from internal/panel/rowpanels_test.go rename to internal/query/rowpanels_test.go index a80511ea..fbae84e3 100644 --- a/internal/panel/rowpanels_test.go +++ b/internal/query/rowpanels_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -14,7 +14,7 @@ import ( func TestRowPanelCandidatesAreBounded(t *testing.T) { for _, tc := range []struct{ sort, order string }{{"", "max(duration_ms) DESC"}, {"+start", "min(start_time) ASC"}, {"errors", "max(duration_ms) DESC"}} { for _, limit := range []int{2, 1000, 2000} { - p := Panel{Viz: "traces", Query: &Query{From: "spans", Sort: tc.sort, Limit: limit}} + p := Panel{Viz: "traces", Query: &Spec{From: "spans", Sort: tc.sort, Limit: limit}} c, err := compileRows(&p, nil, Scope{Start: fixtureStart, End: fixtureStart.Add(time.Hour)}) if err != nil { t.Fatal(err) @@ -33,7 +33,7 @@ func TestRowPanelCandidatesAreBounded(t *testing.T) { func TestRowPanelsReportValidationProblems(t *testing.T) { base := func(viz string) Panel { - p := Panel{ID: "p", Title: "Rows", Viz: viz, Query: &Query{From: "logs"}} + p := Panel{ID: "p", Title: "Rows", Viz: viz, Query: &Spec{From: "logs"}} if viz == "traces" { p.Query.From = "spans" } @@ -138,7 +138,7 @@ func TestPatternRankingAndBound(t *testing.T) { commit(t, repo, nil, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - p := Panel{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto", Limit: 2}} + p := Panel{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto", Limit: 2}} got, err := e.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Patterns", Time: Time{Range: "1h"}, Panels: []Panel{p}}}) if err != nil { t.Fatal(err) @@ -176,7 +176,7 @@ func TestRedactedExemplarHighlight(t *testing.T) { commit(t, repo, spans, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Query{From: "logs"}, Options: &Options{}}}} + d := Dashboard{Name: "Logs", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Spec{From: "logs"}, Options: &Options{}}}} for _, tc := range []struct { highlight string want int @@ -211,7 +211,7 @@ func TestErroringRootRanking(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Erroring", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Traces", Viz: "traces", Query: &Query{From: "spans", Sort: "errors", Limit: 2}}}} + d := Dashboard{Name: "Erroring", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Traces", Viz: "traces", Query: &Spec{From: "spans", Sort: "errors", Limit: 2}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -235,7 +235,7 @@ func TestRowPanelTrendsExposeResolvedIntervalAndLookback(t *testing.T) { start := fixtureStart.Add(-time.Hour) end := start.Add(tc.window) e.now = func() time.Time { return end } - p := Panel{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: tc.bucket}} + p := Panel{ID: "p", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: tc.bucket}} got, err := e.Run(t.Context(), RunRequest{Dashboard: Dashboard{Name: "Trends", Time: Time{From: &start, To: &end}, Panels: []Panel{p}}, Widths: map[string]int{"p": 1600}}) if err != nil { t.Fatal(err) @@ -289,7 +289,7 @@ func TestEmptyDiagnosisAndBodyCap(t *testing.T) { commit(t, repo, []telemetry.Span{span}, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Query{From: "logs", Sort: "+time"}}}} + d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "Logs", Viz: "logs", Query: &Spec{From: "logs", Sort: "+time"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -309,7 +309,7 @@ func TestEmptyDiagnosisAndBodyCap(t *testing.T) { if got[0].Status != StatusEmpty || got[0].Diagnosis != `No logs contain "s3cr3t" in this range` { t.Fatalf("highlight diagnosis: %+v", got) } - d.Panels[0] = Panel{ID: "p", Title: "Traces", Viz: "traces", Query: &Query{From: "spans", Sort: "errors"}} + d.Panels[0] = Panel{ID: "p", Title: "Traces", Viz: "traces", Query: &Spec{From: "spans", Sort: "errors"}} got, err = e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -330,9 +330,9 @@ func TestRowsExecuteAndRedact(t *testing.T) { e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{ - {ID: "logs", Title: "Errors", Viz: "logs", Options: &Options{Highlight: "failed"}, Query: &Query{From: "logs", Where: []string{"service = 'checkout'"}}}, - {ID: "patterns", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto"}}, - {ID: "traces", Title: "Slow traces", Viz: "traces", Query: &Query{From: "spans", Where: []string{"service = 'checkout'"}, Sort: "duration_ms", Limit: 20}}, + {ID: "logs", Title: "Errors", Viz: "logs", Options: &Options{Highlight: "failed"}, Query: &Spec{From: "logs", Where: []string{"service = 'checkout'"}}}, + {ID: "patterns", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto"}}, + {ID: "traces", Title: "Slow traces", Viz: "traces", Query: &Spec{From: "spans", Where: []string{"service = 'checkout'"}, Sort: "duration_ms", Limit: 20}}, }} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -378,7 +378,7 @@ func TestLogRowPanelsCapNewestRows(t *testing.T) { commit(t, repo, nil, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "logs", Title: "Logs", Viz: "logs", Query: &Query{From: "logs"}}}} + d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "logs", Title: "Logs", Viz: "logs", Query: &Spec{From: "logs"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { t.Fatal(err) @@ -402,7 +402,7 @@ func TestLogPatternsHonoursLimit50(t *testing.T) { commit(t, repo, nil, logs) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Patterns", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto"}}}} + d := Dashboard{Name: "Patterns", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "auto"}}}} for _, tc := range []struct{ limit, want int }{{0, 20}, {30, 30}, {50, 50}, {80, 50}} { d.Panels[0].Query.Limit = tc.limit got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) @@ -430,8 +430,8 @@ func TestRowsNanosecondOrderingAndPatternTail(t *testing.T) { e := NewExecutor(engine, 30) e.now = func() time.Time { return end } d := Dashboard{Name: "Precise rows", Time: Time{From: &start, To: &end}, Panels: []Panel{ - {ID: "logs", Title: "Logs", Viz: "logs", Query: &Query{From: "logs", Limit: 2}}, - {ID: "patterns", Title: "Patterns", Viz: "log_patterns", Query: &Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "30s"}}, + {ID: "logs", Title: "Logs", Viz: "logs", Query: &Spec{From: "logs", Limit: 2}}, + {ID: "patterns", Title: "Patterns", Viz: "log_patterns", Query: &Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}, Bucket: "30s"}}, }} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil { @@ -471,7 +471,7 @@ func TestRowsTraceSortsAndSentinel(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Traces", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "traces", Title: "Traces", Viz: "traces", Query: &Query{From: "spans"}}}} + d := Dashboard{Name: "Traces", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "traces", Title: "Traces", Viz: "traces", Query: &Spec{From: "spans"}}}} for _, tc := range []struct { sort string limit, rows int @@ -529,7 +529,7 @@ func TestRowsValidation(t *testing.T) { {name: "pattern measure", viz: "log_patterns", from: "logs", measures: []string{"rate()"}, by: []string{"body_template"}}, } { t.Run(tc.name, func(t *testing.T) { - d := Dashboard{Name: "Rows", Panels: []Panel{{ID: "p", Title: "Rows", Viz: tc.viz, Options: &Options{Highlight: tc.highlight}, Query: &Query{From: tc.from, Sort: tc.sort, Bucket: tc.bucket, Measures: tc.measures, By: tc.by}}}} + d := Dashboard{Name: "Rows", Panels: []Panel{{ID: "p", Title: "Rows", Viz: tc.viz, Options: &Options{Highlight: tc.highlight}, Query: &Spec{From: tc.from, Sort: tc.sort, Bucket: tc.bucket, Measures: tc.measures, By: tc.by}}}} Normalize(&d) if problems := Validate(&d); (len(problems) == 0) != tc.valid { t.Fatalf("valid=%v: %v", tc.valid, problems) diff --git a/internal/panel/schema.go b/internal/query/schema.go similarity index 99% rename from internal/panel/schema.go rename to internal/query/schema.go index ef87c833..af764392 100644 --- a/internal/panel/schema.go +++ b/internal/query/schema.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/schema_test.go b/internal/query/schema_test.go similarity index 97% rename from internal/panel/schema_test.go rename to internal/query/schema_test.go index b0802efa..2e34d296 100644 --- a/internal/panel/schema_test.go +++ b/internal/query/schema_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -22,7 +22,7 @@ func TestSchemaDiscoversColumnsAttributesAndValues(t *testing.T) { if got := schema.SQLRelations["resource_inventory"]; got.Columns[3].SQLType != "VARIANT" || got.Columns[4].SQLType != "TIMESTAMPTZ_NS" { t.Fatalf("inventory types: %+v", got) } - d := Dashboard{Name: "Invalid structured inventory", Panels: []Panel{{ID: "resources", Title: "Resources", Viz: "stat", Query: &Query{From: "resource_inventory", Measures: []string{"count()"}}}}} + d := Dashboard{Name: "Invalid structured inventory", Panels: []Panel{{ID: "resources", Title: "Resources", Viz: "stat", Query: &Spec{From: "resource_inventory", Measures: []string{"count()"}}}}} if err := e.Validate(t.Context(), &d); err == nil { t.Fatal("SQL-only relation accepted as structured signal") } diff --git a/internal/panel/series_palette_test.go b/internal/query/series_palette_test.go similarity index 90% rename from internal/panel/series_palette_test.go rename to internal/query/series_palette_test.go index e300f395..858a8bac 100644 --- a/internal/panel/series_palette_test.go +++ b/internal/query/series_palette_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -20,7 +20,7 @@ func TestSeriesTopDefaultAndClamp(t *testing.T) { } func TestSeriesTopEightValidationProblem(t *testing.T) { - d := Dashboard{Name: "Series", Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Options: &Options{Top: 8}, Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}}} + d := Dashboard{Name: "Series", Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Options: &Options{Top: 8}, Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}}} Normalize(&d) for _, problem := range Validate(&d) { if problem.Path == "panels[0].options.top" && problem.Hint != "" { @@ -47,7 +47,7 @@ func TestSeriesSeventhFoldsIntoOther(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(duck, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Series", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "1m"}}}} + d := Dashboard{Name: "Series", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "1m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame == nil { t.Fatalf("run: %+v %v", got, err) @@ -82,7 +82,7 @@ func TestGroupedBarOtherAggregatesBeforeErrorRate(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(duck, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Bars", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "bar", Better: "higher", Query: &Query{From: "spans", Measures: []string{"error_rate()"}, By: []string{"http_route", "service"}}}}} + d := Dashboard{Name: "Bars", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "bar", Better: "higher", Query: &Spec{From: "spans", Measures: []string{"error_rate()"}, By: []string{"http_route", "service"}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame == nil { t.Fatalf("run: %+v %v", got, err) @@ -112,7 +112,7 @@ func TestTimelineTwelveRows(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(duck, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "states", Title: "States", Viz: "state_timeline", Options: &Options{Top: 12}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "1m"}}}} + d := Dashboard{Name: "Rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "states", Title: "States", Viz: "state_timeline", Options: &Options{Top: 12}, Thresholds: []Threshold{{Value: 5, Status: "bad"}}, Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "1m"}}}} Normalize(&d) if problems := Validate(&d); len(problems) != 0 { t.Fatalf("timeline rejected: %+v", problems) @@ -171,7 +171,7 @@ func TestWorstFirstSeries(t *testing.T) { {"avg(duration_ms)", "higher", []string{"svc1", "svc2", "svc3"}}, } { t.Run(tc.measure+tc.better, func(t *testing.T) { - d := Dashboard{Name: "Ranking", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Better: tc.better, Options: &Options{Top: 3}, Query: &Query{From: "spans", Measures: []string{tc.measure}, By: []string{"service"}, Bucket: "1m"}}}} + d := Dashboard{Name: "Ranking", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "s", Title: "S", Viz: "timeseries", Better: tc.better, Options: &Options{Top: 3}, Query: &Spec{From: "spans", Measures: []string{tc.measure}, By: []string{"service"}, Bucket: "1m"}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Frame == nil { t.Fatalf("run: %+v %v", got, err) diff --git a/internal/panel/service_input.go b/internal/query/service_input.go similarity index 99% rename from internal/panel/service_input.go rename to internal/query/service_input.go index 71422885..24d973f5 100644 --- a/internal/panel/service_input.go +++ b/internal/query/service_input.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/shape.go b/internal/query/shape.go similarity index 92% rename from internal/panel/shape.go rename to internal/query/shape.go index 7a5ddaad..27b56e89 100644 --- a/internal/panel/shape.go +++ b/internal/query/shape.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" @@ -21,9 +21,9 @@ type VizCompat struct { Requires []VizRequirement `json:"requires"` } -// QueryShape checks query-only structure without normalizing or using an engine. +// Shape checks query-only structure without normalizing or using an engine. // A nil vars map omits declaration checks. All problem paths are query-relative. -func QueryShape(q *Query, viz string, vars map[string]Variable, prepared ...[]Measure) (Problems, []VizRequirement) { +func Shape(q *Spec, viz string, vars map[string]Variable, prepared ...[]Measure) (Problems, []VizRequirement) { requirements := []VizRequirement{} if viz == "gauge" { requirements = append(requirements, RequiresMinMax) @@ -62,14 +62,14 @@ func QueryShape(q *Query, viz string, vars map[string]Variable, prepared ...[]Me } // CompatibleVizzes lists the query visualizations accepting the query unchanged. -func CompatibleVizzes(q *Query, vars map[string]Variable, prepared ...[]Measure) []VizCompat { +func CompatibleVizzes(q *Spec, vars map[string]Variable, prepared ...[]Measure) []VizCompat { out := []VizCompat{} for _, viz := range vizOrder { // Text and fixed rollup scopes are not FanQL query visualization targets. if viz == "text" || viz == "health" || viz == "service_map" { continue } - problems, requires := QueryShape(q, viz, vars, prepared...) + problems, requires := Shape(q, viz, vars, prepared...) if len(problems) == 0 { out = append(out, VizCompat{Viz: viz, Requires: requires}) } @@ -77,7 +77,7 @@ func CompatibleVizzes(q *Query, vars map[string]Variable, prepared ...[]Measure) return out } -func queryShapeVariables(q *Query, vars map[string]Variable, path string, problems *Problems) { +func queryShapeVariables(q *Spec, vars map[string]Variable, path string, problems *Problems) { for _, ref := range varRefs(strings.Join(q.Where, " ")) { if _, ok := vars[ref]; !ok { problems.addHint(path+".where", fmt.Sprintf("$%s is not a dashboard variable", ref), suggest.Spelling(ref, mapKeys(vars))) @@ -186,7 +186,7 @@ func queryShapeAggregate(p *Panel, spec vizSpec, path string, problems *Problems return measures, true } -func queryShapeAggregateTail(q *Query, viz, path string, measures []Measure, problems *Problems) { +func queryShapeAggregateTail(q *Spec, viz, path string, measures []Measure, problems *Problems) { if q.Limit < 0 || q.Limit > 1000 { problems.add(path+".limit", "limit must be 0 to 1000") } @@ -207,13 +207,13 @@ func queryShapeAggregateTail(q *Query, viz, path string, measures []Measure, pro } -func queryShapeReduce(q *Query, spec vizSpec, viz, path string, problems *Problems) { +func queryShapeReduce(q *Spec, spec vizSpec, viz, path string, problems *Problems) { if spec.reduces && len(q.Measures) != 1 { problems.add(path+".measures", fmt.Sprintf("%s panels show one measure", viz)) } } -func queryShapeRows(q *Query, viz, path string, problems *Problems) { +func queryShapeRows(q *Spec, viz, path string, problems *Problems) { if viz != "logs" && viz != "traces" && viz != "log_patterns" { return } @@ -267,7 +267,7 @@ func queryShapeRows(q *Query, viz, path string, problems *Problems) { } } -func queryShapeItems(q *Query, viz, path string, problems *Problems) { +func queryShapeItems(q *Spec, viz, path string, problems *Problems) { if q == nil { return } diff --git a/internal/panel/shape_test.go b/internal/query/shape_test.go similarity index 52% rename from internal/panel/shape_test.go rename to internal/query/shape_test.go index a10bf7fe..2595cdce 100644 --- a/internal/panel/shape_test.go +++ b/internal/query/shape_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "reflect" @@ -10,20 +10,20 @@ import ( func TestQueryShapeMatchesValidateQueryProblems(t *testing.T) { queries := []struct { viz string - q Query + q Spec }{ - {"stat", Query{From: "spans", Measures: []string{"count()"}}}, - {"gauge", Query{From: "spans", Measures: []string{"count()", "rate()"}}}, - {"timeseries", Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, - {"bar", Query{From: "spans", Measures: []string{"count()"}}}, - {"table", Query{From: "spans", Measures: []string{"count()"}, Sort: "wrong"}}, - {"heatmap", Query{From: "spans", Measures: []string{"count()"}, Bucket: "auto"}}, - {"histogram", Query{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, - {"scatter", Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, - {"state_timeline", Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto", Sort: "count"}}, - {"logs", Query{From: "spans", Measures: []string{"count()"}, Sort: "wrong"}}, - {"log_patterns", Query{From: "logs", Measures: []string{"count()"}, By: []string{"service"}}}, - {"traces", Query{From: "spans", Sort: "+start", Where: []string{"service = 'api'"}}}, + {"stat", Spec{From: "spans", Measures: []string{"count()"}}}, + {"gauge", Spec{From: "spans", Measures: []string{"count()", "rate()"}}}, + {"timeseries", Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, + {"bar", Spec{From: "spans", Measures: []string{"count()"}}}, + {"table", Spec{From: "spans", Measures: []string{"count()"}, Sort: "wrong"}}, + {"heatmap", Spec{From: "spans", Measures: []string{"count()"}, Bucket: "auto"}}, + {"histogram", Spec{From: "spans", Measures: []string{"count()"}, Histogram: &Histogram{Field: "duration_ms", Buckets: "log2"}}}, + {"scatter", Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}}, + {"state_timeline", Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}, Bucket: "auto", Sort: "count"}}, + {"logs", Spec{From: "spans", Measures: []string{"count()"}, Sort: "wrong"}}, + {"log_patterns", Spec{From: "logs", Measures: []string{"count()"}, By: []string{"service"}}}, + {"traces", Spec{From: "spans", Sort: "+start", Where: []string{"service = 'api'"}}}, } for _, tc := range queries { t.Run(tc.viz, func(t *testing.T) { @@ -41,7 +41,7 @@ func TestQueryShapeMatchesValidateQueryProblems(t *testing.T) { want = append(want, p) } } - got, _ := QueryShape(&tc.q, tc.viz, nil) + got, _ := Shape(&tc.q, tc.viz, nil) if !reflect.DeepEqual(got, want) { t.Errorf("shape = %#v; validate = %#v", got, want) } @@ -50,12 +50,12 @@ func TestQueryShapeMatchesValidateQueryProblems(t *testing.T) { } func TestQueryShapeRequires(t *testing.T) { - q := &Query{From: "spans", Measures: []string{"count()"}} + q := &Spec{From: "spans", Measures: []string{"count()"}} for _, tc := range []struct { viz string want []VizRequirement }{{"gauge", []VizRequirement{RequiresMinMax}}, {"state_timeline", []VizRequirement{RequiresThresholds}}, {"table", []VizRequirement{}}} { - _, got := QueryShape(q, tc.viz, nil) + _, got := Shape(q, tc.viz, nil) if !slices.Equal(got, tc.want) { t.Errorf("%s requires %v, want %v", tc.viz, got, tc.want) } @@ -63,8 +63,8 @@ func TestQueryShapeRequires(t *testing.T) { } func TestQueryShapeRejectsIncompleteMeasure(t *testing.T) { - q := &Query{From: "spans", Measures: []string{"count() + as x"}} - got, _ := QueryShape(q, "table", nil) + q := &Spec{From: "spans", Measures: []string{"count() + as x"}} + got, _ := Shape(q, "table", nil) if len(got) == 0 { t.Fatal("shape accepted an incomplete arithmetic expression") } @@ -82,22 +82,22 @@ func TestQueryShapeRejectsIncompleteMeasure(t *testing.T) { } func TestQueryShapeCountIfDefaultAlias(t *testing.T) { - q := &Query{From: "spans", Measures: []string{"count_if(status = 'STATUS_CODE_ERROR')"}, Sort: "count_if"} - if problems, _ := QueryShape(q, "table", nil); len(problems) != 0 { + q := &Spec{From: "spans", Measures: []string{"count_if(status = 'STATUS_CODE_ERROR')"}, Sort: "count_if"} + if problems, _ := Shape(q, "table", nil); len(problems) != 0 { t.Fatalf("count_if shape: %v", problems) } } func TestCompatibleVizzesOnQueryAsWritten(t *testing.T) { for _, tc := range []struct { - q Query + q Spec want []string }{ - {Query{From: "spans", Where: []string{"kind = 'SPAN_KIND_SERVER'"}, Measures: []string{"count()"}, By: []string{"http_route"}}, []string{"bar", "table"}}, - {Query{From: "spans", Where: []string{"kind = 'SPAN_KIND_SERVER'"}, Measures: []string{"count()"}, By: []string{"http_route"}, Bucket: "auto"}, []string{"timeseries", "state_timeline"}}, - {Query{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}}, []string{"traces"}}, - {Query{From: "logs"}, []string{"logs"}}, - {Query{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}}, []string{"bar", "table", "log_patterns"}}, + {Spec{From: "spans", Where: []string{"kind = 'SPAN_KIND_SERVER'"}, Measures: []string{"count()"}, By: []string{"http_route"}}, []string{"bar", "table"}}, + {Spec{From: "spans", Where: []string{"kind = 'SPAN_KIND_SERVER'"}, Measures: []string{"count()"}, By: []string{"http_route"}, Bucket: "auto"}, []string{"timeseries", "state_timeline"}}, + {Spec{From: "spans", Where: []string{"status = 'STATUS_CODE_ERROR'"}}, []string{"traces"}}, + {Spec{From: "logs"}, []string{"logs"}}, + {Spec{From: "logs", Measures: []string{"count()"}, By: []string{"body_template"}}, []string{"bar", "table", "log_patterns"}}, } { var got []string for _, c := range CompatibleVizzes(&tc.q, nil) { @@ -113,12 +113,12 @@ func TestCompatibleVizzesOnQueryAsWritten(t *testing.T) { } func TestExistingValidateBehaviourUnchanged(t *testing.T) { - q := &Query{From: "spans", Measures: []string{"count()"}, Where: []string{"service = $missing"}} - got, _ := QueryShape(q, "table", map[string]Variable{}) + q := &Spec{From: "spans", Measures: []string{"count()"}, Where: []string{"service = $missing"}} + got, _ := Shape(q, "table", map[string]Variable{}) if len(got) != 1 || got[0].Path != "where" || !strings.Contains(got[0].Message, "$missing is not a dashboard variable") { t.Fatalf("variables = %#v", got) } - if got, _ := QueryShape(q, "table", nil); len(got) != 0 { + if got, _ := Shape(q, "table", nil); len(got) != 0 { t.Fatalf("nil declarations: %v", got) } } diff --git a/internal/panel/spec.go b/internal/query/spec.go similarity index 74% rename from internal/panel/spec.go rename to internal/query/spec.go index 98eaace9..6a5cccc0 100644 --- a/internal/panel/spec.go +++ b/internal/query/spec.go @@ -1,7 +1,7 @@ // Package panel defines Fanout's dashboard spec: the typed, validated contract // between the agent, the API, storage and the browser renderer. The Go types // are the single source of the JSON Schema the MCP tools publish. -package panel +package query import "time" @@ -51,30 +51,30 @@ type Variable struct { } type Panel struct { - ID string `json:"id" jsonschema:"Stable identifier: lowercase letters, digits and underscores; edits address panels by id"` - Title string `json:"title" jsonschema:"Panel title, at most 80 characters; may reference $variables"` - Description string `json:"description,omitempty" jsonschema:"Help text, at most 280 characters"` - Viz string `json:"viz" jsonschema:"stat, gauge, timeseries, bar, table, text, heatmap, histogram, scatter, state_timeline, logs, log_patterns, traces, service_map or health; log_patterns returns body_template, count, trend, dominant severity (frequency then higher severity) and top service"` - Width int `json:"width,omitempty" jsonschema:"Grid columns from 1 to 12; default depends on viz"` - Height string `json:"height,omitempty" jsonschema:"s, m or l; default depends on viz"` - Query *Query `json:"query,omitempty" jsonschema:"Structured query; exactly one of query or sql, except text panels"` - SQL string `json:"sql,omitempty" jsonschema:"One read-only SELECT over spans, logs, metrics, service_rollup or edge_rollup; must use $__window(time_column). Compare time columns with TIMESTAMP 'YYYY-MM-DD HH:MM:SS' (UTC), or cast TIMESTAMPTZ literals with ::TIMESTAMPTZ_NS."` - Unit string `json:"unit,omitempty" jsonschema:"ms, s, ns, percent, ratio, count, per_second, per_minute, bytes or none; inferred when omitted"` - XUnit string `json:"x_unit,omitempty" jsonschema:"scatter x axis unit; unit describes y"` - Reduce string `json:"reduce,omitempty" jsonschema:"stat and gauge: window (default), last, mean, min, max or sum"` - Thresholds []Threshold `json:"thresholds,omitempty" jsonschema:"Up to 4 status boundaries"` - Better string `json:"better,omitempty" jsonschema:"lower or higher; inferred for known measures"` - Min *float64 `json:"min,omitempty" jsonschema:"gauge: scale minimum"` - Max *float64 `json:"max,omitempty" jsonschema:"gauge: scale maximum"` - Options *Options `json:"options,omitempty"` - Click *Click `json:"click,omitempty" jsonschema:"Clicking a bar, row or series sets a variable"` - Drill string `json:"drill,omitempty" jsonschema:"traces or logs: what a click on a point opens"` - Time *PanelTime `json:"time,omitempty" jsonschema:"Override the dashboard time for this panel"` - Content string `json:"content,omitempty" jsonschema:"text panels: Markdown, at most 4000 characters"` - Grid *Grid `json:"grid,omitempty" jsonschema:"Position set by the server or by dragging; omit when authoring"` + ID string `json:"id" jsonschema:"Stable identifier: lowercase letters, digits and underscores; edits address panels by id"` + Title string `json:"title" jsonschema:"Panel title, at most 80 characters; may reference $variables"` + Description string `json:"description,omitempty" jsonschema:"Help text, at most 280 characters"` + Viz string `json:"viz" jsonschema:"stat, gauge, timeseries, bar, table, text, heatmap, histogram, scatter, state_timeline, logs, log_patterns, traces, service_map or health; log_patterns returns body_template, count, trend, dominant severity (frequency then higher severity) and top service"` + Width int `json:"width,omitempty" jsonschema:"Grid columns from 1 to 12; default depends on viz"` + Height string `json:"height,omitempty" jsonschema:"s, m or l; default depends on viz"` + Query *Spec `json:"query,omitempty" jsonschema:"Structured query; exactly one of query or sql, except text panels"` + SQL string `json:"sql,omitempty" jsonschema:"One read-only SELECT over spans, logs, metrics, service_rollup or edge_rollup; must use $__window(time_column). Compare time columns with TIMESTAMP 'YYYY-MM-DD HH:MM:SS' (UTC), or cast TIMESTAMPTZ literals with ::TIMESTAMPTZ_NS."` + Unit string `json:"unit,omitempty" jsonschema:"ms, s, ns, percent, ratio, count, per_second, per_minute, bytes or none; inferred when omitted"` + XUnit string `json:"x_unit,omitempty" jsonschema:"scatter x axis unit; unit describes y"` + Reduce string `json:"reduce,omitempty" jsonschema:"stat and gauge: window (default), last, mean, min, max or sum"` + Thresholds []Threshold `json:"thresholds,omitempty" jsonschema:"Up to 4 status boundaries"` + Better string `json:"better,omitempty" jsonschema:"lower or higher; inferred for known measures"` + Min *float64 `json:"min,omitempty" jsonschema:"gauge: scale minimum"` + Max *float64 `json:"max,omitempty" jsonschema:"gauge: scale maximum"` + Options *Options `json:"options,omitempty"` + Click *Click `json:"click,omitempty" jsonschema:"Clicking a bar, row or series sets a variable"` + Drill string `json:"drill,omitempty" jsonschema:"traces or logs: what a click on a point opens"` + Time *TimeOverride `json:"time,omitempty" jsonschema:"Override the dashboard time for this panel"` + Content string `json:"content,omitempty" jsonschema:"text panels: Markdown, at most 4000 characters"` + Grid *Grid `json:"grid,omitempty" jsonschema:"Position set by the server or by dragging; omit when authoring"` } -type Query struct { +type Spec struct { From string `json:"from" jsonschema:"spans, logs or metrics"` Where []string `json:"where,omitempty" jsonschema:"Filter expressions joined by AND, e.g. service = $service or attributes['http.route'] = '/cart'"` Measures []string `json:"measures,omitempty" jsonschema:"For spans and logs aggregate panels: count_if(SQL filter) and + - * / expressions with constants; expressions require as alias and an aggregate, share() stands alone, division by zero returns null. Metrics do not support arithmetic. At most 256 tokens, 64 nodes, depth 8 and 8 aggregates per measure; 256 nodes and 24 aggregates per query. Fixed logs, traces, service_map and health take no measures; other queries take 1 to 6 of fn(field) [as alias]: count(), rate(), error_rate(), share(), avg, min, max, sum, last, p50, p75, p90, p95, p99, quantile(field, q), count_distinct(field)"` @@ -120,7 +120,7 @@ type Click struct { SetVariable string `json:"set_variable" jsonschema:"Variable set to the clicked value"` } -type PanelTime struct { +type TimeOverride struct { Range string `json:"range,omitempty" jsonschema:"Replace the dashboard range, e.g. 30d"` Shift string `json:"shift,omitempty" jsonschema:"Move the dashboard range back, e.g. 1d"` } diff --git a/internal/panel/sql_relations.go b/internal/query/sql_relations.go similarity index 99% rename from internal/panel/sql_relations.go rename to internal/query/sql_relations.go index baff15df..0a9cf36b 100644 --- a/internal/panel/sql_relations.go +++ b/internal/query/sql_relations.go @@ -1,4 +1,4 @@ -package panel +package query // SQLRelationSchema describes a panel-SQL-only relation. Its rows are not raw // events, so it deliberately has neither a signal time column nor sample counts. diff --git a/internal/panel/sqlast.go b/internal/query/sqlast.go similarity index 99% rename from internal/panel/sqlast.go rename to internal/query/sqlast.go index ca8b624a..9bcc54e1 100644 --- a/internal/panel/sqlast.go +++ b/internal/query/sqlast.go @@ -1,4 +1,4 @@ -package panel +package query import "fmt" diff --git a/internal/panel/sqlpanel.go b/internal/query/sqlpanel.go similarity index 98% rename from internal/panel/sqlpanel.go rename to internal/query/sqlpanel.go index 61b00854..d6c88b94 100644 --- a/internal/panel/sqlpanel.go +++ b/internal/query/sqlpanel.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/labstack/fanout/internal/query" + "github.com/labstack/fanout/internal/engine" ) var ( @@ -52,7 +52,7 @@ func canonicalSQL(ctx context.Context, parser Parser, expanded string) (string, if err != nil { return "", err } - query.NormalizeLogQualifiers(node) + engine.NormalizeLogQualifiers(node) if err := redactSQLLogTables(ctx, parser, node, nil); err != nil { return "", err } diff --git a/internal/panel/table_semantics_test.go b/internal/query/table_semantics_test.go similarity index 91% rename from internal/panel/table_semantics_test.go rename to internal/query/table_semantics_test.go index 58adb4ec..811bc581 100644 --- a/internal/panel/table_semantics_test.go +++ b/internal/query/table_semantics_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -28,7 +28,7 @@ func TestTableSparklinesShareOneQueryAcrossRowsAndMeasures(t *testing.T) { e := newFixtureExecutor(t) counter := &countingTableTrendEngine{Engine: e.engine} e.engine = counter - d := Dashboard{Name: "Three rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", By: []string{"service", "http_route"}, Measures: []string{"count()", "avg(duration_ms) as latency"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "latency", Format: "sparkline"}}}}}} + d := Dashboard{Name: "Three rows", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", By: []string{"service", "http_route"}, Measures: []string{"count()", "avg(duration_ms) as latency"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "latency", Format: "sparkline"}}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || len(got) != 1 || got[0].Status != StatusOK || got[0].Frame.Rows < 3 { t.Fatalf("table: %+v %v", got, err) @@ -70,7 +70,7 @@ func TestTrendNotesAppend(t *testing.T) { for _, mode := range []string{"failure", "allocation", "query"} { t.Run(mode, func(t *testing.T) { e := newFixtureExecutor(t) - p := Panel{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", By: []string{"service"}, Measures: []string{"count()"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}}}} + p := Panel{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", By: []string{"service"}, Measures: []string{"count()"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}}}} d := Dashboard{Name: "Notes", Panels: []Panel{p}} Normalize(&d) checked, problems, err := Check(t.Context(), e.engine, &d) diff --git a/internal/panel/table_trends.go b/internal/query/table_trends.go similarity index 99% rename from internal/panel/table_trends.go rename to internal/query/table_trends.go index 08978e85..09648709 100644 --- a/internal/panel/table_trends.go +++ b/internal/query/table_trends.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/table_trends_test.go b/internal/query/table_trends_test.go similarity index 91% rename from internal/panel/table_trends_test.go rename to internal/query/table_trends_test.go index 9e474a3c..98bce223 100644 --- a/internal/panel/table_trends_test.go +++ b/internal/query/table_trends_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" @@ -14,7 +14,7 @@ import ( func TestStructuredTableSparklineRejectsDimension(t *testing.T) { e := newFixtureExecutor(t) - d := Dashboard{Name: "Invalid trend", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}, Options: &Options{Columns: []ColumnFormat{{Field: "service", Format: "sparkline"}}}}}} + d := Dashboard{Name: "Invalid trend", Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", Measures: []string{"count()"}, By: []string{"service"}}, Options: &Options{Columns: []ColumnFormat{{Field: "service", Format: "sparkline"}}}}}} Normalize(&d) _, problems, err := Check(t.Context(), e.engine, &d) if err != nil { @@ -37,7 +37,7 @@ func TestTableTrendsRedactedLogSource(t *testing.T) { commit(t, repo, nil, []telemetry.Log{{ServiceName: "checkout", BodyTemplate: "token=templatesecret failed <*>", EventUnixNanos: n, IngestedAt: n}}) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Log trends", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "body_template", Format: "log_template"}}}}}} + d := Dashboard{Name: "Log trends", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "logs", By: []string{"body_template"}, Measures: []string{"count()"}}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "body_template", Format: "log_template"}}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || len(got) != 1 || got[0].Status != StatusOK { t.Fatalf("logs: %+v %v", got, err) @@ -146,7 +146,7 @@ func TestTableTrendsPerTableCellBudget(t *testing.T) { commit(t, repo, spans, nil) e := NewExecutor(engine, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Bounded trends", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", By: []string{"service"}, Measures: []string{"count()", "avg(duration_ms) as latency"}, Limit: 200}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "latency", Format: "sparkline"}}}}}} + d := Dashboard{Name: "Bounded trends", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", By: []string{"service"}, Measures: []string{"count()", "avg(duration_ms) as latency"}, Limit: 200}, Options: &Options{Columns: []ColumnFormat{{Field: "count", Format: "sparkline"}, {Field: "latency", Format: "sparkline"}}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("budget query: %+v %v", got, err) @@ -286,7 +286,7 @@ func TestLimitedShareTrendUsesOriginalScope(t *testing.T) { counter := &countingTableTrendEngine{Engine: engine} e := NewExecutor(counter, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } - d := Dashboard{Name: "Shares", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Query{From: "spans", By: []string{"service"}, Measures: []string{"share()"}, Limit: 1}, Options: &Options{Columns: []ColumnFormat{{Field: "share", Format: "sparkline"}}}}}} + d := Dashboard{Name: "Shares", Time: Time{Range: "1h"}, Panels: []Panel{{ID: "p", Title: "P", Viz: "table", Query: &Spec{From: "spans", By: []string{"service"}, Measures: []string{"share()"}, Limit: 1}, Options: &Options{Columns: []ColumnFormat{{Field: "share", Format: "sparkline"}}}}}} got, err := e.Run(t.Context(), RunRequest{Dashboard: d}) if err != nil || got[0].Status != StatusOK { t.Fatalf("run: %+v %v", got, err) diff --git a/internal/panel/testhelpers_test.go b/internal/query/testhelpers_test.go similarity index 93% rename from internal/panel/testhelpers_test.go rename to internal/query/testhelpers_test.go index 64b28749..5767106a 100644 --- a/internal/panel/testhelpers_test.go +++ b/internal/query/testhelpers_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "database/sql" @@ -9,8 +9,8 @@ import ( "time" "github.com/labstack/fanout/internal/config" - "github.com/labstack/fanout/internal/query" - "github.com/labstack/fanout/internal/query/querytest" + "github.com/labstack/fanout/internal/engine" + "github.com/labstack/fanout/internal/engine/querytest" "github.com/labstack/fanout/internal/telemetry" telemetrystore "github.com/labstack/fanout/internal/telemetry/store" ) @@ -19,14 +19,14 @@ import ( // would be unnecessary; tests query 12:00–13:00 UTC on 2026-10-01. var fixtureStart = time.Date(2026, 10, 1, 12, 0, 0, 0, time.UTC) -func newTestEngine(t *testing.T) (*query.Duck, *telemetrystore.Repository) { +func newTestEngine(t *testing.T) (*engine.Duck, *telemetrystore.Repository) { t.Helper() cfg := config.Config{DataDir: t.TempDir(), DuckDBMemory: "256MB", DuckDBThreads: 2, DuckDBMaxConns: 4, RollupInterval: time.Hour} repo, err := telemetrystore.Open(cfg.TelemetryDir()) if err != nil { t.Fatal(err) } - d, err := query.NewDuck(t.Context(), cfg, repo) + d, err := engine.NewDuck(t.Context(), cfg, repo) if err != nil { t.Fatal(err) } @@ -85,13 +85,13 @@ func metricFixture(t *testing.T) (*Executor, *sql.DB) { if _, err := db.Exec("SET TimeZone='UTC'"); err != nil { t.Fatal(err) } - if err := querytest.CreateTables(db, query.CreateCacheTables); err != nil { + if err := querytest.CreateTables(db, engine.CreateCacheTables); err != nil { t.Fatal(err) } - if err := query.CreateViews(db); err != nil { + if err := engine.CreateViews(db); err != nil { t.Fatal(err) } - e := NewExecutor(&query.Duck{DB: db}, 30) + e := NewExecutor(&engine.Duck{DB: db}, 30) e.now = func() time.Time { return fixtureStart.Add(time.Hour) } return e, db } diff --git a/internal/panel/timerange.go b/internal/query/timerange.go similarity index 93% rename from internal/panel/timerange.go rename to internal/query/timerange.go index 3bdc5239..5b5126a9 100644 --- a/internal/panel/timerange.go +++ b/internal/query/timerange.go @@ -1,4 +1,4 @@ -package panel +package query import ( "errors" @@ -16,7 +16,7 @@ func (e *Executor) ResolveWindow(start, end time.Time) (time.Time, time.Time, er // resolveWindow turns a dashboard time, optionally overridden by a panel, // into a concrete UTC range no longer than retention. A range longer than // retention keeps its end and loses its oldest part rather than failing. -func resolveWindow(t Time, override *PanelTime, now time.Time, maxWindow time.Duration) (time.Time, time.Time, error) { +func resolveWindow(t Time, override *TimeOverride, now time.Time, maxWindow time.Duration) (time.Time, time.Time, error) { var start, end time.Time if t.From != nil && t.To != nil { start, end = t.From.UTC(), t.To.UTC() diff --git a/internal/panel/timerange_test.go b/internal/query/timerange_test.go similarity index 90% rename from internal/panel/timerange_test.go rename to internal/query/timerange_test.go index e9f67019..7ac9a6ec 100644 --- a/internal/panel/timerange_test.go +++ b/internal/query/timerange_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "strings" @@ -13,14 +13,14 @@ func TestResolveWindow(t *testing.T) { cases := []struct { name string t Time - override *PanelTime + override *TimeOverride start, end time.Time err string }{ {"relative", Time{Range: "1h"}, nil, now.Add(-time.Hour), now, ""}, {"absolute", Time{From: &from, To: &to}, nil, from, to, ""}, - {"panel range clamped to retention", Time{Range: "1h"}, &PanelTime{Range: "30d"}, now.Add(-week), now, ""}, - {"panel shift", Time{Range: "1h"}, &PanelTime{Shift: "1d"}, now.Add(-25 * time.Hour), now.Add(-24 * time.Hour), ""}, + {"panel range clamped to retention", Time{Range: "1h"}, &TimeOverride{Range: "30d"}, now.Add(-week), now, ""}, + {"panel shift", Time{Range: "1h"}, &TimeOverride{Shift: "1d"}, now.Add(-25 * time.Hour), now.Add(-24 * time.Hour), ""}, {"from after to", Time{From: &to, To: &from}, nil, time.Time{}, time.Time{}, "start before it ends"}, {"bad range", Time{Range: "90m"}, nil, time.Time{}, time.Time{}, "unsupported range"}, } diff --git a/internal/panel/unit_regression_test.go b/internal/query/unit_regression_test.go similarity index 93% rename from internal/panel/unit_regression_test.go rename to internal/query/unit_regression_test.go index f5df9e6c..47c7152a 100644 --- a/internal/panel/unit_regression_test.go +++ b/internal/query/unit_regression_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -6,7 +6,7 @@ import ( ) func TestCompileMeasureUnitsOverridePanelUnit(t *testing.T) { - p := &Panel{ID: "mixed", Viz: "table", Unit: "ms", Query: &Query{From: "spans"}} + p := &Panel{ID: "mixed", Viz: "table", Unit: "ms", Query: &Spec{From: "spans"}} texts := []string{"p95(duration_ms)", "count_distinct(service)", "count()", "rate()", "error_rate()", "share()", "avg(duration_ms)", "min(duration_ms)", "max(duration_ms)", "sum(duration_ms)", "sum(attributes['unknown'])"} want := []string{"ms", "count", "count", "per_second", "percent", "percent", "ms", "ms", "ms", "ms", ""} c, err := compileQuery(p, measuresOf(t, "spans", texts...), nil, Scope{Start: compileStart, End: compileEnd}) diff --git a/internal/panel/validate.go b/internal/query/validate.go similarity index 99% rename from internal/panel/validate.go rename to internal/query/validate.go index 98b1c733..78611e58 100644 --- a/internal/panel/validate.go +++ b/internal/query/validate.go @@ -1,4 +1,4 @@ -package panel +package query import ( "fmt" diff --git a/internal/panel/validate_test.go b/internal/query/validate_test.go similarity index 95% rename from internal/panel/validate_test.go rename to internal/query/validate_test.go index cb215152..d770790f 100644 --- a/internal/panel/validate_test.go +++ b/internal/query/validate_test.go @@ -1,4 +1,4 @@ -package panel +package query import ( "encoding/json" @@ -58,7 +58,7 @@ func TestValidateAcceptsSpecExample(t *testing.T) { func TestNormalizeFillsDefaults(t *testing.T) { d := Dashboard{Name: " Ops ", Panels: []Panel{ - {ID: "rps", Title: "Requests", Viz: "timeseries", Query: &Query{From: "spans", Measures: []string{"rate()"}}}, + {ID: "rps", Title: "Requests", Viz: "timeseries", Query: &Spec{From: "spans", Measures: []string{"rate()"}}}, {ID: "notes", Title: "Notes", Viz: "text", Content: "Hello"}, }} Normalize(&d) @@ -74,7 +74,7 @@ func TestNormalizeFillsDefaults(t *testing.T) { } func TestNormalizeServiceMapLargeDefault(t *testing.T) { - d := Dashboard{Name: "Map", Panels: []Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &Query{From: "spans"}}}} + d := Dashboard{Name: "Map", Panels: []Panel{{ID: "map", Title: "Map", Viz: "service_map", Query: &Spec{From: "spans"}}}} Normalize(&d) if d.Panels[0].Height != "l" { t.Fatalf("service map height=%q", d.Panels[0].Height) @@ -170,7 +170,7 @@ func TestGroupedPanelsRequireOneMeasure(t *testing.T) { {"timeseries", []string{"service"}}, {"bar", []string{"service", "operation"}}, } { t.Run(tc.viz, func(t *testing.T) { - d := Dashboard{Name: "Grouped", Panels: []Panel{{ID: "p", Title: "P", Viz: tc.viz, Query: &Query{From: "spans", By: tc.by, Measures: []string{"p50(duration_ms)", "p95(duration_ms)"}}}}} + d := Dashboard{Name: "Grouped", Panels: []Panel{{ID: "p", Title: "P", Viz: tc.viz, Query: &Spec{From: "spans", By: tc.by, Measures: []string{"p50(duration_ms)", "p95(duration_ms)"}}}}} Normalize(&d) for _, p := range Validate(&d) { if p.Path == "panels[0].query.measures" && p.Message == "grouped panels show one measure" && p.Hint == "use one panel per measure, or remove by" { diff --git a/internal/panel/variables.go b/internal/query/variables.go similarity index 99% rename from internal/panel/variables.go rename to internal/query/variables.go index c5eb0fe5..d6d2ad07 100644 --- a/internal/panel/variables.go +++ b/internal/query/variables.go @@ -1,4 +1,4 @@ -package panel +package query import ( "context" diff --git a/internal/panel/vocabulary.go b/internal/query/vocabulary.go similarity index 99% rename from internal/panel/vocabulary.go rename to internal/query/vocabulary.go index 670eb47b..24cdaa2e 100644 --- a/internal/panel/vocabulary.go +++ b/internal/query/vocabulary.go @@ -1,4 +1,4 @@ -package panel +package query import ( "maps" diff --git a/internal/store/store_test.go b/internal/store/store_test.go index 359a65f5..ced7fd2e 100644 --- a/internal/store/store_test.go +++ b/internal/store/store_test.go @@ -205,7 +205,7 @@ func TestNewSQLite_InitializesWithOnlyGooseMetadata(t *testing.T) { if err := s.DB.QueryRow(`SELECT COUNT(*) FROM goose_db_version WHERE version_id > 0 AND is_applied=1`).Scan(&applied); err != nil { t.Fatal(err) } - if applied != 4 { - t.Fatalf("applied versions = %d, want 4", applied) + if applied != 5 { + t.Fatalf("applied versions = %d, want 5", applied) } } diff --git a/internal/telemetry/parquet.go b/internal/telemetry/parquet.go index 9cbbfdb1..dfe7b635 100644 --- a/internal/telemetry/parquet.go +++ b/internal/telemetry/parquet.go @@ -939,7 +939,7 @@ func (p *ParquetStore) PublishReplacement(stage string, metadata BatchMetadata, } // ensureSchemaBatch writes _schema.batch: an empty Parquet batch whose only -// purpose is to carry this binary's column list. internal/query derives every +// purpose is to carry this binary's column list. internal/engine derives every // view's explicit read_parquet(schema=MAP{...}) from it, so a column absent // here is a column absent from the view. // diff --git a/internal/telemetry/schema_batch_test.go b/internal/telemetry/schema_batch_test.go index 5d54baf7..8053c772 100644 --- a/internal/telemetry/schema_batch_test.go +++ b/internal/telemetry/schema_batch_test.go @@ -9,7 +9,7 @@ import ( ) // _schema.batch is an empty Parquet batch whose only job is to carry this -// binary's column list: internal/query derives every view's explicit +// binary's column list: internal/engine derives every view's explicit // read_parquet(schema=MAP{...}) from it, so a column missing there is a column // missing from the view. // diff --git a/internal/ui/dist/assets/WarningCircle.es-e9h3eY6B.js b/internal/ui/dist/assets/WarningCircle.es-eZ--e_KS.js similarity index 98% rename from internal/ui/dist/assets/WarningCircle.es-e9h3eY6B.js rename to internal/ui/dist/assets/WarningCircle.es-eZ--e_KS.js index 36b603ff..2d33fed5 100644 --- a/internal/ui/dist/assets/WarningCircle.es-e9h3eY6B.js +++ b/internal/ui/dist/assets/WarningCircle.es-eZ--e_KS.js @@ -1 +1 @@ -import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{M as r,Y as i,a,f as o,w as s}from"./brand-DUaZkIz1.js";import{at as c,ct as l,it as u,nt as d,ot as f,rt as p,st as m,tt as h}from"./index-eh4vL-r5.js";var g={root:`m_849cf0da`},_=t(),v={underline:`hover`},y=s(e=>{let{underline:t,className:n,unstyled:a,mod:s,...c}=r(`Anchor`,v,e);return(0,_.jsx)(o,{component:`a`,className:i({[g.root]:!a},n),...c,mod:[{underline:t},s],__staticSelector:`Anchor`,unstyled:a})});y.classes=g,y.displayName=`@mantine/core/Anchor`;var b=class extends p{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),f(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&u(t.mutationKey)!==u(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onSubscribe(){this.listeners.size===1&&this.#n&&(this.#n.addObserver(this),this.#i())}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??h();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){d.batch(()=>{let t=this.#r;if(t&&this.hasListeners()){let n=this.#t.variables,r=this.#t.context,i={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{t.onSuccess?.(e.data,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(e.data,null,n,r,i)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{t.onError?.(e.error,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(void 0,e.error,n,r,i)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},x=n(e(),1);function S(e,t){let n=l(t),[r]=x.useState(()=>new b(n,e));x.useEffect(()=>{r.setOptions(e)},[r,e]);let i=x.useSyncExternalStore(x.useCallback(e=>r.subscribe(d.batchCalls(e)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),a=x.useCallback((...e)=>{r.mutate(e[0],e[1]).catch(c)},[r]);if(i.error&&m(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:a,mutateAsync:i.mutate}}var C=new Map([[`bold`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm-12-80V80a12,12,0,0,1,24,0v52a12,12,0,0,1-24,0Zm28,40a16,16,0,1,1-16-16A16,16,0,0,1,144,172Z`}))],[`duotone`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z`}))],[`fill`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,56a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm8,104a12,12,0,1,1,12-12A12,12,0,0,1,128,184Z`}))],[`light`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm-6-82V80a6,6,0,0,1,12,0v56a6,6,0,0,1-12,0Zm16,36a10,10,0,1,1-10-10A10,10,0,0,1,138,172Z`}))],[`regular`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z`}))],[`thin`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm-4-84V80a4,4,0,0,1,8,0v56a4,4,0,0,1-8,0Zm12,36a8,8,0,1,1-8-8A8,8,0,0,1,136,172Z`}))]]),w=x.forwardRef((e,t)=>x.createElement(a,{ref:t,...e,weights:C}));w.displayName=`WarningCircleIcon`;var T=w;export{S as n,y as r,T as t}; \ No newline at end of file +import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{M as r,Y as i,a,f as o,w as s}from"./brand-DUaZkIz1.js";import{at as c,ct as l,it as u,nt as d,ot as f,rt as p,st as m,tt as h}from"./index-B7LmyWZW.js";var g={root:`m_849cf0da`},_=t(),v={underline:`hover`},y=s(e=>{let{underline:t,className:n,unstyled:a,mod:s,...c}=r(`Anchor`,v,e);return(0,_.jsx)(o,{component:`a`,className:i({[g.root]:!a},n),...c,mod:[{underline:t},s],__staticSelector:`Anchor`,unstyled:a})});y.classes=g,y.displayName=`@mantine/core/Anchor`;var b=class extends p{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),f(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&u(t.mutationKey)!==u(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onSubscribe(){this.listeners.size===1&&this.#n&&(this.#n.addObserver(this),this.#i())}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??h();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){d.batch(()=>{let t=this.#r;if(t&&this.hasListeners()){let n=this.#t.variables,r=this.#t.context,i={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{t.onSuccess?.(e.data,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(e.data,null,n,r,i)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{t.onError?.(e.error,n,r,i)}catch(e){Promise.reject(e)}try{t.onSettled?.(void 0,e.error,n,r,i)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},x=n(e(),1);function S(e,t){let n=l(t),[r]=x.useState(()=>new b(n,e));x.useEffect(()=>{r.setOptions(e)},[r,e]);let i=x.useSyncExternalStore(x.useCallback(e=>r.subscribe(d.batchCalls(e)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),a=x.useCallback((...e)=>{r.mutate(e[0],e[1]).catch(c)},[r]);if(i.error&&m(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:a,mutateAsync:i.mutate}}var C=new Map([[`bold`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm-12-80V80a12,12,0,0,1,24,0v52a12,12,0,0,1-24,0Zm28,40a16,16,0,1,1-16-16A16,16,0,0,1,144,172Z`}))],[`duotone`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z`}))],[`fill`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,56a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm8,104a12,12,0,1,1,12-12A12,12,0,0,1,128,184Z`}))],[`light`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm-6-82V80a6,6,0,0,1,12,0v56a6,6,0,0,1-12,0Zm16,36a10,10,0,1,1-10-10A10,10,0,0,1,138,172Z`}))],[`regular`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z`}))],[`thin`,x.createElement(x.Fragment,null,x.createElement(`path`,{d:`M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm-4-84V80a4,4,0,0,1,8,0v56a4,4,0,0,1-8,0Zm12,36a8,8,0,1,1-8-8A8,8,0,0,1,136,172Z`}))]]),w=x.forwardRef((e,t)=>x.createElement(a,{ref:t,...e,weights:C}));w.displayName=`WarningCircleIcon`;var T=w;export{S as n,y as r,T as t}; \ No newline at end of file diff --git a/internal/ui/dist/assets/chat-0Bi74QKL.js b/internal/ui/dist/assets/chat-BDYP-JLf.js similarity index 99% rename from internal/ui/dist/assets/chat-0Bi74QKL.js rename to internal/ui/dist/assets/chat-BDYP-JLf.js index 1292e2e7..df5a2062 100644 --- a/internal/ui/dist/assets/chat-0Bi74QKL.js +++ b/internal/ui/dist/assets/chat-BDYP-JLf.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mcp-app-frame-RnhKpud9.js","assets/useRouter-ByJ6_rwb.js","assets/brand-DUaZkIz1.js","assets/index-eh4vL-r5.js","assets/useNavigate-B1zgPEUp.js","assets/preload-helper-DJZNfKNH.js","assets/Tooltip-B3r3s_B9.js","assets/index-ADB9ThEc.css"])))=>i.map(i=>d[i]); -import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{A as r,C as i,M as a,S as o,T as s,_ as c,a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,tt as b,u as x,x as S,y as C}from"./brand-DUaZkIz1.js";import{n as w,t as T}from"./preload-helper-DJZNfKNH.js";import{t as E}from"./Tooltip-B3r3s_B9.js";import{a as D,c as O,d as k,l as A,n as j,r as M,t as N,u as P}from"./dashboard-change-chips-DcQEgN0t.js";import{B as ee,G as F,H as I,K as L,R,U as z,V as te,W as ne,Yt as B,z as re}from"./index-eh4vL-r5.js";var V=n(e(),1),H=t(),ie=[`borderBottomWidth`,`borderLeftWidth`,`borderRightWidth`,`borderTopWidth`,`boxSizing`,`fontFamily`,`fontSize`,`fontStyle`,`fontWeight`,`letterSpacing`,`lineHeight`,`paddingBottom`,`paddingLeft`,`paddingRight`,`paddingTop`,`tabSize`,`textIndent`,`textRendering`,`textTransform`,`width`,`wordBreak`,`wordSpacing`,`scrollbarGutter`],U={"min-height":`0`,"max-height":`none`,height:`0`,visibility:`hidden`,overflow:`hidden`,position:`absolute`,"z-index":`-1000`,top:`0`,right:`0`,display:`block`};function W(e){Object.keys(U).forEach(t=>{e.style.setProperty(t,U[t],`important`)})}function ae(e){let t=window.getComputedStyle(e);if(t===null)return null;let n={};for(let e of ie)n[e]=t[e];return n.boxSizing===``?null:{sizingStyle:n,paddingSize:parseFloat(n.paddingBottom)+parseFloat(n.paddingTop),borderSize:parseFloat(n.borderBottomWidth)+parseFloat(n.borderTopWidth)}}var G=null;function oe(e,t,n=1,r=1/0){G||(G=document.createElement(`textarea`),G.setAttribute(`tabindex`,`-1`),G.setAttribute(`aria-hidden`,`true`),G.setAttribute(`aria-label`,`autosize measurement`),W(G)),G.parentNode===null&&document.body.appendChild(G);let{paddingSize:i,borderSize:a,sizingStyle:o}=e,{boxSizing:s}=o;Object.keys(o).forEach(e=>{G.style[e]=o[e]}),W(G),G.value=t;let c=s===`border-box`?G.scrollHeight+a:G.scrollHeight-i;G.value=t,c=s===`border-box`?G.scrollHeight+a:G.scrollHeight-i,G.value=`x`;let l=G.scrollHeight-i,u=l*n;s===`border-box`&&(u=u+i+a),c=Math.max(u,c);let d=l*r;return s===`border-box`&&(d=d+i+a),c=Math.min(d,c),[c,l]}function se({maxRows:e,minRows:t,onChange:n,ref:r,...i}){let a=i.value!==void 0,o=(0,V.useRef)(null),s=b(o,r),c=(0,V.useRef)(0),l=(0,V.useRef)(0),u=()=>{let n=o.current;if(!n)return;let r=ae(n);if(!r)return;let[i]=oe(r,n.value||n.placeholder||`x`,t,e);c.current!==i&&(c.current=i,n.style.setProperty(`height`,`${i}px`,`important`))},d=(0,V.useEffectEvent)(u),f=e=>{a||u(),n?.(e)};return(0,V.useLayoutEffect)(u),(0,V.useEffect)(()=>{let e=()=>u();return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]),(0,V.useEffect)(()=>{let e=o.current;if(!e||typeof ResizeObserver>`u`)return;l.current=e.offsetWidth;let t=0,n=new ResizeObserver(()=>{o.current&&o.current.offsetWidth!==l.current&&(l.current=o.current.offsetWidth,cancelAnimationFrame(t),t=requestAnimationFrame(d))});return n.observe(e),()=>{cancelAnimationFrame(t),n.disconnect()}},[]),(0,V.useEffect)(()=>{let e=()=>u();return document.fonts.addEventListener(`loadingdone`,e),()=>document.fonts.removeEventListener(`loadingdone`,e)},[]),(0,V.useEffect)(()=>{let e=e=>{if(o.current?.form===e.target&&!a){let e=o.current.value;requestAnimationFrame(()=>{o.current&&e!==o.current.value&&u()})}};return document.body.addEventListener(`reset`,e),()=>document.body.removeEventListener(`reset`,e)},[a]),(0,H.jsx)(`textarea`,{rows:t,...i,onChange:f,ref:s})}var K=s(e=>{let{autosize:t,maxRows:n,minRows:r,__staticSelector:i,resize:o,bottomSection:s,bottomSectionProps:c,...l}=a([`Input`,`InputWrapper`,`Textarea`],null,e),u=t&&k()!==`test`,d=u?{maxRows:n,minRows:r}:{};return(0,H.jsx)(h,{component:u?se:`textarea`,...l,__staticSelector:i||`Textarea`,__bottomSection:s,__bottomSectionProps:c,multiline:!0,"data-no-overflow":t&&n===void 0||void 0,__vars:{"--input-resize":o},...d})});K.classes=h.classes,K.displayName=`@mantine/core/Textarea`;var q={root:`m_d08caa0`},J=s(e=>{let t=a(`Typography`,null,e),{classNames:n,className:o,style:s,styles:c,unstyled:l,attributes:u,...d}=t,f=r({name:`Typography`,classes:q,props:t,className:o,style:s,classNames:n,styles:c,unstyled:l,attributes:u});return(0,H.jsx)(i,{...f(`root`),...d})});J.classes=q,J.displayName=`@mantine/core/Typography`;var ce=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208.49,152.49l-72,72a12,12,0,0,1-17,0l-72-72a12,12,0,0,1,17-17L116,187V40a12,12,0,0,1,24,0V187l51.51-51.52a12,12,0,0,1,17,17Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,144l-72,72L56,144Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M207.39,140.94A8,8,0,0,0,200,136H136V40a8,8,0,0,0-16,0v96H56a8,8,0,0,0-5.66,13.66l72,72a8,8,0,0,0,11.32,0l72-72A8,8,0,0,0,207.39,140.94ZM128,204.69,75.31,152H180.69Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72A8,8,0,0,1,56,136h64V40a8,8,0,0,1,16,0v96h64a8,8,0,0,1,5.66,13.66Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M204.24,148.24l-72,72a6,6,0,0,1-8.48,0l-72-72a6,6,0,0,1,8.48-8.48L122,201.51V40a6,6,0,0,1,12,0V201.51l61.76-61.75a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72a8,8,0,0,1,11.32-11.32L120,196.69V40a8,8,0,0,1,16,0V196.69l58.34-58.35a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M202.83,146.83l-72,72a4,4,0,0,1-5.66,0l-72-72a4,4,0,0,1,5.66-5.66L124,206.34V40a4,4,0,0,1,8,0V206.34l65.17-65.17a4,4,0,0,1,5.66,5.66Z`}))]]),le=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M176,128,96,208V48Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M181.66,122.34l-80-80A8,8,0,0,0,88,48V208a8,8,0,0,0,13.66,5.66l80-80A8,8,0,0,0,181.66,122.34ZM104,188.69V67.31L164.69,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M181.66,133.66l-80,80A8,8,0,0,1,88,208V48a8,8,0,0,1,13.66-5.66l80,80A8,8,0,0,1,181.66,133.66Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M180.24,132.24l-80,80a6,6,0,0,1-8.48-8.48L167.51,128,91.76,52.24a6,6,0,0,1,8.48-8.48l80,80A6,6,0,0,1,180.24,132.24Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M178.83,130.83l-80,80a4,4,0,0,1-5.66-5.66L170.34,128,93.17,50.83a4,4,0,0,1,5.66-5.66l80,80A4,4,0,0,1,178.83,130.83Z`}))]]),ue=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M230.14,25.86a20,20,0,0,0-19.57-5.11l-.22.07L18.44,79a20,20,0,0,0-3.06,37.25L99,157l40.71,83.65a19.81,19.81,0,0,0,18,11.38c.57,0,1.15,0,1.73-.07A19.82,19.82,0,0,0,177,237.56L235.18,45.65a1.42,1.42,0,0,0,.07-.22A20,20,0,0,0,230.14,25.86ZM156.91,221.07l-34.37-70.64,46-45.95a12,12,0,0,0-17-17l-46,46L34.93,99.09,210,46Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M223.69,42.18l-58.22,192a8,8,0,0,1-14.92,1.25L108,148,20.58,105.45a8,8,0,0,1,1.25-14.92l192-58.22A8,8,0,0,1,223.69,42.18Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M227.32,28.68a16,16,0,0,0-15.66-4.08l-.15,0L19.57,82.84a16,16,0,0,0-2.49,29.8L102,154l41.3,84.87A15.86,15.86,0,0,0,157.74,248q.69,0,1.38-.06a15.88,15.88,0,0,0,14-11.51l58.2-191.94c0-.05,0-.1,0-.15A16,16,0,0,0,227.32,28.68ZM157.83,231.85l-.05.14,0-.07-40.06-82.3,48-48a8,8,0,0,0-11.31-11.31l-48,48L24.08,98.25l-.07,0,.14,0L216,40Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M231.4,44.34s0,.1,0,.15l-58.2,191.94a15.88,15.88,0,0,1-14,11.51q-.69.06-1.38.06a15.86,15.86,0,0,1-14.42-9.15L107,164.15a4,4,0,0,1,.77-4.58l57.92-57.92a8,8,0,0,0-11.31-11.31L96.43,148.26a4,4,0,0,1-4.58.77L17.08,112.64a16,16,0,0,1,2.49-29.8l191.94-58.2.15,0A16,16,0,0,1,231.4,44.34Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M225.88,30.12a13.83,13.83,0,0,0-13.7-3.58l-.11,0L20.14,84.77A14,14,0,0,0,18,110.85l85.56,41.64L145.12,238a13.87,13.87,0,0,0,12.61,8c.4,0,.81,0,1.21-.05a13.9,13.9,0,0,0,12.29-10.09l58.2-191.93,0-.11A13.83,13.83,0,0,0,225.88,30.12Zm-8,10.4L159.73,232.43l0,.11a2,2,0,0,1-3.76.26l-40.68-83.58,49-49a6,6,0,1,0-8.49-8.49l-49,49L23.15,100a2,2,0,0,1,.31-3.74l.11,0L215.48,38.08a1.94,1.94,0,0,1,1.92.52A2,2,0,0,1,217.92,40.52Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M227.32,28.68a16,16,0,0,0-15.66-4.08l-.15,0L19.57,82.84a16,16,0,0,0-2.49,29.8L102,154l41.3,84.87A15.86,15.86,0,0,0,157.74,248q.69,0,1.38-.06a15.88,15.88,0,0,0,14-11.51l58.2-191.94c0-.05,0-.1,0-.15A16,16,0,0,0,227.32,28.68ZM157.83,231.85l-.05.14,0-.07-40.06-82.3,48-48a8,8,0,0,0-11.31-11.31l-48,48L24.08,98.25l-.07,0,.14,0L216,40Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224.47,31.52a11.87,11.87,0,0,0-11.82-3L20.74,86.67a12,12,0,0,0-1.91,22.38L105,151l41.92,86.15A11.88,11.88,0,0,0,157.74,244c.34,0,.69,0,1,0a11.89,11.89,0,0,0,10.52-8.63l58.21-192,0-.08A11.85,11.85,0,0,0,224.47,31.52Zm-4.62,9.54-58.23,192a4,4,0,0,1-7.48.59l-41.3-84.86,50-50a4,4,0,1,0-5.66-5.66l-50,50-84.9-41.31a3.88,3.88,0,0,1-2.27-4,3.93,3.93,0,0,1,3-3.54L214.9,36.16A3.93,3.93,0,0,1,216,36a4,4,0,0,1,2.79,1.19A3.93,3.93,0,0,1,219.85,41.06Z`}))]]),de=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,36H56A20,20,0,0,0,36,56V200a20,20,0,0,0,20,20H200a20,20,0,0,0,20-20V56A20,20,0,0,0,200,36Zm-4,160H60V60H196Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,56V200a8,8,0,0,1-8,8H56a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8H200A8,8,0,0,1,208,56Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,42H56A14,14,0,0,0,42,56V200a14,14,0,0,0,14,14H200a14,14,0,0,0,14-14V56A14,14,0,0,0,200,42Zm2,158a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2H200a2,2,0,0,1,2,2Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,44H56A12,12,0,0,0,44,56V200a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V56A12,12,0,0,0,200,44Zm4,156a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4H200a4,4,0,0,1,4,4Z`}))]]),Y=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:ce}));Y.displayName=`ArrowDownIcon`;var fe=Y,X=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:le}));X.displayName=`CaretRightIcon`;var pe=X,me=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:ue}));me.displayName=`PaperPlaneTiltIcon`;var he=me,ge=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:de}));ge.displayName=`StopIcon`;var _e=ge;function ve(e){return e.dashboard.panels.length===1?e.dashboard.panels[0].title:e.dashboard.name}function ye(e){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Missing panel view`);let t=e;if(!t.view||![`preset`,`query`].includes(t.view.kind)||!/^[a-f0-9]{64}$/.test(t.view.key))throw Error(`Invalid panel view identity`);if(t.dashboard?.version!==1||!Array.isArray(t.dashboard.panels)||!t.dashboard.panels.length||t.dashboard.panels.length>40||!Array.isArray(t.results)||t.dashboard.panels.some(e=>!e||typeof e.id!=`string`||!e.id)||t.results.some(e=>!e||typeof e.id!=`string`))throw Error(`Invalid panel view`);let n=new Set(t.dashboard.panels.map(e=>e.id));if(n.size!==t.dashboard.panels.length||t.results.length!==n.size||new Set(t.results.map(e=>e.id)).size!==n.size||t.results.some(e=>!n.has(e.id)||![`ok`,`empty`,`error`].includes(e.status)))throw Error(`Panel results do not match the view`);if(t.vars!==void 0&&(!t.vars||typeof t.vars!=`object`||Array.isArray(t.vars)||Object.values(t.vars).some(e=>typeof e!=`string`&&!(Array.isArray(e)&&e.every(e=>typeof e==`string`)))))throw Error(`Invalid panel variables`);if(t.trace!==void 0&&(!t.trace?.data||!Array.isArray(t.trace.data.spans)||!Array.isArray(t.trace.data.logs)||!Array.isArray(t.trace.data.services)))throw Error(`Invalid trace detail`);return t}var be=new WeakSet;function xe(e){if(!e||typeof e!=`object`||Array.isArray(e))return;if(be.has(e))return e;let t=e;if(Object.keys(t).sort().join(`,`)===`is_error,resource_uri,tool_input,tool_name,tool_result`&&t.resource_uri===`ui://fanout/panels.html`&&typeof t.tool_name==`string`&&t.tool_name&&typeof t.is_error==`boolean`&&t.tool_input&&typeof t.tool_input==`object`&&!Array.isArray(t.tool_input)){try{ye(t.tool_result)}catch{return}return be.add(t),t}}var Se=16,Ce=new Set([`ArrowUp`,`ArrowDown`,`PageUp`,`PageDown`,`Home`,`End`,` `]);function we(e){let t=(0,V.useRef)(null),n=(0,V.useRef)(null),r=(0,V.useRef)(null),i=(0,V.useRef)(!0),a=(0,V.useRef)(e),o=(0,V.useRef)(()=>{}),s=(0,V.useRef)(null),c=(0,V.useRef)(new Set),l=(0,V.useRef)(null),u=(0,V.useRef)(null),[d,f]=(0,V.useState)(!1),p=(0,V.useCallback)(()=>{let e=t.current,n=r.current?.lastElementChild,i=!e||!n||n.getBoundingClientRect().bottom>e.getBoundingClientRect().top+e.clientTop+e.clientHeight+1;f(!!e&&i&&e.scrollHeight-e.clientHeight-e.scrollTop>1)},[]),m=(0,V.useCallback)(()=>{let e=t.current;if(!e)return;let n=e.getBoundingClientRect().top+e.clientTop,r=[...e.querySelectorAll(`[data-chat-anchor]`)].find(e=>e.getBoundingClientRect().bottom>n);l.current=r?{node:r,top:r.getBoundingClientRect().top}:null},[]),h=(0,V.useCallback)((e,t)=>{e.scrollTop=t,u.current=e.scrollTop},[]),g=(0,V.useCallback)(()=>{let e=t.current;if(e){if(r.current){let t=n.current&&parseFloat(getComputedStyle(n.current).paddingBottom)||0;r.current.style.minHeight=`${Math.max(0,e.clientHeight-Se-t)}px`,i.current&&h(e,e.scrollTop+r.current.getBoundingClientRect().top-e.getBoundingClientRect().top-e.clientTop-Se)}if(!i.current){let t=l.current;t?.node.isConnected&&h(e,e.scrollTop+t.node.getBoundingClientRect().top-t.top),m()}p()}},[m,h,p]),_=(0,V.useCallback)(()=>{let e=t.current,i=n.current;if(!e||!i){s.current?.disconnect(),s.current=null,c.current.clear();return}s.current??=new ResizeObserver(g);let a=new Set([e,i,...i.querySelectorAll(`[data-chat-anchor]`)]);r.current&&a.add(r.current);for(let e of c.current)a.has(e)||s.current.unobserve(e);for(let e of a)c.current.has(e)||s.current.observe(e);c.current=a},[g]),v=(0,V.useCallback)(e=>{if(o.current(),t.current=e,u.current=null,l.current=null,i.current=!0,_(),!e)return;let n=!1,r=()=>{i.current=!1,m()},a=e=>{let t=e.target;!e.defaultPrevented&&Ce.has(e.key)&&(t instanceof HTMLElement&&(t.closest(`input, textarea, select, [contenteditable]`)||(e.key===` `?t.closest(`button`):t.closest(`[role=slider]`)))||r())},s=()=>{n=!0},c=()=>{n=!1},d=()=>{n&&e.scrollTop!==u.current&&r(),i.current||m(),p()};e.addEventListener(`scroll`,d,{passive:!0}),e.addEventListener(`wheel`,r,{passive:!0}),e.addEventListener(`touchmove`,r,{passive:!0}),e.addEventListener(`keydown`,a),e.addEventListener(`pointerdown`,s),window.addEventListener(`pointerup`,c),window.addEventListener(`pointercancel`,c),o.current=()=>{e.removeEventListener(`scroll`,d),e.removeEventListener(`wheel`,r),e.removeEventListener(`touchmove`,r),e.removeEventListener(`keydown`,a),e.removeEventListener(`pointerdown`,s),window.removeEventListener(`pointerup`,c),window.removeEventListener(`pointercancel`,c),o.current=()=>{}},g()},[g,m,_,p]),y=(0,V.useCallback)(e=>{n.current=e,_()},[_]),b=(0,V.useCallback)(e=>{r.current?.style.removeProperty(`min-height`),r.current=e,_()},[_]);return(0,V.useLayoutEffect)(()=>{a.current!==e&&(a.current=e,i.current=!0,l.current=null),_(),g()}),{scrollRef:v,contentRef:y,turnRef:b,showJump:d,jumpToLatest:(0,V.useCallback)(()=>{let e=t.current;e&&(e.focus({preventScroll:!0}),i.current=!1,h(e,e.scrollHeight),m(),p())},[m,h,p])}}function Te(e=1500){let[t,n]=(0,V.useState)(`idle`),r=(0,V.useRef)(null);(0,V.useEffect)(()=>()=>{r.current&&clearTimeout(r.current)},[]);function i(t){r.current&&clearTimeout(r.current),n(`idle`),(navigator.clipboard?navigator.clipboard.writeText(t):Promise.reject(Error(`clipboard unavailable`))).then(()=>n(`copied`),()=>n(`failed`)).finally(()=>{r.current=setTimeout(()=>n(`idle`),e)})}return{state:t,copy:i}}var Z=e=>`${(e/1e3).toFixed(1)} s`;function Ee({receipt:e,running:t=!1,activity:n=``,awaitingAnswer:r=!1}){let[i,a]=(0,V.useState)(!1),o=(0,V.useId)(),s=e.saved,l=s?.receipt.save_check,p=t=>Object.hasOwn(e.panel_titles,t)?e.panel_titles[t]:t,m=Object.values(e.stages).filter(e=>e.state===`complete`).length,h=[e.stages.schema.state===`complete`?`Read telemetry`:void 0,e.panel_count===void 0?void 0:`${e.panel_count} ${e.panel_count===1?`panel`:`panels`}`,l?.checked?`Checked in ${Z(l.elapsed_ms)}`:void 0,s?`Saved v${s.version}`:void 0].filter(Boolean).join(` · `)||`Building dashboard`,g=[...s?te(s.receipt):[],...new Map(e.corrections.map(e=>[e.panel_id,`Fixed ${e.title}`])).values()];return(0,H.jsx)(S,{"data-build-receipt":e.turn_id,"data-dashboard-result":s?.id,"data-chat-anchor":!0,withBorder:!0,radius:`md`,p:`sm`,children:(0,H.jsxs)(u,{gap:6,children:[(0,H.jsxs)(c,{gap:`xs`,justify:`space-between`,children:[(0,H.jsxs)(f,{size:`sm`,role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:[h,(0,H.jsxs)(f,{span:!0,c:`dimmed`,size:`xs`,children:[` · `,m,` stages complete`]})]}),(0,H.jsxs)(d,{component:`button`,variant:`subtle`,color:`gray`,size:`compact-xs`,"aria-expanded":i,"aria-controls":o,onClick:()=>a(e=>!e),children:[`Details`,g.length>4?` (+${g.length-4})`:``]})]}),t&&r&&(0,H.jsxs)(c,{gap:`xs`,"data-build-running":!0,children:[(0,H.jsx)(C,{type:`dots`,size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:n||`Analyzing your system`})]}),(0,H.jsx)(N,{labels:g.slice(0,4)}),e.explanations.map(e=>t?e.split(` · `).filter(e=>!e.endsWith(`: incomplete`)).join(` · `):e).filter(Boolean).map((e,t)=>(0,H.jsx)(f,{size:`xs`,c:`dimmed`,"data-receipt-attention":!0,children:e},t)),s&&(0,H.jsx)(d,{renderRoot:e=>(0,H.jsx)(w,{...e,to:`/dashboards/$dashboardId`,params:{dashboardId:s.id},search:{}}),variant:`subtle`,size:`compact-sm`,color:`gray`,style:{alignSelf:`flex-start`},children:`Open dashboard`}),(0,H.jsx)(P,{expanded:i,id:o,children:(0,H.jsxs)(u,{gap:4,children:[s&&(0,H.jsxs)(f,{size:`xs`,children:[s.label,` `,s.name,` · opens the current dashboard`]}),Object.entries(e.stages).map(([e,n])=>(0,H.jsxs)(f,{size:`xs`,c:`dimmed`,children:[z[e],`: `,t&&n.state===`incomplete`?`in progress`:n.state,n.elapsed_ms===void 0?``:` · ${Z(n.elapsed_ms)}`]},e)),e.save_attempts.map((e,t)=>e.state===`retried`&&(0,H.jsxs)(f,{size:`xs`,c:`dimmed`,children:[`Save attempt `,t+1,`: retried`]},e.call_id)),!!e.context_counts.deploys&&(0,H.jsxs)(f,{size:`xs`,children:[e.context_counts.deploys,` deploys observed`]}),!!e.context_counts.anomalies&&(0,H.jsxs)(f,{size:`xs`,children:[e.context_counts.anomalies,` anomalies observed`]}),e.panels.map(e=>(0,H.jsxs)(f,{size:`xs`,children:[`Preview · `,p(e.id),`: `,e.status,e.elapsed_ms===void 0?``:` · ${Z(e.elapsed_ms)}`]},e.id)),l&&(0,H.jsxs)(f,{size:`xs`,children:[`Save check: `,l.checked?`checked`:`incomplete`,` · `,Z(l.elapsed_ms)]}),l?.panels.map(e=>(0,H.jsxs)(f,{size:`xs`,children:[`Save · `,p(e.id),`: `,e.status,` · `,e.rows??0,` rows`,e.elapsed_ms===void 0?``:` · ${Z(e.elapsed_ms)}`]},e.id)),g.slice(4).map((e,t)=>(0,H.jsx)(f,{size:`xs`,children:e},t)),e.corrections.map((e,t)=>(0,H.jsxs)(f,{size:`xs`,children:[`Fixed `,e.title,`: `,e.message]},t))]})})]})})}var De=(0,V.lazy)(()=>T(()=>import(`./mcp-app-frame-RnhKpud9.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]))),Oe=e=>e.tool_result.view.kind===`preset`;function ke(e){let t=new Map,n=new Set,r=[],i=()=>{let e=new Map;for(let t of r){let n=t.content.tool_result.view.key;e.set(n,t)}let i=new Set([...e.values()].map(e=>e.id)),a=[...e.values()].some(e=>Oe(e.content)),o=r.filter(e=>i.has(e.id)).at(-1)?.id;for(let e of r)i.has(e.id)?t.set(e.id,{content:e.content,expanded:Oe(e.content)||!a&&e.id===o}):n.add(e.id);r=[]};for(let t of e)if(t.role===`user`&&i(),t.role===`activity`&&t.activityType===`mcp-app`){let e=xe(t.content);e&&r.push({id:t.id,content:e})}return i(),{views:t,duplicates:n}}function Ae(e,t){return Array.isArray(e)?e.flatMap(e=>{if(!L(e)||typeof e.message!=`string`)return[];let n=typeof e.path==`string`?/^panels\[(\d+)\](?:\.|$)/.exec(e.path)?.[1]:void 0,r=n===void 0?void 0:t?.[Number(n)];return[r&&!e.message.startsWith(r)?`${r}: ${e.message}`:e.message]}):[]}function je(e){let t=new Map,n=new Map,r=new Map,i=`unattributed`;for(let a of e){if(a.role===`user`&&(n.clear(),r.clear(),i=a.id),a.role===`assistant`){i=a.id;for(let e of a.toolCalls??[]){let t=[`create_dashboard`,`replace_dashboard`].includes(e.function.name)?ne(e.function.arguments)?.dashboard:void 0,r=L(t)&&Array.isArray(t.panels)?t.panels.map(e=>L(e)&&typeof e.title==`string`?e.title:``):void 0;n.set(e.id,{assistant:i,name:e.function.name,titles:r})}}if(a.role===`tool`){let e=ne(a.content);if(!a.error&&!e?.error&&e?.isError!==!0)continue;let o=n.get(a.toolCallId);if(o&&F.has(o.name)&&I(a))continue;let s=L(e?.error)?e?.error:void 0;if(s?.code===`no_data`||s?.code===`unknown_service`)continue;let c=o?.assistant??i,l=r.get(c)??a.id;r.set(c,l);let u=t.get(l)??[],d=typeof s?.message==`string`?s.message:typeof a.error==`string`&&a.error?a.error:`Could not complete this step. Try again.`,f=[`create_dashboard`,`edit_dashboard`,`replace_dashboard`].includes(o?.name??``)&&(s?.code===`invalid_spec`||s?.code===`dashboard_version_conflict`);u.push({name:R(o?.name??``),message:d,details:f?Ae(e?.problems,o?.titles):[],readOnly:s?.code===`answer_only`,rejected:f}),t.set(l,u)}}return t}function Me({failures:e}){let[t,n]=(0,V.useState)({rejected:!1,failed:!1}),r=e.filter(e=>e.rejected),a=e.filter(e=>!e.readOnly&&!e.rejected),s=[{key:`rejected`,items:r,label:`${r.length} ${r.length===1?`draft`:`drafts`} rejected`},{key:`failed`,items:a,label:`${a.length} ${a.length===1?`step`:`steps`} failed`}];return(0,H.jsxs)(i,{"data-chat-anchor":!0,children:[e.some(e=>e.readOnly)&&(0,H.jsx)(f,{size:`sm`,c:`dimmed`,children:`Not saved: Explain is read-only`}),s.map(({key:e,items:r,label:a})=>r.length>0&&(0,H.jsxs)(i,{children:[(0,H.jsxs)(o,{className:`chat-app-toggle`,"aria-expanded":t[e],onClick:()=>n(t=>({...t,[e]:!t[e]})),style:{color:`var(--mantine-color-dimmed)`},children:[(0,H.jsx)(`span`,{className:`chat-app-chevron`,"aria-hidden":`true`,children:t[e]?(0,H.jsx)(O,{size:14}):(0,H.jsx)(pe,{size:14})}),(0,H.jsx)(`span`,{className:`chat-app-summary`,children:a})]}),t[e]&&(0,H.jsx)(u,{gap:`xs`,pl:`md`,children:r.flatMap((e,t)=>(e.details.length?e.details:[`${e.name}: ${e.message}`]).map((e,n)=>(0,H.jsx)(f,{size:`sm`,c:`dimmed`,style:{whiteSpace:`pre-wrap`,overflowWrap:`anywhere`},children:e},`${t}-${n}`)))})]},e))]})}function Ne({view:e}){let[t,n]=(0,V.useState)(e.expanded);(0,V.useEffect)(()=>n(e.expanded),[e.expanded]);let r=e.content.tool_result,i=ve(r),a=[...new Set(r.dashboard.panels.map(e=>e.viz===`timeseries`?`time series`:e.viz.replaceAll(`_`,` `)))].join(`, `),s=r.results.reduce((e,t)=>e+(t.frame?.rows??0),0),c=new Map;for(let e of r.results)e.status!==`ok`&&c.set(e.status,(c.get(e.status)??0)+1);let l=r.dashboard.panels.length>1?Array.from(c,([e,t])=>`${t} ${e}`).join(` · `):c.size?[...c.keys()].join(`, `):`${s} ${s===1?`row`:`rows`}`;return(0,H.jsxs)(S,{"data-chat-app":!0,"data-chat-anchor":!0,withBorder:!0,radius:`lg`,style:{overflow:`hidden`},children:[(0,H.jsxs)(o,{className:`chat-app-toggle`,"aria-expanded":t,onClick:()=>n(e=>!e),children:[(0,H.jsx)(`span`,{className:`chat-app-chevron`,"aria-hidden":`true`,children:t?(0,H.jsx)(O,{size:14}):(0,H.jsx)(pe,{size:14})}),(0,H.jsx)(`span`,{className:`chat-app-summary`,children:[i,a,l].filter(Boolean).join(` · `)})]}),t&&(0,H.jsx)(V.Suspense,{fallback:(0,H.jsx)(x,{mih:180,children:(0,H.jsx)(C,{size:`sm`})}),children:(0,H.jsx)(De,{content:e.content})})]})}var Pe=[`Summarize system health for the last hour`,`Find the source of elevated errors`,`Map the current service dependencies`,`Show the slowest endpoints`];function Fe(){let{agentAvailable:e,messages:t,messageTimes:n,ready:r,running:a,activity:o,stopped:s,error:l,threadMissing:p,send:h,retry:g,reloadThread:y,newThread:b}=ee(),w=re(t),T=t.filter(e=>e.role===`user`).at(-1)?.id,{scrollRef:D,contentRef:O,turnRef:k,showJump:A,jumpToLatest:j}=we(T);if(!e)return(0,H.jsx)(m,{size:`sm`,py:96,children:(0,H.jsx)(S,{withBorder:!0,radius:`lg`,p:{base:`xl`,sm:40},children:(0,H.jsxs)(u,{gap:`md`,children:[(0,H.jsx)(f,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Optional capability`}),(0,H.jsx)(_,{order:1,fz:28,children:`Chat is not configured`}),(0,H.jsx)(f,{c:`dimmed`,children:`Add an AI provider key to enable chat. Telemetry ingest, dashboards, traces, logs, and metrics remain available without it.`}),(0,H.jsx)(d,{component:`a`,href:`/dashboards`,variant:`light`,mt:`sm`,children:`Open dashboards`})]})})});let M=ke(t),N=je(t),P=t.filter(e=>M.duplicates.has(e.id)?!1:e.role===`tool`?N.has(e.id):e.role===`assistant`?!e.toolCalls?.length&&typeof e.content==`string`&&e.content.trim().length>0:e.role===`activity`?e.activityType===`mcp-app`||e.activityType===`agent-outcome`:e.role===`user`),F=t.findIndex(e=>e.id===T),I=t.slice(F+1).some(e=>e.role===`assistant`&&!e.toolCalls?.length&&typeof e.content==`string`&&e.content.length>0),L=t.slice(F+1).filter(e=>e.role===`assistant`&&!e.toolCalls?.length&&typeof e.content==`string`&&e.content.trim().length>0).at(-1),R=[];for(let e of P)(e.role===`user`||R.length===0)&&R.push({id:e.id,messages:[]}),R.at(-1).messages.push(e);R.length===0&&R.push({id:`draft`,messages:[]});let z=e=>N.has(e.id)?(0,H.jsx)(Me,{failures:N.get(e.id)},e.id):(0,H.jsxs)(i,{children:[(0,H.jsx)(Re,{message:e,time:n[e.id],appView:M.views.get(e.id)}),w.has(e.id)&&(0,H.jsx)(i,{mt:`sm`,children:(0,H.jsx)(Ee,{receipt:w.get(e.id),running:a&&e.id===T,awaitingAnswer:!I,activity:o})})]},e.id);return(0,H.jsxs)(i,{className:`chat-pane`,children:[(0,H.jsxs)(i,{className:`chat-viewport`,children:[(0,H.jsx)(i,{className:`chat-scroll`,ref:D,tabIndex:0,role:`log`,"aria-label":`Conversation`,children:(0,H.jsxs)(m,{size:880,px:{base:`md`,sm:`xl`},py:`lg`,ref:O,children:[p&&(0,H.jsx)(v,{color:`warn`,radius:`lg`,title:`This chat no longer exists`,children:(0,H.jsxs)(c,{justify:`space-between`,children:[(0,H.jsx)(f,{size:`sm`,children:`It was deleted, or the link is wrong.`}),(0,H.jsx)(d,{size:`compact-sm`,variant:`light`,onClick:b,children:`New chat`})]})}),!p&&!r&&l&&(0,H.jsx)(Q,{message:l,onRetry:y,onNewThread:b}),!p&&!r&&!l&&(0,H.jsxs)(x,{mih:`40vh`,children:[(0,H.jsx)(C,{size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,ml:`sm`,children:`Loading chat`})]}),!p&&r&&(0,H.jsxs)(H.Fragment,{children:[P.length===0&&(0,H.jsx)(Le,{onSelect:h}),(0,H.jsx)(u,{gap:`lg`,children:R.map((e,t)=>(0,H.jsxs)(u,{gap:`lg`,ref:e.id===T?k:void 0,"data-chat-turn":e.id===T?T:void 0,children:[e.messages.filter(e=>e.id!==L?.id).map(z),t===R.length-1&&(0,H.jsxs)(H.Fragment,{children:[L&&(0,H.jsx)(i,{"data-answer-position":!0,children:(0,H.jsx)(Re,{message:L,time:n[L.id]})},`answer-${T??`draft`}`),a&&!I&&!w.has(T??``)&&(0,H.jsxs)(c,{gap:`xs`,role:`status`,children:[(0,H.jsx)(C,{type:`dots`,size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:o||`Analyzing your system`})]}),s&&(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:`Stopped`}),l&&(0,H.jsx)(Q,{message:l,onRetry:g})]})]},e.id))})]})]})}),A&&(0,H.jsx)(E,{label:`Jump to latest`,children:(0,H.jsx)(B,{className:`chat-jump`,variant:`default`,size:36,radius:`xl`,"aria-label":`Jump to latest`,onClick:j,children:(0,H.jsx)(fe,{size:18,"aria-hidden":`true`})})})]}),!p&&(0,H.jsx)(Ie,{})]})}function Q({message:e,onRetry:t,onNewThread:n}){return(0,H.jsx)(v,{color:`bad`,radius:`lg`,title:`Something went wrong`,children:(0,H.jsxs)(c,{justify:`space-between`,gap:`sm`,wrap:`nowrap`,children:[(0,H.jsx)(f,{size:`sm`,children:e}),(0,H.jsxs)(c,{gap:`xs`,wrap:`nowrap`,children:[n&&(0,H.jsx)(d,{size:`compact-sm`,variant:`subtle`,color:`bad`,onClick:n,children:`New chat`}),(0,H.jsx)(d,{size:`compact-sm`,variant:`light`,color:`bad`,onClick:t,children:`Retry`})]})]})})}function Ie(){let{input:e,setInput:t,inputRef:n,submit:r,send:a,stop:o,ready:s,running:l}=ee();return(0,H.jsx)(i,{className:`chat-composer`,children:(0,H.jsxs)(m,{size:880,px:{base:`md`,sm:`xl`},children:[(0,H.jsx)(S,{component:`form`,onSubmit:r,className:`chat-composer-field`,withBorder:!0,radius:24,py:6,pl:`lg`,pr:6,children:(0,H.jsxs)(c,{align:`flex-end`,gap:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(K,{ref:n,"aria-label":`Message Fanout`,value:e,onChange:e=>t(e.currentTarget.value),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),a(e))},placeholder:l?`Fanout is working…`:`Ask about health, errors, or latency…`,disabled:!s,autosize:!0,minRows:1,maxRows:8,variant:`unstyled`,flex:1}),l?(0,H.jsx)(E,{label:`Stop`,children:(0,H.jsx)(B,{type:`button`,variant:`default`,size:40,radius:`xl`,"aria-label":`Stop`,onClick:o,children:(0,H.jsx)(_e,{size:16,weight:`fill`})})}):(0,H.jsx)(B,{type:`submit`,variant:`filled`,size:40,radius:`xl`,disabled:!e.trim()||!s,"aria-label":`Send message`,children:(0,H.jsx)(he,{size:17,weight:`fill`})})]})}),(0,H.jsx)(f,{c:`dimmed`,size:`xs`,ta:`center`,mt:6,children:`Enter to send, Shift+Enter for a new line`})]})})}function Le({onSelect:e}){return(0,H.jsxs)(u,{align:`center`,gap:`md`,pt:{base:32,sm:88},pb:`xl`,ta:`center`,children:[(0,H.jsx)(g,{size:`large`}),(0,H.jsx)(_,{order:1,fz:24,fw:500,lh:1.25,maw:560,children:`What do you want to know about your system?`}),(0,H.jsx)(c,{justify:`center`,gap:`xs`,mt:`xs`,maw:720,children:Pe.map(t=>(0,H.jsx)(d,{variant:`default`,size:`sm`,radius:`xl`,onClick:()=>void e(t),children:t},t))})]})}function Re({message:e,time:t,appView:n}){if(e.role===`activity`)return e.activityType===`agent-outcome`&&e.content&&typeof e.content==`object`&&`message`in e.content&&typeof e.content.message==`string`?`status`in e.content&&e.content.status===`stopped`?(0,H.jsx)(f,{c:`dimmed`,size:`sm`,"data-chat-anchor":!0,children:e.content.message}):(0,H.jsx)(v,{color:`bad`,title:`Something went wrong`,"data-chat-anchor":!0,children:e.content.message}):e.activityType===`mcp-app`?n?(0,H.jsx)(Ne,{view:n}):(0,H.jsx)(v,{color:`bad`,"data-chat-anchor":!0,children:`This view could not be loaded. Please try again.`}):null;if(e.role===`assistant`&&e.toolCalls?.length)return null;let r=typeof e.content==`string`?e.content:JSON.stringify(e.content);if(!r&&e.role===`assistant`)return null;let a=e.role===`user`,o=t?new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`}).format(new Date(t)):``;return(0,H.jsxs)(i,{className:`chat-message`,"data-chat-anchor":!0,"data-role":a?`user`:`assistant`,children:[a?(0,H.jsx)(S,{radius:`lg`,px:`md`,py:`sm`,bg:`var(--mantine-color-brand-light)`,maw:`70%`,ml:`auto`,w:`fit-content`,children:(0,H.jsx)(f,{style:{whiteSpace:`pre-wrap`},children:r})}):(0,H.jsx)(J,{className:`chat-markdown`,children:(0,H.jsx)(M,{remarkPlugins:[j],components:Be,children:r})}),(o||!a)&&(0,H.jsxs)(c,{className:`chat-message-meta`,gap:6,justify:a?`flex-end`:`flex-start`,mt:4,h:24,children:[o&&t&&(0,H.jsx)(f,{c:`dimmed`,size:`xs`,title:D(t),children:o}),!a&&(0,H.jsx)(ze,{text:r,label:`Copy message`})]})]})}function ze({text:e,label:t}){let{state:n,copy:r}=Te();return(0,H.jsx)(E,{label:n===`failed`?`Could not copy`:n===`copied`?`Copied`:t,children:(0,H.jsx)(B,{variant:`subtle`,color:`gray`,size:`sm`,"aria-label":t,"data-state":n===`idle`?void 0:n,onClick:()=>r(e),children:n===`copied`?(0,H.jsx)(p,{size:13,weight:`bold`}):(0,H.jsx)(y,{size:13})})})}var Be={table:({children:e})=>(0,H.jsx)(i,{className:`chat-table`,children:(0,H.jsx)(A,{striped:!0,highlightOnHover:!0,withTableBorder:!0,verticalSpacing:`xs`,fz:`sm`,children:e})}),thead:({children:e})=>(0,H.jsx)(A.Thead,{children:e}),tbody:({children:e})=>(0,H.jsx)(A.Tbody,{children:e}),tr:({children:e})=>(0,H.jsx)(A.Tr,{children:e}),th:({children:e})=>(0,H.jsx)(A.Th,{children:e}),td:({children:e})=>(0,H.jsx)(A.Td,{children:e}),pre:({children:e})=>(0,H.jsx)(Ve,{children:e}),a:({href:e,children:t})=>(0,H.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,children:t})};function Ve({children:e}){let t=$(e);return(0,H.jsxs)(i,{className:`chat-code`,pos:`relative`,children:[(0,H.jsx)(i,{className:`chat-code-actions`,pos:`absolute`,top:6,right:6,children:(0,H.jsx)(ze,{text:t,label:`Copy code`})}),(0,H.jsx)(`pre`,{children:e})]})}function $(e){return typeof e==`string`?e:Array.isArray(e)?e.map($).join(``):e&&typeof e==`object`&&`props`in e?$(e.props.children):``}export{xe as n,Fe as t}; \ No newline at end of file +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mcp-app-frame-BzM2b2mm.js","assets/useRouter-ByJ6_rwb.js","assets/brand-DUaZkIz1.js","assets/index-B7LmyWZW.js","assets/useNavigate-B1zgPEUp.js","assets/preload-helper-DJZNfKNH.js","assets/Tooltip-B3r3s_B9.js","assets/index-ADB9ThEc.css"])))=>i.map(i=>d[i]); +import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{A as r,C as i,M as a,S as o,T as s,_ as c,a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,tt as b,u as x,x as S,y as C}from"./brand-DUaZkIz1.js";import{n as w,t as T}from"./preload-helper-DJZNfKNH.js";import{t as E}from"./Tooltip-B3r3s_B9.js";import{a as D,c as O,d as k,l as A,n as j,r as M,t as N,u as P}from"./dashboard-change-chips-CghpARdt.js";import{B as ee,G as F,H as I,K as L,R,U as z,V as te,W as ne,Yt as B,z as re}from"./index-B7LmyWZW.js";var V=n(e(),1),H=t(),ie=[`borderBottomWidth`,`borderLeftWidth`,`borderRightWidth`,`borderTopWidth`,`boxSizing`,`fontFamily`,`fontSize`,`fontStyle`,`fontWeight`,`letterSpacing`,`lineHeight`,`paddingBottom`,`paddingLeft`,`paddingRight`,`paddingTop`,`tabSize`,`textIndent`,`textRendering`,`textTransform`,`width`,`wordBreak`,`wordSpacing`,`scrollbarGutter`],U={"min-height":`0`,"max-height":`none`,height:`0`,visibility:`hidden`,overflow:`hidden`,position:`absolute`,"z-index":`-1000`,top:`0`,right:`0`,display:`block`};function W(e){Object.keys(U).forEach(t=>{e.style.setProperty(t,U[t],`important`)})}function ae(e){let t=window.getComputedStyle(e);if(t===null)return null;let n={};for(let e of ie)n[e]=t[e];return n.boxSizing===``?null:{sizingStyle:n,paddingSize:parseFloat(n.paddingBottom)+parseFloat(n.paddingTop),borderSize:parseFloat(n.borderBottomWidth)+parseFloat(n.borderTopWidth)}}var G=null;function oe(e,t,n=1,r=1/0){G||(G=document.createElement(`textarea`),G.setAttribute(`tabindex`,`-1`),G.setAttribute(`aria-hidden`,`true`),G.setAttribute(`aria-label`,`autosize measurement`),W(G)),G.parentNode===null&&document.body.appendChild(G);let{paddingSize:i,borderSize:a,sizingStyle:o}=e,{boxSizing:s}=o;Object.keys(o).forEach(e=>{G.style[e]=o[e]}),W(G),G.value=t;let c=s===`border-box`?G.scrollHeight+a:G.scrollHeight-i;G.value=t,c=s===`border-box`?G.scrollHeight+a:G.scrollHeight-i,G.value=`x`;let l=G.scrollHeight-i,u=l*n;s===`border-box`&&(u=u+i+a),c=Math.max(u,c);let d=l*r;return s===`border-box`&&(d=d+i+a),c=Math.min(d,c),[c,l]}function se({maxRows:e,minRows:t,onChange:n,ref:r,...i}){let a=i.value!==void 0,o=(0,V.useRef)(null),s=b(o,r),c=(0,V.useRef)(0),l=(0,V.useRef)(0),u=()=>{let n=o.current;if(!n)return;let r=ae(n);if(!r)return;let[i]=oe(r,n.value||n.placeholder||`x`,t,e);c.current!==i&&(c.current=i,n.style.setProperty(`height`,`${i}px`,`important`))},d=(0,V.useEffectEvent)(u),f=e=>{a||u(),n?.(e)};return(0,V.useLayoutEffect)(u),(0,V.useEffect)(()=>{let e=()=>u();return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]),(0,V.useEffect)(()=>{let e=o.current;if(!e||typeof ResizeObserver>`u`)return;l.current=e.offsetWidth;let t=0,n=new ResizeObserver(()=>{o.current&&o.current.offsetWidth!==l.current&&(l.current=o.current.offsetWidth,cancelAnimationFrame(t),t=requestAnimationFrame(d))});return n.observe(e),()=>{cancelAnimationFrame(t),n.disconnect()}},[]),(0,V.useEffect)(()=>{let e=()=>u();return document.fonts.addEventListener(`loadingdone`,e),()=>document.fonts.removeEventListener(`loadingdone`,e)},[]),(0,V.useEffect)(()=>{let e=e=>{if(o.current?.form===e.target&&!a){let e=o.current.value;requestAnimationFrame(()=>{o.current&&e!==o.current.value&&u()})}};return document.body.addEventListener(`reset`,e),()=>document.body.removeEventListener(`reset`,e)},[a]),(0,H.jsx)(`textarea`,{rows:t,...i,onChange:f,ref:s})}var K=s(e=>{let{autosize:t,maxRows:n,minRows:r,__staticSelector:i,resize:o,bottomSection:s,bottomSectionProps:c,...l}=a([`Input`,`InputWrapper`,`Textarea`],null,e),u=t&&k()!==`test`,d=u?{maxRows:n,minRows:r}:{};return(0,H.jsx)(h,{component:u?se:`textarea`,...l,__staticSelector:i||`Textarea`,__bottomSection:s,__bottomSectionProps:c,multiline:!0,"data-no-overflow":t&&n===void 0||void 0,__vars:{"--input-resize":o},...d})});K.classes=h.classes,K.displayName=`@mantine/core/Textarea`;var q={root:`m_d08caa0`},J=s(e=>{let t=a(`Typography`,null,e),{classNames:n,className:o,style:s,styles:c,unstyled:l,attributes:u,...d}=t,f=r({name:`Typography`,classes:q,props:t,className:o,style:s,classNames:n,styles:c,unstyled:l,attributes:u});return(0,H.jsx)(i,{...f(`root`),...d})});J.classes=q,J.displayName=`@mantine/core/Typography`;var ce=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208.49,152.49l-72,72a12,12,0,0,1-17,0l-72-72a12,12,0,0,1,17-17L116,187V40a12,12,0,0,1,24,0V187l51.51-51.52a12,12,0,0,1,17,17Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,144l-72,72L56,144Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M207.39,140.94A8,8,0,0,0,200,136H136V40a8,8,0,0,0-16,0v96H56a8,8,0,0,0-5.66,13.66l72,72a8,8,0,0,0,11.32,0l72-72A8,8,0,0,0,207.39,140.94ZM128,204.69,75.31,152H180.69Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72A8,8,0,0,1,56,136h64V40a8,8,0,0,1,16,0v96h64a8,8,0,0,1,5.66,13.66Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M204.24,148.24l-72,72a6,6,0,0,1-8.48,0l-72-72a6,6,0,0,1,8.48-8.48L122,201.51V40a6,6,0,0,1,12,0V201.51l61.76-61.75a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72a8,8,0,0,1,11.32-11.32L120,196.69V40a8,8,0,0,1,16,0V196.69l58.34-58.35a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M202.83,146.83l-72,72a4,4,0,0,1-5.66,0l-72-72a4,4,0,0,1,5.66-5.66L124,206.34V40a4,4,0,0,1,8,0V206.34l65.17-65.17a4,4,0,0,1,5.66,5.66Z`}))]]),le=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M176,128,96,208V48Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M181.66,122.34l-80-80A8,8,0,0,0,88,48V208a8,8,0,0,0,13.66,5.66l80-80A8,8,0,0,0,181.66,122.34ZM104,188.69V67.31L164.69,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M181.66,133.66l-80,80A8,8,0,0,1,88,208V48a8,8,0,0,1,13.66-5.66l80,80A8,8,0,0,1,181.66,133.66Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M180.24,132.24l-80,80a6,6,0,0,1-8.48-8.48L167.51,128,91.76,52.24a6,6,0,0,1,8.48-8.48l80,80A6,6,0,0,1,180.24,132.24Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M178.83,130.83l-80,80a4,4,0,0,1-5.66-5.66L170.34,128,93.17,50.83a4,4,0,0,1,5.66-5.66l80,80A4,4,0,0,1,178.83,130.83Z`}))]]),ue=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M230.14,25.86a20,20,0,0,0-19.57-5.11l-.22.07L18.44,79a20,20,0,0,0-3.06,37.25L99,157l40.71,83.65a19.81,19.81,0,0,0,18,11.38c.57,0,1.15,0,1.73-.07A19.82,19.82,0,0,0,177,237.56L235.18,45.65a1.42,1.42,0,0,0,.07-.22A20,20,0,0,0,230.14,25.86ZM156.91,221.07l-34.37-70.64,46-45.95a12,12,0,0,0-17-17l-46,46L34.93,99.09,210,46Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M223.69,42.18l-58.22,192a8,8,0,0,1-14.92,1.25L108,148,20.58,105.45a8,8,0,0,1,1.25-14.92l192-58.22A8,8,0,0,1,223.69,42.18Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M227.32,28.68a16,16,0,0,0-15.66-4.08l-.15,0L19.57,82.84a16,16,0,0,0-2.49,29.8L102,154l41.3,84.87A15.86,15.86,0,0,0,157.74,248q.69,0,1.38-.06a15.88,15.88,0,0,0,14-11.51l58.2-191.94c0-.05,0-.1,0-.15A16,16,0,0,0,227.32,28.68ZM157.83,231.85l-.05.14,0-.07-40.06-82.3,48-48a8,8,0,0,0-11.31-11.31l-48,48L24.08,98.25l-.07,0,.14,0L216,40Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M231.4,44.34s0,.1,0,.15l-58.2,191.94a15.88,15.88,0,0,1-14,11.51q-.69.06-1.38.06a15.86,15.86,0,0,1-14.42-9.15L107,164.15a4,4,0,0,1,.77-4.58l57.92-57.92a8,8,0,0,0-11.31-11.31L96.43,148.26a4,4,0,0,1-4.58.77L17.08,112.64a16,16,0,0,1,2.49-29.8l191.94-58.2.15,0A16,16,0,0,1,231.4,44.34Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M225.88,30.12a13.83,13.83,0,0,0-13.7-3.58l-.11,0L20.14,84.77A14,14,0,0,0,18,110.85l85.56,41.64L145.12,238a13.87,13.87,0,0,0,12.61,8c.4,0,.81,0,1.21-.05a13.9,13.9,0,0,0,12.29-10.09l58.2-191.93,0-.11A13.83,13.83,0,0,0,225.88,30.12Zm-8,10.4L159.73,232.43l0,.11a2,2,0,0,1-3.76.26l-40.68-83.58,49-49a6,6,0,1,0-8.49-8.49l-49,49L23.15,100a2,2,0,0,1,.31-3.74l.11,0L215.48,38.08a1.94,1.94,0,0,1,1.92.52A2,2,0,0,1,217.92,40.52Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M227.32,28.68a16,16,0,0,0-15.66-4.08l-.15,0L19.57,82.84a16,16,0,0,0-2.49,29.8L102,154l41.3,84.87A15.86,15.86,0,0,0,157.74,248q.69,0,1.38-.06a15.88,15.88,0,0,0,14-11.51l58.2-191.94c0-.05,0-.1,0-.15A16,16,0,0,0,227.32,28.68ZM157.83,231.85l-.05.14,0-.07-40.06-82.3,48-48a8,8,0,0,0-11.31-11.31l-48,48L24.08,98.25l-.07,0,.14,0L216,40Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224.47,31.52a11.87,11.87,0,0,0-11.82-3L20.74,86.67a12,12,0,0,0-1.91,22.38L105,151l41.92,86.15A11.88,11.88,0,0,0,157.74,244c.34,0,.69,0,1,0a11.89,11.89,0,0,0,10.52-8.63l58.21-192,0-.08A11.85,11.85,0,0,0,224.47,31.52Zm-4.62,9.54-58.23,192a4,4,0,0,1-7.48.59l-41.3-84.86,50-50a4,4,0,1,0-5.66-5.66l-50,50-84.9-41.31a3.88,3.88,0,0,1-2.27-4,3.93,3.93,0,0,1,3-3.54L214.9,36.16A3.93,3.93,0,0,1,216,36a4,4,0,0,1,2.79,1.19A3.93,3.93,0,0,1,219.85,41.06Z`}))]]),de=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,36H56A20,20,0,0,0,36,56V200a20,20,0,0,0,20,20H200a20,20,0,0,0,20-20V56A20,20,0,0,0,200,36Zm-4,160H60V60H196Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,56V200a8,8,0,0,1-8,8H56a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8H200A8,8,0,0,1,208,56Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,42H56A14,14,0,0,0,42,56V200a14,14,0,0,0,14,14H200a14,14,0,0,0,14-14V56A14,14,0,0,0,200,42Zm2,158a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2H200a2,2,0,0,1,2,2Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M200,44H56A12,12,0,0,0,44,56V200a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V56A12,12,0,0,0,200,44Zm4,156a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4H200a4,4,0,0,1,4,4Z`}))]]),Y=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:ce}));Y.displayName=`ArrowDownIcon`;var fe=Y,X=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:le}));X.displayName=`CaretRightIcon`;var pe=X,me=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:ue}));me.displayName=`PaperPlaneTiltIcon`;var he=me,ge=V.forwardRef((e,t)=>V.createElement(l,{ref:t,...e,weights:de}));ge.displayName=`StopIcon`;var _e=ge;function ve(e){return e.dashboard.panels.length===1?e.dashboard.panels[0].title:e.dashboard.name}function ye(e){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Missing panel view`);let t=e;if(!t.view||![`preset`,`query`].includes(t.view.kind)||!/^[a-f0-9]{64}$/.test(t.view.key))throw Error(`Invalid panel view identity`);if(t.dashboard?.version!==1||!Array.isArray(t.dashboard.panels)||!t.dashboard.panels.length||t.dashboard.panels.length>40||!Array.isArray(t.results)||t.dashboard.panels.some(e=>!e||typeof e.id!=`string`||!e.id)||t.results.some(e=>!e||typeof e.id!=`string`))throw Error(`Invalid panel view`);let n=new Set(t.dashboard.panels.map(e=>e.id));if(n.size!==t.dashboard.panels.length||t.results.length!==n.size||new Set(t.results.map(e=>e.id)).size!==n.size||t.results.some(e=>!n.has(e.id)||![`ok`,`empty`,`error`].includes(e.status)))throw Error(`Panel results do not match the view`);if(t.vars!==void 0&&(!t.vars||typeof t.vars!=`object`||Array.isArray(t.vars)||Object.values(t.vars).some(e=>typeof e!=`string`&&!(Array.isArray(e)&&e.every(e=>typeof e==`string`)))))throw Error(`Invalid panel variables`);if(t.trace!==void 0&&(!t.trace?.data||!Array.isArray(t.trace.data.spans)||!Array.isArray(t.trace.data.logs)||!Array.isArray(t.trace.data.services)))throw Error(`Invalid trace detail`);return t}var be=new WeakSet;function xe(e){if(!e||typeof e!=`object`||Array.isArray(e))return;if(be.has(e))return e;let t=e;if(Object.keys(t).sort().join(`,`)===`is_error,resource_uri,tool_input,tool_name,tool_result`&&t.resource_uri===`ui://fanout/panels.html`&&typeof t.tool_name==`string`&&t.tool_name&&typeof t.is_error==`boolean`&&t.tool_input&&typeof t.tool_input==`object`&&!Array.isArray(t.tool_input)){try{ye(t.tool_result)}catch{return}return be.add(t),t}}var Se=16,Ce=new Set([`ArrowUp`,`ArrowDown`,`PageUp`,`PageDown`,`Home`,`End`,` `]);function we(e){let t=(0,V.useRef)(null),n=(0,V.useRef)(null),r=(0,V.useRef)(null),i=(0,V.useRef)(!0),a=(0,V.useRef)(e),o=(0,V.useRef)(()=>{}),s=(0,V.useRef)(null),c=(0,V.useRef)(new Set),l=(0,V.useRef)(null),u=(0,V.useRef)(null),[d,f]=(0,V.useState)(!1),p=(0,V.useCallback)(()=>{let e=t.current,n=r.current?.lastElementChild,i=!e||!n||n.getBoundingClientRect().bottom>e.getBoundingClientRect().top+e.clientTop+e.clientHeight+1;f(!!e&&i&&e.scrollHeight-e.clientHeight-e.scrollTop>1)},[]),m=(0,V.useCallback)(()=>{let e=t.current;if(!e)return;let n=e.getBoundingClientRect().top+e.clientTop,r=[...e.querySelectorAll(`[data-chat-anchor]`)].find(e=>e.getBoundingClientRect().bottom>n);l.current=r?{node:r,top:r.getBoundingClientRect().top}:null},[]),h=(0,V.useCallback)((e,t)=>{e.scrollTop=t,u.current=e.scrollTop},[]),g=(0,V.useCallback)(()=>{let e=t.current;if(e){if(r.current){let t=n.current&&parseFloat(getComputedStyle(n.current).paddingBottom)||0;r.current.style.minHeight=`${Math.max(0,e.clientHeight-Se-t)}px`,i.current&&h(e,e.scrollTop+r.current.getBoundingClientRect().top-e.getBoundingClientRect().top-e.clientTop-Se)}if(!i.current){let t=l.current;t?.node.isConnected&&h(e,e.scrollTop+t.node.getBoundingClientRect().top-t.top),m()}p()}},[m,h,p]),_=(0,V.useCallback)(()=>{let e=t.current,i=n.current;if(!e||!i){s.current?.disconnect(),s.current=null,c.current.clear();return}s.current??=new ResizeObserver(g);let a=new Set([e,i,...i.querySelectorAll(`[data-chat-anchor]`)]);r.current&&a.add(r.current);for(let e of c.current)a.has(e)||s.current.unobserve(e);for(let e of a)c.current.has(e)||s.current.observe(e);c.current=a},[g]),v=(0,V.useCallback)(e=>{if(o.current(),t.current=e,u.current=null,l.current=null,i.current=!0,_(),!e)return;let n=!1,r=()=>{i.current=!1,m()},a=e=>{let t=e.target;!e.defaultPrevented&&Ce.has(e.key)&&(t instanceof HTMLElement&&(t.closest(`input, textarea, select, [contenteditable]`)||(e.key===` `?t.closest(`button`):t.closest(`[role=slider]`)))||r())},s=()=>{n=!0},c=()=>{n=!1},d=()=>{n&&e.scrollTop!==u.current&&r(),i.current||m(),p()};e.addEventListener(`scroll`,d,{passive:!0}),e.addEventListener(`wheel`,r,{passive:!0}),e.addEventListener(`touchmove`,r,{passive:!0}),e.addEventListener(`keydown`,a),e.addEventListener(`pointerdown`,s),window.addEventListener(`pointerup`,c),window.addEventListener(`pointercancel`,c),o.current=()=>{e.removeEventListener(`scroll`,d),e.removeEventListener(`wheel`,r),e.removeEventListener(`touchmove`,r),e.removeEventListener(`keydown`,a),e.removeEventListener(`pointerdown`,s),window.removeEventListener(`pointerup`,c),window.removeEventListener(`pointercancel`,c),o.current=()=>{}},g()},[g,m,_,p]),y=(0,V.useCallback)(e=>{n.current=e,_()},[_]),b=(0,V.useCallback)(e=>{r.current?.style.removeProperty(`min-height`),r.current=e,_()},[_]);return(0,V.useLayoutEffect)(()=>{a.current!==e&&(a.current=e,i.current=!0,l.current=null),_(),g()}),{scrollRef:v,contentRef:y,turnRef:b,showJump:d,jumpToLatest:(0,V.useCallback)(()=>{let e=t.current;e&&(e.focus({preventScroll:!0}),i.current=!1,h(e,e.scrollHeight),m(),p())},[m,h,p])}}function Te(e=1500){let[t,n]=(0,V.useState)(`idle`),r=(0,V.useRef)(null);(0,V.useEffect)(()=>()=>{r.current&&clearTimeout(r.current)},[]);function i(t){r.current&&clearTimeout(r.current),n(`idle`),(navigator.clipboard?navigator.clipboard.writeText(t):Promise.reject(Error(`clipboard unavailable`))).then(()=>n(`copied`),()=>n(`failed`)).finally(()=>{r.current=setTimeout(()=>n(`idle`),e)})}return{state:t,copy:i}}var Z=e=>`${(e/1e3).toFixed(1)} s`;function Ee({receipt:e,running:t=!1,activity:n=``,awaitingAnswer:r=!1}){let[i,a]=(0,V.useState)(!1),o=(0,V.useId)(),s=e.saved,l=s?.receipt.save_check,p=t=>Object.hasOwn(e.panel_titles,t)?e.panel_titles[t]:t,m=Object.values(e.stages).filter(e=>e.state===`complete`).length,h=[e.stages.schema.state===`complete`?`Read telemetry`:void 0,e.panel_count===void 0?void 0:`${e.panel_count} ${e.panel_count===1?`panel`:`panels`}`,l?.checked?`Checked in ${Z(l.elapsed_ms)}`:void 0,s?`Saved v${s.version}`:void 0].filter(Boolean).join(` · `)||`Building dashboard`,g=[...s?te(s.receipt):[],...new Map(e.corrections.map(e=>[e.panel_id,`Fixed ${e.title}`])).values()];return(0,H.jsx)(S,{"data-build-receipt":e.turn_id,"data-dashboard-result":s?.id,"data-chat-anchor":!0,withBorder:!0,radius:`md`,p:`sm`,children:(0,H.jsxs)(u,{gap:6,children:[(0,H.jsxs)(c,{gap:`xs`,justify:`space-between`,children:[(0,H.jsxs)(f,{size:`sm`,role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:[h,(0,H.jsxs)(f,{span:!0,c:`dimmed`,size:`xs`,children:[` · `,m,` stages complete`]})]}),(0,H.jsxs)(d,{component:`button`,variant:`subtle`,color:`gray`,size:`compact-xs`,"aria-expanded":i,"aria-controls":o,onClick:()=>a(e=>!e),children:[`Details`,g.length>4?` (+${g.length-4})`:``]})]}),t&&r&&(0,H.jsxs)(c,{gap:`xs`,"data-build-running":!0,children:[(0,H.jsx)(C,{type:`dots`,size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:n||`Analyzing your system`})]}),(0,H.jsx)(N,{labels:g.slice(0,4)}),e.explanations.map(e=>t?e.split(` · `).filter(e=>!e.endsWith(`: incomplete`)).join(` · `):e).filter(Boolean).map((e,t)=>(0,H.jsx)(f,{size:`xs`,c:`dimmed`,"data-receipt-attention":!0,children:e},t)),s&&(0,H.jsx)(d,{renderRoot:e=>(0,H.jsx)(w,{...e,to:`/dashboards/$dashboardId`,params:{dashboardId:s.id},search:{}}),variant:`subtle`,size:`compact-sm`,color:`gray`,style:{alignSelf:`flex-start`},children:`Open dashboard`}),(0,H.jsx)(P,{expanded:i,id:o,children:(0,H.jsxs)(u,{gap:4,children:[s&&(0,H.jsxs)(f,{size:`xs`,children:[s.label,` `,s.name,` · opens the current dashboard`]}),Object.entries(e.stages).map(([e,n])=>(0,H.jsxs)(f,{size:`xs`,c:`dimmed`,children:[z[e],`: `,t&&n.state===`incomplete`?`in progress`:n.state,n.elapsed_ms===void 0?``:` · ${Z(n.elapsed_ms)}`]},e)),e.save_attempts.map((e,t)=>e.state===`retried`&&(0,H.jsxs)(f,{size:`xs`,c:`dimmed`,children:[`Save attempt `,t+1,`: retried`]},e.call_id)),!!e.context_counts.deploys&&(0,H.jsxs)(f,{size:`xs`,children:[e.context_counts.deploys,` deploys observed`]}),!!e.context_counts.anomalies&&(0,H.jsxs)(f,{size:`xs`,children:[e.context_counts.anomalies,` anomalies observed`]}),e.panels.map(e=>(0,H.jsxs)(f,{size:`xs`,children:[`Preview · `,p(e.id),`: `,e.status,e.elapsed_ms===void 0?``:` · ${Z(e.elapsed_ms)}`]},e.id)),l&&(0,H.jsxs)(f,{size:`xs`,children:[`Save check: `,l.checked?`checked`:`incomplete`,` · `,Z(l.elapsed_ms)]}),l?.panels.map(e=>(0,H.jsxs)(f,{size:`xs`,children:[`Save · `,p(e.id),`: `,e.status,` · `,e.rows??0,` rows`,e.elapsed_ms===void 0?``:` · ${Z(e.elapsed_ms)}`]},e.id)),g.slice(4).map((e,t)=>(0,H.jsx)(f,{size:`xs`,children:e},t)),e.corrections.map((e,t)=>(0,H.jsxs)(f,{size:`xs`,children:[`Fixed `,e.title,`: `,e.message]},t))]})})]})})}var De=(0,V.lazy)(()=>T(()=>import(`./mcp-app-frame-BzM2b2mm.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]))),Oe=e=>e.tool_result.view.kind===`preset`;function ke(e){let t=new Map,n=new Set,r=[],i=()=>{let e=new Map;for(let t of r){let n=t.content.tool_result.view.key;e.set(n,t)}let i=new Set([...e.values()].map(e=>e.id)),a=[...e.values()].some(e=>Oe(e.content)),o=r.filter(e=>i.has(e.id)).at(-1)?.id;for(let e of r)i.has(e.id)?t.set(e.id,{content:e.content,expanded:Oe(e.content)||!a&&e.id===o}):n.add(e.id);r=[]};for(let t of e)if(t.role===`user`&&i(),t.role===`activity`&&t.activityType===`mcp-app`){let e=xe(t.content);e&&r.push({id:t.id,content:e})}return i(),{views:t,duplicates:n}}function Ae(e,t){return Array.isArray(e)?e.flatMap(e=>{if(!L(e)||typeof e.message!=`string`)return[];let n=typeof e.path==`string`?/^panels\[(\d+)\](?:\.|$)/.exec(e.path)?.[1]:void 0,r=n===void 0?void 0:t?.[Number(n)];return[r&&!e.message.startsWith(r)?`${r}: ${e.message}`:e.message]}):[]}function je(e){let t=new Map,n=new Map,r=new Map,i=`unattributed`;for(let a of e){if(a.role===`user`&&(n.clear(),r.clear(),i=a.id),a.role===`assistant`){i=a.id;for(let e of a.toolCalls??[]){let t=[`create_dashboard`,`replace_dashboard`].includes(e.function.name)?ne(e.function.arguments)?.dashboard:void 0,r=L(t)&&Array.isArray(t.panels)?t.panels.map(e=>L(e)&&typeof e.title==`string`?e.title:``):void 0;n.set(e.id,{assistant:i,name:e.function.name,titles:r})}}if(a.role===`tool`){let e=ne(a.content);if(!a.error&&!e?.error&&e?.isError!==!0)continue;let o=n.get(a.toolCallId);if(o&&F.has(o.name)&&I(a))continue;let s=L(e?.error)?e?.error:void 0;if(s?.code===`no_data`||s?.code===`unknown_service`)continue;let c=o?.assistant??i,l=r.get(c)??a.id;r.set(c,l);let u=t.get(l)??[],d=typeof s?.message==`string`?s.message:typeof a.error==`string`&&a.error?a.error:`Could not complete this step. Try again.`,f=[`create_dashboard`,`edit_dashboard`,`replace_dashboard`].includes(o?.name??``)&&(s?.code===`invalid_spec`||s?.code===`dashboard_version_conflict`);u.push({name:R(o?.name??``),message:d,details:f?Ae(e?.problems,o?.titles):[],readOnly:s?.code===`answer_only`,rejected:f}),t.set(l,u)}}return t}function Me({failures:e}){let[t,n]=(0,V.useState)({rejected:!1,failed:!1}),r=e.filter(e=>e.rejected),a=e.filter(e=>!e.readOnly&&!e.rejected),s=[{key:`rejected`,items:r,label:`${r.length} ${r.length===1?`draft`:`drafts`} rejected`},{key:`failed`,items:a,label:`${a.length} ${a.length===1?`step`:`steps`} failed`}];return(0,H.jsxs)(i,{"data-chat-anchor":!0,children:[e.some(e=>e.readOnly)&&(0,H.jsx)(f,{size:`sm`,c:`dimmed`,children:`Not saved: Explain is read-only`}),s.map(({key:e,items:r,label:a})=>r.length>0&&(0,H.jsxs)(i,{children:[(0,H.jsxs)(o,{className:`chat-app-toggle`,"aria-expanded":t[e],onClick:()=>n(t=>({...t,[e]:!t[e]})),style:{color:`var(--mantine-color-dimmed)`},children:[(0,H.jsx)(`span`,{className:`chat-app-chevron`,"aria-hidden":`true`,children:t[e]?(0,H.jsx)(O,{size:14}):(0,H.jsx)(pe,{size:14})}),(0,H.jsx)(`span`,{className:`chat-app-summary`,children:a})]}),t[e]&&(0,H.jsx)(u,{gap:`xs`,pl:`md`,children:r.flatMap((e,t)=>(e.details.length?e.details:[`${e.name}: ${e.message}`]).map((e,n)=>(0,H.jsx)(f,{size:`sm`,c:`dimmed`,style:{whiteSpace:`pre-wrap`,overflowWrap:`anywhere`},children:e},`${t}-${n}`)))})]},e))]})}function Ne({view:e}){let[t,n]=(0,V.useState)(e.expanded);(0,V.useEffect)(()=>n(e.expanded),[e.expanded]);let r=e.content.tool_result,i=ve(r),a=[...new Set(r.dashboard.panels.map(e=>e.viz===`timeseries`?`time series`:e.viz.replaceAll(`_`,` `)))].join(`, `),s=r.results.reduce((e,t)=>e+(t.frame?.rows??0),0),c=new Map;for(let e of r.results)e.status!==`ok`&&c.set(e.status,(c.get(e.status)??0)+1);let l=r.dashboard.panels.length>1?Array.from(c,([e,t])=>`${t} ${e}`).join(` · `):c.size?[...c.keys()].join(`, `):`${s} ${s===1?`row`:`rows`}`;return(0,H.jsxs)(S,{"data-chat-app":!0,"data-chat-anchor":!0,withBorder:!0,radius:`lg`,style:{overflow:`hidden`},children:[(0,H.jsxs)(o,{className:`chat-app-toggle`,"aria-expanded":t,onClick:()=>n(e=>!e),children:[(0,H.jsx)(`span`,{className:`chat-app-chevron`,"aria-hidden":`true`,children:t?(0,H.jsx)(O,{size:14}):(0,H.jsx)(pe,{size:14})}),(0,H.jsx)(`span`,{className:`chat-app-summary`,children:[i,a,l].filter(Boolean).join(` · `)})]}),t&&(0,H.jsx)(V.Suspense,{fallback:(0,H.jsx)(x,{mih:180,children:(0,H.jsx)(C,{size:`sm`})}),children:(0,H.jsx)(De,{content:e.content})})]})}var Pe=[`Summarize system health for the last hour`,`Find the source of elevated errors`,`Map the current service dependencies`,`Show the slowest endpoints`];function Fe(){let{agentAvailable:e,messages:t,messageTimes:n,ready:r,running:a,activity:o,stopped:s,error:l,threadMissing:p,send:h,retry:g,reloadThread:y,newThread:b}=ee(),w=re(t),T=t.filter(e=>e.role===`user`).at(-1)?.id,{scrollRef:D,contentRef:O,turnRef:k,showJump:A,jumpToLatest:j}=we(T);if(!e)return(0,H.jsx)(m,{size:`sm`,py:96,children:(0,H.jsx)(S,{withBorder:!0,radius:`lg`,p:{base:`xl`,sm:40},children:(0,H.jsxs)(u,{gap:`md`,children:[(0,H.jsx)(f,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Optional capability`}),(0,H.jsx)(_,{order:1,fz:28,children:`Chat is not configured`}),(0,H.jsx)(f,{c:`dimmed`,children:`Add an AI provider key to enable chat. Telemetry ingest, dashboards, traces, logs, and metrics remain available without it.`}),(0,H.jsx)(d,{component:`a`,href:`/dashboards`,variant:`light`,mt:`sm`,children:`Open dashboards`})]})})});let M=ke(t),N=je(t),P=t.filter(e=>M.duplicates.has(e.id)?!1:e.role===`tool`?N.has(e.id):e.role===`assistant`?!e.toolCalls?.length&&typeof e.content==`string`&&e.content.trim().length>0:e.role===`activity`?e.activityType===`mcp-app`||e.activityType===`agent-outcome`:e.role===`user`),F=t.findIndex(e=>e.id===T),I=t.slice(F+1).some(e=>e.role===`assistant`&&!e.toolCalls?.length&&typeof e.content==`string`&&e.content.length>0),L=t.slice(F+1).filter(e=>e.role===`assistant`&&!e.toolCalls?.length&&typeof e.content==`string`&&e.content.trim().length>0).at(-1),R=[];for(let e of P)(e.role===`user`||R.length===0)&&R.push({id:e.id,messages:[]}),R.at(-1).messages.push(e);R.length===0&&R.push({id:`draft`,messages:[]});let z=e=>N.has(e.id)?(0,H.jsx)(Me,{failures:N.get(e.id)},e.id):(0,H.jsxs)(i,{children:[(0,H.jsx)(Re,{message:e,time:n[e.id],appView:M.views.get(e.id)}),w.has(e.id)&&(0,H.jsx)(i,{mt:`sm`,children:(0,H.jsx)(Ee,{receipt:w.get(e.id),running:a&&e.id===T,awaitingAnswer:!I,activity:o})})]},e.id);return(0,H.jsxs)(i,{className:`chat-pane`,children:[(0,H.jsxs)(i,{className:`chat-viewport`,children:[(0,H.jsx)(i,{className:`chat-scroll`,ref:D,tabIndex:0,role:`log`,"aria-label":`Conversation`,children:(0,H.jsxs)(m,{size:880,px:{base:`md`,sm:`xl`},py:`lg`,ref:O,children:[p&&(0,H.jsx)(v,{color:`warn`,radius:`lg`,title:`This chat no longer exists`,children:(0,H.jsxs)(c,{justify:`space-between`,children:[(0,H.jsx)(f,{size:`sm`,children:`It was deleted, or the link is wrong.`}),(0,H.jsx)(d,{size:`compact-sm`,variant:`light`,onClick:b,children:`New chat`})]})}),!p&&!r&&l&&(0,H.jsx)(Q,{message:l,onRetry:y,onNewThread:b}),!p&&!r&&!l&&(0,H.jsxs)(x,{mih:`40vh`,children:[(0,H.jsx)(C,{size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,ml:`sm`,children:`Loading chat`})]}),!p&&r&&(0,H.jsxs)(H.Fragment,{children:[P.length===0&&(0,H.jsx)(Le,{onSelect:h}),(0,H.jsx)(u,{gap:`lg`,children:R.map((e,t)=>(0,H.jsxs)(u,{gap:`lg`,ref:e.id===T?k:void 0,"data-chat-turn":e.id===T?T:void 0,children:[e.messages.filter(e=>e.id!==L?.id).map(z),t===R.length-1&&(0,H.jsxs)(H.Fragment,{children:[L&&(0,H.jsx)(i,{"data-answer-position":!0,children:(0,H.jsx)(Re,{message:L,time:n[L.id]})},`answer-${T??`draft`}`),a&&!I&&!w.has(T??``)&&(0,H.jsxs)(c,{gap:`xs`,role:`status`,children:[(0,H.jsx)(C,{type:`dots`,size:`sm`}),(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:o||`Analyzing your system`})]}),s&&(0,H.jsx)(f,{c:`dimmed`,size:`sm`,children:`Stopped`}),l&&(0,H.jsx)(Q,{message:l,onRetry:g})]})]},e.id))})]})]})}),A&&(0,H.jsx)(E,{label:`Jump to latest`,children:(0,H.jsx)(B,{className:`chat-jump`,variant:`default`,size:36,radius:`xl`,"aria-label":`Jump to latest`,onClick:j,children:(0,H.jsx)(fe,{size:18,"aria-hidden":`true`})})})]}),!p&&(0,H.jsx)(Ie,{})]})}function Q({message:e,onRetry:t,onNewThread:n}){return(0,H.jsx)(v,{color:`bad`,radius:`lg`,title:`Something went wrong`,children:(0,H.jsxs)(c,{justify:`space-between`,gap:`sm`,wrap:`nowrap`,children:[(0,H.jsx)(f,{size:`sm`,children:e}),(0,H.jsxs)(c,{gap:`xs`,wrap:`nowrap`,children:[n&&(0,H.jsx)(d,{size:`compact-sm`,variant:`subtle`,color:`bad`,onClick:n,children:`New chat`}),(0,H.jsx)(d,{size:`compact-sm`,variant:`light`,color:`bad`,onClick:t,children:`Retry`})]})]})})}function Ie(){let{input:e,setInput:t,inputRef:n,submit:r,send:a,stop:o,ready:s,running:l}=ee();return(0,H.jsx)(i,{className:`chat-composer`,children:(0,H.jsxs)(m,{size:880,px:{base:`md`,sm:`xl`},children:[(0,H.jsx)(S,{component:`form`,onSubmit:r,className:`chat-composer-field`,withBorder:!0,radius:24,py:6,pl:`lg`,pr:6,children:(0,H.jsxs)(c,{align:`flex-end`,gap:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(K,{ref:n,"aria-label":`Message Fanout`,value:e,onChange:e=>t(e.currentTarget.value),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),a(e))},placeholder:l?`Fanout is working…`:`Ask about health, errors, or latency…`,disabled:!s,autosize:!0,minRows:1,maxRows:8,variant:`unstyled`,flex:1}),l?(0,H.jsx)(E,{label:`Stop`,children:(0,H.jsx)(B,{type:`button`,variant:`default`,size:40,radius:`xl`,"aria-label":`Stop`,onClick:o,children:(0,H.jsx)(_e,{size:16,weight:`fill`})})}):(0,H.jsx)(B,{type:`submit`,variant:`filled`,size:40,radius:`xl`,disabled:!e.trim()||!s,"aria-label":`Send message`,children:(0,H.jsx)(he,{size:17,weight:`fill`})})]})}),(0,H.jsx)(f,{c:`dimmed`,size:`xs`,ta:`center`,mt:6,children:`Enter to send, Shift+Enter for a new line`})]})})}function Le({onSelect:e}){return(0,H.jsxs)(u,{align:`center`,gap:`md`,pt:{base:32,sm:88},pb:`xl`,ta:`center`,children:[(0,H.jsx)(g,{size:`large`}),(0,H.jsx)(_,{order:1,fz:24,fw:500,lh:1.25,maw:560,children:`What do you want to know about your system?`}),(0,H.jsx)(c,{justify:`center`,gap:`xs`,mt:`xs`,maw:720,children:Pe.map(t=>(0,H.jsx)(d,{variant:`default`,size:`sm`,radius:`xl`,onClick:()=>void e(t),children:t},t))})]})}function Re({message:e,time:t,appView:n}){if(e.role===`activity`)return e.activityType===`agent-outcome`&&e.content&&typeof e.content==`object`&&`message`in e.content&&typeof e.content.message==`string`?`status`in e.content&&e.content.status===`stopped`?(0,H.jsx)(f,{c:`dimmed`,size:`sm`,"data-chat-anchor":!0,children:e.content.message}):(0,H.jsx)(v,{color:`bad`,title:`Something went wrong`,"data-chat-anchor":!0,children:e.content.message}):e.activityType===`mcp-app`?n?(0,H.jsx)(Ne,{view:n}):(0,H.jsx)(v,{color:`bad`,"data-chat-anchor":!0,children:`This view could not be loaded. Please try again.`}):null;if(e.role===`assistant`&&e.toolCalls?.length)return null;let r=typeof e.content==`string`?e.content:JSON.stringify(e.content);if(!r&&e.role===`assistant`)return null;let a=e.role===`user`,o=t?new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`}).format(new Date(t)):``;return(0,H.jsxs)(i,{className:`chat-message`,"data-chat-anchor":!0,"data-role":a?`user`:`assistant`,children:[a?(0,H.jsx)(S,{radius:`lg`,px:`md`,py:`sm`,bg:`var(--mantine-color-brand-light)`,maw:`70%`,ml:`auto`,w:`fit-content`,children:(0,H.jsx)(f,{style:{whiteSpace:`pre-wrap`},children:r})}):(0,H.jsx)(J,{className:`chat-markdown`,children:(0,H.jsx)(M,{remarkPlugins:[j],components:Be,children:r})}),(o||!a)&&(0,H.jsxs)(c,{className:`chat-message-meta`,gap:6,justify:a?`flex-end`:`flex-start`,mt:4,h:24,children:[o&&t&&(0,H.jsx)(f,{c:`dimmed`,size:`xs`,title:D(t),children:o}),!a&&(0,H.jsx)(ze,{text:r,label:`Copy message`})]})]})}function ze({text:e,label:t}){let{state:n,copy:r}=Te();return(0,H.jsx)(E,{label:n===`failed`?`Could not copy`:n===`copied`?`Copied`:t,children:(0,H.jsx)(B,{variant:`subtle`,color:`gray`,size:`sm`,"aria-label":t,"data-state":n===`idle`?void 0:n,onClick:()=>r(e),children:n===`copied`?(0,H.jsx)(p,{size:13,weight:`bold`}):(0,H.jsx)(y,{size:13})})})}var Be={table:({children:e})=>(0,H.jsx)(i,{className:`chat-table`,children:(0,H.jsx)(A,{striped:!0,highlightOnHover:!0,withTableBorder:!0,verticalSpacing:`xs`,fz:`sm`,children:e})}),thead:({children:e})=>(0,H.jsx)(A.Thead,{children:e}),tbody:({children:e})=>(0,H.jsx)(A.Tbody,{children:e}),tr:({children:e})=>(0,H.jsx)(A.Tr,{children:e}),th:({children:e})=>(0,H.jsx)(A.Th,{children:e}),td:({children:e})=>(0,H.jsx)(A.Td,{children:e}),pre:({children:e})=>(0,H.jsx)(Ve,{children:e}),a:({href:e,children:t})=>(0,H.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,children:t})};function Ve({children:e}){let t=$(e);return(0,H.jsxs)(i,{className:`chat-code`,pos:`relative`,children:[(0,H.jsx)(i,{className:`chat-code-actions`,pos:`absolute`,top:6,right:6,children:(0,H.jsx)(ze,{text:t,label:`Copy code`})}),(0,H.jsx)(`pre`,{children:e})]})}function $(e){return typeof e==`string`?e:Array.isArray(e)?e.map($).join(``):e&&typeof e==`object`&&`props`in e?$(e.props.children):``}export{xe as n,Fe as t}; \ No newline at end of file diff --git a/internal/ui/dist/assets/chat._threadId-COFCWU9S.js b/internal/ui/dist/assets/chat._threadId-COFCWU9S.js new file mode 100644 index 00000000..9ea6c1a9 --- /dev/null +++ b/internal/ui/dist/assets/chat._threadId-COFCWU9S.js @@ -0,0 +1 @@ +import{t as e}from"./chat-BDYP-JLf.js";var t=e;export{t as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/chat._threadId-CVg1vCUR.js b/internal/ui/dist/assets/chat._threadId-CVg1vCUR.js deleted file mode 100644 index 2c350ddc..00000000 --- a/internal/ui/dist/assets/chat._threadId-CVg1vCUR.js +++ /dev/null @@ -1 +0,0 @@ -import{t as e}from"./chat-0Bi74QKL.js";var t=e;export{t as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/chat.index-COFCWU9S.js b/internal/ui/dist/assets/chat.index-COFCWU9S.js new file mode 100644 index 00000000..9ea6c1a9 --- /dev/null +++ b/internal/ui/dist/assets/chat.index-COFCWU9S.js @@ -0,0 +1 @@ +import{t as e}from"./chat-BDYP-JLf.js";var t=e;export{t as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/chat.index-CVg1vCUR.js b/internal/ui/dist/assets/chat.index-CVg1vCUR.js deleted file mode 100644 index 2c350ddc..00000000 --- a/internal/ui/dist/assets/chat.index-CVg1vCUR.js +++ /dev/null @@ -1 +0,0 @@ -import{t as e}from"./chat-0Bi74QKL.js";var t=e;export{t as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/dashboard-change-chips-DcQEgN0t.js b/internal/ui/dist/assets/dashboard-change-chips-CghpARdt.js similarity index 99% rename from internal/ui/dist/assets/dashboard-change-chips-DcQEgN0t.js rename to internal/ui/dist/assets/dashboard-change-chips-CghpARdt.js index 3b2ffa5e..26e15722 100644 --- a/internal/ui/dist/assets/dashboard-change-chips-DcQEgN0t.js +++ b/internal/ui/dist/assets/dashboard-change-chips-CghpARdt.js @@ -1,4 +1,4 @@ -import{a as e,i as t,o as n,r,s as i}from"./useRouter-ByJ6_rwb.js";import{A as a,C as o,K as s,M as c,P as l,Q as u,T as d,X as f,_ as p,_t as m,a as h,et as g,mt as _,rt as v,ut as y,z as b}from"./brand-DUaZkIz1.js";import{E as x,S,o as C}from"./Tooltip-B3r3s_B9.js";import{Kt as w}from"./index-eh4vL-r5.js";var T=i(t(),1),E=i(m(),1);function D(e){if(!e||typeof e==`string`)return 0;let t=e/36;return Math.round((4+15*t**.25+t/5)*10)}function O(e){return e.current?e.current.scrollHeight:`auto`}function k(e){return typeof e==`number`&&e>0}function ee({transitionDuration:e,transitionTimingFunction:t=`ease`,onTransitionEnd:n,onTransitionStart:r,expanded:i,keepMounted:a}){let o={height:0,overflow:`hidden`,...a?{}:{display:`none`}},s=(0,T.useEffectEvent)(()=>r?.()),c=(0,T.useEffectEvent)(()=>n?.()),l=(0,T.useRef)(null),[u,d]=(0,T.useState)(i?{}:o),[f,p]=(0,T.useState)(i?`entered`:`exited`),m=e=>{(0,E.flushSync)(()=>d(e))},h=e=>{m(t=>({...t,...e}))},_=n=>{let r=e??D(n);return{transition:`height ${r}ms ${t}, opacity ${r}ms ${t}`}},y=(0,T.useRef)(0);v(()=>{y.current+=1;let t=y.current,n=()=>y.current===t;e!==0&&s(),i?window.requestAnimationFrame(()=>{n()&&l.current&&((0,E.flushSync)(()=>p(`entering`)),h({willChange:`height`,display:`block`,overflow:`hidden`}),window.requestAnimationFrame(()=>{if(!n()||!l.current)return;let e=O(l);if(!k(e)){m({}),p(`entered`),c();return}h({..._(e),height:e})}))}):window.requestAnimationFrame(()=>{if(!n()||!l.current)return;(0,E.flushSync)(()=>p(`exiting`));let e=O(l);if(!k(e)){m(o),p(`exited`),c();return}h({..._(e),willChange:`height`,height:e}),window.requestAnimationFrame(()=>{n()&&l.current&&h({height:0,overflow:`hidden`})})})},[i]);let b=e=>{if(e.target===l.current&&e.propertyName===`height`){if(i){let e=O(l);e===u.height?m({}):h({height:e}),p(`entered`),c()}else u.height===0&&(m(o),p(`exited`),c())}};return{state:f,getCollapseProps:e=>({"aria-hidden":!i,inert:!i,ref:g(l,e?.ref),onTransitionEnd:b,style:{boxSizing:`border-box`,...e?.style,...u}})}}function te(e){if(!e||typeof e==`string`)return 0;let t=e/36;return Math.round((4+15*t**.25+t/5)*10)}function A(e){return e.current?e.current.scrollWidth:`auto`}function j({transitionDuration:e,transitionTimingFunction:t=`ease`,onTransitionEnd:n,onTransitionStart:r,expanded:i,keepMounted:a}){let o={width:0,overflow:`hidden`,...a?{}:{display:`none`}},s=(0,T.useEffectEvent)(()=>r?.()),c=(0,T.useEffectEvent)(()=>n?.()),l=(0,T.useRef)(null),[u,d]=(0,T.useState)(i?{}:o),[f,p]=(0,T.useState)(i?`entered`:`exited`),m=e=>{(0,E.flushSync)(()=>d(e))},h=e=>{m(t=>({...t,...e}))},_=n=>{let r=e??te(n);return{transition:`width ${r}ms ${t}, opacity ${r}ms ${t}`}},y=(0,T.useRef)(0);v(()=>{y.current+=1;let t=y.current,n=()=>y.current===t;e!==0&&s(),i?window.requestAnimationFrame(()=>{n()&&l.current&&((0,E.flushSync)(()=>p(`entering`)),h({willChange:`width`,display:`block`,overflow:`hidden`}),window.requestAnimationFrame(()=>{if(!n()||!l.current)return;let e=A(l);if(!k(e)){m({}),p(`entered`),c();return}h({..._(e),width:e})}))}):window.requestAnimationFrame(()=>{if(!n()||!l.current)return;(0,E.flushSync)(()=>p(`exiting`));let e=A(l);if(!k(e)){m(o),p(`exited`),c();return}h({..._(e),willChange:`width`,width:e}),window.requestAnimationFrame(()=>{n()&&l.current&&h({width:0,overflow:`hidden`})})})},[i]);let b=e=>{if(e.target===l.current&&e.propertyName===`width`){if(i){let e=A(l);e===u.width?m({}):h({width:e}),p(`entered`),c()}else u.width===0&&(m(o),p(`exited`),c())}};return{state:f,getCollapseProps:e=>({"aria-hidden":!i,inert:!i,ref:g(l,e?.ref),onTransitionEnd:b,style:{boxSizing:`border-box`,...e?.style,...u}})}}function ne(){return`development`}var M=r(),N={transitionDuration:200,transitionTimingFunction:`ease`,animateOpacity:!0,orientation:`vertical`,keepMounted:!0,keepMountedMode:`activity`},re=d(e=>{let{children:t,expanded:n,transitionDuration:r,transitionTimingFunction:i,style:a,onTransitionEnd:s,onTransitionStart:d,animateOpacity:f,keepMounted:p,keepMountedMode:m,ref:h,orientation:g,..._}=c(`Collapse`,N,e),v=b(),y=l(),x=u(),C=y.respectReducedMotion&&x?0:r,w=(g===`horizontal`?j:ee)({expanded:n,transitionDuration:C,transitionTimingFunction:i,onTransitionEnd:s,onTransitionStart:d,keepMounted:!1});if(C===0)return p===!0&&(m===`display-none`||v!==`test`)?m===`display-none`?(0,M.jsx)(o,{..._,style:{...S(a,y),...n?{}:{display:`none`}},ref:h,children:t}):(0,M.jsx)(T.Activity,{mode:n?`visible`:`hidden`,children:(0,M.jsx)(o,{..._,style:a,ref:h,children:t})}):n?(0,M.jsx)(o,{..._,style:a,ref:h,children:t}):null;let E=w.state===`exited`,D;return D=p===!1?E?null:t:p===!0?m===`display-none`?t:(0,M.jsx)(T.Activity,{mode:E?`hidden`:`visible`,children:t}):t,(0,M.jsx)(o,{..._,...w.getCollapseProps({style:{opacity:n||!f?1:0,transition:f?`opacity ${C}ms ${i}`:`none`,...S(a,y),...p&&m===`display-none`&&E?{display:`none`}:{}},ref:h}),children:D})});re.displayName=`@mantine/core/Collapse`;var[ie,ae]=x(`Table component was not found in the tree`),oe={table:`m_b23fa0ef`,th:`m_4e7aa4f3`,tr:`m_4e7aa4fd`,td:`m_4e7aa4ef`,tbody:`m_b2404537`,thead:`m_b242d975`,caption:`m_9e5a3ac7`,scrollContainer:`m_a100c15`,scrollContainerInner:`m_62259741`};function se(e,t){if(!t)return;let n={};return t.columnBorder&&e.withColumnBorders&&(n[`data-with-column-border`]=!0),t.rowBorder&&e.withRowBorders&&(n[`data-with-row-border`]=!0),t.striped&&e.striped&&(n[`data-striped`]=e.striped),t.highlightOnHover&&e.highlightOnHover&&(n[`data-hover`]=!0),t.captionSide&&e.captionSide&&(n[`data-side`]=e.captionSide),t.stickyHeader&&e.stickyHeader&&(n[`data-sticky`]=!0),n}function ce(e,t){let n=`Table${e.charAt(0).toUpperCase()}${e.slice(1)}`,r=d(r=>{let i=c(n,{},r),{classNames:a,className:s,style:l,styles:u,...d}=i,f=ae();return(0,M.jsx)(o,{component:e,...se(f,t),...f.getStyles(e,{className:s,classNames:a,style:l,styles:u,props:i}),...d})});return r.displayName=`@mantine/core/${n}`,r.classes=oe,r}var le=ce(`th`,{columnBorder:!0}),ue=ce(`td`,{columnBorder:!0}),de=ce(`tr`,{rowBorder:!0,striped:!0,highlightOnHover:!0}),fe=ce(`thead`,{stickyHeader:!0}),pe=ce(`tbody`),me=ce(`tfoot`),he=ce(`caption`,{captionSide:!0}),ge={type:`scrollarea`},_e=f((e,{minWidth:t,maxHeight:n,type:r})=>({scrollContainer:{"--table-min-width":_(t),"--table-max-height":_(n),"--table-overflow":r===`native`?`auto`:void 0}})),ve=d(e=>{let t=c(`TableScrollContainer`,ge,e),{classNames:n,className:r,style:i,styles:s,unstyled:l,vars:u,children:d,minWidth:f,maxHeight:p,type:m,scrollAreaProps:h,attributes:g,..._}=t,v=a({name:`TableScrollContainer`,classes:oe,props:t,className:r,style:i,classNames:n,styles:s,unstyled:l,attributes:g,vars:u,varsResolver:_e,rootSelector:`scrollContainer`});return(0,M.jsx)(o,{component:m===`scrollarea`?C:`div`,...m===`scrollarea`?p?{offsetScrollbars:`xy`,...h}:{offsetScrollbars:`x`,...h}:{},...v(`scrollContainer`),..._,children:(0,M.jsx)(`div`,{...v(`scrollContainerInner`),children:d})})});ve.classes=oe,ve.varsResolver=_e,ve.displayName=`@mantine/core/TableScrollContainer`;function ye({data:e}){return(0,M.jsxs)(M.Fragment,{children:[e.caption&&(0,M.jsx)(he,{children:e.caption}),e.head&&(0,M.jsx)(fe,{children:(0,M.jsx)(de,{children:e.head.map((e,t)=>(0,M.jsx)(le,{children:e},t))})}),e.body&&(0,M.jsx)(pe,{children:e.body.map((e,t)=>(0,M.jsx)(de,{children:e.map((e,t)=>(0,M.jsx)(ue,{children:e},t))},t))}),e.foot&&(0,M.jsx)(me,{children:(0,M.jsx)(de,{children:e.foot.map((e,t)=>(0,M.jsx)(le,{children:e},t))})})]})}ye.displayName=`@mantine/core/TableDataRenderer`;var be={withRowBorders:!0,verticalSpacing:7},xe=f((e,{layout:t,captionSide:n,horizontalSpacing:r,verticalSpacing:i,borderColor:a,stripedColor:o,highlightOnHoverColor:c,striped:l,highlightOnHover:u,stickyHeaderOffset:d,stickyHeader:f})=>({table:{"--table-layout":t,"--table-caption-side":n,"--table-horizontal-spacing":y(r),"--table-vertical-spacing":y(i),"--table-border-color":a?s(a,e):void 0,"--table-striped-color":l&&o?s(o,e):void 0,"--table-highlight-on-hover-color":u&&c?s(c,e):void 0,"--table-sticky-header-offset":f?_(d):void 0}})),P=d(e=>{let t=c(`Table`,be,e),{classNames:n,className:r,style:i,styles:s,unstyled:l,vars:u,horizontalSpacing:d,verticalSpacing:f,captionSide:p,stripedColor:m,highlightOnHoverColor:h,striped:g,highlightOnHover:_,withColumnBorders:v,withRowBorders:y,withTableBorder:b,borderColor:x,layout:S,data:C,children:w,stickyHeader:E,stickyHeaderOffset:D,mod:O,tabularNums:k,attributes:ee,...te}=t,A=a({name:`Table`,props:t,className:r,style:i,classes:oe,classNames:n,styles:s,unstyled:l,attributes:ee,rootSelector:`table`,vars:u,varsResolver:xe,stable:!0}),j=g===!0?`odd`:g||void 0,ne=p||`bottom`,N=(0,T.useMemo)(()=>({getStyles:A,stickyHeader:E,striped:j,highlightOnHover:_,withColumnBorders:v,withRowBorders:y,captionSide:ne}),[A,E,j,_,v,y,ne]);return(0,M.jsx)(ie,{value:N,children:(0,M.jsx)(o,{component:`table`,mod:[{withTableBorder:b,tabularNums:k},O],...A(`table`),...te,children:w||!!C&&(0,M.jsx)(ye,{data:C})})})});P.classes=oe,P.varsResolver=xe,P.displayName=`@mantine/core/Table`,P.Td=ue,P.Th=le,P.Tr=de,P.Thead=fe,P.Tbody=pe,P.Tfoot=me,P.Caption=he,P.ScrollContainer=ve,P.DataRenderer=ye;var Se=new Map([[`bold`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z`}))],[`duotone`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M208,96l-80,80L48,96Z`,opacity:`0.2`}),T.createElement(`path`,{d:`M215.39,92.94A8,8,0,0,0,208,88H48a8,8,0,0,0-5.66,13.66l80,80a8,8,0,0,0,11.32,0l80-80A8,8,0,0,0,215.39,92.94ZM128,164.69,67.31,104H188.69Z`}))],[`fill`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z`}))],[`light`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M212.24,100.24l-80,80a6,6,0,0,1-8.48,0l-80-80a6,6,0,0,1,8.48-8.48L128,167.51l75.76-75.75a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M210.83,98.83l-80,80a4,4,0,0,1-5.66,0l-80-80a4,4,0,0,1,5.66-5.66L128,170.34l77.17-77.17a4,4,0,1,1,5.66,5.66Z`}))]]),Ce=T.forwardRef((e,t)=>T.createElement(h,{ref:t,...e,weights:Se}));Ce.displayName=`CaretDownIcon`;var we=Ce,Te=new Intl.NumberFormat(void 0,{maximumFractionDigits:0});function Ee(e){return Number.isFinite(e)?e>0&&e<1e-4?`<0.01%`:`${(e*100).toFixed(e>=.1?1:2)}%`:`—`}function De(e){if(!Number.isFinite(e))return`—`;if(e<0)return`-${De(-e)}`;if(e===0)return`0ms`;if(e<.01)return`<0.01ms`;if(e<1)return`${e.toFixed(2)}ms`;if(Math.round(e*10)/10<100)return`${e.toFixed(1)}ms`;if(Math.round(e)<1e3)return`${Math.round(e)}ms`;let t=Math.round(e/100)/10;if(t<10)return`${(e/1e3).toFixed(2)}s`;if(t<60)return`${t.toFixed(1)}s`;let n=Math.round(e/1e3),r=Math.floor(n/60),i=n%60;if(r<60)return i===0?`${r}m`:`${r}m ${i}s`;let a=Math.floor(r/60),o=r%60;return o===0?`${a}h`:`${a}h ${o}m`}function Oe(e){let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.valueOf())?String(e):t.toLocaleString([],{year:`numeric`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`,timeZoneName:`short`})}function ke(e,t){let n=t||{};return(e[e.length-1]===``?[...e,``]:e).join((n.padRight?` `:``)+`,`+(n.padLeft===!1?``:` `)).trim()}var Ae=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,je=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,Me={};function Ne(e,t){return((t||Me).jsx?je:Ae).test(e)}var Pe=/[ \t\n\f\r]/g;function Fe(e){return typeof e==`object`?e.type===`text`&&Ie(e.value):Ie(e)}function Ie(e){return e.replace(Pe,``)===``}var Le=class{constructor(e,t,n){this.normal=t,this.property=e,n&&(this.space=n)}};Le.prototype.normal={},Le.prototype.property={},Le.prototype.space=void 0;function Re(e,t){let n={},r={};for(let t of e)Object.assign(n,t.property),Object.assign(r,t.normal);return new Le(n,r,t)}function ze(e){return e.toLowerCase()}var F=class{constructor(e,t){this.attribute=t,this.property=e}};F.prototype.attribute=``,F.prototype.booleanish=!1,F.prototype.boolean=!1,F.prototype.commaOrSpaceSeparated=!1,F.prototype.commaSeparated=!1,F.prototype.defined=!1,F.prototype.mustUseProperty=!1,F.prototype.number=!1,F.prototype.overloadedBoolean=!1,F.prototype.property=``,F.prototype.spaceSeparated=!1,F.prototype.space=void 0;var Be=n({boolean:()=>I,booleanish:()=>L,commaOrSpaceSeparated:()=>B,commaSeparated:()=>Ue,number:()=>R,overloadedBoolean:()=>He,spaceSeparated:()=>z}),Ve=0,I=We(),L=We(),He=We(),R=We(),z=We(),Ue=We(),B=We();function We(){return 2**++Ve}var Ge=Object.keys(Be),Ke=class extends F{constructor(e,t,n,r){let i=-1;if(super(e,t),qe(this,`space`,r),typeof n==`number`)for(;++i4&&n.slice(0,4)===`data`&&ot.test(t)){if(t.charAt(4)===`-`){let e=t.slice(5).replace(at,lt);r=`data`+e.charAt(0).toUpperCase()+e.slice(1)}else{let e=t.slice(4);if(!at.test(e)){let n=e.replace(it,ct);n.charAt(0)!==`-`&&(n=`-`+n),t=`data`+n}}i=Ke}return new i(r,t)}function ct(e){return`-`+e.toLowerCase()}function lt(e){return e.charAt(1).toUpperCase()}var ut=Re([Ye,Qe,et,tt,nt],`html`),dt=Re([Ye,$e,et,tt,nt],`svg`);function ft(e){return e.join(` `).trim()}var pt=e(((e,t)=>{var n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,r=/\n/g,i=/^\s*/,a=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,o=/^:\s*/,s=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,c=/^[;\s]*/,l=/^\s+|\s+$/g;function u(e,t){if(typeof e!=`string`)throw TypeError(`First argument must be a string`);if(!e)return[];t||={};var l=1,u=1;function f(e){var t=e.match(r);t&&(l+=t.length);var n=e.lastIndexOf(` +import{a as e,i as t,o as n,r,s as i}from"./useRouter-ByJ6_rwb.js";import{A as a,C as o,K as s,M as c,P as l,Q as u,T as d,X as f,_ as p,_t as m,a as h,et as g,mt as _,rt as v,ut as y,z as b}from"./brand-DUaZkIz1.js";import{E as x,S,o as C}from"./Tooltip-B3r3s_B9.js";import{Kt as w}from"./index-B7LmyWZW.js";var T=i(t(),1),E=i(m(),1);function D(e){if(!e||typeof e==`string`)return 0;let t=e/36;return Math.round((4+15*t**.25+t/5)*10)}function O(e){return e.current?e.current.scrollHeight:`auto`}function k(e){return typeof e==`number`&&e>0}function ee({transitionDuration:e,transitionTimingFunction:t=`ease`,onTransitionEnd:n,onTransitionStart:r,expanded:i,keepMounted:a}){let o={height:0,overflow:`hidden`,...a?{}:{display:`none`}},s=(0,T.useEffectEvent)(()=>r?.()),c=(0,T.useEffectEvent)(()=>n?.()),l=(0,T.useRef)(null),[u,d]=(0,T.useState)(i?{}:o),[f,p]=(0,T.useState)(i?`entered`:`exited`),m=e=>{(0,E.flushSync)(()=>d(e))},h=e=>{m(t=>({...t,...e}))},_=n=>{let r=e??D(n);return{transition:`height ${r}ms ${t}, opacity ${r}ms ${t}`}},y=(0,T.useRef)(0);v(()=>{y.current+=1;let t=y.current,n=()=>y.current===t;e!==0&&s(),i?window.requestAnimationFrame(()=>{n()&&l.current&&((0,E.flushSync)(()=>p(`entering`)),h({willChange:`height`,display:`block`,overflow:`hidden`}),window.requestAnimationFrame(()=>{if(!n()||!l.current)return;let e=O(l);if(!k(e)){m({}),p(`entered`),c();return}h({..._(e),height:e})}))}):window.requestAnimationFrame(()=>{if(!n()||!l.current)return;(0,E.flushSync)(()=>p(`exiting`));let e=O(l);if(!k(e)){m(o),p(`exited`),c();return}h({..._(e),willChange:`height`,height:e}),window.requestAnimationFrame(()=>{n()&&l.current&&h({height:0,overflow:`hidden`})})})},[i]);let b=e=>{if(e.target===l.current&&e.propertyName===`height`){if(i){let e=O(l);e===u.height?m({}):h({height:e}),p(`entered`),c()}else u.height===0&&(m(o),p(`exited`),c())}};return{state:f,getCollapseProps:e=>({"aria-hidden":!i,inert:!i,ref:g(l,e?.ref),onTransitionEnd:b,style:{boxSizing:`border-box`,...e?.style,...u}})}}function te(e){if(!e||typeof e==`string`)return 0;let t=e/36;return Math.round((4+15*t**.25+t/5)*10)}function A(e){return e.current?e.current.scrollWidth:`auto`}function j({transitionDuration:e,transitionTimingFunction:t=`ease`,onTransitionEnd:n,onTransitionStart:r,expanded:i,keepMounted:a}){let o={width:0,overflow:`hidden`,...a?{}:{display:`none`}},s=(0,T.useEffectEvent)(()=>r?.()),c=(0,T.useEffectEvent)(()=>n?.()),l=(0,T.useRef)(null),[u,d]=(0,T.useState)(i?{}:o),[f,p]=(0,T.useState)(i?`entered`:`exited`),m=e=>{(0,E.flushSync)(()=>d(e))},h=e=>{m(t=>({...t,...e}))},_=n=>{let r=e??te(n);return{transition:`width ${r}ms ${t}, opacity ${r}ms ${t}`}},y=(0,T.useRef)(0);v(()=>{y.current+=1;let t=y.current,n=()=>y.current===t;e!==0&&s(),i?window.requestAnimationFrame(()=>{n()&&l.current&&((0,E.flushSync)(()=>p(`entering`)),h({willChange:`width`,display:`block`,overflow:`hidden`}),window.requestAnimationFrame(()=>{if(!n()||!l.current)return;let e=A(l);if(!k(e)){m({}),p(`entered`),c();return}h({..._(e),width:e})}))}):window.requestAnimationFrame(()=>{if(!n()||!l.current)return;(0,E.flushSync)(()=>p(`exiting`));let e=A(l);if(!k(e)){m(o),p(`exited`),c();return}h({..._(e),willChange:`width`,width:e}),window.requestAnimationFrame(()=>{n()&&l.current&&h({width:0,overflow:`hidden`})})})},[i]);let b=e=>{if(e.target===l.current&&e.propertyName===`width`){if(i){let e=A(l);e===u.width?m({}):h({width:e}),p(`entered`),c()}else u.width===0&&(m(o),p(`exited`),c())}};return{state:f,getCollapseProps:e=>({"aria-hidden":!i,inert:!i,ref:g(l,e?.ref),onTransitionEnd:b,style:{boxSizing:`border-box`,...e?.style,...u}})}}function ne(){return`development`}var M=r(),N={transitionDuration:200,transitionTimingFunction:`ease`,animateOpacity:!0,orientation:`vertical`,keepMounted:!0,keepMountedMode:`activity`},re=d(e=>{let{children:t,expanded:n,transitionDuration:r,transitionTimingFunction:i,style:a,onTransitionEnd:s,onTransitionStart:d,animateOpacity:f,keepMounted:p,keepMountedMode:m,ref:h,orientation:g,..._}=c(`Collapse`,N,e),v=b(),y=l(),x=u(),C=y.respectReducedMotion&&x?0:r,w=(g===`horizontal`?j:ee)({expanded:n,transitionDuration:C,transitionTimingFunction:i,onTransitionEnd:s,onTransitionStart:d,keepMounted:!1});if(C===0)return p===!0&&(m===`display-none`||v!==`test`)?m===`display-none`?(0,M.jsx)(o,{..._,style:{...S(a,y),...n?{}:{display:`none`}},ref:h,children:t}):(0,M.jsx)(T.Activity,{mode:n?`visible`:`hidden`,children:(0,M.jsx)(o,{..._,style:a,ref:h,children:t})}):n?(0,M.jsx)(o,{..._,style:a,ref:h,children:t}):null;let E=w.state===`exited`,D;return D=p===!1?E?null:t:p===!0?m===`display-none`?t:(0,M.jsx)(T.Activity,{mode:E?`hidden`:`visible`,children:t}):t,(0,M.jsx)(o,{..._,...w.getCollapseProps({style:{opacity:n||!f?1:0,transition:f?`opacity ${C}ms ${i}`:`none`,...S(a,y),...p&&m===`display-none`&&E?{display:`none`}:{}},ref:h}),children:D})});re.displayName=`@mantine/core/Collapse`;var[ie,ae]=x(`Table component was not found in the tree`),oe={table:`m_b23fa0ef`,th:`m_4e7aa4f3`,tr:`m_4e7aa4fd`,td:`m_4e7aa4ef`,tbody:`m_b2404537`,thead:`m_b242d975`,caption:`m_9e5a3ac7`,scrollContainer:`m_a100c15`,scrollContainerInner:`m_62259741`};function se(e,t){if(!t)return;let n={};return t.columnBorder&&e.withColumnBorders&&(n[`data-with-column-border`]=!0),t.rowBorder&&e.withRowBorders&&(n[`data-with-row-border`]=!0),t.striped&&e.striped&&(n[`data-striped`]=e.striped),t.highlightOnHover&&e.highlightOnHover&&(n[`data-hover`]=!0),t.captionSide&&e.captionSide&&(n[`data-side`]=e.captionSide),t.stickyHeader&&e.stickyHeader&&(n[`data-sticky`]=!0),n}function ce(e,t){let n=`Table${e.charAt(0).toUpperCase()}${e.slice(1)}`,r=d(r=>{let i=c(n,{},r),{classNames:a,className:s,style:l,styles:u,...d}=i,f=ae();return(0,M.jsx)(o,{component:e,...se(f,t),...f.getStyles(e,{className:s,classNames:a,style:l,styles:u,props:i}),...d})});return r.displayName=`@mantine/core/${n}`,r.classes=oe,r}var le=ce(`th`,{columnBorder:!0}),ue=ce(`td`,{columnBorder:!0}),de=ce(`tr`,{rowBorder:!0,striped:!0,highlightOnHover:!0}),fe=ce(`thead`,{stickyHeader:!0}),pe=ce(`tbody`),me=ce(`tfoot`),he=ce(`caption`,{captionSide:!0}),ge={type:`scrollarea`},_e=f((e,{minWidth:t,maxHeight:n,type:r})=>({scrollContainer:{"--table-min-width":_(t),"--table-max-height":_(n),"--table-overflow":r===`native`?`auto`:void 0}})),ve=d(e=>{let t=c(`TableScrollContainer`,ge,e),{classNames:n,className:r,style:i,styles:s,unstyled:l,vars:u,children:d,minWidth:f,maxHeight:p,type:m,scrollAreaProps:h,attributes:g,..._}=t,v=a({name:`TableScrollContainer`,classes:oe,props:t,className:r,style:i,classNames:n,styles:s,unstyled:l,attributes:g,vars:u,varsResolver:_e,rootSelector:`scrollContainer`});return(0,M.jsx)(o,{component:m===`scrollarea`?C:`div`,...m===`scrollarea`?p?{offsetScrollbars:`xy`,...h}:{offsetScrollbars:`x`,...h}:{},...v(`scrollContainer`),..._,children:(0,M.jsx)(`div`,{...v(`scrollContainerInner`),children:d})})});ve.classes=oe,ve.varsResolver=_e,ve.displayName=`@mantine/core/TableScrollContainer`;function ye({data:e}){return(0,M.jsxs)(M.Fragment,{children:[e.caption&&(0,M.jsx)(he,{children:e.caption}),e.head&&(0,M.jsx)(fe,{children:(0,M.jsx)(de,{children:e.head.map((e,t)=>(0,M.jsx)(le,{children:e},t))})}),e.body&&(0,M.jsx)(pe,{children:e.body.map((e,t)=>(0,M.jsx)(de,{children:e.map((e,t)=>(0,M.jsx)(ue,{children:e},t))},t))}),e.foot&&(0,M.jsx)(me,{children:(0,M.jsx)(de,{children:e.foot.map((e,t)=>(0,M.jsx)(le,{children:e},t))})})]})}ye.displayName=`@mantine/core/TableDataRenderer`;var be={withRowBorders:!0,verticalSpacing:7},xe=f((e,{layout:t,captionSide:n,horizontalSpacing:r,verticalSpacing:i,borderColor:a,stripedColor:o,highlightOnHoverColor:c,striped:l,highlightOnHover:u,stickyHeaderOffset:d,stickyHeader:f})=>({table:{"--table-layout":t,"--table-caption-side":n,"--table-horizontal-spacing":y(r),"--table-vertical-spacing":y(i),"--table-border-color":a?s(a,e):void 0,"--table-striped-color":l&&o?s(o,e):void 0,"--table-highlight-on-hover-color":u&&c?s(c,e):void 0,"--table-sticky-header-offset":f?_(d):void 0}})),P=d(e=>{let t=c(`Table`,be,e),{classNames:n,className:r,style:i,styles:s,unstyled:l,vars:u,horizontalSpacing:d,verticalSpacing:f,captionSide:p,stripedColor:m,highlightOnHoverColor:h,striped:g,highlightOnHover:_,withColumnBorders:v,withRowBorders:y,withTableBorder:b,borderColor:x,layout:S,data:C,children:w,stickyHeader:E,stickyHeaderOffset:D,mod:O,tabularNums:k,attributes:ee,...te}=t,A=a({name:`Table`,props:t,className:r,style:i,classes:oe,classNames:n,styles:s,unstyled:l,attributes:ee,rootSelector:`table`,vars:u,varsResolver:xe,stable:!0}),j=g===!0?`odd`:g||void 0,ne=p||`bottom`,N=(0,T.useMemo)(()=>({getStyles:A,stickyHeader:E,striped:j,highlightOnHover:_,withColumnBorders:v,withRowBorders:y,captionSide:ne}),[A,E,j,_,v,y,ne]);return(0,M.jsx)(ie,{value:N,children:(0,M.jsx)(o,{component:`table`,mod:[{withTableBorder:b,tabularNums:k},O],...A(`table`),...te,children:w||!!C&&(0,M.jsx)(ye,{data:C})})})});P.classes=oe,P.varsResolver=xe,P.displayName=`@mantine/core/Table`,P.Td=ue,P.Th=le,P.Tr=de,P.Thead=fe,P.Tbody=pe,P.Tfoot=me,P.Caption=he,P.ScrollContainer=ve,P.DataRenderer=ye;var Se=new Map([[`bold`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z`}))],[`duotone`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M208,96l-80,80L48,96Z`,opacity:`0.2`}),T.createElement(`path`,{d:`M215.39,92.94A8,8,0,0,0,208,88H48a8,8,0,0,0-5.66,13.66l80,80a8,8,0,0,0,11.32,0l80-80A8,8,0,0,0,215.39,92.94ZM128,164.69,67.31,104H188.69Z`}))],[`fill`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z`}))],[`light`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M212.24,100.24l-80,80a6,6,0,0,1-8.48,0l-80-80a6,6,0,0,1,8.48-8.48L128,167.51l75.76-75.75a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,T.createElement(T.Fragment,null,T.createElement(`path`,{d:`M210.83,98.83l-80,80a4,4,0,0,1-5.66,0l-80-80a4,4,0,0,1,5.66-5.66L128,170.34l77.17-77.17a4,4,0,1,1,5.66,5.66Z`}))]]),Ce=T.forwardRef((e,t)=>T.createElement(h,{ref:t,...e,weights:Se}));Ce.displayName=`CaretDownIcon`;var we=Ce,Te=new Intl.NumberFormat(void 0,{maximumFractionDigits:0});function Ee(e){return Number.isFinite(e)?e>0&&e<1e-4?`<0.01%`:`${(e*100).toFixed(e>=.1?1:2)}%`:`—`}function De(e){if(!Number.isFinite(e))return`—`;if(e<0)return`-${De(-e)}`;if(e===0)return`0ms`;if(e<.01)return`<0.01ms`;if(e<1)return`${e.toFixed(2)}ms`;if(Math.round(e*10)/10<100)return`${e.toFixed(1)}ms`;if(Math.round(e)<1e3)return`${Math.round(e)}ms`;let t=Math.round(e/100)/10;if(t<10)return`${(e/1e3).toFixed(2)}s`;if(t<60)return`${t.toFixed(1)}s`;let n=Math.round(e/1e3),r=Math.floor(n/60),i=n%60;if(r<60)return i===0?`${r}m`:`${r}m ${i}s`;let a=Math.floor(r/60),o=r%60;return o===0?`${a}h`:`${a}h ${o}m`}function Oe(e){let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.valueOf())?String(e):t.toLocaleString([],{year:`numeric`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`,timeZoneName:`short`})}function ke(e,t){let n=t||{};return(e[e.length-1]===``?[...e,``]:e).join((n.padRight?` `:``)+`,`+(n.padLeft===!1?``:` `)).trim()}var Ae=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,je=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,Me={};function Ne(e,t){return((t||Me).jsx?je:Ae).test(e)}var Pe=/[ \t\n\f\r]/g;function Fe(e){return typeof e==`object`?e.type===`text`&&Ie(e.value):Ie(e)}function Ie(e){return e.replace(Pe,``)===``}var Le=class{constructor(e,t,n){this.normal=t,this.property=e,n&&(this.space=n)}};Le.prototype.normal={},Le.prototype.property={},Le.prototype.space=void 0;function Re(e,t){let n={},r={};for(let t of e)Object.assign(n,t.property),Object.assign(r,t.normal);return new Le(n,r,t)}function ze(e){return e.toLowerCase()}var F=class{constructor(e,t){this.attribute=t,this.property=e}};F.prototype.attribute=``,F.prototype.booleanish=!1,F.prototype.boolean=!1,F.prototype.commaOrSpaceSeparated=!1,F.prototype.commaSeparated=!1,F.prototype.defined=!1,F.prototype.mustUseProperty=!1,F.prototype.number=!1,F.prototype.overloadedBoolean=!1,F.prototype.property=``,F.prototype.spaceSeparated=!1,F.prototype.space=void 0;var Be=n({boolean:()=>I,booleanish:()=>L,commaOrSpaceSeparated:()=>B,commaSeparated:()=>Ue,number:()=>R,overloadedBoolean:()=>He,spaceSeparated:()=>z}),Ve=0,I=We(),L=We(),He=We(),R=We(),z=We(),Ue=We(),B=We();function We(){return 2**++Ve}var Ge=Object.keys(Be),Ke=class extends F{constructor(e,t,n,r){let i=-1;if(super(e,t),qe(this,`space`,r),typeof n==`number`)for(;++i4&&n.slice(0,4)===`data`&&ot.test(t)){if(t.charAt(4)===`-`){let e=t.slice(5).replace(at,lt);r=`data`+e.charAt(0).toUpperCase()+e.slice(1)}else{let e=t.slice(4);if(!at.test(e)){let n=e.replace(it,ct);n.charAt(0)!==`-`&&(n=`-`+n),t=`data`+n}}i=Ke}return new i(r,t)}function ct(e){return`-`+e.toLowerCase()}function lt(e){return e.charAt(1).toUpperCase()}var ut=Re([Ye,Qe,et,tt,nt],`html`),dt=Re([Ye,$e,et,tt,nt],`svg`);function ft(e){return e.join(` `).trim()}var pt=e(((e,t)=>{var n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,r=/\n/g,i=/^\s*/,a=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,o=/^:\s*/,s=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,c=/^[;\s]*/,l=/^\s+|\s+$/g;function u(e,t){if(typeof e!=`string`)throw TypeError(`First argument must be a string`);if(!e)return[];t||={};var l=1,u=1;function f(e){var t=e.match(r);t&&(l+=t.length);var n=e.lastIndexOf(` `);u=~n?e.length-n:u+e.length}function p(){var e={line:l,column:u};return function(t){return t.position=new m(e),_(),t}}function m(e){this.start=e,this.end={line:l,column:u},this.source=t.source}m.prototype.content=e;function h(n){var r=Error(t.source+`:`+l+`:`+u+`: `+n);if(r.reason=n,r.filename=t.source,r.line=l,r.column=u,r.source=e,!t.silent)throw r}function g(t){var n=t.exec(e);if(n){var r=n[0];return f(r),e=e.slice(r.length),n}}function _(){g(i)}function v(e){var t;for(e||=[];t=y();)t!==!1&&e.push(t);return e}function y(){var t=p();if(e.charAt(0)==`/`&&e.charAt(1)==`*`){for(var n=2;e.charAt(n)!=``&&(e.charAt(n)!=`*`||e.charAt(n+1)!=`/`);)++n;if(n+=2,e.charAt(n-1)===``)return h(`End of comment missing`);var r=e.slice(2,n-2);return u+=2,f(r),e=e.slice(n),u+=2,t({type:`comment`,comment:r})}}function b(){var e=p(),t=g(a);if(t){if(y(),!g(o))return h(`property missing ':'`);var r=g(s),i=e({type:`declaration`,property:d(t[0].replace(n,``)),value:r?d(r[0].replace(n,``)):``});return g(c),i}}function x(){var e=[];v(e);for(var t;t=b();)t!==!1&&(e.push(t),v(e));return e}return _(),x()}function d(e){return e?e.replace(l,``):``}t.exports=u})),mt=e((e=>{var t=e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.default=r;var n=t(pt());function r(e,t){let r=null;if(!e||typeof e!=`string`)return r;let i=(0,n.default)(e),a=typeof t==`function`;return i.forEach(e=>{if(e.type!==`declaration`)return;let{property:n,value:i}=e;a?t(n,i,e):i&&(r||={},r[n]=i)}),r}})),ht=e((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.camelCase=void 0;var t=/^--[a-zA-Z0-9_-]+$/,n=/-([a-z])/g,r=/^[^-]+$/,i=/^-(webkit|moz|ms|o|khtml)-/,a=/^-(ms)-/,o=function(e){return!e||r.test(e)||t.test(e)},s=function(e,t){return t.toUpperCase()},c=function(e,t){return`${t}-`};e.camelCase=function(e,t){return t===void 0&&(t={}),o(e)?e:(e=e.toLowerCase(),e=t.reactCompat?e.replace(a,c):e.replace(i,c),e.replace(n,s))}})),gt=e(((e,t)=>{var n=(e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}})(mt()),r=ht();function i(e,t){var i={};return!e||typeof e!=`string`||(0,n.default)(e,function(e,n){e&&n&&(i[(0,r.camelCase)(e,t)]=n)}),i}i.default=i,t.exports=i})),_t=yt(`end`),vt=yt(`start`);function yt(e){return t;function t(t){let n=t&&t.position&&t.position[e]||{};if(typeof n.line==`number`&&n.line>0&&typeof n.column==`number`&&n.column>0)return{line:n.line,column:n.column,offset:typeof n.offset==`number`&&n.offset>-1?n.offset:void 0}}}function bt(e){let t=vt(e),n=_t(e);if(t&&n)return{start:t,end:n}}function xt(e){return!e||typeof e!=`object`?``:`position`in e||`type`in e?Ct(e.position):`start`in e||`end`in e?Ct(e):`line`in e||`column`in e?St(e):``}function St(e){return wt(e&&e.line)+`:`+wt(e&&e.column)}function Ct(e){return St(e&&e.start)+`-`+St(e&&e.end)}function wt(e){return e&&typeof e==`number`?e:1}var V=class extends Error{constructor(e,t,n){super(),typeof t==`string`&&(n=t,t=void 0);let r=``,i={},a=!1;if(t&&(i=`line`in t&&`column`in t||`start`in t&&`end`in t?{place:t}:`type`in t?{ancestors:[t],place:t.position}:{...t}),typeof e==`string`?r=e:!i.cause&&e&&(a=!0,r=e.message,i.cause=e),!i.ruleId&&!i.source&&typeof n==`string`){let e=n.indexOf(`:`);e===-1?i.ruleId=n:(i.source=n.slice(0,e),i.ruleId=n.slice(e+1))}if(!i.place&&i.ancestors&&i.ancestors){let e=i.ancestors[i.ancestors.length-1];e&&(i.place=e.position)}let o=i.place&&`start`in i.place?i.place.start:i.place;this.ancestors=i.ancestors||void 0,this.cause=i.cause||void 0,this.column=o?o.column:void 0,this.fatal=void 0,this.file=``,this.message=r,this.line=o?o.line:void 0,this.name=xt(i.place)||`1:1`,this.place=i.place||void 0,this.reason=this.message,this.ruleId=i.ruleId||void 0,this.source=i.source||void 0,this.stack=a&&i.cause&&typeof i.cause.stack==`string`?i.cause.stack:``,this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}};V.prototype.file=``,V.prototype.name=``,V.prototype.reason=``,V.prototype.message=``,V.prototype.stack=``,V.prototype.column=void 0,V.prototype.line=void 0,V.prototype.ancestors=void 0,V.prototype.cause=void 0,V.prototype.fatal=void 0,V.prototype.place=void 0,V.prototype.ruleId=void 0,V.prototype.source=void 0;var Tt=i(gt(),1),Et={}.hasOwnProperty,Dt=new Map,Ot=/[A-Z]/g,kt=new Set([`table`,`tbody`,`thead`,`tfoot`,`tr`]),At=new Set([`td`,`th`]),jt=`https://github.com/syntax-tree/hast-util-to-jsx-runtime`;function Mt(e,t){if(!t||t.Fragment===void 0)throw TypeError("Expected `Fragment` in options");let n=t.filePath||void 0,r;if(t.development){if(typeof t.jsxDEV!=`function`)throw TypeError("Expected `jsxDEV` in options when `development: true`");r=Ut(n,t.jsxDEV)}else{if(typeof t.jsx!=`function`)throw TypeError("Expected `jsx` in production options");if(typeof t.jsxs!=`function`)throw TypeError("Expected `jsxs` in production options");r=Ht(n,t.jsx,t.jsxs)}let i={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:r,elementAttributeNameCase:t.elementAttributeNameCase||`react`,evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space===`svg`?dt:ut,stylePropertyNameCase:t.stylePropertyNameCase||`dom`,tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},a=Nt(i,e,void 0);return a&&typeof a!=`string`?a:i.create(e,i.Fragment,{children:a||void 0},void 0)}function Nt(e,t,n){if(t.type===`element`)return Pt(e,t,n);if(t.type===`mdxFlowExpression`||t.type===`mdxTextExpression`)return Ft(e,t);if(t.type===`mdxJsxFlowElement`||t.type===`mdxJsxTextElement`)return Lt(e,t,n);if(t.type===`mdxjsEsm`)return It(e,t);if(t.type===`root`)return Rt(e,t,n);if(t.type===`text`)return zt(e,t)}function Pt(e,t,n){let r=e.schema,i=r;t.tagName.toLowerCase()===`svg`&&r.space===`html`&&(i=dt,e.schema=i),e.ancestors.push(t);let a=Yt(e,t.tagName,!1),o=Wt(e,t),s=Kt(e,t);return kt.has(t.tagName)&&(s=s.filter(function(e){return typeof e!=`string`||!Fe(e)})),Bt(e,o,a,t),Vt(o,s),e.ancestors.pop(),e.schema=r,e.create(t,a,o,n)}function Ft(e,t){if(t.data&&t.data.estree&&e.evaluater){let n=t.data.estree.body[0];return n.type,e.evaluater.evaluateExpression(n.expression)}Xt(e,t.position)}function It(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);Xt(e,t.position)}function Lt(e,t,n){let r=e.schema,i=r;t.name===`svg`&&r.space===`html`&&(i=dt,e.schema=i),e.ancestors.push(t);let a=t.name===null?e.Fragment:Yt(e,t.name,!0),o=Gt(e,t),s=Kt(e,t);return Bt(e,o,a,t),Vt(o,s),e.ancestors.pop(),e.schema=r,e.create(t,a,o,n)}function Rt(e,t,n){let r={};return Vt(r,Kt(e,t)),e.create(t,e.Fragment,r,n)}function zt(e,t){return t.value}function Bt(e,t,n,r){typeof n!=`string`&&n!==e.Fragment&&e.passNode&&(t.node=r)}function Vt(e,t){if(t.length>0){let n=t.length>1?t:t[0];n&&(e.children=n)}}function Ht(e,t,n){return r;function r(e,r,i,a){let o=Array.isArray(i.children)?n:t;return a?o(r,i,a):o(r,i)}}function Ut(e,t){return n;function n(n,r,i,a){let o=Array.isArray(i.children),s=vt(n);return t(r,i,a,o,{columnNumber:s?s.column-1:void 0,fileName:e,lineNumber:s?s.line:void 0},void 0)}}function Wt(e,t){let n={},r,i;for(i in t.properties)if(i!==`children`&&Et.call(t.properties,i)){let a=qt(e,i,t.properties[i]);if(a){let[i,o]=a;e.tableCellAlignToStyle&&i===`align`&&typeof o==`string`&&At.has(t.tagName)?r=o:n[i]=o}}if(r){let t=n.style||={};t[e.stylePropertyNameCase===`css`?`text-align`:`textAlign`]=r}return n}function Gt(e,t){let n={};for(let r of t.attributes)if(r.type===`mdxJsxExpressionAttribute`){if(r.data&&r.data.estree&&e.evaluater){let t=r.data.estree.body[0];t.type;let i=t.expression;i.type;let a=i.properties[0];a.type,Object.assign(n,e.evaluater.evaluateExpression(a.argument))}else Xt(e,t.position)}else{let i=r.name,a;if(r.value&&typeof r.value==`object`){if(r.value.data&&r.value.data.estree&&e.evaluater){let t=r.value.data.estree.body[0];t.type,a=e.evaluater.evaluateExpression(t.expression)}else Xt(e,t.position)}else a=r.value===null||r.value;n[i]=a}return n}function Kt(e,t){let n=[],r=-1,i=e.passKeys?new Map:Dt;for(;++ri?0:i+t:t>i?i:t,n=n>0?n:0,r.length<1e4)o=Array.from(r),o.unshift(t,n),e.splice(...o);else for(n&&e.splice(t,n);a0?(H(e,e.length,0,t),e):t}var ln={}.hasOwnProperty;function un(e){let t={},n=-1;for(;++n13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)==65535||(n&65535)==65534||n>1114111?`�`:String.fromCodePoint(n)}function W(e){return e.replace(/[\t\n\r ]+/g,` `).replace(/^ | $/g,``).toLowerCase().toUpperCase()}var G=xn(/[A-Za-z]/),K=xn(/[\dA-Za-z]/),mn=xn(/[#-'*+\--9=?A-Z^-~]/);function hn(e){return e!==null&&(e<32||e===127)}var gn=xn(/\d/),_n=xn(/[\dA-Fa-f]/),vn=xn(/[!-/:-@[-`{-~]/);function q(e){return e!==null&&e<-2}function J(e){return e!==null&&(e<0||e===32)}function Y(e){return e===-2||e===-1||e===32}var yn=xn(/\p{P}|\p{S}/u),bn=xn(/\s/);function xn(e){return t;function t(t){return t!==null&&t>-1&&e.test(String.fromCharCode(t))}}function Sn(e){let t=[],n=-1,r=0,i=0;for(;++n55295&&a<57344){let t=e.charCodeAt(n+1);a<56320&&t>56319&&t<57344?(o=String.fromCharCode(a,t),i=1):o=`�`}else o=String.fromCharCode(a);o&&=(t.push(e.slice(r,n),encodeURIComponent(o)),r=n+i+1,``),i&&=(n+=i,0)}return t.join(``)+e.slice(r)}function X(e,t,n,r){let i=r?r-1:1/0,a=0;return o;function o(r){return Y(r)?(e.enter(n),s(r)):t(r)}function s(r){return Y(r)&&a++0&&Y(t)?(e.enter(r),c(t)):l(t)}function c(t){return Y(t)&&o=i?t(e):n(e)}}var wn={tokenize:Tn};function Tn(e){let t=e.attempt(this.parser.constructs.contentInitial,r,i),n;return t;function r(n){if(n===null){e.consume(n);return}return e.enter(`lineEnding`),e.consume(n),e.exit(`lineEnding`),X(e,t,`linePrefix`)}function i(t){return e.enter(`paragraph`),a(t)}function a(t){let r=e.enter(`chunkText`,{contentType:`text`,previous:n});return n&&(n.next=r),n=r,o(t)}function o(t){if(t===null){e.exit(`chunkText`),e.exit(`paragraph`),e.consume(t);return}return q(t)?(e.consume(t),e.exit(`chunkText`),a):(e.consume(t),o)}}var En=class{constructor(){this.index=new Map,this.map=[]}add(e,t,n){Dn(this,e,t,n,!1)}addBefore(e,t,n){Dn(this,e,t,n,!0)}consume(e){if(this.map.sort(function(e,t){return e[0]-t[0]}),this.map.length===0)return;let t=this.map.length,n=[];for(;t>0;)--t,n.push(e.slice(this.map[t][0]+this.map[t][1]),this.map[t][2]),e.length=this.map[t][0];n.push(e.slice()),e.length=0;let r=n.pop();for(;r;){for(let t of r)e.push(t);r=n.pop()}this.map.length=0,this.index.clear()}};function Dn(e,t,n,r,i){if(n===0&&r.length===0)return;let a=e.index.get(t);if(a){a[1]+=n,i?(r.push(...a[2]),a[2]=r):a[2].push(...r);return}let o=[t,n,r];e.map.push(o),e.index.set(t,o)}var On={tokenize:An},kn={tokenize:jn};function An(e){let t=this,n=[],r=0,i,a,o;return s;function s(i){if(ro))return;let n=t.events.length,a=n,s,c;for(;a--;)if(t.events[a][0]===`exit`&&t.events[a][1].type===`chunkFlow`){if(s){c=t.events[a][1].end;break}s=!0}for(_(r),e=n;er;){let r=n[i];t.containerState=r[1],r[0].exit.call(t,e)}n.length=r}function v(){i.write([null]),a=void 0,i=void 0,t.containerState._closeFlow=void 0}}function jn(e,t,n){return X(e,e.attempt(this.parser.constructs.document,t,n),`linePrefix`,this.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)}function Mn(e){if(e===null||J(e)||bn(e))return 1;if(yn(e))return 2}function Nn(e,t,n){let r=[],i=-1;for(;++i1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1,o={...e[i][1].end},s={...e[n][1].start};Ln(o,-a),Ln(s,a);let c={type:a>1?`strongSequence`:`emphasisSequence`,start:o,end:{...e[i][1].end}},l={type:a>1?`strongSequence`:`emphasisSequence`,start:{...e[n][1].start},end:s},u={type:a>1?`strongText`:`emphasisText`,start:{...e[i][1].end},end:{...e[n][1].start}},d={type:a>1?`strong`:`emphasis`,start:{...c.start},end:{...l.end}};e[i][1].end={...c.start},e[n][1].start={...l.end},r=[],e[i][1].end.offset-e[i][1].start.offset&&(r=U(r,[[`enter`,e[i][1],t],[`exit`,e[i][1],t]])),r=U(r,[[`enter`,d,t],[`enter`,c,t],[`exit`,c,t],[`enter`,u,t]]),r=U(r,Nn(t.parser.constructs.insideSpan.null,e.slice(i+1,n),t)),r=U(r,[[`exit`,u,t],[`enter`,l,t],[`exit`,l,t],[`exit`,d,t]]);let f=0;e[n][1].end.offset-e[n][1].start.offset&&(f=2,r=U(r,[[`enter`,e[n][1],t],[`exit`,e[n][1],t]])),H(e,i-1,n-i+3,r),n=i+r.length-f-2;break}}for(n=-1;++n0&&Y(t)?X(e,v,`linePrefix`,a+1)(t):v(t)}function v(t){return t===null||q(t)?e.check(Xn,h,b)(t):(e.enter(`codeFlowValue`),y(t))}function y(t){return t===null||q(t)?(e.exit(`codeFlowValue`),v(t)):(e.consume(t),y)}function b(n){return e.exit(`codeFenced`),t(n)}function x(e,t,n){let i=0;return a;function a(t){return e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),c}function c(t){return e.enter(`codeFencedFence`),Y(t)?X(e,l,`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(t):l(t)}function l(t){return t===s?(e.enter(`codeFencedFenceSequence`),u(t)):n(t)}function u(t){return t===s?(i++,e.consume(t),u):i>=o?(e.exit(`codeFencedFenceSequence`),Y(t)?X(e,d,`whitespace`)(t):d(t)):n(t)}function d(r){return r===null||q(r)?(e.exit(`codeFencedFence`),t(r)):n(r)}}}var er={name:`codeIndented`,tokenize:nr},tr={partial:!0,tokenize:rr};function nr(e,t,n){return r;function r(t){return e.enter(`codeIndented`),Cn(e,i,n,`linePrefix`,4,4)(t)}function i(t){return t===null?o(t):q(t)?e.attempt(tr,i,o)(t):(e.enter(`codeFlowValue`),a(t))}function a(t){return t===null||q(t)?(e.exit(`codeFlowValue`),i(t)):(e.consume(t),a)}function o(n){return e.exit(`codeIndented`),t(n)}}function rr(e,t,n){let r=this;return i;function i(o){return r.parser.lazy[r.now().line]?n(o):q(o)?(e.enter(`lineEnding`),e.consume(o),e.exit(`lineEnding`),i):Cn(e,t,a,`linePrefix`,4,4)(o)}function a(e){return q(e)?i(e):n(e)}}var ir={name:`codeText`,previous:or,resolve:ar,tokenize:sr};function ar(e){let t=e.length-4,n=3,r,i;if((e[n][1].type===`lineEnding`||e[n][1].type===`space`)&&(e[t][1].type===`lineEnding`||e[t][1].type===`space`)){for(r=n;++r=this.left.length+this.right.length)throw RangeError("Cannot access index `"+e+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return ethis.left.length?this.right.slice(this.right.length-n+this.left.length,this.right.length-e+this.left.length).reverse():this.left.slice(e).concat(this.right.slice(this.right.length-n+this.left.length).reverse())}splice(e,t,n){let r=t||0;this.setCursor(Math.trunc(e));let i=this.right.splice(this.right.length-r,1/0);return n&&lr(this.left,n),i.reverse()}pop(){return this.setCursor(1/0),this.left.pop()}push(e){this.setCursor(1/0),this.left.push(e)}pushMany(e){this.setCursor(1/0),lr(this.left,e)}unshift(e){this.setCursor(0),this.right.push(e)}unshiftMany(e){this.setCursor(0),lr(this.right,e.reverse())}setCursor(e){if(!(e===this.left.length||e>this.left.length&&this.right.length===0||e<0&&this.left.length===0)){if(e=4?t(i):e.interrupt(r.parser.constructs.flow,n,t)(i)}}function _r(e,t,n,r,i,a,o,s,c){let l=c||1/0,u=0;return d;function d(t){return t===60?(e.enter(r),e.enter(i),e.enter(a),e.consume(t),e.exit(a),f):t===null||t===32||t===41||hn(t)?n(t):(e.enter(r),e.enter(o),e.enter(s),e.enter(`chunkString`,{contentType:`string`}),h(t))}function f(n){return n===62?(e.enter(a),e.consume(n),e.exit(a),e.exit(i),e.exit(r),t):(e.enter(s),e.enter(`chunkString`,{contentType:`string`}),p(n))}function p(t){return t===62?(e.exit(`chunkString`),e.exit(s),f(t)):t===null||t===60||q(t)?n(t):(e.consume(t),t===92?m:p)}function m(t){return t===60||t===62||t===92?(e.consume(t),p):p(t)}function h(i){return!u&&(i===null||i===41||J(i))?(e.exit(`chunkString`),e.exit(s),e.exit(o),e.exit(r),t(i)):u999||l===null||l===91||l===93&&!c||l===94&&!s&&`_hiddenFootnoteSupport`in o.parser.constructs?n(l):l===93?(e.exit(a),e.enter(i),e.consume(l),e.exit(i),e.exit(r),t):q(l)?(e.enter(`lineEnding`),e.consume(l),e.exit(`lineEnding`),u):(e.enter(`chunkString`,{contentType:`string`}),d(l))}function d(t){return t===null||t===91||t===93||q(t)||s++>999?(e.exit(`chunkString`),u(t)):(e.consume(t),c||=!Y(t),t===92?f:d)}function f(t){return t===91||t===92||t===93?(e.consume(t),s++,d):d(t)}}function yr(e,t,n,r,i,a){let o;return s;function s(t){return t===34||t===39||t===40?(e.enter(r),e.enter(i),e.consume(t),e.exit(i),o=t===40?41:t,c):n(t)}function c(n){return n===o?(e.enter(i),e.consume(n),e.exit(i),e.exit(r),t):(e.enter(a),l(n))}function l(t){return t===o?(e.exit(a),c(o)):t===null?n(t):q(t)?(e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),X(e,l,`linePrefix`)):(e.enter(`chunkString`,{contentType:`string`}),u(t))}function u(t){return t===o||t===null||q(t)?(e.exit(`chunkString`),l(t)):(e.consume(t),t===92?d:u)}function d(t){return t===o||t===92?(e.consume(t),u):u(t)}}function br(e,t){let n;return r;function r(i){return q(i)?(e.enter(`lineEnding`),e.consume(i),e.exit(`lineEnding`),n=!0,r):Y(i)?X(e,r,n?`linePrefix`:`lineSuffix`)(i):t(i)}}var xr={name:`definition`,tokenize:Cr},Sr={partial:!0,tokenize:wr};function Cr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`definition`),o(t)}function o(t){return vr.call(r,e,s,n,`definitionLabel`,`definitionLabelMarker`,`definitionLabelString`)(t)}function s(t){return i=W(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),t===58?(e.enter(`definitionMarker`),e.consume(t),e.exit(`definitionMarker`),c):n(t)}function c(t){return J(t)?br(e,l)(t):l(t)}function l(t){return _r(e,u,n,`definitionDestination`,`definitionDestinationLiteral`,`definitionDestinationLiteralMarker`,`definitionDestinationRaw`,`definitionDestinationString`)(t)}function u(t){return e.attempt(Sr,d,d)(t)}function d(t){return Y(t)?X(e,f,`whitespace`)(t):f(t)}function f(a){return a===null||q(a)?(e.exit(`definition`),r.parser.defined.push(i),t(a)):n(a)}}function wr(e,t,n){return r;function r(t){return J(t)?br(e,i)(t):n(t)}function i(t){return yr(e,a,n,`definitionTitle`,`definitionTitleMarker`,`definitionTitleString`)(t)}function a(t){return Y(t)?X(e,o,`whitespace`)(t):o(t)}function o(e){return e===null||q(e)?t(e):n(e)}}var Tr={name:`hardBreakEscape`,tokenize:Er};function Er(e,t,n){return r;function r(t){return e.enter(`hardBreakEscape`),e.consume(t),i}function i(r){return q(r)?(e.exit(`hardBreakEscape`),t(r)):n(r)}}var Dr={name:`headingAtx`,resolve:Or,tokenize:kr};function Or(e,t){let n=e.length-2,r=3;if(e[r][1].type===`whitespace`&&(r+=2),n-2>r&&e[n][1].type===`whitespace`&&(n-=2),e[n][1].type===`atxHeadingSequence`&&(r===n-1||n-4>r&&e[n-2][1].type===`whitespace`)&&(n-=r+1===n?2:4),n>r){let i={type:`atxHeadingText`,start:e[r][1].start,end:e[n][1].end},a={type:`chunkText`,start:e[r][1].start,end:e[n][1].end,contentType:`text`};H(e,r,n-r+1,[[`enter`,i,t],[`enter`,a,t],[`exit`,a,t],[`exit`,i,t]])}return e}function kr(e,t,n){let r=0;return i;function i(t){return e.enter(`atxHeading`),a(t)}function a(t){return e.enter(`atxHeadingSequence`),o(t)}function o(t){return t===35&&r++<6?(e.consume(t),o):t===null||J(t)?(e.exit(`atxHeadingSequence`),s(t)):n(t)}function s(n){return n===35?(e.enter(`atxHeadingSequence`),c(n)):n===null||q(n)?(e.exit(`atxHeading`),t(n)):Y(n)?X(e,s,`whitespace`)(n):(e.enter(`atxHeadingText`),l(n))}function c(t){return t===35?(e.consume(t),c):(e.exit(`atxHeadingSequence`),s(t))}function l(t){return t===null||t===35||J(t)?(e.exit(`atxHeadingText`),s(t)):(e.consume(t),l)}}var Ar=`address.article.aside.base.basefont.blockquote.body.caption.center.col.colgroup.dd.details.dialog.dir.div.dl.dt.fieldset.figcaption.figure.footer.form.frame.frameset.h1.h2.h3.h4.h5.h6.head.header.hr.html.iframe.legend.li.link.main.menu.menuitem.nav.noframes.ol.optgroup.option.p.param.search.section.summary.table.tbody.td.tfoot.th.thead.title.tr.track.ul`.split(`.`),jr=[`pre`,`script`,`style`,`textarea`],Mr={concrete:!0,name:`htmlFlow`,resolveTo:Pr,tokenize:Fr},Nr={partial:!0,tokenize:Ir};function Pr(e){let t=e.length;for(;t--&&(e[t][0]!==`enter`||e[t][1].type!==`htmlFlow`););return t>1&&e[t-2][1].type===`linePrefix`&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function Fr(e,t,n){let r=this,i,a,o,s,c;return l;function l(e){return u(e)}function u(t){return e.enter(`htmlFlow`),e.enter(`htmlFlowData`),e.consume(t),d}function d(s){return s===33?(e.consume(s),f):s===47?(e.consume(s),a=!0,h):s===63?(e.consume(s),i=3,r.interrupt?t:N):G(s)?(e.consume(s),o=String.fromCharCode(s),g):n(s)}function f(a){return a===45?(e.consume(a),i=2,p):a===91?(e.consume(a),i=5,s=0,m):G(a)?(e.consume(a),i=4,r.interrupt?t:N):n(a)}function p(i){return i===45?(e.consume(i),r.interrupt?t:N):n(i)}function m(i){return i===`CDATA[`.charCodeAt(s++)?(e.consume(i),s===6?r.interrupt?t:O:m):n(i)}function h(t){return G(t)?(e.consume(t),o=String.fromCharCode(t),g):n(t)}function g(s){if(s===null||s===47||s===62||J(s)){let c=s===47,l=o.toLowerCase();return!c&&!a&&jr.includes(l)?(i=1,r.interrupt?t(s):O(s)):Ar.includes(o.toLowerCase())?(i=6,c?(e.consume(s),_):r.interrupt?t(s):O(s)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(s):a?v(s):y(s))}return s===45||K(s)?(e.consume(s),o+=String.fromCharCode(s),g):n(s)}function _(i){return i===62?(e.consume(i),r.interrupt?t:O):n(i)}function v(t){return Y(t)?(e.consume(t),v):E(t)}function y(t){return t===47?(e.consume(t),E):t===58||t===95||G(t)?(e.consume(t),b):Y(t)?(e.consume(t),y):E(t)}function b(t){return t===45||t===46||t===58||t===95||K(t)?(e.consume(t),b):x(t)}function x(t){return t===61?(e.consume(t),S):Y(t)?(e.consume(t),x):y(t)}function S(t){return t===null||t===60||t===61||t===62||t===96?n(t):t===34||t===39?(e.consume(t),c=t,C):Y(t)?(e.consume(t),S):w(t)}function C(t){return t===c?(e.consume(t),c=null,T):t===null||q(t)?n(t):(e.consume(t),C)}function w(t){return t===null||t===34||t===39||t===47||t===60||t===61||t===62||t===96||J(t)?x(t):(e.consume(t),w)}function T(e){return e===47||e===62||Y(e)?y(e):n(e)}function E(t){return t===62?(e.consume(t),D):n(t)}function D(t){return t===null||q(t)?O(t):Y(t)?(e.consume(t),D):n(t)}function O(t){return t===45&&i===2?(e.consume(t),A):t===60&&i===1?(e.consume(t),j):t===62&&i===4?(e.consume(t),re):t===63&&i===3?(e.consume(t),N):t===93&&i===5?(e.consume(t),M):q(t)&&(i===6||i===7)?(e.exit(`htmlFlowData`),e.check(Nr,ie,k)(t)):t===null||q(t)?(e.exit(`htmlFlowData`),k(t)):(e.consume(t),O)}function k(t){return e.check(Xn,ee,ie)(t)}function ee(t){return e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),te}function te(t){return t===null||q(t)?k(t):(e.enter(`htmlFlowData`),O(t))}function A(t){return t===45?(e.consume(t),N):O(t)}function j(t){return t===47?(e.consume(t),o=``,ne):O(t)}function ne(t){if(t===62){let n=o.toLowerCase();return jr.includes(n)?(e.consume(t),re):O(t)}return G(t)&&o.length<8?(e.consume(t),o+=String.fromCharCode(t),ne):O(t)}function M(t){return t===93?(e.consume(t),N):O(t)}function N(t){return t===62?(e.consume(t),re):t===45&&i===2?(e.consume(t),N):O(t)}function re(t){return t===null||q(t)?(e.exit(`htmlFlowData`),ie(t)):(e.consume(t),re)}function ie(n){return e.exit(`htmlFlow`),t(n)}}function Ir(e,t,n){return r;function r(r){return e.enter(`lineEnding`),e.consume(r),e.exit(`lineEnding`),e.attempt(Bn,t,n)}}var Lr={name:`htmlText`,tokenize:Rr};function Rr(e,t,n){let r=this,i,a,o;return s;function s(t){return e.enter(`htmlText`),e.enter(`htmlTextData`),e.consume(t),c}function c(t){return t===33?(e.consume(t),l):t===47?(e.consume(t),x):t===63?(e.consume(t),y):G(t)?(e.consume(t),w):n(t)}function l(t){return t===45?(e.consume(t),u):t===91?(e.consume(t),a=0,m):G(t)?(e.consume(t),v):n(t)}function u(t){return t===45?(e.consume(t),p):n(t)}function d(t){return t===null?n(t):t===45?(e.consume(t),f):q(t)?(o=d,j(t)):(e.consume(t),d)}function f(t){return t===45?(e.consume(t),p):d(t)}function p(e){return e===62?A(e):e===45?f(e):d(e)}function m(t){return t===`CDATA[`.charCodeAt(a++)?(e.consume(t),a===6?h:m):n(t)}function h(t){return t===null?n(t):t===93?(e.consume(t),g):q(t)?(o=h,j(t)):(e.consume(t),h)}function g(t){return t===93?(e.consume(t),_):h(t)}function _(t){return t===62?A(t):t===93?(e.consume(t),_):h(t)}function v(t){return t===null||t===62?A(t):q(t)?(o=v,j(t)):(e.consume(t),v)}function y(t){return t===null?n(t):t===63?(e.consume(t),b):q(t)?(o=y,j(t)):(e.consume(t),y)}function b(e){return e===62?A(e):y(e)}function x(t){return G(t)?(e.consume(t),S):n(t)}function S(t){return t===45||K(t)?(e.consume(t),S):C(t)}function C(t){return q(t)?(o=C,j(t)):Y(t)?(e.consume(t),C):A(t)}function w(t){return t===45||K(t)?(e.consume(t),w):t===47||t===62||J(t)?T(t):n(t)}function T(t){return t===47?(e.consume(t),A):t===58||t===95||G(t)?(e.consume(t),E):q(t)?(o=T,j(t)):Y(t)?(e.consume(t),T):A(t)}function E(t){return t===45||t===46||t===58||t===95||K(t)?(e.consume(t),E):D(t)}function D(t){return t===61?(e.consume(t),O):q(t)?(o=D,j(t)):Y(t)?(e.consume(t),D):T(t)}function O(t){return t===null||t===60||t===61||t===62||t===96?n(t):t===34||t===39?(e.consume(t),i=t,k):q(t)?(o=O,j(t)):Y(t)?(e.consume(t),O):(e.consume(t),ee)}function k(t){return t===i?(e.consume(t),i=void 0,te):t===null?n(t):q(t)?(o=k,j(t)):(e.consume(t),k)}function ee(t){return t===null||t===34||t===39||t===60||t===61||t===96?n(t):t===47||t===62||J(t)?T(t):(e.consume(t),ee)}function te(e){return e===47||e===62||J(e)?T(e):n(e)}function A(r){return r===62?(e.consume(r),e.exit(`htmlTextData`),e.exit(`htmlText`),t):n(r)}function j(t){return e.exit(`htmlTextData`),e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),ne}function ne(t){return Y(t)?X(e,M,`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(t):M(t)}function M(t){return e.enter(`htmlTextData`),o(t)}}var zr={name:`labelEnd`,resolveAll:Ur,resolveTo:Wr,tokenize:Gr},Br={tokenize:Kr},Vr={tokenize:qr},Hr={tokenize:Jr};function Ur(e){let t=-1,n=[];for(;++t0&&i[i.length-1]._balanced;)i.pop();a=i[i.length-1]}return s;function s(t){return a?a._inactive?d(t):(o=r.parser.defined.includes(W(r.sliceSerialize({start:a.end,end:r.now()}))),e.enter(`labelEnd`),e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),e.exit(`labelEnd`),c):n(t)}function c(t){return t===40?e.attempt(Br,u,o?u:d)(t):t===91?e.attempt(Vr,u,o?l:d)(t):o?u(t):d(t)}function l(t){return e.attempt(Hr,u,d)(t)}function u(e){return i.pop(),t(e)}function d(e){return a._balanced=!0,n(e)}}function Kr(e,t,n){return r;function r(t){return e.enter(`resource`),e.enter(`resourceMarker`),e.consume(t),e.exit(`resourceMarker`),i}function i(t){return J(t)?br(e,a)(t):a(t)}function a(t){return t===41?u(t):_r(e,o,s,`resourceDestination`,`resourceDestinationLiteral`,`resourceDestinationLiteralMarker`,`resourceDestinationRaw`,`resourceDestinationString`,32)(t)}function o(t){return J(t)?br(e,c)(t):u(t)}function s(e){return n(e)}function c(t){return t===34||t===39||t===40?yr(e,l,n,`resourceTitle`,`resourceTitleMarker`,`resourceTitleString`)(t):u(t)}function l(t){return J(t)?br(e,u)(t):u(t)}function u(r){return r===41?(e.enter(`resourceMarker`),e.consume(r),e.exit(`resourceMarker`),e.exit(`resource`),t):n(r)}}function qr(e,t,n){let r=this;return i;function i(t){return vr.call(r,e,a,o,`reference`,`referenceMarker`,`referenceString`)(t)}function a(e){return r.parser.defined.includes(W(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)))?t(e):n(e)}function o(e){return n(e)}}function Jr(e,t,n){return r;function r(t){return e.enter(`reference`),e.enter(`referenceMarker`),e.consume(t),e.exit(`referenceMarker`),i}function i(r){return r===93?(e.enter(`referenceMarker`),e.consume(r),e.exit(`referenceMarker`),e.exit(`reference`),t):n(r)}}var Yr={name:`labelStartImage`,resolveAll:zr.resolveAll,tokenize:Xr};function Xr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`labelImage`),e.enter(`labelImageMarker`),e.consume(t),e.exit(`labelImageMarker`),o}function o(t){return t===91?(e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),i=e.exit(`labelImage`),s):n(t)}function s(e){return e===94&&`_hiddenFootnoteSupport`in r.parser.constructs?n(e):(r._labelStarts=r._labelStarts||[],r._labelStarts.push(i),t(e))}}var Zr={name:`labelStartLink`,resolveAll:zr.resolveAll,tokenize:Qr};function Qr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`labelLink`),e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),i=e.exit(`labelLink`),o}function o(e){return e===94&&`_hiddenFootnoteSupport`in r.parser.constructs?n(e):(r._labelStarts=r._labelStarts||[],r._labelStarts.push(i),t(e))}}var $r={name:`lineEnding`,tokenize:ei};function ei(e,t){return n;function n(n){return e.enter(`lineEnding`),e.consume(n),e.exit(`lineEnding`),X(e,t,`linePrefix`)}}var ti={name:`thematicBreak`,tokenize:ni};function ni(e,t,n){let r=0,i;return a;function a(t){return e.enter(`thematicBreak`),o(t)}function o(e){return i=e,s(e)}function s(a){return a===i?(e.enter(`thematicBreakSequence`),c(a)):r>=3&&(a===null||q(a))?(e.exit(`thematicBreak`),t(a)):n(a)}function c(t){return t===i?(e.consume(t),r++,c):(e.exit(`thematicBreakSequence`),Y(t)?X(e,s,`whitespace`)(t):s(t))}}var Z={continuation:{tokenize:oi},exit:ci,name:`list`,tokenize:ai},ri={partial:!0,tokenize:li},ii={partial:!0,tokenize:si};function ai(e,t,n){let r=this,i=r.events[r.events.length-1],a=i&&i[1].type===`linePrefix`?i[2].sliceSerialize(i[1],!0).length:0,o=0;return s;function s(t){let i=r.containerState.type||(t===42||t===43||t===45?`listUnordered`:`listOrdered`);if(i===`listUnordered`?!r.containerState.marker||t===r.containerState.marker:gn(t)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),i===`listUnordered`)return e.enter(`listItemPrefix`),t===42||t===45?e.check(ti,n,l)(t):l(t);if(!r.interrupt||t===49)return e.enter(`listItemPrefix`),e.enter(`listItemValue`),c(t)}return n(t)}function c(t){return gn(t)&&++o<10?(e.consume(t),c):(!r.interrupt||o<2)&&(r.containerState.marker?t===r.containerState.marker:t===41||t===46)?(e.exit(`listItemValue`),l(t)):n(t)}function l(t){return e.enter(`listItemMarker`),e.consume(t),e.exit(`listItemMarker`),r.containerState.marker=r.containerState.marker||t,e.check(Bn,r.interrupt?n:u,e.attempt(ri,f,d))}function u(e){return r.containerState.initialBlankLine=!0,a++,f(e)}function d(t){return Y(t)?(e.enter(`listItemPrefixWhitespace`),e.consume(t),e.exit(`listItemPrefixWhitespace`),f):n(t)}function f(n){return r.containerState.size=a+r.sliceSerialize(e.exit(`listItemPrefix`),!0).length,t(n)}}function oi(e,t,n){let r=this;return r.containerState._closeFlow=void 0,e.check(Bn,i,a);function i(n){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,X(e,t,`listItemIndent`,r.containerState.size+1)(n)}function a(n){return r.containerState.furtherBlankLines||!Y(n)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,o(n)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(ii,t,o)(n))}function o(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,X(e,e.attempt(Z,t,n),`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(i)}}function si(e,t,n){let r=this;return X(e,i,`listItemIndent`,r.containerState.size+1);function i(e){let i=r.events[r.events.length-1];return i&&i[1].type===`listItemIndent`&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?t(e):n(e)}}function ci(e){e.exit(this.containerState.type)}function li(e,t,n){let r=this;return X(e,i,`listItemPrefixWhitespace`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:5);function i(e){let i=r.events[r.events.length-1];return!Y(e)&&i&&i[1].type===`listItemPrefixWhitespace`?t(e):n(e)}}var ui={name:`setextUnderline`,resolveTo:di,tokenize:fi};function di(e,t){let n=new En,r=e.length,i,a,o;for(;r--;)if(e[r][0]===`enter`){if(e[r][1].type===`content`){i=r;break}e[r][1].type===`paragraph`&&(a=r)}else e[r][1].type===`content`&&n.add(r,1,[]),!o&&e[r][1].type===`definition`&&(o=r);let s={type:`setextHeading`,start:{...e[i][1].start},end:{...e[e.length-1][1].end}};return e[a][1].type=`setextHeadingText`,o?(n.add(a,0,[[`enter`,s,t]]),n.add(o+1,0,[[`exit`,e[i][1],t]]),e[i][1].end={...e[o][1].end}):e[i][1]=s,n.add(e.length,0,[[`exit`,s,t]]),n.consume(e),e}function fi(e,t,n){let r=this,i;return a;function a(t){let a=r.events.length,s;for(;a--;)if(r.events[a][1].type!==`lineEnding`&&r.events[a][1].type!==`linePrefix`&&r.events[a][1].type!==`content`){s=r.events[a][1].type===`paragraph`;break}return!r.parser.lazy[r.now().line]&&(r.interrupt||s)?(e.enter(`setextHeadingLine`),i=t,o(t)):n(t)}function o(t){return e.enter(`setextHeadingLineSequence`),s(t)}function s(t){return t===i?(e.consume(t),s):(e.exit(`setextHeadingLineSequence`),Y(t)?X(e,c,`lineSuffix`)(t):c(t))}function c(r){return r===null||q(r)?(e.exit(`setextHeadingLine`),t(r)):n(r)}}var pi={tokenize:mi};function mi(e){let t=this,n=e.attempt(Bn,r,e.attempt(this.parser.constructs.flowInitial,i,X(e,e.attempt(this.parser.constructs.flow,i,e.attempt(fr,i)),`linePrefix`)));return n;function r(r){if(r===null){e.consume(r);return}return e.enter(`lineEndingBlank`),e.consume(r),e.exit(`lineEndingBlank`),t.currentConstruct=void 0,n}function i(r){if(r===null){e.consume(r);return}return e.enter(`lineEnding`),e.consume(r),e.exit(`lineEnding`),t.currentConstruct=void 0,n}}var hi={resolveAll:yi()},gi=vi(`string`),_i=vi(`text`);function vi(e){return{resolveAll:yi(e===`text`?bi:void 0),tokenize:t};function t(t){let n=this,r=this.parser.constructs[e],i=t.attempt(r,a,o);return a;function a(e){return c(e)?i(e):o(e)}function o(e){if(e===null){t.consume(e);return}return t.enter(`data`),t.consume(e),s}function s(e){return c(e)?(t.exit(`data`),i(e)):(t.consume(e),s)}function c(e){if(e===null)return!0;let t=r[e],i=-1;if(t)for(;++iki,contentInitial:()=>Ci,disable:()=>Ai,document:()=>Si,flow:()=>Ti,flowInitial:()=>wi,insideSpan:()=>Oi,string:()=>Ei,text:()=>Di}),Si={42:Z,43:Z,45:Z,48:Z,49:Z,50:Z,51:Z,52:Z,53:Z,54:Z,55:Z,56:Z,57:Z,62:Hn},Ci={91:xr},wi={[-2]:er,[-1]:er,32:er},Ti={35:Dr,42:ti,45:[ui,ti],60:Mr,61:ui,95:ti,96:Qn,126:Qn},Ei={38:Jn,92:Kn},Di={[-5]:$r,[-4]:$r,[-3]:$r,33:Yr,38:Jn,42:Pn,60:[Rn,Lr],91:Zr,92:[Tr,Kn],93:zr,95:Pn,96:ir},Oi={null:[Pn,hi]},ki={null:[42,95]},Ai={null:[]};function ji(e,t,n){let r={_bufferIndex:-1,_index:0,line:n&&n.line||1,column:n&&n.column||1,offset:n&&n.offset||0},i={},a=[],o=[],s=[],c={attempt:C(x),check:C(S),consume:v,enter:y,exit:b,interrupt:C(S,{interrupt:!0})},l={code:null,containerState:{},defineSkip:h,events:[],now:m,parser:e,previous:null,sliceSerialize:f,sliceStream:p,write:d},u=t.tokenize.call(l,c);return t.resolveAll&&a.push(t),l;function d(e){return o=U(o,e),g(),o[o.length-1]===null?(w(t,0),l.events=Nn(a,l.events,l),l.events):[]}function f(e,t){return Ni(p(e),t)}function p(e){return Mi(o,e)}function m(){let{_bufferIndex:e,_index:t,line:n,column:i,offset:a}=r;return{_bufferIndex:e,_index:t,line:n,column:i,offset:a}}function h(e){i[e.line]=e.column,E()}function g(){for(;r._index-1){let e=o[0];typeof e==`string`?o[0]=e.slice(r):o.shift()}a>0&&o.push(e[i].slice(0,a))}return o}function Ni(e,t){let n=-1,r=[],i;for(;++n0){let e=a.tokenStack[a.tokenStack.length-1];(e[1]||qi).call(a,void 0,e[0])}for(r.position={start:Wi(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:Wi(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},d=-1;++dvoid c({to:`/dashboards/$dashboardId`,params:{dashboardId:t},search:a(n),replace:r,resetScroll:t!==e});return(0,o.jsx)(n,{dashboardId:e,search:s,onSearch:(t,n)=>l(e,t,n),onOpen:(e,t)=>l(e,{},t)})}export{s as component}; \ No newline at end of file +import{r as e}from"./useRouter-ByJ6_rwb.js";import{n as t}from"./useNavigate-B1zgPEUp.js";import{t as n}from"./page-BJZPrXpH.js";import{f as r,g as i,y as a}from"./index-B7LmyWZW.js";var o=e();function s(){let{dashboardId:e}=r.useParams(),s=i(r.useSearch()),c=t(),l=(t,n,r)=>void c({to:`/dashboards/$dashboardId`,params:{dashboardId:t},search:a(n),replace:r,resetScroll:t!==e});return(0,o.jsx)(n,{dashboardId:e,search:s,onSearch:(t,n)=>l(e,t,n),onOpen:(e,t)=>l(e,{},t)})}export{s as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/dashboards.index-CSc2aAxM.js b/internal/ui/dist/assets/dashboards.index-CZW2eWRj.js similarity index 68% rename from internal/ui/dist/assets/dashboards.index-CSc2aAxM.js rename to internal/ui/dist/assets/dashboards.index-CZW2eWRj.js index e30b1737..df631076 100644 --- a/internal/ui/dist/assets/dashboards.index-CSc2aAxM.js +++ b/internal/ui/dist/assets/dashboards.index-CZW2eWRj.js @@ -1 +1 @@ -import{r as e}from"./useRouter-ByJ6_rwb.js";import{n as t}from"./useNavigate-B1zgPEUp.js";import{t as n}from"./page-DjMwsK0m.js";import{g as r,p as i,y as a}from"./index-eh4vL-r5.js";var o=e();function s(){let e=r(i.useSearch()),s=t();return(0,o.jsx)(n,{search:e,onSearch:()=>void 0,onOpen:(t,n)=>void s({to:`/dashboards/$dashboardId`,params:{dashboardId:t},search:a(e),replace:n})})}export{s as component}; \ No newline at end of file +import{r as e}from"./useRouter-ByJ6_rwb.js";import{n as t}from"./useNavigate-B1zgPEUp.js";import{t as n}from"./page-BJZPrXpH.js";import{g as r,p as i,y as a}from"./index-B7LmyWZW.js";var o=e();function s(){let e=r(i.useSearch()),s=t();return(0,o.jsx)(n,{search:e,onSearch:()=>void 0,onOpen:(t,n)=>void s({to:`/dashboards/$dashboardId`,params:{dashboardId:t},search:a(e),replace:n})})}export{s as component}; \ No newline at end of file diff --git a/internal/ui/dist/assets/index-eh4vL-r5.js b/internal/ui/dist/assets/index-B7LmyWZW.js similarity index 96% rename from internal/ui/dist/assets/index-eh4vL-r5.js rename to internal/ui/dist/assets/index-B7LmyWZW.js index 8d00ea13..83044fdb 100644 --- a/internal/ui/dist/assets/index-eh4vL-r5.js +++ b/internal/ui/dist/assets/index-B7LmyWZW.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/routes-D2AdaqvY.js","assets/useRouter-ByJ6_rwb.js","assets/useNavigate-B1zgPEUp.js","assets/settings-BolmPCiI.js","assets/brand-DUaZkIz1.js","assets/Tooltip-B3r3s_B9.js","assets/WarningCircle.es-e9h3eY6B.js","assets/chat.index-CVg1vCUR.js","assets/chat-0Bi74QKL.js","assets/preload-helper-DJZNfKNH.js","assets/dashboard-change-chips-DcQEgN0t.js","assets/chat._threadId-CVg1vCUR.js","assets/dashboards.index-CSc2aAxM.js","assets/page-DjMwsK0m.js","assets/dashboards._dashboardId-D2ADrkcC.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/routes-D2AdaqvY.js","assets/useRouter-ByJ6_rwb.js","assets/useNavigate-B1zgPEUp.js","assets/settings-D2EYPvK1.js","assets/brand-DUaZkIz1.js","assets/Tooltip-B3r3s_B9.js","assets/WarningCircle.es-eZ--e_KS.js","assets/chat.index-COFCWU9S.js","assets/chat-BDYP-JLf.js","assets/preload-helper-DJZNfKNH.js","assets/dashboard-change-chips-CghpARdt.js","assets/chat._threadId-COFCWU9S.js","assets/dashboards.index-CZW2eWRj.js","assets/page-BJZPrXpH.js","assets/dashboards._dashboardId-BMU7vUrs.js"])))=>i.map(i=>d[i]); import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./useRouter-ByJ6_rwb.js";import{$ as s,A as c,B as l,C as u,F as d,G as f,H as p,I as m,J as h,K as g,L as _,M as v,N as y,P as b,Q as x,R as S,S as C,T as w,U as T,V as ee,W as E,X as D,Y as O,Z as te,_ as ne,_t as re,a as k,at as ie,b as ae,c as oe,ct as se,d as ce,dt as le,f as ue,gt as de,h as fe,ht as pe,i as me,it as he,j as ge,k as _e,l as ve,lt as ye,m as A,mt as j,nt as be,o as xe,ot as Se,p as Ce,pt as we,q as Te,r as Ee,rt as De,st as Oe,t as ke,tt as Ae,u as je,ut as Me,v as Ne,w as Pe,x as Fe,y as Ie,z as Le}from"./brand-DUaZkIz1.js";import{i as Re,n as ze,r as Be,t as Ve}from"./useNavigate-B1zgPEUp.js";import{_ as He,a as Ue,d as We,f as Ge,g as Ke,h as qe,i as Je,l as Ye,m as Xe,n as Ze,o as Qe,p as $e,r as et,t as tt,u as nt,v as rt}from"./preload-helper-DJZNfKNH.js";import{C as it,E as at,T as ot,_ as st,a as ct,c as lt,d as ut,f as dt,g as ft,h as pt,i as mt,l as ht,m as gt,n as _t,o as vt,p as yt,r as bt,s as xt,t as St,u as Ct,v as wt,x as Tt,y as Et}from"./Tooltip-B3r3s_B9.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var Dt=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&ne(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function ee(){return g?!0:!(e.unstable_now()-Tt&&ee());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ne(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(E)};else if(typeof MessageChannel<`u`){var O=new MessageChannel,te=O.port2;O.port1.onmessage=E,D=function(){te.postMessage(null)}}else D=function(){_(E,0)};function ne(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,ne(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=ee,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),Ot=e(((e,t)=>{t.exports=Dt()})),kt=e((e=>{var n=Ot(),r=t(),i=re();function a(e){var t=`https://react.dev/errors/`+e;if(1Se||(e.current=xe[Se],xe[Se]=null,Se--)}function Te(e,t){Se++,xe[Se]=e.current,e.current=t}var Ee=Ce(null),De=Ce(null),Oe=Ce(null),ke=Ce(null);function Ae(e,t){switch(Te(Oe,t),Te(De,e),Te(Ee,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?xp(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=xp(t),e=Sp(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}we(Ee),Te(Ee,e)}function je(){we(Ee),we(De),we(Oe)}function Me(e){var t=e.memoizedState;t!==null&&(vh._currentValue=t.memoizedState,Te(ke,e)),t=Ee.current;var n=Sp(t,e.type);t!==n&&(Te(De,e),Te(Ee,n))}function Ne(e){De.current===e&&(we(Ee),we(De)),ke.current===e&&(we(ke),vh._currentValue=be)}var Pe,Fe;function Ie(e){if(Pe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Pe=t&&t[1]||``,Fe=-1)`:-1s(e,t,n)},i,a=iE,o=!qT.jitless,s=o&&aE.value,c=t.catchall,l;e._zod.parse=(u,d)=>{l??=n.value;let f=u.value;if(!a(f))return u.issues.push({expected:`object`,code:`invalid_type`,input:f,inst:e}),u;let p=[];if(o&&s&&d?.async===!1&&d.jitless!==!0)i||=r(t.shape),u=i(u,d);else{u.value={};let e=l.shape;for(let t of l.keys){let n=e[t],r=n._zod.run({value:f[t],issues:[]},d),i=n._zod.optin===`optional`&&n._zod.optout===`optional`;r instanceof Promise?p.push(r.then(e=>i?JE(e,u,t,f):qE(e,u,t))):i?JE(r,u,t,f):qE(r,u,t)}}if(!c)return p.length?Promise.all(p).then(()=>u):u;let m=[],h=l.keySet,g=c._zod,_=g.def.type;for(let e of Object.keys(f)){if(h.has(e))continue;if(_===`never`){m.push(e);continue}let t=g.run({value:f[e],issues:[]},d);t instanceof Promise?p.push(t.then(t=>qE(t,u,e))):qE(t,u,e)}return m.length&&u.issues.push({code:`unrecognized_keys`,keys:m,input:f,inst:e}),p.length?Promise.all(p).then(()=>u):u}});function XE(e,t,n,r){for(let n of e)if(n.issues.length===0)return t.value=n.value,t;return t.issues.push({code:`invalid_union`,input:t.value,inst:n,errors:e.map(e=>e.issues.map(e=>xE(e,r,JT())))}),t}var ZE=$(`$ZodUnion`,(e,t)=>{HE.init(e,t),eE(e._zod,`optin`,()=>t.options.some(e=>e._zod.optin===`optional`)?`optional`:void 0),eE(e._zod,`optout`,()=>t.options.some(e=>e._zod.optout===`optional`)?`optional`:void 0),eE(e._zod,`values`,()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),eE(e._zod,`pattern`,()=>{if(t.options.every(e=>e._zod.pattern)){let e=t.options.map(e=>e._zod.pattern);return RegExp(`^(${e.map(e=>$T(e.source)).join(`|`)})$`)}}),e._zod.parse=(n,r)=>{let i=!1,a=[];for(let e of t.options){let t=e._zod.run({value:n.value,issues:[]},r);if(t instanceof Promise)a.push(t),i=!0;else{if(t.issues.length===0)return t;a.push(t)}}return i?Promise.all(a).then(t=>XE(t,n,e,r)):XE(a,n,e,r)}}),QE=$(`$ZodIntersection`,(e,t)=>{HE.init(e,t),e._zod.parse=(e,n)=>{let r=e.value,i=t.left._zod.run({value:r,issues:[]},n),a=t.right._zod.run({value:r,issues:[]},n);return i instanceof Promise||a instanceof Promise?Promise.all([i,a]).then(([t,n])=>eD(e,t,n)):eD(e,i,a)}});function $E(e,t){if(e===t||e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(oE(e)&&oE(t)){let n=Object.keys(t),r=Object.keys(e).filter(e=>n.indexOf(e)!==-1),i={...e,...t};for(let n of r){let r=$E(e[n],t[n]);if(!r.valid)return{valid:!1,mergeErrorPath:[n,...r.mergeErrorPath]};i[n]=r.data}return{valid:!0,data:i}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};let n=[];for(let r=0;r{HE.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!oE(i))return n.issues.push({expected:`record`,code:`invalid_type`,input:i,inst:e}),n;let a=[];if(t.keyType._zod.values){let o=t.keyType._zod.values;n.value={};for(let e of o)if(typeof e==`string`||typeof e==`number`||typeof e==`symbol`){let o=t.valueType._zod.run({value:i[e],issues:[]},r);o instanceof Promise?a.push(o.then(t=>{t.issues.length&&n.issues.push(...yE(e,t.issues)),n.value[e]=t.value})):(o.issues.length&&n.issues.push(...yE(e,o.issues)),n.value[e]=o.value)}let s;for(let e in i)o.has(e)||(s??=[],s.push(e));s&&s.length>0&&n.issues.push({code:`unrecognized_keys`,input:i,inst:e,keys:s})}else{n.value={};for(let o of Reflect.ownKeys(i)){if(o===`__proto__`)continue;let s=t.keyType._zod.run({value:o,issues:[]},r);if(s instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);if(s.issues.length){n.issues.push({origin:`record`,code:`invalid_key`,issues:s.issues.map(e=>xE(e,r,JT())),input:o,path:[o],inst:e}),n.value[s.value]=s.value;continue}let c=t.valueType._zod.run({value:i[o],issues:[]},r);c instanceof Promise?a.push(c.then(e=>{e.issues.length&&n.issues.push(...yE(o,e.issues)),n.value[s.value]=e.value})):(c.issues.length&&n.issues.push(...yE(o,c.issues)),n.value[s.value]=c.value)}}return a.length?Promise.all(a).then(()=>n):n}}),nD=$(`$ZodEnum`,(e,t)=>{HE.init(e,t);let n=YT(t.entries);e._zod.values=new Set(n),e._zod.pattern=RegExp(`^(${n.filter(e=>sE.has(typeof e)).map(e=>typeof e==`string`?cE(e):e.toString()).join(`|`)})$`),e._zod.parse=(t,r)=>{let i=t.value;return e._zod.values.has(i)||t.issues.push({code:`invalid_value`,values:n,input:i,inst:e}),t}}),rD=$(`$ZodLiteral`,(e,t)=>{HE.init(e,t),e._zod.values=new Set(t.values),e._zod.pattern=RegExp(`^(${t.values.map(e=>typeof e==`string`?cE(e):e?e.toString():String(e)).join(`|`)})$`),e._zod.parse=(n,r)=>{let i=n.value;return e._zod.values.has(i)||n.issues.push({code:`invalid_value`,values:t.values,input:i,inst:e}),n}}),iD=$(`$ZodTransform`,(e,t)=>{HE.init(e,t),e._zod.parse=(e,n)=>{let r=t.transform(e.value,e);if(n.async)return(r instanceof Promise?r:Promise.resolve(r)).then(t=>(e.value=t,e));if(r instanceof Promise)throw new KT;return e.value=r,e}}),aD=$(`$ZodOptional`,(e,t)=>{HE.init(e,t),e._zod.optin=`optional`,e._zod.optout=`optional`,eE(e._zod,`values`,()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),eE(e._zod,`pattern`,()=>{let e=t.innerType._zod.pattern;return e?RegExp(`^(${$T(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>t.innerType._zod.optin===`optional`?t.innerType._zod.run(e,n):e.value===void 0?e:t.innerType._zod.run(e,n)}),oD=$(`$ZodNullable`,(e,t)=>{HE.init(e,t),eE(e._zod,`optin`,()=>t.innerType._zod.optin),eE(e._zod,`optout`,()=>t.innerType._zod.optout),eE(e._zod,`pattern`,()=>{let e=t.innerType._zod.pattern;return e?RegExp(`^(${$T(e.source)}|null)$`):void 0}),eE(e._zod,`values`,()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(e,n)=>e.value===null?e:t.innerType._zod.run(e,n)}),sD=$(`$ZodDefault`,(e,t)=>{HE.init(e,t),e._zod.optin=`optional`,eE(e._zod,`values`,()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{if(e.value===void 0)return e.value=t.defaultValue,e;let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(e=>cD(e,t)):cD(r,t)}});function cD(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}var lD=$(`$ZodPrefault`,(e,t)=>{HE.init(e,t),e._zod.optin=`optional`,eE(e._zod,`values`,()=>t.innerType._zod.values),e._zod.parse=(e,n)=>(e.value===void 0&&(e.value=t.defaultValue),t.innerType._zod.run(e,n))}),uD=$(`$ZodNonOptional`,(e,t)=>{HE.init(e,t),eE(e._zod,`values`,()=>{let e=t.innerType._zod.values;return e?new Set([...e].filter(e=>e!==void 0)):void 0}),e._zod.parse=(n,r)=>{let i=t.innerType._zod.run(n,r);return i instanceof Promise?i.then(t=>dD(t,e)):dD(i,e)}});function dD(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:`invalid_type`,expected:`nonoptional`,input:e.value,inst:t}),e}var fD=$(`$ZodCatch`,(e,t)=>{HE.init(e,t),e._zod.optin=`optional`,eE(e._zod,`optout`,()=>t.innerType._zod.optout),eE(e._zod,`values`,()=>t.innerType._zod.values),e._zod.parse=(e,n)=>{let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(r=>(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xE(e,n,JT()))},input:e.value}),e.issues=[]),e)):(e.value=r.value,r.issues.length&&(e.value=t.catchValue({...e,error:{issues:r.issues.map(e=>xE(e,n,JT()))},input:e.value}),e.issues=[]),e)}}),pD=$(`$ZodPipe`,(e,t)=>{HE.init(e,t),eE(e._zod,`values`,()=>t.in._zod.values),eE(e._zod,`optin`,()=>t.in._zod.optin),eE(e._zod,`optout`,()=>t.out._zod.optout),e._zod.parse=(e,n)=>{let r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>mD(e,t,n)):mD(r,t,n)}});function mD(e,t,n){return vE(e)?e:t.out._zod.run({value:e.value,issues:e.issues},n)}var hD=$(`$ZodReadonly`,(e,t)=>{HE.init(e,t),eE(e._zod,`propValues`,()=>t.innerType._zod.propValues),eE(e._zod,`values`,()=>t.innerType._zod.values),eE(e._zod,`optin`,()=>t.innerType._zod.optin),eE(e._zod,`optout`,()=>t.innerType._zod.optout),e._zod.parse=(e,n)=>{let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(gD):gD(r)}});function gD(e){return e.value=Object.freeze(e.value),e}var _D=$(`$ZodLazy`,(e,t)=>{HE.init(e,t),eE(e._zod,`innerType`,()=>t.getter()),eE(e._zod,`pattern`,()=>e._zod.innerType._zod.pattern),eE(e._zod,`propValues`,()=>e._zod.innerType._zod.propValues),eE(e._zod,`optin`,()=>e._zod.innerType._zod.optin),eE(e._zod,`optout`,()=>e._zod.innerType._zod.optout),e._zod.parse=(t,n)=>e._zod.innerType._zod.run(t,n)}),vD=$(`$ZodCustom`,(e,t)=>{FE.init(e,t),HE.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=n=>{let r=n.value,i=t.fn(r);if(i instanceof Promise)return i.then(t=>yD(t,n,r,e));yD(i,n,r,e)}});function yD(e,t,n,r){if(!e){let e={code:`custom`,input:n,inst:r,path:[...r._zod.def.path??[]],continue:!r._zod.def.abort};r._zod.def.params&&(e.params=r._zod.def.params),t.issues.push(CE(e))}}var bD=class{constructor(){this._map=new Map,this._idmap=new Map}add(e,...t){let n=t[0];if(this._map.set(e,n),n&&typeof n==`object`&&`id`in n){if(this._idmap.has(n.id))throw Error(`ID ${n.id} already exists in the registry`);this._idmap.set(n.id,e)}return this}clear(){return this._map=new Map,this._idmap=new Map,this}remove(e){let t=this._map.get(e);return t&&typeof t==`object`&&`id`in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){let t=e._zod.parent;if(t){let n={...this.get(t)??{}};return delete n.id,{...n,...this._map.get(e)}}return this._map.get(e)}has(e){return this._map.has(e)}};function xD(){return new bD}var SD=xD();function CD(e){return new e({type:`unknown`})}function wD(e,t){return new e({type:`never`,...uE(t)})}function TD(e,t){return new IE({check:`max_length`,...uE(t),maximum:e})}function ED(e,t){return new LE({check:`min_length`,...uE(t),minimum:e})}function DD(e,t){return new RE({check:`length_equals`,...uE(t),length:e})}function OD(e){return new zE({check:`overwrite`,tx:e})}function kD(e,t,n){return new e({type:`array`,element:t,...uE(n)})}function AD(e,t,n){return new e({type:`custom`,check:`custom`,fn:t,...uE(n)})}var jD=(e,t)=>{TE.init(e,t),e.name=`ZodError`,Object.defineProperties(e,{format:{value:t=>OE(e,t)},flatten:{value:t=>DE(e,t)},addIssue:{value:t=>e.issues.push(t)},addIssues:{value:t=>e.issues.push(...t)},isEmpty:{get(){return e.issues.length===0}}})};$(`ZodError`,jD);var MD=$(`ZodError`,jD,{Parent:Error}),ND=kE(MD),PD=AE(MD),FD=jE(MD),ID=NE(MD),LD=$(`ZodType`,(e,t)=>(HE.init(e,t),e.def=t,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone({...t,checks:[...t.checks??[],...n.map(e=>typeof e==`function`?{_zod:{check:e,def:{check:`custom`},onattach:[]}}:e)]}),e.clone=(t,n)=>lE(e,t,n),e.brand=()=>e,e.register=((t,n)=>(t.add(e,n),e)),e.parse=(t,n)=>ND(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>FD(e,t,n),e.parseAsync=async(t,n)=>PD(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>ID(e,t,n),e.spa=e.safeParseAsync,e.refine=(t,n)=>e.check(bO(t,n)),e.superRefine=t=>e.check(xO(t)),e.overwrite=t=>e.check(OD(t)),e.optional=()=>nO(e),e.nullable=()=>iO(e),e.nullish=()=>nO(iO(e)),e.nonoptional=t=>uO(e,t),e.array=()=>UD(e),e.or=t=>KD([e,t]),e.and=t=>JD(e,t),e.transform=t=>mO(e,eO(t)),e.default=t=>oO(e,t),e.prefault=t=>cO(e,t),e.catch=t=>fO(e,t),e.pipe=t=>mO(e,t),e.readonly=()=>gO(e),e.describe=t=>{let n=e.clone();return SD.add(n,{description:t}),n},Object.defineProperty(e,"description",{get(){return SD.get(e)?.description},configurable:!0}),e.meta=(...t)=>{if(t.length===0)return SD.get(e);let n=e.clone();return SD.add(n,t[0]),n},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e)),RD=$(`ZodUnknown`,(e,t)=>{UE.init(e,t),LD.init(e,t)});function zD(){return CD(RD)}var BD=$(`ZodNever`,(e,t)=>{WE.init(e,t),LD.init(e,t)});function VD(e){return wD(BD,e)}var HD=$(`ZodArray`,(e,t)=>{KE.init(e,t),LD.init(e,t),e.element=t.element,e.min=(t,n)=>e.check(ED(t,n)),e.nonempty=t=>e.check(ED(1,t)),e.max=(t,n)=>e.check(TD(t,n)),e.length=(t,n)=>e.check(DD(t,n)),e.unwrap=()=>e.element});function UD(e,t){return kD(HD,e,t)}var WD=$(`ZodObject`,(e,t)=>{YE.init(e,t),LD.init(e,t),eE(e,`shape`,()=>t.shape),e.keyof=()=>ZD(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:zD()}),e.loose=()=>e.clone({...e._zod.def,catchall:zD()}),e.strict=()=>e.clone({...e._zod.def,catchall:VD()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>mE(e,t),e.merge=t=>hE(e,t),e.pick=t=>fE(e,t),e.omit=t=>pE(e,t),e.partial=(...t)=>gE(tO,e,t[0]),e.required=(...t)=>_E(lO,e,t[0])}),GD=$(`ZodUnion`,(e,t)=>{ZE.init(e,t),LD.init(e,t),e.options=t.options});function KD(e,t){return new GD({type:`union`,options:e,...uE(t)})}var qD=$(`ZodIntersection`,(e,t)=>{QE.init(e,t),LD.init(e,t)});function JD(e,t){return new qD({type:`intersection`,left:e,right:t})}var YD=$(`ZodRecord`,(e,t)=>{tD.init(e,t),LD.init(e,t),e.keyType=t.keyType,e.valueType=t.valueType}),XD=$(`ZodEnum`,(e,t)=>{nD.init(e,t),LD.init(e,t),e.enum=t.entries,e.options=Object.values(t.entries);let n=new Set(Object.keys(t.entries));e.extract=(e,r)=>{let i={};for(let r of e)if(n.has(r))i[r]=t.entries[r];else throw Error(`Key ${r} not found in enum`);return new XD({...t,checks:[],...uE(r),entries:i})},e.exclude=(e,r)=>{let i={...t.entries};for(let t of e)if(n.has(t))delete i[t];else throw Error(`Key ${t} not found in enum`);return new XD({...t,checks:[],...uE(r),entries:i})}});function ZD(e,t){return new XD({type:`enum`,entries:Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e,...uE(t)})}var QD=$(`ZodLiteral`,(e,t)=>{rD.init(e,t),LD.init(e,t),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})}),$D=$(`ZodTransform`,(e,t)=>{iD.init(e,t),LD.init(e,t),e._zod.parse=(n,r)=>{n.addIssue=r=>{if(typeof r==`string`)n.issues.push(CE(r,n.value,t));else{let t=r;t.fatal&&(t.continue=!1),t.code??=`custom`,t.input??=n.value,t.inst??=e,t.continue??=!0,n.issues.push(CE(t))}};let i=t.transform(n.value,n);return i instanceof Promise?i.then(e=>(n.value=e,n)):(n.value=i,n)}});function eO(e){return new $D({type:`transform`,transform:e})}var tO=$(`ZodOptional`,(e,t)=>{aD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType});function nO(e){return new tO({type:`optional`,innerType:e})}var rO=$(`ZodNullable`,(e,t)=>{oD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType});function iO(e){return new rO({type:`nullable`,innerType:e})}var aO=$(`ZodDefault`,(e,t)=>{sD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function oO(e,t){return new aO({type:`default`,innerType:e,get defaultValue(){return typeof t==`function`?t():t}})}var sO=$(`ZodPrefault`,(e,t)=>{lD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType});function cO(e,t){return new sO({type:`prefault`,innerType:e,get defaultValue(){return typeof t==`function`?t():t}})}var lO=$(`ZodNonOptional`,(e,t)=>{uD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType});function uO(e,t){return new lO({type:`nonoptional`,innerType:e,...uE(t)})}var dO=$(`ZodCatch`,(e,t)=>{fD.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function fO(e,t){return new dO({type:`catch`,innerType:e,catchValue:typeof t==`function`?t:()=>t})}var pO=$(`ZodPipe`,(e,t)=>{pD.init(e,t),LD.init(e,t),e.in=t.in,e.out=t.out});function mO(e,t){return new pO({type:`pipe`,in:e,out:t})}var hO=$(`ZodReadonly`,(e,t)=>{hD.init(e,t),LD.init(e,t)});function gO(e){return new hO({type:`readonly`,innerType:e})}var _O=$(`ZodLazy`,(e,t)=>{_D.init(e,t),LD.init(e,t),e.unwrap=()=>e._zod.def.getter()}),vO=$(`ZodCustom`,(e,t)=>{vD.init(e,t),LD.init(e,t)});function yO(e){let t=new FE({check:`custom`});return t._zod.check=e,t}function bO(e,t={}){return AD(vO,e,t)}function xO(e){let t=yO(n=>(n.addIssue=e=>{if(typeof e==`string`)n.issues.push(CE(e,n.value,t._zod.def));else{let r=e;r.fatal&&(r.continue=!1),r.code??=`custom`,r.input??=n.value,r.inst??=t,r.continue??=!t._zod.def.abort,n.issues.push(CE(r))}},e(n.value,n)));return t}var SO=`@ag-ui/client`;function CO(e){if(!e.metadata||!Object.prototype.hasOwnProperty.call(e.metadata,SO))return;let t=e.metadata?.[SO];if(!t||typeof t!=`object`||Array.isArray(t))return[];if(!Object.prototype.hasOwnProperty.call(t,`authoritativeActivityTypes`))return;let n=t.authoritativeActivityTypes;return n===null?null:Array.isArray(n)&&n.every(e=>typeof e==`string`)?n:[]}var wO=e=>{if(typeof structuredClone==`function`)return structuredClone(e);try{return JSON.parse(JSON.stringify(e))}catch{return Array.isArray(e)?[...e]:{...e}}};function TO(){return Gc()}function EO(e){return e instanceof TypeError&&/read[- ]?only|not extensible|cannot add property|cannot delete property|can't be deleted|unable to delete property|object is frozen|is not writable/i.test(e.message)}function DO(e){if(Object.freeze(e),typeof e==`object`&&e)for(let t of Object.values(e))typeof t==`object`&&t&&!Object.isFrozen(t)&&DO(t);return e}var OO=524288;function kO(e,t,n){let r=0,i=[e,t],a=new WeakSet;for(;i.length>0;){let e=i.pop();if(typeof e==`string`){if(r+=e.length,r>n)return!0}else if(typeof e==`object`&&e){if(a.has(e))continue;if(a.add(e),Array.isArray(e))for(let t=0;tn)return!0;i.push(e[o])}}}}return!1}async function AO(e,t,n,r){let i=typeof process<`u`&&!0,a=i&&!!{}.VITEST_WORKER_ID,o=i&&!!{}.VITEST_WORKER_ID,s=o&&!kO(t,n,OO),c=s?wO(t):t,l=s?wO(n):n,u=!1,d=!1,f;for(let t of e)try{s&&(DO(c),DO(l));let e=await r(t,c,l);if(e===void 0)continue;let n=!1;if(e.messages!==void 0&&e.messages!==c&&(c=wO(e.messages),u=!0,n=!0),e.state!==void 0&&e.state!==l&&(l=wO(e.state),d=!0,n=!0),s&&n&&kO(c,l,OO)&&(s=!1),f=e.stopPropagation,f===!0)break}catch(e){if(a&&e instanceof TypeError)throw e;s&&o&&EO(e)?console.error(`AG-UI: Subscriber attempted to mutate frozen inputs in-place. Return mutations via AgentStateMutation instead of mutating directly.`,e):console.error(`Subscriber error:`,e);continue}return{...u?{messages:Object.isFrozen(c)?wO(c):c}:{},...d?{state:Object.isFrozen(l)?wO(l):l}:{},...f===void 0?{}:{stopPropagation:f}}}function jO(e){if(!e)return{enabled:!1,events:!1,lifecycle:!1,verbose:!1};if(e===!0)return{enabled:!0,events:!0,lifecycle:!0,verbose:!0};let t=e.events??!0,n=e.lifecycle??!0,r=e.verbose??!1;return{enabled:t||n,events:t,lifecycle:n,verbose:r}}function MO(e){if(e instanceof NO)return e;if(e===!0)return new NO(jO(!0))}var NO=class{constructor(e){this.config=e}event(e,t,n,r){this.config.events&&(this.config.verbose?console.debug(`[${e}] ${t}`,typeof n==`string`?n:JSON.stringify(n)):console.debug(`[${e}] ${t}`,r??n))}lifecycle(e,t,n){this.config.lifecycle&&(n?console.debug(`[${e}] ${t}`,n):console.debug(`[${e}] ${t}`))}get eventsEnabled(){return this.config.events}get lifecycleEnabled(){return this.config.lifecycle}get enabled(){return this.config.enabled}};function PO(e){return e.enabled?new NO(e):void 0}function FO(e,t,n){if(t){let r=e.find(e=>e.id===t);if(r?.role===`assistant`)return r;r&&console.warn(`TOOL_CALL_START: parentMessageId '${t}' matches a '${r.role}' message, not assistant — falling back to toolCallId`);let i={id:r?n:t,role:`assistant`,toolCalls:[]};return e.push(i),i}let r={id:n,role:`assistant`,toolCalls:[]};return e.push(r),r}function IO(e,t){return!e||t.metadata===void 0?!1:(e.metadata=Zc(e.metadata,wO(t.metadata)),!0)}var LO=(e,t,n,r,i)=>{let a=MO(i),o=wO(n.messages),s=wO(e.state),c={},l=[],u=new Set,d=e=>{let t=e.outcome?.type===`success`?e.outcome.pendingToolCallIds:void 0;return t!==void 0&&t.length>0?[...t]:l.filter(e=>!u.has(e))},f=e=>{e.messages!==void 0&&(o=e.messages,c.messages=e.messages),e.state!==void 0&&(s=e.state,c.state=e.state)},p=()=>{let e=wO(c);return c={},e.messages!==void 0||e.state!==void 0?gd(e):Lu};return t.pipe(Dd(async t=>{let i=await AO(r,o,s,(r,i,a)=>r.onEvent?.({event:t,agent:n,input:e,messages:i,state:a}));if(f(i),i.stopPropagation===!0?a?.event(`APPLY`,`Event dropped:`,t,{type:t.type,reason:`stopPropagation by subscriber`}):a?.event(`APPLY`,`Event applied:`,t,{type:t.type,subscribers:r.length}),i.stopPropagation===!0)return p();switch(t.type){case L.TEXT_MESSAGE_START:{let i=await AO(r,o,s,(r,i,a)=>r.onTextMessageStartEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{messageId:e,role:n=`assistant`,name:r,subagentRunId:i}=t,a=o.find(t=>t.id===e);if(a?.role===`activity`)return console.warn(`TEXT_MESSAGE_START: Message '${e}' is an activity message — message ids must be unique across activity and text messages`),p();let s=a;if(!s){let t={id:e,role:n,content:``,...r!==void 0&&{name:r},...i!=null&&{subagentRunId:i}};o.push(t),s=t}let c=IO(s,t);(!a||c)&&f({messages:o})}return p()}case L.TEXT_MESSAGE_CONTENT:{let{messageId:i,delta:a}=t,c=o.find(e=>e.id===i);if(!c)return console.warn(`TEXT_MESSAGE_CONTENT: No message found with ID '${i}'`),p();if(c.role===`activity`)return console.warn(`TEXT_MESSAGE_CONTENT: Message '${i}' is an activity message — message ids must be unique across activity and text messages`),p();let l=await AO(r,o,s,(r,i,a)=>r.onTextMessageContentEvent?.({event:t,messages:i,state:a,agent:n,input:e,textMessageBuffer:typeof c.content==`string`?c.content:``}));return f(l),l.stopPropagation!==!0&&(c.content=`${typeof c.content==`string`?c.content:``}${a}`,IO(c,t),f({messages:o})),p()}case L.TEXT_MESSAGE_END:{let{messageId:i}=t,a=o.find(e=>e.id===i);if(!a)return console.warn(`TEXT_MESSAGE_END: No message found with ID '${i}'`),p();if(a.role===`activity`)return console.warn(`TEXT_MESSAGE_END: Message '${i}' is an activity message — message ids must be unique across activity and text messages`),p();let c=await AO(r,o,s,(r,i,o)=>r.onTextMessageEndEvent?.({event:t,messages:i,state:o,agent:n,input:e,textMessageBuffer:typeof a.content==`string`?a.content:``}));return f(c),c.stopPropagation!==!0&&IO(a,t)&&f({messages:o}),await Promise.all(r.map(t=>{t.onNewMessage?.({message:a,messages:o,state:s,agent:n,input:e})})),p()}case L.TOOL_CALL_START:{let i=await AO(r,o,s,(r,i,a)=>r.onToolCallStartEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{toolCallId:e,toolCallName:n,parentMessageId:r,subagentRunId:i}=t;l.includes(e)||l.push(e);let a=o.find(t=>t.toolCalls?.some(t=>t.id===e))?.toolCalls?.find(t=>t.id===e);if(a){let r=a.function.name!==n;return r&&(console.warn(`TOOL_CALL_START: tool call '${e}' already exists with name '${a.function.name}' — updating it to '${n}'`),a.function.name=n),(IO(a,t)||r)&&f({messages:o}),p()}let s=new Set(o.map(e=>e.id)),c=FO(o,r,e);!s.has(c.id)&&i!=null&&c.subagentRunId===void 0&&(c.subagentRunId=i),c.toolCalls??=[];let u={id:e,type:`function`,function:{name:n,arguments:``}};c.toolCalls.push(u),IO(u,t),f({messages:o})}return p()}case L.TOOL_CALL_ARGS:{let{toolCallId:i,delta:a}=t,c=o.find(e=>e.toolCalls?.some(e=>e.id===i));if(!c)return console.warn(`TOOL_CALL_ARGS: No message found containing tool call with ID '${i}'`),p();let l=c.toolCalls?.find(e=>e.id===i);if(!l)return console.warn(`TOOL_CALL_ARGS: No tool call found with ID '${i}'`),p();let u=await AO(r,o,s,(r,i,a)=>{let o=l.function.arguments,s=l.function.name,c={};try{c=Id(o)}catch{}return r.onToolCallArgsEvent?.({event:t,messages:i,state:a,agent:n,input:e,toolCallBuffer:o,toolCallName:s,partialToolCallArgs:c})});return f(u),u.stopPropagation!==!0&&(l.function.arguments+=a,IO(l,t),f({messages:o})),p()}case L.TOOL_CALL_END:{let{toolCallId:i}=t,a=o.find(e=>e.toolCalls?.some(e=>e.id===i));if(!a)return console.warn(`TOOL_CALL_END: No message found containing tool call with ID '${i}'`),p();let c=a.toolCalls?.find(e=>e.id===i);if(!c)return console.warn(`TOOL_CALL_END: No tool call found with ID '${i}'`),p();let l=await AO(r,o,s,(r,i,a)=>{let o=c.function.arguments,s=c.function.name,l={};try{l=JSON.parse(o)}catch{}return r.onToolCallEndEvent?.({event:t,messages:i,state:a,agent:n,input:e,toolCallName:s,toolCallArgs:l})});return f(l),l.stopPropagation!==!0&&IO(c,t)&&f({messages:o}),await Promise.all(r.map(t=>{t.onNewToolCall?.({toolCall:c,messages:o,state:s,agent:n,input:e})})),p()}case L.TOOL_CALL_RESULT:{let i=await AO(r,o,s,(r,i,a)=>r.onToolCallResultEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{messageId:i,toolCallId:a,content:c,role:l,subagentRunId:d}=t;u.add(a);let p={id:i,toolCallId:a,role:l||`tool`,content:c,...d!=null&&{subagentRunId:d}};IO(p,t);let m=o.findIndex(e=>e.role===`assistant`&&e.toolCalls?.some(e=>e.id===a));if(m===-1)o.push(p);else{let e=m+1;for(;e{t.onNewMessage?.({message:p,messages:o,state:s,agent:n,input:e})})),f({messages:o})}return p()}case L.STATE_SNAPSHOT:{let i=await AO(r,o,s,(r,i,a)=>r.onStateSnapshotEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{snapshot:e}=t;s=e,f({state:s})}return p()}case L.STATE_DELTA:{let i=await AO(r,o,s,(r,i,a)=>r.onStateDeltaEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{delta:e}=t;try{s=Fl.applyPatch(s,e,!0,!1).newDocument,f({state:s})}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Failed to apply state patch:\nCurrent state: ${JSON.stringify(s,null,2)}\nPatch operations: ${JSON.stringify(e,null,2)}\nError: ${n}`)}}return p()}case L.MESSAGES_SNAPSHOT:{let i=await AO(r,o,s,(r,i,a)=>r.onMessagesSnapshotEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{messages:e}=t,n=e.map(e=>{if(e.subagentRunId!==null)return e;let t={...e};return delete t.subagentRunId,t}),r=new Map(n.map(e=>[e.id,e])),i=CO(t),a=n.some(e=>e.role===`activity`),s=n.some(e=>e.role===`reasoning`),c=e=>e.role===`activity`&&(i?!i.includes(e.activityType):i!==null&&!a)||e.role===`reasoning`&&!s;o=o.filter(e=>r.has(e.id)||c(e)).map(e=>r.get(e.id)??e);let l=new Set(o.map(e=>e.id));for(let e of n)l.has(e.id)||o.push(e);f({messages:o})}return p()}case L.ACTIVITY_SNAPSHOT:{let i=t,a=o.findIndex(e=>e.id===i.messageId),c=a>=0?o[a]:void 0,l=c?.role===`activity`?c:void 0,u=i.replace??!0,d=await AO(r,o,s,(t,r,a)=>t.onActivitySnapshotEvent?.({event:i,messages:r,state:a,agent:n,input:e,activityMessage:l,existingMessage:c}));if(f(d),d.stopPropagation!==!0){let t={id:i.messageId,role:`activity`,activityType:i.activityType,content:wO(i.content),...i.subagentRunId!=null&&{subagentRunId:i.subagentRunId}},c,d;a===-1?(o.push(t),c=t,d=t):l?(u&&(o[a]={...l,activityType:i.activityType,content:wO(i.content),subagentRunId:i.subagentRunId},i.subagentRunId??delete o[a].subagentRunId),d=o[a]):u&&(o[a]=t,c=t,d=t),IO(d,i),f({messages:o}),c&&await Promise.all(r.map(t=>t.onNewMessage?.({message:c,messages:o,state:s,agent:n,input:e})))}return p()}case L.ACTIVITY_DELTA:{let i=t,a=o.findIndex(e=>e.id===i.messageId);if(a===-1)return p();let c=o[a];if(c.role!==`activity`)return console.warn(`ACTIVITY_DELTA: Message '${i.messageId}' is not an activity message`),p();let l=c,u=await AO(r,o,s,(t,r,a)=>t.onActivityDeltaEvent?.({event:i,messages:r,state:a,agent:n,input:e,activityMessage:l}));if(f(u),u.stopPropagation!==!0)try{IO(l,i)&&f({messages:o});let e=wO(l.content??{}),t=Fl.applyPatch(e,i.patch??[],!0,!1).newDocument;o[a]={...l,content:wO(t),activityType:i.activityType},f({messages:o})}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`Failed to apply activity patch for '${i.messageId}': ${t}`)}return p()}case L.RAW:return f(await AO(r,o,s,(r,i,a)=>r.onRawEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.CUSTOM:return f(await AO(r,o,s,(r,i,a)=>r.onCustomEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.RUN_STARTED:{let i=await AO(r,o,s,(r,i,a)=>r.onRunStartedEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),l=[],u=new Set,i.stopPropagation!==!0){let e=t;if(e.input?.messages){for(let t of e.input.messages){let e=t;if(t.subagentRunId===null){let n={...t};delete n.subagentRunId,e=n}o.find(t=>t.id===e.id)||o.push(e)}f({messages:o})}}return p()}case L.RUN_FINISHED:{let i=t,a=i.outcome?.type===`interrupt`?{event:i,outcome:`interrupt`,interrupts:i.outcome.interrupts}:i.outcome?.type===`cancelled`?{event:i,outcome:`cancelled`}:{event:i,outcome:`success`,result:i.result,pendingToolCallIds:d(i)},c=await AO(r,o,s,(t,r,i)=>t.onRunFinishedEvent?.({...a,messages:r,state:i,agent:n,input:e}));return f(c),c.stopPropagation!==!0&&(n.pendingInterrupts=a.outcome===`interrupt`?a.interrupts.map(e=>{if(e.subagentRunId!==null)return e;let t={...e};return delete t.subagentRunId,t}):[]),p()}case L.RUN_ERROR:return f(await AO(r,o,s,(r,i,a)=>r.onRunErrorEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.STEP_STARTED:return f(await AO(r,o,s,(r,i,a)=>r.onStepStartedEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.STEP_FINISHED:return f(await AO(r,o,s,(r,i,a)=>r.onStepFinishedEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.TEXT_MESSAGE_CHUNK:throw Error(`TEXT_MESSAGE_CHUNK must be transformed before being applied`);case L.TOOL_CALL_CHUNK:throw Error(`TOOL_CALL_CHUNK must be transformed before being applied`);case L.REASONING_START:return f(await AO(r,o,s,(r,i,a)=>r.onReasoningStartEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.REASONING_MESSAGE_START:{let i=await AO(r,o,s,(r,i,a)=>r.onReasoningMessageStartEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(i),i.stopPropagation!==!0){let{messageId:e,subagentRunId:n}=t,r=o.find(t=>t.id===e);if(r?.role===`activity`)return console.warn(`REASONING_MESSAGE_START: Message '${e}' is an activity message — message ids must be unique across activity and reasoning messages`),p();let i=r;if(!i){let t={id:e,role:`reasoning`,content:``,...n!=null&&{subagentRunId:n}};o.push(t),i=t}let a=IO(i,t);(!r||a)&&f({messages:o})}return p()}case L.REASONING_MESSAGE_CONTENT:{let{messageId:i,delta:a}=t,c=o.find(e=>e.id===i);if(!c)return console.warn(`REASONING_MESSAGE_CONTENT: No message found with ID '${i}'`),p();if(c.role===`activity`)return console.warn(`REASONING_MESSAGE_CONTENT: Message '${i}' is an activity message — message ids must be unique across activity and reasoning messages`),p();let l=await AO(r,o,s,(r,i,a)=>r.onReasoningMessageContentEvent?.({event:t,messages:i,state:a,agent:n,input:e,reasoningMessageBuffer:typeof c.content==`string`?c.content:``}));return f(l),l.stopPropagation!==!0&&(c.content=`${typeof c.content==`string`?c.content:``}${a}`,IO(c,t),f({messages:o})),p()}case L.REASONING_MESSAGE_END:{let{messageId:i}=t,a=o.find(e=>e.id===i);if(!a)return console.warn(`REASONING_MESSAGE_END: No message found with ID '${i}'`),p();if(a.role===`activity`)return console.warn(`REASONING_MESSAGE_END: Message '${i}' is an activity message — message ids must be unique across activity and reasoning messages`),p();let c=await AO(r,o,s,(r,i,o)=>r.onReasoningMessageEndEvent?.({event:t,messages:i,state:o,agent:n,input:e,reasoningMessageBuffer:typeof a.content==`string`?a.content:``}));return f(c),c.stopPropagation!==!0&&IO(a,t)&&f({messages:o}),await Promise.all(r.map(t=>{t.onNewMessage?.({message:a,messages:o,state:s,agent:n,input:e})})),p()}case L.REASONING_MESSAGE_CHUNK:throw Error(`REASONING_MESSAGE_CHUNK must be transformed before being applied`);case L.REASONING_END:return f(await AO(r,o,s,(r,i,a)=>r.onReasoningEndEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.REASONING_ENCRYPTED_VALUE:{let{subtype:i,entityId:a,encryptedValue:l}=t,u=await AO(r,o,s,(r,i,a)=>r.onReasoningEncryptedValueEvent?.({event:t,messages:i,state:a,agent:n,input:e}));if(f(u),u.stopPropagation!==!0){let e=!1;if(i===`tool-call`){for(let t of o)if(t.role===`assistant`&&t.toolCalls){let n=t.toolCalls.find(e=>e.id===a);if(n){n.encryptedValue=l,e=!0;break}}}else{let t=o.find(e=>e.id===a);t?.role!==`activity`&&t&&(t.encryptedValue=l,e=!0)}e&&(c.messages=o)}return p()}case L.SUBAGENT_STARTED:return f(await AO(r,o,s,(r,i,a)=>r.onSubagentStartedEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.SUBAGENT_FINISHED:return f(await AO(r,o,s,(r,i,a)=>r.onSubagentFinishedEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p();case L.SUBAGENT_ERROR:return f(await AO(r,o,s,(r,i,a)=>r.onSubagentErrorEvent?.({event:t,messages:i,state:a,agent:n,input:e}))),p()}return t.type,p()}),Sd(),r.length>0?Ad({}):e=>e)};function RO(e,t){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`[ag-ui][compat] Converting deprecated ${e} to ${t}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`)}var zO=e=>t=>{let n=MO(e),r=new Set,i=new Set,a=new Set,o=new Set,s={message:new Map,toolCall:new Map,activity:new Map,reasoning:new Map},c=!1,l=!1,u=!1,d=new Map,f=e=>{let t=d.get(e);return t||(t=new Map,d.set(e,t)),t},p=()=>{for(let e of d.values())if(e.size>0)return!0;return!1},m=new Map,h=new Set,g=!1,_=!1,v=()=>{_=!1,r.clear(),i.clear(),a.clear(),o.clear(),s.message.clear(),s.toolCall.clear(),s.activity.clear(),s.reasoning.clear(),d.clear(),m.clear(),h.clear(),c=!1,l=!1,g=!0},y=(e,t)=>{let n=e??[];if(Array.isArray(n))for(let e of n){if(!e||typeof e.id!=`string`)continue;if(e.subagentRunId===null)return new R(`Cannot send a message (id '${e.id}') with 'subagentRunId: null'. The field is optional — omit it entirely.`);let n=e.role===`reasoning`?s.reasoning:e.role===`activity`?s.activity:s.message;(t||!n.has(e.id))&&n.set(e.id,{subagentRunId:e.subagentRunId});for(let n of e.toolCalls??[])n&&typeof n.id==`string`&&(t||!s.toolCall.has(n.id))&&s.toolCall.set(n.id,{subagentRunId:e.subagentRunId??void 0})}},b=(e,t,n,r,i)=>{if(t!==void 0&&n&&n.subagentRunId!==t)return new R(`Cannot send '${e}': subagentRunId '${t}' does not match the ${r} '${i}' opener's subagent '${n.subagentRunId??`(the parent agent)`}'.`)};return t.pipe(xd(e=>{let t=e.type;if(n?.event(`VERIFY`,`Event:`,e,{type:e.type}),l&&t!==L.RUN_STARTED)return z(()=>new R(`Cannot send event type '${t}': The run has already errored with 'RUN_ERROR'. No further events can be sent.`));if(c&&t!==L.RUN_ERROR&&t!==L.RUN_STARTED)return z(()=>new R(`Cannot send event type '${t}': The run has already finished with 'RUN_FINISHED'. Start a new run with 'RUN_STARTED'.`));if(!u){if(u=!0,t!==L.RUN_STARTED&&t!==L.RUN_ERROR)return z(()=>new R(`First event must be 'RUN_STARTED'`))}else if(t===L.RUN_STARTED){if(g&&!c&&!l)return z(()=>new R(`Cannot send 'RUN_STARTED' while a run is still active. The previous run must be finished with 'RUN_FINISHED' before starting a new run.`));(c||l)&&v()}if(e.subagentRunId===null){_||(_=!0,RO(`subagentRunId: null`,`an absent field`));let{subagentRunId:t,...n}=e;e=n}if(t===L.SUBAGENT_STARTED||t===L.SUBAGENT_FINISHED||t===L.SUBAGENT_ERROR){let n=t===L.SUBAGENT_STARTED?[`description`,`parentSubagentRunId`,`parentToolCallId`,`parentMessageId`]:t===L.SUBAGENT_FINISHED?[`outcome`]:[`code`];for(let r of n)if(e[r]===null)return z(()=>new R(`Cannot send '${t}' with '${r}: null'. The field is optional — omit it entirely.`));let r=e.outcome;if(r!=null&&r.type!==`success`&&r.type!==`suspended`)return z(()=>new R(`Cannot send '${t}' with outcome type '${String(r.type)}'. The outcome is either { type: "success" } or { type: "suspended" }.`));if(r&&r.interruptIds===null)return z(()=>new R(`Cannot send '${t}' with 'outcome.interruptIds: null'. The field is optional — omit it entirely.`));if(r&&Array.isArray(r.interruptIds)&&r.interruptIds.some(e=>typeof e!=`string`))return z(()=>new R(`Cannot send '${t}' with a non-string entry in 'outcome.interruptIds'. Interrupt ids are strings.`))}if(t===L.RUN_FINISHED){let t=e.outcome;if(t?.type===`interrupt`&&Array.isArray(t.interrupts)){for(let e of t.interrupts)if(e&&e.subagentRunId===null)return z(()=>new R(`Cannot send 'RUN_FINISHED' with an interrupt (id '${e.id}') carrying 'subagentRunId: null'. The field is optional — omit it entirely.`))}}switch(t){case L.TEXT_MESSAGE_START:{let n=e.messageId;if(r.has(n))return z(()=>new R(`Cannot send 'TEXT_MESSAGE_START' event: A text message with ID '${n}' is already in progress. Complete it with 'TEXT_MESSAGE_END' first.`));let i=s.message.get(n);if(i){let r=b(t,e.subagentRunId,i,`message`,n);if(r)return z(()=>r)}return r.add(n),i||s.message.set(n,{subagentRunId:e.subagentRunId}),gd(e)}case L.TEXT_MESSAGE_CONTENT:{let n=e.messageId;if(!r.has(n))return z(()=>new R(`Cannot send 'TEXT_MESSAGE_CONTENT' event: No active text message found with ID '${n}'. Start a text message with 'TEXT_MESSAGE_START' first.`));let i=b(t,e.subagentRunId,s.message.get(n),`message`,n);return i?z(()=>i):gd(e)}case L.TEXT_MESSAGE_END:{let n=e.messageId;if(!r.has(n))return z(()=>new R(`Cannot send 'TEXT_MESSAGE_END' event: No active text message found with ID '${n}'. A 'TEXT_MESSAGE_START' event must be sent first.`));let i=b(t,e.subagentRunId,s.message.get(n),`message`,n);return i?z(()=>i):(r.delete(n),gd(e))}case L.TOOL_CALL_START:{let n=e.toolCallId;if(i.has(n))return z(()=>new R(`Cannot send 'TOOL_CALL_START' event: A tool call with ID '${n}' is already in progress. Complete it with 'TOOL_CALL_END' first.`));let r=e.parentMessageId,a=e.subagentRunId,o;if(r!==void 0){let e=s.message.get(r);if(e){if(a!==void 0&&a!==e.subagentRunId)return z(()=>new R(`Cannot send 'TOOL_CALL_START': subagentRunId '${a}' does not match its parent message '${r}' owner '${e.subagentRunId??`(the parent agent)`}'. A tool call belongs to the message that carries it.`));o=e}}let c=s.toolCall.get(n);if(c){let e=b(t,a,c,`tool call`,n);if(e)return z(()=>e);if(a===void 0&&o&&o.subagentRunId!==c.subagentRunId)return z(()=>new R(`Cannot send 'TOOL_CALL_START': tool call '${n}' is owned by '${c.subagentRunId??`(the parent agent)`}' but its parent message '${r}' is owned by '${o.subagentRunId??`(the parent agent)`}'. A tool call belongs to the message that carries it.`))}return i.add(n),c||s.toolCall.set(n,a===void 0?o??{subagentRunId:void 0}:{subagentRunId:a}),gd(e)}case L.TOOL_CALL_ARGS:{let n=e.toolCallId;if(!i.has(n))return z(()=>new R(`Cannot send 'TOOL_CALL_ARGS' event: No active tool call found with ID '${n}'. Start a tool call with 'TOOL_CALL_START' first.`));let r=b(t,e.subagentRunId,s.toolCall.get(n),`tool call`,n);return r?z(()=>r):gd(e)}case L.TOOL_CALL_END:{let n=e.toolCallId;if(!i.has(n))return z(()=>new R(`Cannot send 'TOOL_CALL_END' event: No active tool call found with ID '${n}'. A 'TOOL_CALL_START' event must be sent first.`));let r=b(t,e.subagentRunId,s.toolCall.get(n),`tool call`,n);return r?z(()=>r):(i.delete(n),gd(e))}case L.STEP_STARTED:{let t=e.stepName,n=e.subagentRunId;return f(n).has(t)?z(()=>new R(`Step "${t}" is already active for 'STEP_STARTED'${n===void 0?``:` in subagent '${n}'`}`)):(f(n).set(t,!0),gd(e))}case L.STEP_FINISHED:{let t=e.stepName,n=e.subagentRunId;if(!f(n).has(t)){let e,r=!1;for(let[i,a]of d)if(i!==n&&a.has(t)){e=i,r=!0;break}return z(r?()=>new R(`Cannot send 'STEP_FINISHED' for step "${t}" attributed to ${n===void 0?`the parent agent`:`subagent '${n}'`}: that step is open under ${e===void 0?`the parent agent`:`subagent '${e}'`}. A step must be finished by whoever started it.`):()=>new R(`Cannot send 'STEP_FINISHED' for step "${t}" that was not started`))}return f(n).delete(t),gd(e)}case L.ACTIVITY_SNAPSHOT:{let t=e.messageId;return(!s.activity.has(t)||e.replace!==!1)&&s.activity.set(t,{subagentRunId:e.subagentRunId}),gd(e)}case L.TOOL_CALL_RESULT:{let t=e.messageId;return typeof t==`string`&&s.message.set(t,{subagentRunId:e.subagentRunId}),gd(e)}case L.REASONING_START:case L.REASONING_MESSAGE_START:{let n=e.messageId,r=t===L.REASONING_START,i=r?a:o;if(i.has(n))return z(()=>new R(r?`Cannot send 'REASONING_START' event: A reasoning span with ID '${n}' is already in progress. Complete it with 'REASONING_END' first.`:`Cannot send 'REASONING_MESSAGE_START' event: A reasoning message with ID '${n}' is already in progress. Complete it with 'REASONING_MESSAGE_END' first.`));let c=s.reasoning.get(n);if(c){let r=b(t,e.subagentRunId,c,`reasoning message`,n);if(r)return z(()=>r)}return i.add(n),c||s.reasoning.set(n,{subagentRunId:e.subagentRunId}),gd(e)}case L.REASONING_MESSAGE_CONTENT:case L.REASONING_MESSAGE_END:case L.REASONING_END:{let n=e.messageId,r=t===L.REASONING_END,i=r?a:o;if(!i.has(n))return z(()=>new R(r?`Cannot send 'REASONING_END' event: No active reasoning span found with ID '${n}'. A 'REASONING_START' event must be sent first.`:`Cannot send '${t}' event: No active reasoning message found with ID '${n}'. Start a reasoning message with 'REASONING_MESSAGE_START' first.`));let c=b(t,e.subagentRunId,s.reasoning.get(n),`reasoning message`,n);return c?z(()=>c):((t===L.REASONING_END||t===L.REASONING_MESSAGE_END)&&i.delete(n),gd(e))}case L.REASONING_ENCRYPTED_VALUE:{let n=e.entityId,r=e.subtype,i=r===`tool-call`?s.toolCall.get(n):r===`message`?s.message.get(n)??s.reasoning.get(n):s.reasoning.get(n),a=r===`tool-call`?`tool call`:r===`message`?`message`:`reasoning message`,o=b(t,e.subagentRunId,i,a,n);return o?z(()=>o):gd(e)}case L.ACTIVITY_DELTA:{let n=e.messageId,r=b(t,e.subagentRunId,s.activity.get(n),`activity`,n);return r?z(()=>r):gd(e)}case L.SUBAGENT_STARTED:{if(typeof e.subagentRunId!=`string`)return z(()=>new R(`Cannot send 'SUBAGENT_STARTED' without a 'subagentRunId'.`));if(typeof e.name!=`string`)return z(()=>new R(`Cannot send 'SUBAGENT_STARTED' without a 'name'.`));let t=e.subagentRunId,n=e.parentSubagentRunId;return m.has(t)?z(()=>new R(`Cannot send 'SUBAGENT_STARTED': subagent '${t}' is already active. Finish it with 'SUBAGENT_FINISHED' first.`)):h.has(t)?z(()=>new R(`Cannot send 'SUBAGENT_STARTED': subagent '${t}' has already finished in this run. Subagent IDs are per-invocation and cannot be reused.`)):n!==void 0&&!m.has(n)&&!h.has(n)?z(()=>new R(`Cannot send 'SUBAGENT_STARTED': parentSubagentRunId '${n}' has not been started in this run.`)):(m.set(t,!0),gd(e))}case L.SUBAGENT_FINISHED:case L.SUBAGENT_ERROR:{if(typeof e.subagentRunId!=`string`)return z(()=>new R(`Cannot send '${t}' without a 'subagentRunId'.`));if(t===L.SUBAGENT_ERROR&&typeof e.message!=`string`)return z(()=>new R(`Cannot send 'SUBAGENT_ERROR' without a 'message'.`));let n=e.subagentRunId;return m.has(n)?(m.delete(n),h.add(n),gd(e)):z(()=>new R(`Cannot send '${t}': no active subagent found with ID '${n}'. A 'SUBAGENT_STARTED' event must be sent first.`))}case L.MESSAGES_SNAPSHOT:{let t=y(e.messages,!0);if(t)return z(()=>t)}return gd(e);case L.RUN_STARTED:g=!0;{let t=y((e.input??{}).messages,!1);if(t)return z(()=>t)}return gd(e);case L.RUN_FINISHED:if(p()){let e=[];for(let[t,n]of d)for(let r of n.keys())e.push(t===void 0?r:`${r} (subagent '${t}')`);let t=e.join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while steps are still active: ${t}`))}if(r.size>0){let e=Array.from(r.keys()).join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while text messages are still active: ${e}`))}if(o.size>0){let e=Array.from(o.keys()).join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while reasoning messages are still active: ${e}`))}if(a.size>0){let e=Array.from(a.keys()).join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while reasoning spans are still active: ${e}`))}if(i.size>0){let e=Array.from(i.keys()).join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while tool calls are still active: ${e}`))}if(m.size>0){let e=Array.from(m.keys()).join(`, `);return z(()=>new R(`Cannot send 'RUN_FINISHED' while subagents are still active: ${e}`))}return c=!0,gd(e);case L.RUN_ERROR:return l=!0,gd(e);case L.CUSTOM:return gd(e);default:return gd(e)}}))},BO=function(e){return e.HEADERS=`headers`,e.DATA=`data`,e}({}),VO=e=>wd(()=>hd(e())).pipe(Md(e=>{if(!e.ok){let t=e.headers.get(`content-type`)||``;return hd(e.text()).pipe(xd(n=>{let r=n;if(t.includes(`application/json`))try{r=JSON.parse(n)}catch{}let i=Error(`HTTP ${e.status}: ${typeof r==`string`?r:JSON.stringify(r)}`);return i.status=e.status,i.payload=r,z(()=>i)}))}let t={type:BO.HEADERS,status:e.status,headers:e.headers},n=e.body?.getReader();return n?new wu(e=>{let r=!1;return e.next(t),(async()=>{try{for(;!e.closed;){let{done:t,value:i}=await n.read();if(t){r=!0;break}let a={type:BO.DATA,data:i};e.next(a)}e.complete()}catch(t){r=!0,e.error(t)}})(),()=>{r||n.cancel().catch(e=>{e?.name!==`AbortError`&&console.warn(`Failed to cancel HTTP response stream:`,e)})}}):z(()=>Error(`Failed to getReader() from response`))})),HO=10485760,UO=(e,t)=>{let n=MO(t),r=new Nu,i=new TextDecoder(`utf-8`,{fatal:!1}),a=``;e.subscribe({next:e=>{if(e.type!==BO.HEADERS&&e.type===BO.DATA&&e.data){let t=i.decode(e.data,{stream:!0});a+=t;let n=a.split(/\n\n/);a=n.pop()||``;for(let e of n)o(e);if(a.length>HO){r.error(Error(`SSE buffer size exceeded maximum limit of ${HO/1048576} MB`));return}}},error:e=>r.error(e),complete:()=>{a&&(a+=i.decode(),o(a)),r.complete()}});function o(e){let t=e.split(` `),i=[];for(let e of t)e.startsWith(`data:`)&&i.push(e.slice(5).replace(/^ /,``));if(i.length>0)try{let e=i.join(` `),t=JSON.parse(e);n?.event(`SSE`,`Event received:`,t,{type:t?.type}),r.next(t)}catch(e){r.error(e)}}return r.asObservable()},WO=10485760,GO=()=>typeof process<`u`&&!!{}.SUPPRESS_TRANSFORMATION_WARNINGS,KO=(e,t)=>{let n=MO(t),r=new Nu,i=new Uint8Array,a=!1;e.subscribe({next:e=>{if(e.type!==BO.HEADERS&&e.type===BO.DATA&&e.data){let t=new Uint8Array(i.length+e.data.length);t.set(i,0),t.set(e.data,i.length),i=t,o()}},error:e=>r.error(e),complete:()=>{if(o(),!a){if(i.length>0){r.error(Error(`The binary stream ended mid-frame: ${i.length} trailing bytes could not be read as a complete message.`));return}r.complete()}}});function o(){if(!a)for(;i.length>=4;){let e=4+new DataView(i.buffer,i.byteOffset,4).getUint32(0,!1);if(e>WO){r.error(Error(`Protobuf message size exceeded maximum limit of ${WO/1048576} MB`));return}if(i.length{let n=MO(t),r=new Nu,i=new Iu(1),a=!1,o,s=!1,c=()=>{s=!0,o?.unsubscribe()},l=e=>{c(),r.error(e)},u=()=>{c(),r.complete()};return o=e.subscribe({next:e=>{if(i.next(e),e.type===BO.HEADERS&&!a){a=!0;let t=e.headers.get(`content-type`);n?.lifecycle(`HTTP`,`Stream format detected:`,{contentType:t,parser:t===`application/vnd.ag-ui.event+proto`?`protobuf`:`sse`}),t===`application/vnd.ag-ui.event+proto`?KO(i,n).subscribe({next:e=>r.next(e),error:e=>l(e),complete:()=>u()}):UO(i,n).subscribe({next:e=>{if(typeof e!=`object`||!e||Array.isArray(e)){let t=Error(`Invalid event: the frame is not a JSON object.`);n?.event(`HTTP`,`Event invalid:`,{json:e,error:String(t)}),l(t);return}let t=e;if(typeof t.type!=`string`||t.type.length===0){let t=Error(`Invalid event: the frame carries no event type.`);n?.event(`HTTP`,`Event invalid:`,{json:e,error:String(t)}),l(t);return}n?.event(`HTTP`,`Event received:`,e,{type:t.type}),r.next(e)},error:e=>{if(e?.name===`AbortError`){r.next({type:L.RUN_ERROR,message:e.message||`Request aborted`,code:`abort`,rawEvent:e}),u();return}return l(e)},complete:()=>u()})}else a||l(Error(`No headers event received before data events`))},error:e=>{i.error(e),l(e)},complete:()=>{i.complete()}}),s&&o.unsubscribe(),r.asObservable()},JO={TextMessageStart:`TextMessageStart`,TextMessageContent:`TextMessageContent`,TextMessageEnd:`TextMessageEnd`,ActionExecutionStart:`ActionExecutionStart`,ActionExecutionArgs:`ActionExecutionArgs`,ActionExecutionEnd:`ActionExecutionEnd`,ActionExecutionResult:`ActionExecutionResult`,AgentStateMessage:`AgentStateMessage`,MetaEvent:`MetaEvent`,RunStarted:`RunStarted`,RunFinished:`RunFinished`,RunError:`RunError`,NodeStarted:`NodeStarted`,NodeFinished:`NodeFinished`},YO=e=>{if(typeof e==`string`)return e;if(!Array.isArray(e))return;let t=e.filter(e=>e.type===`text`).map(e=>e.text).filter(e=>e.length>0);if(t.length!==0)return t.join(` -`)};function XO(e,t){return $c(t)&&ZO(`[ag-ui][legacy] The result of tool call '${e}' carries content parts the legacy protocol cannot represent; only its text parts are bridged and the rest is dropped.`),Qc(t)}var ZO=e=>{typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(e)},QO=(e,t,n)=>r=>{let i={},a=!0,o=!0,s=``,c=null,l=null,u=[],d={},f=!1,p=e=>{typeof e==`object`&&e&&(`messages`in e&&delete e.messages,i=e)};return r.pipe(xd(r=>{switch(r.type){case L.TEXT_MESSAGE_START:{let e=r;return[{type:JO.TextMessageStart,messageId:e.messageId,role:e.role}]}case L.TEXT_MESSAGE_CONTENT:{let e=r;return[{type:JO.TextMessageContent,messageId:e.messageId,content:e.delta}]}case L.TEXT_MESSAGE_END:{let e=r;return[{type:JO.TextMessageEnd,messageId:e.messageId}]}case L.TOOL_CALL_START:{let e=r;return u.push({id:e.toolCallId,type:`function`,function:{name:e.toolCallName,arguments:``}}),o=!0,d[e.toolCallId]=e.toolCallName,[{type:JO.ActionExecutionStart,actionExecutionId:e.toolCallId,actionName:e.toolCallName,parentMessageId:e.parentMessageId}]}case L.TOOL_CALL_ARGS:{let c=r,d=u.find(e=>e.id===c.toolCallId);if(!d)return ZO(`[ag-ui][legacy] TOOL_CALL_ARGS: No tool call found with ID '${c.toolCallId}'`),[];d.function.arguments+=c.delta;let f=!1;if(l){let e=l.find(e=>e.tool==d.function.name);if(e)try{let t=JSON.parse(Id(d.function.arguments));e.tool_argument&&e.tool_argument in t?(p({...i,[e.state_key]:t[e.tool_argument]}),f=!0):e.tool_argument||(p({...i,[e.state_key]:t}),f=!0)}catch{}}return[{type:JO.ActionExecutionArgs,actionExecutionId:c.toolCallId,args:c.delta},...f?[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}]:[]]}case L.TOOL_CALL_END:{let e=r;return[{type:JO.ActionExecutionEnd,actionExecutionId:e.toolCallId}]}case L.TOOL_CALL_RESULT:{let e=r,t=d[e.toolCallId];return(t===void 0||t===``)&&ZO(`[ag-ui][legacy] No usable tool name was seen for tool call '${e.toolCallId}' (${t===void 0?`no TOOL_CALL_START reached this bridge`:`its TOOL_CALL_START carried an empty toolCallName`}), so its result is being bridged with the fabricated action name "unknown". Downstream consumers route on that name.`),[{type:JO.ActionExecutionResult,actionExecutionId:e.toolCallId,result:XO(e.toolCallId,e.content),actionName:t||`unknown`}]}case L.RAW:return f||(f=!0,ZO(`[ag-ui][legacy] Dropping RAW events: the legacy runtime protocol has no equivalent, so the provider payloads they carry do not reach the legacy stream. Reported once per stream.`)),[];case L.CUSTOM:{let e=r;switch(e.name){case`Exit`:a=!1;break;case`PredictState`:l=e.value}return[{type:JO.MetaEvent,name:e.name,value:e.value}]}case L.STATE_SNAPSHOT:return p(r.snapshot),[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}];case L.STATE_DELTA:{let c=r,l;try{l=Fl.applyPatch(i,c.delta,!0,!1).newDocument}catch(e){let t=e instanceof Error?e.message:String(e);return ZO(`[ag-ui][legacy] Failed to apply state patch:\nCurrent state: ${JSON.stringify(i,null,2)}\nPatch operations: ${JSON.stringify(c.delta,null,2)}\nError: ${t}`),[]}return p(l),[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}]}case L.MESSAGES_SNAPSHOT:return c=r.messages,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify({...i,...c?{messages:c}:{}}),active:!0}];case L.RUN_STARTED:return[];case L.RUN_FINISHED:{if(c&&(i.messages=c),Object.keys(i).length===0)return[];let r=null;if(c)try{r=$O(c)}catch(e){return[{type:JO.RunError,message:e.message}]}return[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify({...i,...r?{messages:r}:{}}),active:!1}]}case L.RUN_ERROR:{let e=r;return[{type:JO.RunError,message:e.message,code:e.code}]}case L.STEP_STARTED:return s=r.stepName,u=[],l=null,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:!0}];case L.STEP_FINISHED:return u=[],l=null,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:!1}];default:return[]}}))};function $O(e){let t=[];for(let n of e)if(n.role===`assistant`||n.role===`user`||n.role===`system`){let e=YO(n.content);if(e){let r={id:n.id,role:n.role,content:e};t.push(r)}if(n.role===`assistant`&&n.toolCalls&&n.toolCalls.length>0)for(let e of n.toolCalls){let r;try{r=JSON.parse(e.function.arguments)}catch(t){throw Error(`Failed to parse arguments for tool call '${e.id}' (${e.function.name}): ${t.message}`)}let i={id:e.id,name:e.function.name,arguments:r,parentMessageId:n.id};t.push(i)}}else if(n.role===`tool`){let r=`unknown`;for(let t of e)if(t.role===`assistant`&&t.toolCalls?.length){for(let e of t.toolCalls)if(e.id===n.toolCallId){r=e.function.name;break}}let i={id:n.id,result:XO(n.toolCallId,n.content),actionExecutionId:n.toolCallId,actionName:r};t.push(i)}return t}var ek=e=>e.kind===`tool`?e.fields.toolCallId:e.fields.messageId,tk=e=>e===`tool`?`toolCallId`:`messageId`,nk=(e,t,n,r,i)=>{if(r!==void 0&&r!==i)throw Error(`Cannot continue ${e} '${t}': chunk ${n} '${r}' does not match the open stream's ${n} ${i===void 0?`(absent)`:`'${i}'`}.`)},rk=(e,t)=>t.metadata===void 0?e:{...e,metadata:t.metadata},ik=(e,t)=>{let n=rk(e,t);return t.rawEvent===void 0?n:{...n,rawEvent:t.rawEvent}},ak=e=>new Set(Object.keys(e.shape)),ok=ak(bx),sk=ak(wx),ck=ak(sS),lk=(e,t)=>{let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n},uk=e=>{typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`[ag-ui][transform] ${e} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`)},dk=(e,t,n,r)=>{if(t===void 0||n||e.length===0)return;let i=e[e.length-1],a=Object.keys(t).filter(e=>Object.prototype.hasOwnProperty.call(i,e));a.length>0&&uk(`A ${r} carried ${a.map(e=>`'${e}'`).join(`, `)}, which the synthesized ${String(i.type)} already describes. The synthesized value is kept and the chunk's is dropped — this stage does not judge a described field, so the producer's value cannot be substituted for its own.`),e[e.length-1]={...t,...i}},fk=e=>t=>{let n=MO(e),r=new Map,i=e=>{let t=r.get(e);if(!t)return[];switch(r.delete(e),t.kind){case`text`:{let e={type:L.TEXT_MESSAGE_END,messageId:t.fields.messageId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`TEXT_MESSAGE_END`,e,{messageId:e.messageId}),[e]}case`tool`:{let e={type:L.TOOL_CALL_END,toolCallId:t.fields.toolCallId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`TOOL_CALL_END`,e,{toolCallId:e.toolCallId}),[e]}case`reasoning`:{let e={type:L.REASONING_MESSAGE_END,messageId:t.fields.messageId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`REASONING_MESSAGE_END`,e,{messageId:e.messageId}),[e]}}},a=()=>[...r.keys()].flatMap(e=>i(e)),o=(e,t)=>{for(let[n,i]of r)if(i.kind===e&&ek(i)===t)return{owner:n}},s=(e,t,n,i,a)=>{if(t!==void 0){let r=o(e,t);if(r){if(n!==void 0&&n!==r.owner)throw Error(`Cannot continue ${a} '${t}': chunk subagentRunId '${n}' does not match the open stream's subagent '${r.owner??`(the parent agent)`}'.`);return r.owner}return n}if(n!==void 0)return n;if(r.get(void 0)?.kind===e)return;let s=[...r.entries()].filter(([,t])=>t.kind===e);if(s.length===1)return s[0][0];if(s.length>1)throw Error(`Ambiguous ${i}: it carries neither a ${tk(e)} nor a subagentRunId, but ${s.length} lanes have an open ${a}. Attribute the chunk to the subagent it belongs to.`)};return t.pipe(xd(e=>{switch(e.type){case L.TEXT_MESSAGE_START:case L.TEXT_MESSAGE_CONTENT:case L.TEXT_MESSAGE_END:case L.TOOL_CALL_START:case L.TOOL_CALL_ARGS:case L.TOOL_CALL_END:case L.TOOL_CALL_RESULT:case L.STATE_SNAPSHOT:case L.STATE_DELTA:case L.CUSTOM:case L.STEP_STARTED:case L.STEP_FINISHED:case L.REASONING_START:case L.REASONING_MESSAGE_START:case L.REASONING_MESSAGE_CONTENT:case L.REASONING_MESSAGE_END:case L.REASONING_END:return[...i(e.subagentRunId??void 0),e];case L.RUN_STARTED:case L.RUN_FINISHED:case L.RUN_ERROR:case L.MESSAGES_SNAPSHOT:return[...a(),e];case L.RAW:case L.ACTIVITY_SNAPSHOT:case L.ACTIVITY_DELTA:case L.REASONING_ENCRYPTED_VALUE:case L.SUBAGENT_STARTED:return[e];case L.SUBAGENT_FINISHED:case L.SUBAGENT_ERROR:{let t=e.subagentRunId;return t==null?[e]:[...i(t),e]}case L.TEXT_MESSAGE_CHUNK:{let t=e,a=lk(e,ok),o=s(`text`,t.messageId,t.subagentRunId??void 0,`TEXT_MESSAGE_CHUNK`,`text message`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`text`&&(t.messageId===void 0||t.messageId===c.fields.messageId))nk(`text message`,c.fields.messageId,`role`,t.role,c.fields.role),nk(`text message`,c.fields.messageId,`name`,t.name,c.fields.name),d=c.fields;else{if(l.push(...i(o)),t.messageId===void 0)throw Error(`First TEXT_MESSAGE_CHUNK must have a messageId`);d={messageId:t.messageId,role:t.role===void 0?`assistant`:t.role,name:t.name,subagentRunId:t.subagentRunId},r.set(o,{kind:`text`,fields:d});let e=rk({type:L.TEXT_MESSAGE_START,messageId:t.messageId,role:d.role,...t.name!==void 0&&{name:t.name},...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`TEXT_MESSAGE_START`,e,{messageId:t.messageId})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.TEXT_MESSAGE_CONTENT,messageId:d.messageId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`TEXT_MESSAGE_CONTENT`,r,{messageId:d.messageId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.TEXT_MESSAGE_CONTENT,messageId:d.messageId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`TEXT_MESSAGE_CHUNK`),l}case L.TOOL_CALL_CHUNK:{let t=e,a=lk(e,sk),o=s(`tool`,t.toolCallId,t.subagentRunId??void 0,`TOOL_CALL_CHUNK`,`tool call`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`tool`&&(t.toolCallId===void 0||t.toolCallId===c.fields.toolCallId))nk(`tool call`,c.fields.toolCallId,`toolCallName`,t.toolCallName,c.fields.toolCallName),nk(`tool call`,c.fields.toolCallId,`parentMessageId`,t.parentMessageId,c.fields.parentMessageId),d=c.fields;else{if(l.push(...i(o)),t.toolCallId===void 0)throw Error(`First TOOL_CALL_CHUNK must have a toolCallId`);if(t.toolCallName===void 0)throw Error(`First TOOL_CALL_CHUNK must have a toolCallName`);d={toolCallId:t.toolCallId,toolCallName:t.toolCallName,parentMessageId:t.parentMessageId,subagentRunId:t.subagentRunId},r.set(o,{kind:`tool`,fields:d});let e=rk({type:L.TOOL_CALL_START,toolCallId:t.toolCallId,toolCallName:t.toolCallName,...t.parentMessageId!==void 0&&{parentMessageId:t.parentMessageId},...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`TOOL_CALL_START`,e,{toolCallId:t.toolCallId,toolCallName:t.toolCallName})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.TOOL_CALL_ARGS,toolCallId:d.toolCallId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`TOOL_CALL_ARGS`,r,{toolCallId:d.toolCallId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.TOOL_CALL_ARGS,toolCallId:d.toolCallId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`TOOL_CALL_CHUNK`),l}case L.REASONING_MESSAGE_CHUNK:{let t=e,a=lk(e,ck),o=s(`reasoning`,t.messageId,t.subagentRunId??void 0,`REASONING_MESSAGE_CHUNK`,`reasoning message`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`reasoning`&&(t.messageId===void 0||t.messageId===c.fields.messageId))d=c.fields;else{if(l.push(...i(o)),t.messageId===void 0)throw Error(`First REASONING_MESSAGE_CHUNK must have a messageId`);d={messageId:t.messageId,subagentRunId:t.subagentRunId},r.set(o,{kind:`reasoning`,fields:d});let e=rk({type:L.REASONING_MESSAGE_START,messageId:t.messageId,role:`reasoning`,...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`REASONING_MESSAGE_START`,e,{messageId:t.messageId})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.REASONING_MESSAGE_CONTENT,messageId:d.messageId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`REASONING_MESSAGE_CONTENT`,r,{messageId:d.messageId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.REASONING_MESSAGE_CONTENT,messageId:d.messageId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`REASONING_MESSAGE_CHUNK`),l}}return e.type,[e]}),jd(()=>{a()}))},pk=Symbol(`agui.strip.drop`);function mk(e){let t=e;for(;;){if(t instanceof tO||t instanceof rO||t instanceof aO||t instanceof hO||t instanceof dO){t=t.unwrap();continue}if(t instanceof pO){t=t.def.in;continue}if(t instanceof _O){t=t.def.getter();continue}return t}}function hk(e){let t=e.def;return typeof t?.discriminator==`string`?t.discriminator:void 0}function gk(e){let t=e,n=Array.isArray(t.def?.values)?t.def.values:t.values?Array.from(t.values):void 0;return n&&n.length===1?n[0]:t.value}function _k(e){let t=mk(e);return t instanceof QD?gk(t):void 0}function vk(e,t,n,r){let i=mk(t);if(i instanceof WD){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=i.shape,a=e,o={},s=i.meta()?.specOpen===!0;for(let e of Object.keys(a)){let i=Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;if(i===void 0){if(s){o[e]=a[e];continue}r.push(`${n}/${e}`);continue}let c=r.length,l=vk(a[e],i,`${n}/${e}`,r);if(l===pk){if(r.length=c,i.safeParse(void 0).success){r.push(`${n}/${e}`);continue}return pk}o[e]=l}return o}if(i instanceof HD){if(!Array.isArray(e))return e;let t=i.element,a=[];return e.forEach((e,i)=>{let o=r.length,s=vk(e,t,`${n}/${i}`,r);if(s===pk){r.length=o,r.push(`${n}/${i}`);return}a.push(s)}),a}if(i instanceof YD){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=i.def.valueType,a=e,o={};for(let e of Object.keys(a)){let i=r.length,s=vk(a[e],t,`${n}/${e}`,r);if(s===pk){r.length=i,r.push(`${n}/${e}`);continue}o[e]=s}return o}if(i instanceof GD){let t=i.options,a=hk(i);if(a!==void 0){if(typeof e!=`object`||!e||Array.isArray(e))return e;let i=e[a];for(let o of t){let t=mk(o);if(!(t instanceof WD))continue;let s=t.shape;if(_k(s[a])===i)return vk(e,o,n,r)}return pk}let o=t.filter(e=>mk(e)instanceof WD),s=typeof e==`object`&&!!e&&!Array.isArray(e);if(o.length>1&&s)return e;for(let i of t){let t=mk(i);if(t instanceof HD&&Array.isArray(e)||t instanceof WD&&s)return vk(e,i,n,r)}return e}return e}function yk(e,t){let n=[],r=vk(e,t,``,n);if(r===pk)throw Error(`Internal error: the stripper found the whole value unrecognisable, which the schemas are not supposed to allow — schema/stripper mismatch.`);return{value:r,stripped:n}}var bk=new Set(Object.values(L));function xk(e){return bk.has(e.type)}var Sk=new Map(pS.options.map(e=>{let t=e.shape;return[String(gk(t.type)),e]})),Ck=()=>typeof process<`u`&&!!{}.SUPPRESS_TRANSFORMATION_WARNINGS;function wk(e){Ck()||console.warn(`[ag-ui][enforce] ${e}`)}var Tk=e=>t=>{let n=MO(e);return t.pipe(xd(e=>{if(!xk(e))return wk(`Dropping unrecognised event '${String(e.type)}': no middleware translated it and the protocol does not describe it.`),n?.event(`ENFORCE`,`Unrecognised event dropped:`,e,{type:e.type}),Lu;let t=Sk.get(e.type);if(t===void 0)throw Error(`No validator for recognised event type '${String(e.type)}'`);let{value:r,stripped:i}=yk(e,t);for(let t of i)wk(`Removed unrecognised material at '${t}' on ${String(e.type)}. Nothing handled it; see the repo-root DEPRECATIONS.md if it is a retired shape.`);return gd(t.parse(r))}))};function Ek(e){let{value:t,stripped:n}=yk(Yc(e,`RunAgentInput`),qx);for(let e of n)wk(`Removed unrecognised material at '${e}' from the outgoing input.`);return qx.parse(t)}var Dk=class{runNext(e,t){return t.run(e).pipe(fk(!1))}runNextWithState(e,t){let n=wO(e.messages||[]),r=wO(e.state===void 0?{}:e.state),i=new Iu;return LO(e,i,t,[]).subscribe({next:e=>{e.messages!==void 0&&(n=e.messages),e.state!==void 0&&(r=e.state)},error:()=>{}}),this.runNext(e,t).pipe(Dd(async e=>(i.next(e),await new Promise(e=>setTimeout(e,0)),{event:e,messages:wO(n),state:wO(r)})))}},Ok=class extends Dk{constructor(e){super(),this.fn=e}run(e,t){return this.fn(e,t)}};function kk(e){return e.startsWith(`image/`)?`image`:e.startsWith(`audio/`)?`audio`:e.startsWith(`video/`)?`video`:`document`}function Ak(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`binary`&&`mimeType`in e&&typeof e.mimeType==`string`}function jk(e){let t=kk(e.mimeType);return e.data?{type:t,source:{type:`data`,value:e.data,mimeType:e.mimeType},...e.filename?{metadata:{filename:e.filename}}:{}}:e.url?{type:t,source:{type:`url`,value:e.url,mimeType:e.mimeType},...e.filename?{metadata:{filename:e.filename}}:{}}:((typeof process>`u`||!{}.SUPPRESS_TRANSFORMATION_WARNINGS)&&console.warn(`[ag-ui][compat] A binary content part carries only an id ('${e.id??``}') and cannot be converted to a modern media part; a 1.0 peer will not accept it. Provide data or a url. See the repo-root DEPRECATIONS.md.`),e)}function Mk(e,t,n){if(typeof e!=`object`||!e||!(`type`in e)||e.type!==t.type||!(`source`in e))return!1;let r=e.source;return typeof r!=`object`||!r||!(`type`in r)||r.type!==t.source.type||!(`value`in r)||r.value!==t.source.value||!(`mimeType`in r)||r.mimeType!==t.source.mimeType?!1:!n||`metadata`in e&&typeof e.metadata==`object`&&e.metadata!==null&&`filename`in e.metadata&&e.metadata.filename===n}function Nk(e){let t=e.content;if(!Array.isArray(t))return e;let n=t.flatMap(e=>{if(Ak(e)){let n=jk(e);return n.type!==`binary`&&t.some(t=>Mk(t,n,e.filename))?[]:[n]}return[e]});return{...e,content:n}}var Pk=`THINKING_START`,Fk=`THINKING_END`,Ik=`THINKING_TEXT_MESSAGE_START`,Lk=`THINKING_TEXT_MESSAGE_CONTENT`,Rk=`THINKING_TEXT_MESSAGE_END`;function zk(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var Bk={event:[`rawEvent`,`subagentRunId`],[L.RUN_STARTED]:[`parentRunId`,`input`],[L.RUN_FINISHED]:[`result`,`outcome`],[L.RUN_ERROR]:[`usage`],[L.SUBAGENT_FINISHED]:[`result`],[L.TOOL_CALL_START]:[`parentMessageId`],[L.TOOL_CALL_CHUNK]:[`parentMessageId`],[L.TOOL_CALL_RESULT]:[`role`],"RUN_FINISHED.outcome":[`pendingToolCallIds`],"RUN_FINISHED.usage[]":[`provider`,`reasoningTokens`,`cachedInputTokens`,`cacheWriteInputTokens`],RunAgentInput:[`forwardedProps`],Tool:[`parameters`],ResumeEntry:[`payload`],"input content":[`metadata`]},Vk=new Map(Object.entries(Bk).filter(([e])=>Object.values(L).includes(e))),Hk=e=>RO(e,`an absent field`);function Uk(e,t,n,r){if(!zk(e))return e;let i;for(let a of t)e[a]===null&&(r(n===void 0?`${a}: null`:`${n}.${a}: null`),i??={...e},delete i[a]);return i??e}function Wk(e,t,n){if(!zk(e)||!Array.isArray(e[t]))return e;let r=e[t],i=r.map(n);return i.some((e,t)=>e!==r[t])?{...e,[t]:i}:e}function Gk(e,t){return Wk(e,`content`,e=>{if(!zk(e))return e;switch(e.type){case`image`:case`audio`:case`video`:case`document`:return Uk(e,Bk[`input content`],`${e.type} input content`,t);default:return e}})}function Kk(e,t=Hk){let n=Uk(e,Bk.RunAgentInput,`RunAgentInput`,t);return n=Wk(n,`tools`,e=>Uk(e,Bk.Tool,`Tool`,t)),n=Wk(n,`resume`,e=>Uk(e,Bk.ResumeEntry,`ResumeEntry`,t)),Wk(n,`messages`,e=>Gk(e,t))}var qk=class extends Dk{constructor(...e){super(...e),this.currentReasoningId=null,this.currentMessageId=null,this.nullsNoticedThisRun=new Set,this.noticeNullOncePerRun=e=>{this.nullsNoticedThisRun.has(e)||(this.nullsNoticedThisRun.add(e),RO(e,`an absent field`))}}warn(e,t){RO(e,t)}mintedContinuationId(e,t){if(t!==null)return t;let n=TO();return this.warnAside(`Minting a messageId ('${n}') for ${e}: no THINKING opener preceded it, so there was no id to continue. The id is this client's invention, not the producer's, and verification will reject the translated event for naming something nothing opened.`),n}warnAside(e){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`[ag-ui][compat] ${e} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`)}run(e,t){return this.currentReasoningId=null,this.currentMessageId=null,this.nullsNoticedThisRun.clear(),e.messages=e.messages.map(Nk),t.run(e).pipe(yd(e=>this.transformEvent(e)))}transformEvent(e){let t=this.noticeNullOncePerRun;e.type===L.RUN_STARTED&&this.nullsNoticedThisRun.clear(),e=Uk(e,Bk.event,void 0,t);let n=Vk.get(e.type);switch(n&&(e=Uk(e,n,e.type,t)),e.type){case Pk:{this.currentReasoningId=TO();let{title:t,...n}=e;return this.warn(Pk,L.REASONING_START),t!==void 0&&this.warnAside(`Dropping ${Pk}.title ${JSON.stringify(t)}: ${L.REASONING_START} has no title field, so the span's label cannot be carried and nothing downstream can recover it.`),{...n,type:L.REASONING_START,messageId:this.currentReasoningId}}case Ik:return this.currentMessageId=TO(),this.warn(Ik,L.REASONING_MESSAGE_START),{...e,type:L.REASONING_MESSAGE_START,messageId:this.currentMessageId,role:`reasoning`};case Lk:{let{delta:t,...n}=e;return this.warn(Lk,L.REASONING_MESSAGE_CONTENT),{...n,type:L.REASONING_MESSAGE_CONTENT,messageId:this.mintedContinuationId(Lk,this.currentMessageId),delta:t}}case Rk:{let t=this.mintedContinuationId(Rk,this.currentMessageId);return this.currentMessageId=null,this.warn(Rk,L.REASONING_MESSAGE_END),{...e,type:L.REASONING_MESSAGE_END,messageId:t}}case Fk:{let t=this.mintedContinuationId(Fk,this.currentReasoningId);return this.currentReasoningId=null,this.warn(Fk,L.REASONING_END),{...e,type:L.REASONING_END,messageId:t}}case L.RUN_FINISHED:{let n=e,r=Uk(n.outcome,Bk[`RUN_FINISHED.outcome`],`RUN_FINISHED.outcome`,t);return Wk(r===n.outcome?n:{...n,outcome:r},`usage`,e=>Uk(e,Bk[`RUN_FINISHED.usage[]`],`RUN_FINISHED.usage[]`,t))}case L.MESSAGES_SNAPSHOT:{let t=e;return Array.isArray(t.messages)?{...t,messages:t.messages.map(e=>this.upgradeInboundMessage(e))}:e}case L.RUN_STARTED:{let n=Kk(e.input,t),r=n===e.input?e:{...e,input:n},i=r;return!i.input||!Array.isArray(i.input.messages)?r:{...i,input:{...i.input,messages:i.input.messages.map(e=>this.upgradeInboundMessage(e))}}}default:return e}}upgradeInboundMessage(e){e=Gk(e,this.noticeNullOncePerRun);let t=e.content;return!Array.isArray(t)||!t.some(e=>typeof e==`object`&&!!e&&e.type===`binary`)?e:(this.warn(`binary input content`,`the modern media content parts`),Nk(e))}},Jk=()=>e=>wd(()=>{let t=new qk;return e.pipe(yd(e=>t.transformEvent(e)))});function Yk(e,t=new Date){return e.expiresAt!==void 0&&new Date(e.expiresAt)<=t}function Xk(){return typeof process<`u`&&!!{}.SUPPRESS_TRANSFORMATION_WARNINGS}function Zk(e){Xk()||console.warn(`[ag-ui][compat] Flattening message content for a <=0.0.39 peer DROPS non-text parts (${e.join(`, `)}). The peer cannot receive them; upgrade it to keep media content. See the repo-root DEPRECATIONS.md.`)}function Qk(e){Xk()||console.warn(`[ag-ui][compat] Not flattening message content for a <=0.0.39 peer: ${e} content part(s) claim type "text" but carry a malformed 'text' value. That is a defect in the message, not media the peer cannot represent, and a downgrade must not repair it — the content is passed on unchanged so the outgoing enforcement boundary reports it. See the repo-root DEPRECATIONS.md.`)}function $k(e){let t=e.content;if(Array.isArray(t)){let n=e=>typeof e==`object`&&!!e&&`type`in e&&e.type===`text`,r=e=>n(e)&&typeof e.text==`string`,i=t.filter(e=>n(e)&&!r(e));if(i.length>0)return Qk(i.length),e;let a=t.filter(e=>!r(e)).map(e=>typeof e==`object`&&e&&`type`in e?String(e.type):typeof e);a.length>0&&Zk(a);let o=t.filter(r).map(e=>e.text).join(``);return{...e,content:o}}return typeof t==`string`?e:t===void 0?{...e,content:``}:e}var eA=class extends Dk{run(e,t){let{parentRunId:n,...r}=e,i={...r,messages:r.messages.map($k)};return this.runNext(i,t)}},tA=`THINKING_START`,nA=`THINKING_END`,rA=`THINKING_TEXT_MESSAGE_START`,iA=`THINKING_TEXT_MESSAGE_CONTENT`,aA=`THINKING_TEXT_MESSAGE_END`,oA=class extends Dk{constructor(...e){super(...e),this.currentReasoningId=null,this.currentMessageId=null}warnAboutTransformation(e,t){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`AG-UI is converting ${e} to ${t}. To remove this warning, upgrade your AG-UI integration package (e.g. @ag-ui/langgraph). To surpress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`)}run(e,t){return this.currentReasoningId=null,this.currentMessageId=null,this.runNext(e,t).pipe(yd(e=>this.transformEvent(e)))}transformEvent(e){switch(e.type){case tA:{this.currentReasoningId=TO();let{title:t,...n}=e;return this.warnAboutTransformation(tA,L.REASONING_START),{...n,type:L.REASONING_START,messageId:this.currentReasoningId}}case rA:return this.currentMessageId=TO(),this.warnAboutTransformation(rA,L.REASONING_MESSAGE_START),{...e,type:L.REASONING_MESSAGE_START,messageId:this.currentMessageId,role:`reasoning`};case iA:{let{delta:t,...n}=e;return this.warnAboutTransformation(iA,L.REASONING_MESSAGE_CONTENT),{...n,type:L.REASONING_MESSAGE_CONTENT,messageId:this.currentMessageId??TO(),delta:t}}case aA:{let t=this.currentMessageId??TO();return this.warnAboutTransformation(aA,L.REASONING_MESSAGE_END),{...e,type:L.REASONING_MESSAGE_END,messageId:t}}case nA:{let t=this.currentReasoningId??TO();return this.warnAboutTransformation(nA,L.REASONING_END),{...e,type:L.REASONING_END,messageId:t}}default:return e}}},sA=`SUBAGENT_STARTED`,cA=`SUBAGENT_FINISHED`,lA=`SUBAGENT_ERROR`;function uA(e){if(e&&typeof e==`object`&&`subagentRunId`in e){let{subagentRunId:t,...n}=e;return n}return e}function dA(e){return e.map(e=>uA(e))}var fA=class extends Dk{warnDroppedLifecycleEvent(e){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`AG-UI is dropping ${e} because the target agent predates subagent support. To remove this warning, upgrade your AG-UI integration package. To suppress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`)}run(e,t){let n={...e,messages:(e.messages??[]).map(e=>uA(e))};return this.runNext(n,t).pipe(Pd(e=>{let t=e.type;(t===sA||t===cA||t===lA)&&this.warnDroppedLifecycleEvent(t)}),Td(e=>{let t=e.type;return t!==sA&&t!==cA&&t!==lA}),yd(e=>{let t=uA(e);if(t.type===L.MESSAGES_SNAPSHOT){let e=t;if(Array.isArray(e.messages))return{...e,messages:dA(e.messages)}}if(t.type===L.RUN_FINISHED){let e=t;if(e.outcome&&Array.isArray(e.outcome.interrupts))return{...e,outcome:{...e.outcome,interrupts:e.outcome.interrupts.map(e=>uA(e))}}}if(t.type===L.RUN_STARTED){let e=t;if(e.input&&Array.isArray(e.input.messages))return{...e,input:{...e.input,messages:dA(e.input.messages)}}}return t}))}},pA=`1.0.2`,mA=!1,hA=new WeakSet,gA=(e,t)=>/^\d+\.\d+$/.test(e)?WT(e,t)>0?`newer`:`not-newer`:`uninterpretable`,_A=e=>{let t=e.protocolVersion;if(t!==void 0&&t!==`1.0`)switch(gA(t,`1.0`)){case`uninterpretable`:console.warn(`[ag-ui] The producer declared protocol version '${t}', which this client cannot interpret.`);return;case`newer`:console.warn(`[ag-ui] The producer speaks protocol ${t}; this client speaks 1.0. Unrecognised material will be stripped with warnings.`);return;case`not-newer`:return}},vA=class e{resolvePeerCeiling(t){if(this.resolvingPeerCeiling)return pA;let n=Object.getOwnPropertyDescriptor(this,`maxVersion`),r=Object.getOwnPropertyDescriptor(this,`maxProtocolVersion`),i=Object.getPrototypeOf(this);for(;i&&i!==e.prototype;)n??=Object.getOwnPropertyDescriptor(i,`maxVersion`),r??=Object.getOwnPropertyDescriptor(i,`maxProtocolVersion`),i=Object.getPrototypeOf(i);if(t===`maxVersion`&&n)return pA;let a=t===`maxProtocolVersion`?n:r;if(!a)return pA;this.resolvingPeerCeiling=!0;try{return a.get?a.get.call(this):a.value}finally{this.resolvingPeerCeiling=!1}}get maxProtocolVersion(){return this.resolvePeerCeiling(`maxProtocolVersion`)}get maxVersion(){return!this.resolvingPeerCeiling&&!mA&&(mA=!0,console.warn(`[ag-ui] AbstractAgent.maxVersion is deprecated — use maxProtocolVersion. Same value; the new name says whose version it is and that it is a ceiling.`)),this.resolvePeerCeiling(`maxVersion`)}get debug(){return this._debug}set debug(e){this._debug=jO(e),this._debugLogger=PO(this._debug)}get debugLogger(){return this._debugLogger}set debugLogger(e){this._debugLogger=typeof e==`boolean`?e?PO(jO(!0)):void 0:e}resolvedCeilingDuringConstruction(){let e=this.maxProtocolVersion;if(typeof e!=`string`||!GT(e))throw new R(`maxProtocolVersion resolved to ${JSON.stringify(e)} during construction, which is not a version this client can compare. A ceiling read from an instance field is not available yet — return a literal from the getter.`);return e}constructor({agentId:e,description:t,threadId:n,initialMessages:r,initialState:i,debug:a}={}){this.subscribers=[],this.isRunning=!1,this.pendingInterrupts=[],this.middlewares=[],this.resolvingPeerCeiling=!1,this.agentId=e,this.description=t??``,this.threadId=n??Gc(),this.messages=wO(r??[]),this.state=wO(i??{}),this._debug=jO(a),this._debugLogger=PO(this._debug);let o=this.resolvedCeilingDuringConstruction();WT(o,`0.0.39`)<=0&&this.middlewares.unshift(new eA),WT(o,`0.0.45`)<=0&&this.middlewares.unshift(new oA),WT(o,`0.0.57`)<=0&&this.middlewares.unshift(new fA)}subscribe(e){return this.subscribers.push(e),{unsubscribe:()=>{this.subscribers=this.subscribers.filter(t=>t!==e)}}}use(...e){let t=e.map(e=>typeof e==`function`?new Ok(e):e);return this.middlewares.push(...t),this}async runAgent(e,t){try{this.isRunning=!0,this.agentId=this.agentId??Gc();let n=this.prepareRunAgentInput(e);this.debugLogger?.lifecycle(`LIFECYCLE`,`Run started:`,{agentId:this.agentId,threadId:this.threadId});let r,i=new Set(this.messages.map(e=>e.id)),a=[{onRunStartedEvent:({event:e})=>_A(e),onRunFinishedEvent:e=>{e.outcome===`success`&&(r=e.result)}},...this.subscribers,t??{}];hA.add(n),await this.onInitialize(n,a),this.activeRunDetach$=new Nu;let o;this.activeRunCompletionPromise=new Promise(e=>{o=e}),await vd(Su(()=>[...this.middlewares,new qk].reduceRight((e,t)=>({run:n=>t.run(n,e),get messages(){return e.messages},get state(){return e.state}}),this).run(n),Tk(this.debugLogger),fk(this.debugLogger),zO(this.debugLogger),e=>e.pipe(Nd(this.activeRunDetach$)),e=>this.applyBeforeSourceError(n,e,a),Ed(e=>(this.debugLogger?.lifecycle(`LIFECYCLE`,`Run errored:`,{agentId:this.agentId,error:e instanceof Error?e.message:String(e)}),this.isRunning=!1,this.onError(n,e,a))),jd(()=>{this.debugLogger?.lifecycle(`LIFECYCLE`,`Run finished:`,{agentId:this.agentId,threadId:this.threadId}),this.isRunning=!1,this.onFinalize(n,a),o?.(),o=void 0,this.activeRunCompletionPromise=void 0,this.activeRunDetach$=void 0}))(gd(null)));let s=wO(this.messages).filter(e=>!i.has(e.id));return{result:r,newMessages:s}}finally{this.isRunning=!1}}connect(e){throw new Xc}async connectAgent(e,t){try{this.isRunning=!0,this.agentId=this.agentId??Gc();let n=this.prepareRunAgentInput(e),r,i=new Set(this.messages.map(e=>e.id)),a=[{onRunStartedEvent:({event:e})=>_A(e),onRunFinishedEvent:e=>{e.outcome===`success`&&(r=e.result)}},...this.subscribers,t??{}];await this.onInitialize(n,a),this.activeRunDetach$=new Nu;let o;this.activeRunCompletionPromise=new Promise(e=>{o=e}),await vd(Su(()=>wd(()=>this.connect(n)),e=>Tk(this.debugLogger)(Jk()(e)),fk(this.debugLogger),zO(this.debugLogger),e=>e.pipe(Nd(this.activeRunDetach$)),e=>this.applyBeforeSourceError(n,e,a),Ed(e=>(this.isRunning=!1,e instanceof Xc?Lu:this.onError(n,e,a))),jd(()=>{this.isRunning=!1,this.onFinalize(n,a),o?.(),o=void 0,this.activeRunCompletionPromise=void 0,this.activeRunDetach$=void 0}))(gd(null)),{defaultValue:void 0});let s=wO(this.messages).filter(e=>!i.has(e.id));return{result:r,newMessages:s}}finally{this.isRunning=!1}}abortRun(){}async detachActiveRun(){if(!this.activeRunDetach$)return;let e=this.activeRunCompletionPromise??Promise.resolve();this.activeRunDetach$.next(),this.activeRunDetach$?.complete(),await e}applyBeforeSourceError(e,t,n){return wd(()=>{let r,i=t.pipe(Ed(e=>(r={error:e},Lu)));return this.processApplyEvents(e,this.apply(e,i,n),n).pipe(kd(wd(()=>{let e=r;return e?z(()=>e.error):Lu})))})}apply(e,t,n){return LO(e,t,this,n,this.debugLogger)}processApplyEvents(e,t,n){return t.pipe(Pd(t=>{t.messages&&(this.messages=t.messages,n.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),t.state!==void 0&&(this.state=t.state,n.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))}))}prepareRunAgentInput(e){let t=wO(this.messages);for(let e of t)e.subagentRunId===null&&delete e.subagentRunId;let n=t.filter(e=>e.role!==`activity`);return{threadId:this.threadId,runId:e?.runId||Gc(),...WT(this.maxProtocolVersion,pA)>=0&&{protocolVersion:`1.0`},tools:wO(e?.tools??[]),context:wO(e?.context??[]),forwardedProps:wO(e?.forwardedProps??{}),state:wO(this.state),messages:n,...e?.resume===void 0?{}:{resume:wO(e.resume)}}}async onInitialize(e,t){if(hA.has(e)&&this.pendingInterrupts.length>0){let t=new Set((e.resume??[]).map(e=>e.interruptId)),n=this.pendingInterrupts.map(e=>e.id).filter(e=>!t.has(e));if(n.length>0)throw new R(`Thread has ${n.length} pending interrupt(s) not addressed by resume: ${n.join(`, `)}`);for(let t of this.pendingInterrupts)if(Yk(t)&&(e.resume??[]).find(e=>e.interruptId===t.id)?.status!==`cancelled`)throw new R(`Interrupt ${t.id} expired at ${t.expiresAt} and can no longer be answered. Cancel it to continue the thread.`)}let n=await AO(t,this.messages,this.state,(t,n,r)=>t.onRunInitialized?.({messages:n,state:r,agent:this,input:e}));if(n.messages!==void 0||n.state!==void 0){if(n.messages){this.messages=n.messages;for(let e of n.messages)e.subagentRunId===null&&delete e.subagentRunId;e.messages=n.messages.filter(e=>e.role!==`activity`),t.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})}n.state!==void 0&&(this.state=n.state,e.state=n.state,t.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))}}onError(e,t,n){return hd(AO(n,this.messages,this.state,(n,r,i)=>n.onRunFailed?.({error:t,messages:r,state:i,agent:this,input:e}))).pipe(yd(r=>{let i=r;if((i.messages!==void 0||i.state!==void 0)&&(i.messages!==void 0&&(this.messages=i.messages,n.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),i.state!==void 0&&(this.state=i.state,n.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))),i.stopPropagation!==!0){let e=String(t);if(t.name!==`AbortError`&&t.message!==`Fetch is aborted`&&t.message!==`signal is aborted without reason`&&t.message!==`component unmounted`&&e!==`component unmounted`)throw console.error(`Agent execution failed:`,t),t}return{}}))}async onFinalize(e,t){let n=await AO(t,this.messages,this.state,(t,n,r)=>t.onRunFinalized?.({messages:n,state:r,agent:this,input:e}));(n.messages!==void 0||n.state!==void 0)&&(n.messages!==void 0&&(this.messages=n.messages,t.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),n.state!==void 0&&(this.state=n.state,t.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})})))}clone(){let e=Object.create(Object.getPrototypeOf(this));return e.agentId=this.agentId,e.description=this.description,e.threadId=this.threadId,e.messages=wO(this.messages),e.state=wO(this.state),e._debug=this._debug,e._debugLogger=this._debugLogger,e.isRunning=this.isRunning,e.subscribers=[...this.subscribers],e.middlewares=[...this.middlewares],e.pendingInterrupts=wO(this.pendingInterrupts),e}addMessage(e){this.messages.push(e),(async()=>{for(let t of this.subscribers)await t.onNewMessage?.({message:e,messages:this.messages,state:this.state,agent:this});if(e.role===`assistant`&&e.toolCalls)for(let t of e.toolCalls)for(let e of this.subscribers)await e.onNewToolCall?.({toolCall:t,messages:this.messages,state:this.state,agent:this});for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}addMessages(e){this.messages.push(...e),(async()=>{for(let t of e){for(let e of this.subscribers)await e.onNewMessage?.({message:t,messages:this.messages,state:this.state,agent:this});if(t.role===`assistant`&&t.toolCalls)for(let e of t.toolCalls)for(let t of this.subscribers)await t.onNewToolCall?.({toolCall:e,messages:this.messages,state:this.state,agent:this})}for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}setMessages(e){this.messages=wO(e),(async()=>{for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}setState(e){this.state=wO(e),(async()=>{for(let e of this.subscribers)await e.onStateChanged?.({messages:this.messages,state:this.state,agent:this})})()}legacy_to_be_removed_runAgentBridged(e){this.agentId=this.agentId??Gc();let t=this.prepareRunAgentInput(e);return[...this.middlewares,new qk].reduceRight((e,t)=>({run:n=>t.run(n,e),get messages(){return e.messages},get state(){return e.state}}),this).run(t).pipe(Tk(this.debugLogger),fk(this.debugLogger),zO(this.debugLogger),QO(this.threadId,t.runId,this.agentId),e=>e.pipe(yd(e=>(this.debugLogger?.event(`LEGACY`,`Event:`,e,{type:e.type}),e))))}};function yA(e){if(!Array.isArray(e.messages))return e;let t=!1,n=e.messages.map(e=>{if(e.subagentRunId===null){t=!0;let n={...e};return delete n.subagentRunId,n}return e});return t?{...e,messages:n}:e}var bA=class extends vA{requestInit(e){return{method:`POST`,headers:{...this.headers,"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify(yA(e)),signal:this.abortController.signal}}runAgent(e,t){return this.abortController=e?.abortController??new AbortController,super.runAgent(e,t)}abortRun(){this.abortController.abort(),super.abortRun()}constructor(e){super(e),this.abortController=new AbortController,this.url=e.url,this.headers=wO(e.headers??{}),this.fetch=e.fetch??((e,t)=>fetch(e,t))}run(e){return qO(VO(()=>this.fetch(this.url,this.requestInit(Ek(e)))),this.debugLogger)}clone(){let e=super.clone();e.url=this.url,e.headers=wO(this.headers??{}),e.fetch=this.fetch;let t=new AbortController,n=this.abortController.signal;return n.aborted&&t.abort(n.reason),e.abortController=t,e}},xA=M.createContext(void 0),SA=e=>{let t=M.useContext(xA);if(e)return e;if(!t)throw Error(`No QueryClient set, use QueryClientProvider to set one`);return t},CA=({client:e,children:t})=>(M.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),(0,N.jsx)(xA.Provider,{value:e,children:t})),wA={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},TA=new class{#e=wA;setTimeoutProvider(e){this.#e=e}setTimeout(e,t){return this.#e.setTimeout(e,t)}clearTimeout(e){this.#e.clearTimeout(e)}setInterval(e,t){return this.#e.setInterval(e,t)}clearInterval(e){this.#e.clearInterval(e)}};function EA(e){setTimeout(e,0)}var DA=typeof window>`u`||`Deno`in globalThis;function OA(){}function kA(e,t){return typeof e==`function`?e(t):e}function AA(e){return typeof e==`number`&&e>=0&&e!==1/0}function jA(e,t){return Math.max(e+(t||0)-Date.now(),0)}function MA(e,t){return typeof e==`function`?e(t):e}function NA(e,t){let{type:n=`all`,exact:r,fetchStatus:i,predicate:a,queryKey:o,stale:s}=e;if(o){if(r){if(t.queryHash!==FA(o,t.options))return!1}else if(!LA(t.queryKey,o))return!1}if(n!==`all`){let e=t.isActive();if(n===`active`&&!e||n===`inactive`&&e)return!1}return!(typeof s==`boolean`&&t.isStale()!==s||i&&i!==t.state.fetchStatus||a&&!a(t))}function PA(e,t){let{exact:n,status:r,predicate:i,mutationKey:a}=e;if(a){if(!t.options.mutationKey)return!1;if(n){if(IA(t.options.mutationKey)!==IA(a))return!1}else if(!LA(t.options.mutationKey,a))return!1}return!(r&&t.state.status!==r||i&&!i(t))}function FA(e,t){return(t?.queryKeyHashFn||IA)(e)}function IA(e){return JSON.stringify(e,(e,t)=>HA(t)?Object.keys(t).sort().reduce((e,n)=>(e[n]=t[n],e),{}):t)}function LA(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(Array.isArray(e)&&Array.isArray(t)){if(t.length>e.length)return!1;for(let n=0;n500)return t;let r=VA(e)&&VA(t);if(!r&&!(HA(e)&&HA(t)))return t;let i=(r?e:Object.keys(e)).length,a=r?t:Object.keys(t),o=a.length,s=r?Array(o):{},c=0;for(let l=0;l{TA.setTimeout(t,e)})}function GA(e,t,n){return typeof n.structuralSharing==`function`?n.structuralSharing(e,t):n.structuralSharing===!1?t:zA(e,t)}function KA(e,t,n=0){let r=[...e,t];return n&&r.length>n?r.slice(1):r}function qA(e,t,n=0){let r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var JA=Symbol();function YA(e,t){return!e.queryFn&&t?.initialPromise?()=>t.initialPromise:!e.queryFn||e.queryFn===JA?()=>Promise.reject(Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function XA(e,t){return typeof e==`function`?e(...t):!!e}function ZA(e,t,n){let r=!1,i;return Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(i??=t(),r?i:(r=!0,i.aborted?n():i.addEventListener(`abort`,n,{once:!0}),i))}),e}var QA=()=>DA,$A=()=>QA(),ej=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},tj=new class extends ej{#e;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e();return window.addEventListener(`visibilitychange`,t,!1),()=>{window.removeEventListener(`visibilitychange`,t)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(e=>{typeof e==`boolean`?this.setFocused(e):this.onFocus()})}setFocused(e){this.#e!==e&&(this.#e=e,this.onFocus())}onFocus(){let e=this.isFocused();this.listeners.forEach(t=>{t(e)})}isFocused(){return typeof this.#e==`boolean`?this.#e:globalThis.document?.visibilityState!==`hidden`}},nj=EA;function rj(){let e=[],t=0,n=e=>{e()},r=e=>{e()},i=nj,a=r=>{t?e.push(r):i(()=>{n(r)})},o=()=>{let t=e;e=[],t.length&&i(()=>{r(()=>{t.forEach(e=>{n(e)})})})};return{batch:e=>{let n;t++;try{n=e()}finally{t--,t||o()}return n},batchCalls:e=>(...t)=>{a(()=>{e(...t)})},schedule:a,setNotifyFunction:e=>{n=e},setBatchNotifyFunction:e=>{r=e},setScheduler:e=>{i=e}}}var ij=rj(),aj=new class extends ej{#e=!0;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e(!0),n=()=>e(!1);return window.addEventListener(`online`,t,!1),window.addEventListener(`offline`,n,!1),()=>{window.removeEventListener(`online`,t),window.removeEventListener(`offline`,n)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(this.setOnline.bind(this))}setOnline(e){this.#e!==e&&(this.#e=e,this.listeners.forEach(t=>{t(e)}))}isOnline(){return this.#e}};function oj(e){return Math.min(1e3*2**e,3e4)}function sj(e){return(e??`online`)!==`online`||aj.isOnline()}var cj=class extends Error{constructor(e){super(`CancelledError`),this.revert=e?.revert,this.silent=e?.silent}};function lj(e){let t=!1,n=0,r,i=`pending`,a,o,s=new Promise((e,t)=>{a=e,o=t});s.catch(OA);let c=()=>i!==`pending`,l=t=>{if(!c()){let n=new cj(t);h(n),e.onCancel?.(n)}},u=()=>{t=!0},d=()=>{t=!1},f=()=>tj.isFocused()&&(e.networkMode===`always`||aj.isOnline())&&e.canRun(),p=()=>sj(e.networkMode)&&e.canRun(),m=e=>{c()||(r?.(),i=`resolved`,a(e))},h=e=>{c()||(r?.(),i=`rejected`,o(e))},g=t=>new Promise(n=>{r=e=>{(c()||t())&&n(e)},e.onPause?.()}).then(()=>{r=void 0,c()||e.onContinue?.()}),_=()=>{if(c())return;let r,i=n===0?e.initialPromise:void 0;try{r=i??e.fn()}catch(e){r=Promise.reject(e)}Promise.resolve(r).then(m).catch(r=>{if(c())return;let i=e.retry??($A()?0:3),a=e.retryDelay??oj,o=typeof a==`function`?a(n,r):a,s=i===!0||typeof i==`number`&&nf()?void 0:g(f)).then(()=>{t?h(r):_()})})};return{promise:s,status:()=>i,cancel:l,continue:()=>(r?.(),s),cancelRetry:u,continueRetry:d,canStart:p,start:()=>(p()?_():g(p).then(_),s)}}var uj=class{#e;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),AA(this.gcTime)&&(this.#e=TA.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??($A()?1/0:3e5))}clearGcTimeout(){this.#e!==void 0&&(TA.clearTimeout(this.#e),this.#e=void 0)}};function dj(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,l=async()=>{let n=!1,l=e=>{ZA(e,()=>t.signal,()=>n=!0)},u=YA(t.options,t.fetchOptions),d=async(e,r,i)=>{if(n)return Promise.reject(t.signal.reason);if(r==null&&e.pages.length)return Promise.resolve(e);let a=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return l(e),e})(),o=await u(a),{maxPages:s}=t.options,c=i?qA:KA;return{pages:c(e.pages,o,s),pageParams:c(e.pageParams,r,s)}};if(i&&a.length){let e=i===`backward`,t=e?pj:fj,n={pages:a,pageParams:o};s=await d(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:fj(r,s);if(c>0&&e==null)break;s=await d(s,e),c++}while(ct.options.persister?.(l,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):l}}}function fj(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function pj(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}function mj(e,t){return t?fj(e,t)!=null:!1}function hj(e,t){return!t||!e.getPreviousPageParam?!1:pj(e,t)!=null}var gj=class extends uj{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e){super(),this.#s=!1,this.#o=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#i=e.client,this.#r=this.#i.getQueryCache(),this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#t=yj(this.options),this.state=e.state??this.#t,this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return this.#e}get promise(){return this.#a?.promise}setOptions(e){if(this.options={...this.#o,...e},e?._type&&(this.#e=e._type),this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){let e=yj(this.options);e.data!==void 0&&(this.setState(vj(e.data,e.dataUpdatedAt)),this.#t=e)}}optionalRemove(){!this.observers.length&&this.state.fetchStatus===`idle`&&this.#r.remove(this)}setData(e,t){let n=GA(this.state.data,e,this.options);return this.#c({data:n,type:`success`,dataUpdatedAt:t?.updatedAt,manual:t?.manual}),n}setState(e){this.#c({type:`setState`,state:e})}cancel(e){let t=this.#a?.promise;return this.#a?.cancel(e),t?t.then(OA).catch(OA):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return this.#t}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(e=>MA(e.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===JA||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0&&this.observers.some(e=>MA(e.options.staleTime,this)===`static`)}isStale(){return this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(e=0){return this.state.data===void 0?!0:e===`static`?!1:this.state.isInvalidated?!0:!jA(this.state.dataUpdatedAt,e)}onFocus(){this.observers.find(e=>e.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#a?.continue()}onOnline(){this.observers.find(e=>e.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#a?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#r.notify({type:`observerAdded`,query:this,observer:e}))}removeObserver(e){let t=this.observers.indexOf(e);t!==-1&&(this.observers.splice(t,1),this.observers.length||(this.#a&&(this.#s||this.state.fetchStatus===`paused`&&this.state.status===`pending`?this.#a.cancel({revert:!0}):this.#a.cancelRetry()),this.scheduleGc()),this.#r.notify({type:`observerRemoved`,query:this,observer:e}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||this.#c({type:`invalidate`})}async fetch(e,t){if(this.state.fetchStatus!==`idle`&&this.#a?.status()!==`rejected`){if(this.state.data!==void 0&&t?.cancelRefetch)this.cancel({silent:!0});else if(this.#a)return this.#a.continueRetry(),this.#a.promise}if(e&&this.setOptions(e),!this.options.queryFn){let e=this.observers.find(e=>e.options.queryFn);e&&this.setOptions(e.options)}let n=new AbortController,r=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(this.#s=!0,n.signal)})},i=()=>{let e=YA(this.options,t),n=(()=>{let e={client:this.#i,queryKey:this.queryKey,meta:this.meta};return r(e),e})();return this.#s=!1,this.options.persister?this.options.persister(e,n,this):e(n)},a=(()=>{let e={fetchOptions:t,options:this.options,queryKey:this.queryKey,client:this.#i,state:this.state,fetchFn:i};return r(e),e})();(this.#e===`infinite`?dj(this.options.pages):this.options.behavior)?.onFetch(a,this),this.#n=this.state,(this.state.fetchStatus===`idle`||this.state.fetchMeta!==a.fetchOptions?.meta)&&this.#c({type:`fetch`,meta:a.fetchOptions?.meta});let o=this.#a=lj({initialPromise:t?.initialPromise,fn:a.fetchFn,onCancel:e=>{e instanceof cj&&e.revert&&this.setState({...this.#n,fetchStatus:`idle`}),n.abort()},onFail:(e,t)=>{this.#c({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#c({type:`pause`})},onContinue:()=>{this.#c({type:`continue`})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0});try{let e=await o.start();if(e===void 0)throw Error(`${this.queryHash} data is undefined`);return this.setData(e),this.#r.config.onSuccess?.(e,this),this.#r.config.onSettled?.(e,this.state.error,this),e}catch(e){if(e instanceof cj){if(e.silent)return this.#a.promise;if(e.revert){if(this.state.data===void 0)throw e;return this.state.data}}throw this.#c({type:`error`,error:e}),this.#r.config.onError?.(e,this),this.#r.config.onSettled?.(this.state.data,e,this),e}finally{this.#a===o&&(this.#a=void 0),this.scheduleGc()}}#c(e){let t=t=>{switch(e.type){case`failed`:return{...t,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case`pause`:return{...t,fetchStatus:`paused`};case`continue`:return{...t,fetchStatus:`fetching`};case`fetch`:return{...t,..._j(t.data,this.options),fetchMeta:e.meta??null};case`success`:let n={...t,...vj(e.data,e.dataUpdatedAt),dataUpdateCount:t.dataUpdateCount+1,...!e.manual&&{fetchStatus:`idle`,fetchFailureCount:0,fetchFailureReason:null}};return this.#n=e.manual?n:void 0,n;case`error`:let r=e.error;return{...t,error:r,errorUpdateCount:t.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:t.fetchFailureCount+1,fetchFailureReason:r,fetchStatus:`idle`,status:`error`,isInvalidated:!0};case`invalidate`:return{...t,isInvalidated:!0};case`setState`:return{...t,...e.state}}};this.state=t(this.state),ij.batch(()=>{this.observers.slice().forEach(e=>{e.onQueryUpdate()}),this.#r.notify({query:this,type:`updated`,action:e})})}};function _j(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:sj(t.networkMode)?`fetching`:`paused`,...e===void 0&&{error:null,status:`pending`}}}function vj(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:`success`}}function yj(e){let t=typeof e.initialData==`function`?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt==`function`?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?`success`:`pending`,fetchStatus:`idle`}}var bj=class extends ej{#e;#t=void 0;#n=void 0;#r=void 0;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p=new Set;constructor(e,t){super(),this.options=t,this.#e=e,this.#o=null,this.bindMethods(),this.setOptions(t)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.#t.addObserver(this),Sj(this.#t,this.options)?this.#m():this.updateResult(),this.#y())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Cj(this.#t,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Cj(this.#t,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#b(),this.#x(),this.#t.removeObserver(this)}setOptions(e){let t=this.options,n=this.#t;if(this.options=this.#e.defaultQueryOptions(e),this.options.enabled!==void 0&&typeof this.options.enabled!=`boolean`&&typeof this.options.enabled!=`function`&&typeof MA(this.options.enabled,this.#t)!=`boolean`)throw Error(`Expected enabled to be a boolean or a callback that returns a boolean`);this.#S(),this.#t.setOptions(this.options),t._defaulted&&!BA(this.options,t)&&this.#e.getQueryCache().notify({type:`observerOptionsUpdated`,query:this.#t,observer:this});let r=this.hasListeners();r&&wj(this.#t,n,this.options,t)&&this.#m(),this.updateResult(),r&&(this.#t!==n||MA(this.options.enabled,this.#t)!==MA(t.enabled,this.#t)||MA(this.options.staleTime,this.#t)!==MA(t.staleTime,this.#t))&&this.#g();let i=this.#_();r&&(this.#t!==n||MA(this.options.enabled,this.#t)!==MA(t.enabled,this.#t)||i!==this.#f)&&this.#v(i)}getOptimisticResult(e){let t=this.#e.getQueryCache().build(this.#e,e),n=this.createResult(t,e);return BA(this.getCurrentResult(),n)||(this.#r=n,this.#a=this.options,this.#i=this.#t.state),n}getCurrentResult(){return this.#r}trackResult(e,t){return new Proxy(e,{get:(e,n)=>(this.trackProp(n),t?.(n),Reflect.get(e,n))})}trackProp(e){this.#p.add(e)}getCurrentQuery(){return this.#t}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),n=this.#e.getQueryCache().build(this.#e,t),r=()=>{},i,a=new Promise(e=>{i=e,r=this.#e.getQueryCache().subscribe(i=>{i.type===`updated`&&i.query.queryHash===n.queryHash&&n.state.data!==void 0&&(r(),e(this.createResult(n,t)))})});return Promise.race([n.fetch().then(()=>{let e=this.createResult(n,t);return i?.(e),e}).finally(()=>{r()}),a])}fetch(e){return this.#m({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#r))}#m(e){this.#S();let t=this.#t.fetch(this.options,e);return e?.throwOnError||(t=t.catch(OA)),t}#h(e){return!$A()&&MA(this.options.enabled,this.#t)!==!1&&AA(e)}#g(){this.#b();let e=MA(this.options.staleTime,this.#t);if(this.#r.isStale||!this.#h(e))return;let t=jA(this.#r.dataUpdatedAt,e)+1;this.#u=TA.setTimeout(()=>{this.#r.isStale||this.updateResult()},t)}#_(){return MA(this.options.refetchInterval,this.#t)??!1}#v(e){this.#x(),this.#f=e,this.#f!==0&&this.#h(this.#f)&&(this.#d=TA.setInterval(()=>{(this.options.refetchIntervalInBackground||tj.isFocused())&&this.#m()},this.#f))}#y(){this.#g(),this.#v(this.#_())}#b(){this.#u!==void 0&&(TA.clearTimeout(this.#u),this.#u=void 0)}#x(){this.#d!==void 0&&(TA.clearInterval(this.#d),this.#d=void 0)}createResult(e,t){let n=this.#t,r=this.options,i=this.#r,a=this.#i,o=this.#a,s=e===n?this.#n:e.state,{state:c}=e,l={...c},u=!1,d;if(t._optimisticResults){let i=this.hasListeners(),a=!i&&Sj(e,t),o=i&&wj(e,n,t,r);(a||o)&&(l={...l,..._j(c.data,e.options)}),t._optimisticResults===`isRestoring`&&(l.fetchStatus=`idle`)}let{error:f,errorUpdatedAt:p,status:m}=l;d=l.data;let h=!1;if(t.placeholderData!==void 0&&d===void 0&&m===`pending`){let e;i?.isPlaceholderData&&t.placeholderData===o?.placeholderData?(e=i.data,h=!0):e=typeof t.placeholderData==`function`?t.placeholderData(this.#l?.state.data,this.#l):t.placeholderData,e!==void 0&&(m=`success`,d=GA(i?.data,e,t),u=!0)}if(t.select&&d!==void 0&&!h){if(i&&d===a?.data&&t.select===this.#s)d=this.#c;else try{this.#s=t.select,d=t.select(d),d=GA(i?.data,d,t),this.#c=d,this.#o=null}catch(e){this.#o=e}}else d===void 0&&(this.#o=null);this.#o&&(f=this.#o,d=this.#c,p=Date.now(),m=`error`,u=!1);let g=l.fetchStatus===`fetching`,_=m===`pending`,v=m===`error`,y=_&&g,b=d!==void 0;return{status:m,fetchStatus:l.fetchStatus,isPending:_,isSuccess:m===`success`,isError:v,isInitialLoading:y,isLoading:y,data:d,dataUpdatedAt:l.dataUpdatedAt,error:f,errorUpdatedAt:p,failureCount:l.fetchFailureCount,failureReason:l.fetchFailureReason,errorUpdateCount:l.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:l.dataUpdateCount>s.dataUpdateCount||l.errorUpdateCount>s.errorUpdateCount,isFetching:g,isRefetching:g&&!_,isLoadingError:v&&!b,isPaused:l.fetchStatus===`paused`,isPlaceholderData:u,isRefetchError:v&&b,isStale:Tj(e,t),refetch:this.refetch,isEnabled:MA(t.enabled,e)!==!1}}updateResult(){let e=this.#r,t=this.createResult(this.#t,this.options);if(this.#i=this.#t.state,this.#a=this.options,this.#i.data!==void 0&&(this.#l=this.#t),BA(t,e))return;this.#r=t;let n=(()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,n=typeof t==`function`?t():t;if(n===`all`||!n&&!this.#p.size)return!0;let r=new Set(n??this.#p);return this.options.throwOnError&&r.add(`error`),Object.keys(this.#r).some(t=>{let n=t;return this.#r[n]!==e[n]&&r.has(n)})})();ij.batch(()=>{n&&this.listeners.forEach(e=>{e(this.#r)}),this.#e.getQueryCache().notify({query:this.#t,type:`observerResultsUpdated`})})}#S(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#t)return;let t=this.#t;this.#t=e,this.#n=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()}};function xj(e,t){return MA(t.enabled,e)!==!1&&e.state.data===void 0&&(e.state.status!==`error`||MA(t.retryOnMount,e)!==!1)}function Sj(e,t){return xj(e,t)||e.state.data!==void 0&&Cj(e,t,t.refetchOnMount)}function Cj(e,t,n){if(MA(t.enabled,e)!==!1&&MA(t.staleTime,e)!==`static`){let r=MA(n,e);return r===`always`||r!==!1&&Tj(e,t)}return!1}function wj(e,t,n,r){return(e!==t||MA(r.enabled,e)===!1)&&(!n.suspense||e.state.status!==`error`)&&Tj(e,n)}function Tj(e,t){return MA(t.enabled,e)!==!1&&e.isStaleByTime(MA(t.staleTime,e))}var Ej=class extends bj{constructor(e,t){super(e,t)}bindMethods(){super.bindMethods(),this.fetchNextPage=this.fetchNextPage.bind(this),this.fetchPreviousPage=this.fetchPreviousPage.bind(this)}setOptions(e){e._type=`infinite`,super.setOptions(e)}getOptimisticResult(e){return e._type=`infinite`,super.getOptimisticResult(e)}fetchNextPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`forward`}}})}fetchPreviousPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`backward`}}})}createResult(e,t){let{state:n}=e,r=super.createResult(e,t),{isFetching:i,isRefetching:a,isError:o,isRefetchError:s}=r,c=n.fetchMeta?.fetchMore?.direction,l=o&&c===`forward`,u=i&&c===`forward`,d=o&&c===`backward`,f=i&&c===`backward`;return{...r,fetchNextPage:this.fetchNextPage,fetchPreviousPage:this.fetchPreviousPage,hasNextPage:mj(t,n.data),hasPreviousPage:hj(t,n.data),isFetchNextPageError:l,isFetchingNextPage:u,isFetchPreviousPageError:d,isFetchingPreviousPage:f,isRefetchError:s&&!l&&!d,isRefetching:a&&!u&&!f}}},Dj=class extends uj{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||Oj(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:`observerAdded`,mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:`observerRemoved`,mutation:this,observer:e})}optionalRemove(){this.#t.length||(this.state.status===`pending`?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??(this.state.status===`pending`?this.execute(this.state.variables):Promise.resolve())}async execute(e){let t=()=>{this.#i({type:`continue`})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey},r=this.#r=lj({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error(`No mutationFn found`)),onFail:(e,t)=>{this.#i({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#i({type:`pause`})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)}),i=this.state.status===`pending`,a=!r.canStart();try{if(i)t();else{this.#i({type:`pending`,variables:e,isPaused:a}),this.#n.config.onMutate&&await this.#n.config.onMutate(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#i({type:`pending`,context:t,variables:e,isPaused:a})}let o=await r.start();return await this.#n.config.onSuccess?.(o,e,this.state.context,this,n),await this.options.onSuccess?.(o,e,this.state.context,n),await this.#n.config.onSettled?.(o,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(o,null,e,this.state.context,n),this.#i({type:`success`,data:o}),o}catch(t){try{await this.#n.config.onError?.(t,e,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,n)}catch(e){Promise.reject(e)}try{await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,n)}catch(e){Promise.reject(e)}throw this.#i({type:`error`,error:t}),t}finally{this.#r===r&&(this.#r=void 0),this.#n.runNext(this)}}#i(e){let t=t=>{switch(e.type){case`failed`:return{...t,failureCount:e.failureCount,failureReason:e.error};case`pause`:return{...t,isPaused:!0};case`continue`:return{...t,isPaused:!1};case`pending`:return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:`pending`,variables:e.variables,submittedAt:Date.now()};case`success`:return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:`success`,isPaused:!1};case`error`:return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:`error`}}};this.state=t(this.state),ij.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:`updated`,action:e})})}};function Oj(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:`idle`,variables:void 0,submittedAt:0}}var kj=class extends ej{#e;#t;#n;constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}build(e,t,n){let r=new Dj({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t);if(n){if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}return!0}runNext(e){let t=Aj(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){ij.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>PA(t,e))}findAll(e={}){return this.getAll().filter(t=>PA(e,t))}notify(e){ij.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return ij.batch(()=>Promise.all(e.map(e=>e.continue().catch(OA))))}};function Aj(e){return e.options.scope?.id}var jj=class extends ej{#e;constructor(e={}){super(),this.config=e,this.#e=new Map}build(e,t,n){let r=t.queryKey,i=t.queryHash??FA(r,t),a=this.get(i);return a||(a=new gj({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){this.#e.get(e.queryHash)===e&&(e.destroy(),this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){ij.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>NA(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>NA(e,t)):t}notify(e){ij.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){ij.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){ij.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},Mj=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new jj,this.#t=e.mutationCache||new kj,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=tj.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=aj.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(MA(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=kA(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return ij.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;ij.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return ij.batch(()=>{let r=n.findAll(e),i=new Set(r);return r.forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,predicate:e=>i.has(e)},t)})}cancelQueries(e,t={}){let n={revert:!0,...t},r=ij.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(OA).catch(OA)}invalidateQueries(e,t={}){return ij.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=ij.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(OA)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(OA)}async query(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t),r=n.isStaleByTime(MA(t.staleTime,n))?await n.fetch(t):n.state.data,i=t.select;return i?i(r):r}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(MA(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(OA).catch(OA)}infiniteQuery(e){return e._type=`infinite`,this.query(e)}fetchInfiniteQuery(e){return e._type=`infinite`,this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(OA).catch(OA)}ensureInfiniteQueryData(e){return e._type=`infinite`,this.ensureQueryData(e)}resumePausedMutations(){return aj.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(IA(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{LA(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(IA(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{LA(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=FA(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===JA&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},Nj=M.createContext(!1),Pj=()=>M.useContext(Nj);Nj.Provider;function Fj(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var Ij=M.createContext(Fj()),Lj=()=>M.useContext(Ij),Rj=(e,t,n)=>{let r=n?.state.error&&typeof e.throwOnError==`function`?XA(e.throwOnError,[n.state.error,n]):e.throwOnError;(e.suspense||r)&&(t.isReset()||(e.retryOnMount=!1))},zj=e=>{M.useEffect(()=>{e.clearReset()},[e])},Bj=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(i&&e.data===void 0||XA(n,[e.error,r])),Vj=e=>{if(e.suspense){let t=1e3,n=e=>e===`static`?e:Math.max(e??t,t),r=e.staleTime;e.staleTime=typeof r==`function`?(...e)=>n(r(...e)):n(r),typeof e.gcTime==`number`&&(e.gcTime=Math.max(e.gcTime,t))}},Hj=(e,t)=>e?.suspense&&t.isPending,Uj=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function Wj(e,t,n){let r=Pj(),i=Lj(),a=SA(n),o=a.defaultQueryOptions(e),s=a.getQueryCache().get(o.queryHash),c=e.subscribed!==!1;o._optimisticResults=r?`isRestoring`:c?`optimistic`:void 0,Vj(o),Rj(o,i,s),zj(i);let[l]=M.useState(()=>new t(a,o)),u=l.getOptimisticResult(o),d=!r&&c;if(M.useSyncExternalStore(M.useCallback(e=>{let t=d?l.subscribe(ij.batchCalls(e)):OA;return l.updateResult(),t},[l,d]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),M.useEffect(()=>{l.setOptions(o)},[o,l]),Hj(o,u))throw Uj(o,l,i);if(Bj({result:u,errorResetBoundary:i,throwOnError:o.throwOnError,query:s,suspense:o.suspense}))throw u.error;return o.notifyOnChangeProps?u:l.trackResult(u)}function Gj(e,t){return Wj(e,bj,t)}function Kj(e,t){return Wj(e,Ej,t)}var qj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H69l51.52,51.51a12,12,0,0,1-17,17l-72-72a12,12,0,0,1,0-17l72-72a12,12,0,0,1,17,17L69,116H216A12,12,0,0,1,228,128Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M112,56V200L40,128Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M216,120H120V56a8,8,0,0,0-13.66-5.66l-72,72a8,8,0,0,0,0,11.32l72,72A8,8,0,0,0,120,200V136h96a8,8,0,0,0,0-16ZM104,180.69,51.31,128,104,75.31Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H120v64a8,8,0,0,1-13.66,5.66l-72-72a8,8,0,0,1,0-11.32l72-72A8,8,0,0,1,120,56v64h96A8,8,0,0,1,224,128Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H54.49l61.75,61.76a6,6,0,1,1-8.48,8.48l-72-72a6,6,0,0,1,0-8.48l72-72a6,6,0,0,1,8.48,8.48L54.49,122H216A6,6,0,0,1,222,128Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H49.66l65.17,65.17a4,4,0,0,1-5.66,5.66l-72-72a4,4,0,0,1,0-5.66l72-72a4,4,0,0,1,5.66,5.66L49.66,124H216A4,4,0,0,1,220,128Z`}))]]),Jj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,128l-72,72V56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,133.66l-72,72A8,8,0,0,1,136,200V136H40a8,8,0,0,1,0-16h96V56a8,8,0,0,1,13.66-5.66l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220.24,132.24l-72,72a6,6,0,0,1-8.48-8.48L201.51,134H40a6,6,0,0,1,0-12H201.51L139.76,60.24a6,6,0,0,1,8.48-8.48l72,72A6,6,0,0,1,220.24,132.24Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M218.83,130.83l-72,72a4,4,0,0,1-5.66-5.66L206.34,132H40a4,4,0,0,1,0-8H206.34L141.17,58.83a4,4,0,0,1,5.66-5.66l72,72A4,4,0,0,1,218.83,130.83Z`}))]]),Yj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,44H160a43.86,43.86,0,0,0-32,13.85A43.86,43.86,0,0,0,96,44H24A12,12,0,0,0,12,56V200a12,12,0,0,0,12,12H96a20,20,0,0,1,20,20,12,12,0,0,0,24,0,20,20,0,0,1,20-20h72a12,12,0,0,0,12-12V56A12,12,0,0,0,232,44ZM96,188H36V68H96a20,20,0,0,1,20,20V192.81A43.79,43.79,0,0,0,96,188Zm124,0H160a43.71,43.71,0,0,0-20,4.83V88a20,20,0,0,1,20-20h60Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,56V200H160a32,32,0,0,0-32,32,32,32,0,0,0-32-32H24V56H96a32,32,0,0,1,32,32,32,32,0,0,1,32-32Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240,56V200a8,8,0,0,1-8,8H160a24,24,0,0,0-24,23.94,7.9,7.9,0,0,1-5.12,7.55A8,8,0,0,1,120,232a24,24,0,0,0-24-24H24a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8H88a32,32,0,0,1,32,32v87.73a8.17,8.17,0,0,0,7.47,8.25,8,8,0,0,0,8.53-8V80a32,32,0,0,1,32-32h64A8,8,0,0,1,240,56Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,50H160a38,38,0,0,0-32,17.55A38,38,0,0,0,96,50H24a6,6,0,0,0-6,6V200a6,6,0,0,0,6,6H96a26,26,0,0,1,26,26,6,6,0,0,0,12,0,26,26,0,0,1,26-26h72a6,6,0,0,0,6-6V56A6,6,0,0,0,232,50ZM96,194H30V62H96a26,26,0,0,1,26,26V204.31A37.86,37.86,0,0,0,96,194Zm130,0H160a37.87,37.87,0,0,0-26,10.32V88a26,26,0,0,1,26-26h66Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,52H160a36,36,0,0,0-32,19.54A36,36,0,0,0,96,52H24a4,4,0,0,0-4,4V200a4,4,0,0,0,4,4H96a28,28,0,0,1,28,28,4,4,0,0,0,8,0,28,28,0,0,1,28-28h72a4,4,0,0,0,4-4V56A4,4,0,0,0,232,52ZM96,196H28V60H96a28,28,0,0,1,28,28V209.4A35.93,35.93,0,0,0,96,196Zm132,0H160a35.94,35.94,0,0,0-28,13.41V88a28,28,0,0,1,28-28h68Z`}))]]),Xj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M144,128a16,16,0,1,1-16-16A16,16,0,0,1,144,128ZM60,112a16,16,0,1,0,16,16A16,16,0,0,0,60,112Zm136,0a16,16,0,1,0,16,16A16,16,0,0,0,196,112Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240,96v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V96A16,16,0,0,1,32,80H224A16,16,0,0,1,240,96Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm56-12a12,12,0,1,0,12,12A12,12,0,0,0,196,116ZM60,116a12,12,0,1,0,12,12A12,12,0,0,0,60,116Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,80H32A16,16,0,0,0,16,96v64a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V96A16,16,0,0,0,224,80ZM60,140a12,12,0,1,1,12-12A12,12,0,0,1,60,140Zm68,0a12,12,0,1,1,12-12A12,12,0,0,1,128,140Zm68,0a12,12,0,1,1,12-12A12,12,0,0,1,196,140Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M138,128a10,10,0,1,1-10-10A10,10,0,0,1,138,128ZM60,118a10,10,0,1,0,10,10A10,10,0,0,0,60,118Zm136,0a10,10,0,1,0,10,10A10,10,0,0,0,196,118Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm56-12a12,12,0,1,0,12,12A12,12,0,0,0,196,116ZM60,116a12,12,0,1,0,12,12A12,12,0,0,0,60,116Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M136,128a8,8,0,1,1-8-8A8,8,0,0,1,136,128Zm-76-8a8,8,0,1,0,8,8A8,8,0,0,0,60,120Zm136,0a8,8,0,1,0,8,8A8,8,0,0,0,196,120Z`}))]]),Zj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232.49,215.51,185,168a92.12,92.12,0,1,0-17,17l47.53,47.54a12,12,0,0,0,17-17ZM44,112a68,68,0,1,1,68,68A68.07,68.07,0,0,1,44,112Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M168,112a56,56,0,1,1-56-56A56,56,0,0,1,168,112Zm61.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88,88,0,1,1,11.32-11.31l50.06,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228.24,219.76l-51.38-51.38a86.15,86.15,0,1,0-8.48,8.48l51.38,51.38a6,6,0,0,0,8.48-8.48ZM38,112a74,74,0,1,1,74,74A74.09,74.09,0,0,1,38,112Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M226.83,221.17l-52.7-52.7a84.1,84.1,0,1,0-5.66,5.66l52.7,52.7a4,4,0,0,0,5.66-5.66ZM36,112a76,76,0,1,1,76,76A76.08,76.08,0,0,1,36,112Z`}))]]),Qj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M236.37,139.4a12,12,0,0,0-12-3A84.07,84.07,0,0,1,119.6,31.59a12,12,0,0,0-15-15A108.86,108.86,0,0,0,49.69,55.07,108,108,0,0,0,136,228a107.09,107.09,0,0,0,64.93-21.69,108.86,108.86,0,0,0,38.44-54.94A12,12,0,0,0,236.37,139.4Zm-49.88,47.74A84,84,0,0,1,68.86,69.51,84.93,84.93,0,0,1,92.27,48.29Q92,52.13,92,56A108.12,108.12,0,0,0,200,164q3.87,0,7.71-.27A84.79,84.79,0,0,1,186.49,187.14Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.89,147.89A96,96,0,1,1,108.11,28.11,96.09,96.09,0,0,0,227.89,147.89Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M235.54,150.21a104.84,104.84,0,0,1-37,52.91A104,104,0,0,1,32,120,103.09,103.09,0,0,1,52.88,57.48a104.84,104.84,0,0,1,52.91-37,8,8,0,0,1,10,10,88.08,88.08,0,0,0,109.8,109.8,8,8,0,0,1,10,10Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232.13,143.64a6,6,0,0,0-6-1.49A90.07,90.07,0,0,1,113.86,29.85a6,6,0,0,0-7.49-7.48A102.88,102.88,0,0,0,54.48,58.68,102,102,0,0,0,197.32,201.52a102.88,102.88,0,0,0,36.31-51.89A6,6,0,0,0,232.13,143.64Zm-42,48.29a90,90,0,0,1-126-126A90.9,90.9,0,0,1,99.65,37.66,102.06,102.06,0,0,0,218.34,156.35,90.9,90.9,0,0,1,190.1,191.93Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M230.72,145.06a4,4,0,0,0-4-1A92.08,92.08,0,0,1,111.94,29.27a4,4,0,0,0-5-5A100.78,100.78,0,0,0,56.08,59.88a100,100,0,0,0,140,140,100.78,100.78,0,0,0,35.59-50.87A4,4,0,0,0,230.72,145.06ZM191.3,193.53A92,92,0,0,1,62.47,64.7a93,93,0,0,1,39.88-30.35,100.09,100.09,0,0,0,119.3,119.3A93,93,0,0,1,191.3,193.53Z`}))]]),$j=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M230.14,70.54,185.46,25.85a20,20,0,0,0-28.29,0L33.86,149.17A19.85,19.85,0,0,0,28,163.31V208a20,20,0,0,0,20,20H92.69a19.86,19.86,0,0,0,14.14-5.86L230.14,98.82a20,20,0,0,0,0-28.28ZM91,204H52V165l84-84,39,39ZM192,103,153,64l18.34-18.34,39,39Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,90.34,192,120,136,64l29.66-29.66a8,8,0,0,1,11.31,0L221.66,79A8,8,0,0,1,221.66,90.34Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M225.9,74.78,181.21,30.09a14,14,0,0,0-19.8,0L38.1,153.41a13.94,13.94,0,0,0-4.1,9.9V208a14,14,0,0,0,14,14H92.69a13.94,13.94,0,0,0,9.9-4.1L225.9,94.58a14,14,0,0,0,0-19.8ZM94.1,209.41a2,2,0,0,1-1.41.59H48a2,2,0,0,1-2-2V163.31a2,2,0,0,1,.59-1.41L136,72.48,183.51,120ZM217.41,86.1,192,111.51,144.49,64,169.9,38.58a2,2,0,0,1,2.83,0l44.68,44.69a2,2,0,0,1,0,2.83Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224.49,76.2,179.8,31.51a12,12,0,0,0-17,0L133.17,61.17h0L39.52,154.83A11.9,11.9,0,0,0,36,163.31V208a12,12,0,0,0,12,12H92.69a12,12,0,0,0,8.48-3.51L224.48,93.17a12,12,0,0,0,0-17Zm-129,134.63A4,4,0,0,1,92.69,212H48a4,4,0,0,1-4-4V163.31a4,4,0,0,1,1.17-2.83L136,69.65,186.34,120ZM218.83,87.51,192,114.34,141.66,64l26.82-26.83a4,4,0,0,1,5.66,0l44.69,44.68a4,4,0,0,1,0,5.66Z`}))]]),eM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240.49,15.51a12,12,0,0,0-17,0L173.94,65.09l-2.54-2.55a36.05,36.05,0,0,0-50.91,0L100,83l-3.51-3.52a12,12,0,0,0-17,17L83,100,62.54,120.49a36,36,0,0,0,0,50.91l2.55,2.54L15.51,223.51a12,12,0,0,0,17,17l49.57-49.58,2.54,2.55a36.06,36.06,0,0,0,50.91,0L156,173l3.51,3.52a12,12,0,0,0,17-17L173,156l20.49-20.49a36,36,0,0,0,0-50.91l-2.55-2.54,49.58-49.57A12,12,0,0,0,240.49,15.51Zm-121.95,161a12,12,0,0,1-17,0L79.51,154.43a12,12,0,0,1,0-17L100,117l39,39Zm58-57.95h0L156,139l-39-39,20.49-20.49a12,12,0,0,1,17,0l22.06,22.06a12,12,0,0,1,0,17ZM85.27,33.37a12,12,0,0,1,21.46-10.74l8,16A12,12,0,1,1,93.27,49.37Zm-68,57.26a12,12,0,0,1,16.1-5.36l16,8a12,12,0,1,1-10.74,21.46l-16-8A12,12,0,0,1,17.27,90.63Zm221.46,74.74a12,12,0,0,1-16.1,5.36l-16-8a12,12,0,0,1,10.74-21.46l16,8A12,12,0,0,1,238.73,165.37Zm-68,57.26a12,12,0,1,1-21.46,10.74l-8-16a12,12,0,0,1,21.46-10.74Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M185,127,127,185a24,24,0,0,1-33.94,0L71,162.91A24,24,0,0,1,71,129L129,71a24,24,0,0,1,33.94,0L185,93.09A24,24,0,0,1,185,127Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M237.66,18.34a8,8,0,0,0-11.32,0l-52.4,52.41-5.37-5.38a32.05,32.05,0,0,0-45.26,0L100,88.69l-6.34-6.35A8,8,0,0,0,82.34,93.66L88.69,100,65.37,123.31a32,32,0,0,0,0,45.26l5.38,5.37-52.41,52.4a8,8,0,0,0,11.32,11.32l52.4-52.41,5.37,5.38a32.06,32.06,0,0,0,45.26,0L156,167.31l6.34,6.35a8,8,0,0,0,11.32-11.32L167.31,156l23.32-23.31a32,32,0,0,0,0-45.26l-5.38-5.37,52.41-52.4A8,8,0,0,0,237.66,18.34Zm-116.29,161a16,16,0,0,1-22.62,0L76.69,157.25a16,16,0,0,1,0-22.62L100,111.31,144.69,156Zm57.94-57.94h0L156,144.69,111.31,100l23.32-23.31a16,16,0,0,1,22.62,0l22.06,22a16,16,0,0,1,0,22.63ZM88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM24.57,93A8,8,0,0,1,35,88.57l20,8A8,8,0,0,1,49,111.43l-20-8A8,8,0,0,1,24.57,93ZM231.43,163a8,8,0,0,1-10.4,4.46l-20-8A8,8,0,1,1,207,144.57l20,8A8,8,0,0,1,231.43,163Zm-64,58.06A8,8,0,0,1,152.57,227l-8-20A8,8,0,0,1,159.43,201Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM29,103.43l20,8A8,8,0,1,0,55,96.57l-20-8A8,8,0,0,0,29,103.43ZM227,152.57l-20-8A8,8,0,1,0,201,159.43l20,8A8,8,0,0,0,227,152.57ZM159.43,201A8,8,0,0,0,144.57,207l8,20A8,8,0,1,0,167.43,221ZM237.91,18.52a8,8,0,0,0-11.5-.18L174,70.75l-5.38-5.38a32,32,0,0,0-45.28,0L106.14,82.54a4,4,0,0,0,0,5.66l61.7,61.66a4,4,0,0,0,5.66,0l16.74-16.74a32.76,32.76,0,0,0,9.81-22.52,31.82,31.82,0,0,0-9.37-23.17l-5.38-5.37,52.2-52.17A8.22,8.22,0,0,0,237.91,18.52ZM85.64,90.34a8,8,0,0,0-11.49.18,8.22,8.22,0,0,0,.41,11.37L80.67,108,65.34,123.31A31.82,31.82,0,0,0,56,146.47,32.75,32.75,0,0,0,65.77,169l5,4.94L18.49,226.13a8.21,8.21,0,0,0-.61,11.1,8,8,0,0,0,11.72.43L82,185.25l5.37,5.38a32.1,32.1,0,0,0,45.29,0L148,175.31l6.34,6.35a8,8,0,0,0,11.32-11.32Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M236.24,19.76a6,6,0,0,0-8.48,0L173.94,73.57l-6.79-6.78a30,30,0,0,0-42.42,0L100,91.51l-7.76-7.75a6,6,0,0,0-8.48,8.48L91.51,100,66.79,124.73a30,30,0,0,0,0,42.42l6.78,6.79L19.76,227.76a6,6,0,1,0,8.48,8.48l53.82-53.81,6.79,6.78a30,30,0,0,0,42.42,0L156,164.49l7.76,7.75a6,6,0,0,0,8.48-8.48L164.49,156l24.72-24.73a30,30,0,0,0,0-42.42l-6.78-6.79,53.81-53.82A6,6,0,0,0,236.24,19.76Zm-113.45,161a18,18,0,0,1-25.46,0L75.27,158.67a18,18,0,0,1,0-25.46L100,108.49,147.51,156Zm57.94-57.94L156,147.51,108.49,100l24.72-24.73a18,18,0,0,1,25.46,0l22.06,22.06a18,18,0,0,1,0,25.46ZM90.43,34.23a6,6,0,0,1,11.14-4.46l8,20a6,6,0,1,1-11.14,4.46Zm-64,59.54a6,6,0,0,1,7.8-3.34l20,8a6,6,0,1,1-4.46,11.14l-20-8A6,6,0,0,1,26.43,93.77Zm203.14,68.46a6,6,0,0,1-7.8,3.34l-20-8a6,6,0,0,1,4.46-11.14l20,8A6,6,0,0,1,229.57,162.23Zm-64,59.54a6,6,0,1,1-11.14,4.46l-8-20a6,6,0,0,1,11.14-4.46Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M237.66,18.34a8,8,0,0,0-11.32,0l-52.4,52.41-5.37-5.38a32.05,32.05,0,0,0-45.26,0L100,88.69l-6.34-6.35A8,8,0,0,0,82.34,93.66L88.69,100,65.37,123.31a32,32,0,0,0,0,45.26l5.38,5.37-52.41,52.4a8,8,0,0,0,11.32,11.32l52.4-52.41,5.37,5.38a32,32,0,0,0,45.26,0L156,167.31l6.34,6.35a8,8,0,0,0,11.32-11.32L167.31,156l23.32-23.31a32,32,0,0,0,0-45.26l-5.38-5.37,52.41-52.4A8,8,0,0,0,237.66,18.34Zm-116.29,161a16,16,0,0,1-22.62,0L76.69,157.25a16,16,0,0,1,0-22.62L100,111.31,144.69,156Zm57.94-57.94L156,144.69,111.31,100l23.32-23.31a16,16,0,0,1,22.62,0l22.06,22A16,16,0,0,1,179.31,121.37ZM88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM24.57,93A8,8,0,0,1,35,88.57l20,8A8,8,0,0,1,49,111.43l-20-8A8,8,0,0,1,24.57,93ZM231.43,163a8,8,0,0,1-10.4,4.46l-20-8A8,8,0,1,1,207,144.57l20,8A8,8,0,0,1,231.43,163Zm-64,58.06A8,8,0,0,1,152.57,227l-8-20A8,8,0,0,1,159.43,201Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M234.83,21.17a4,4,0,0,0-5.66,0L173.94,76.4l-8.2-8.2a28,28,0,0,0-39.6,0L100,94.34l-9.17-9.17a4,4,0,0,0-5.66,5.66L94.34,100,68.2,126.14a28,28,0,0,0,0,39.6l8.2,8.2L21.17,229.17a4,4,0,0,0,5.66,5.66L82.06,179.6l8.2,8.2a28,28,0,0,0,39.6,0L156,161.66l9.17,9.17a4,4,0,0,0,5.66-5.66L161.66,156l26.14-26.14a28,28,0,0,0,0-39.6l-8.2-8.2,55.23-55.23A4,4,0,0,0,234.83,21.17Zm-110.63,161a20,20,0,0,1-28.28,0L73.86,160.08a20,20,0,0,1,0-28.28L100,105.66,150.34,156Zm57.94-57.94L156,150.34,105.66,100,131.8,73.86a20,20,0,0,1,28.28,0l22.06,22.06A20,20,0,0,1,182.14,124.2ZM92.29,33.49a4,4,0,1,1,7.42-3l8,20a4,4,0,0,1-2.22,5.2A3.91,3.91,0,0,1,104,56a4,4,0,0,1-3.71-2.51Zm-64,61a4,4,0,0,1,5.2-2.22l20,8A4,4,0,0,1,52,108a3.91,3.91,0,0,1-1.49-.29l-20-8A4,4,0,0,1,28.29,94.51Zm199.42,67A4,4,0,0,1,224,164a3.91,3.91,0,0,1-1.49-.29l-20-8a4,4,0,1,1,3-7.42l20,8A4,4,0,0,1,227.71,161.49Zm-64,61a4,4,0,0,1-2.22,5.2A3.91,3.91,0,0,1,160,228a4,4,0,0,1-3.71-2.51l-8-20a4,4,0,0,1,7.42-3Z`}))]]),tM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H136v48a8,8,0,0,1-16,0V136H72a8,8,0,0,1,0-16h48V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H134v82a6,6,0,0,1-12,0V134H40a6,6,0,0,1,0-12h82V40a6,6,0,0,1,12,0v82h82A6,6,0,0,1,222,128Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H132v84a4,4,0,0,1-8,0V132H40a4,4,0,0,1,0-8h84V40a4,4,0,0,1,8,0v84h84A4,4,0,0,1,220,128Z`}))]]),nM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M124,216a12,12,0,0,1-12,12H48a12,12,0,0,1-12-12V40A12,12,0,0,1,48,28h64a12,12,0,0,1,0,24H60V204h52A12,12,0,0,1,124,216Zm108.49-96.49-40-40a12,12,0,0,0-17,17L195,116H112a12,12,0,0,0,0,24h83l-19.52,19.51a12,12,0,0,0,17,17l40-40A12,12,0,0,0,232.49,119.51Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,56V200a16,16,0,0,1-16,16H48V40H208A16,16,0,0,1,224,56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40A8,8,0,0,0,176,88v32H112a8,8,0,0,0,0,16h64v32a8,8,0,0,0,13.66,5.66l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M118,216a6,6,0,0,1-6,6H48a6,6,0,0,1-6-6V40a6,6,0,0,1,6-6h64a6,6,0,0,1,0,12H54V210h58A6,6,0,0,1,118,216Zm110.24-92.24-40-40a6,6,0,0,0-8.48,8.48L209.51,122H112a6,6,0,0,0,0,12h97.51l-29.75,29.76a6,6,0,1,0,8.48,8.48l40-40A6,6,0,0,0,228.24,123.76Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M116,216a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V40a4,4,0,0,1,4-4h64a4,4,0,0,1,0,8H52V212h60A4,4,0,0,1,116,216Zm110.83-90.83-40-40a4,4,0,0,0-5.66,5.66L214.34,124H112a4,4,0,0,0,0,8H214.34l-33.17,33.17a4,4,0,0,0,5.66,5.66l40-40A4,4,0,0,0,226.83,125.17Z`}))]]),rM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M199,125.31l-49.88-18.39L130.69,57a19.92,19.92,0,0,0-37.38,0L74.92,106.92,25,125.31a19.92,19.92,0,0,0,0,37.38l49.88,18.39L93.31,231a19.92,19.92,0,0,0,37.38,0l18.39-49.88L199,162.69a19.92,19.92,0,0,0,0-37.38Zm-63.38,35.16a12,12,0,0,0-7.11,7.11L112,212.28l-16.47-44.7a12,12,0,0,0-7.11-7.11L43.72,144l44.7-16.47a12,12,0,0,0,7.11-7.11L112,75.72l16.47,44.7a12,12,0,0,0,7.11,7.11L180.28,144ZM140,40a12,12,0,0,1,12-12h12V16a12,12,0,0,1,24,0V28h12a12,12,0,0,1,0,24H188V64a12,12,0,0,1-24,0V52H152A12,12,0,0,1,140,40ZM252,88a12,12,0,0,1-12,12h-4v4a12,12,0,0,1-24,0v-4h-4a12,12,0,0,1,0-24h4V72a12,12,0,0,1,24,0v4h4A12,12,0,0,1,252,88Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M194.82,151.43l-55.09,20.3-20.3,55.09a7.92,7.92,0,0,1-14.86,0l-20.3-55.09-55.09-20.3a7.92,7.92,0,0,1,0-14.86l55.09-20.3,20.3-55.09a7.92,7.92,0,0,1,14.86,0l20.3,55.09,55.09,20.3A7.92,7.92,0,0,1,194.82,151.43Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M208,144a15.78,15.78,0,0,1-10.42,14.94L146,178l-19,51.62a15.92,15.92,0,0,1-29.88,0L78,178l-51.62-19a15.92,15.92,0,0,1,0-29.88L78,110l19-51.62a15.92,15.92,0,0,1,29.88,0L146,110l51.62,19A15.78,15.78,0,0,1,208,144ZM152,48h16V64a8,8,0,0,0,16,0V48h16a8,8,0,0,0,0-16H184V16a8,8,0,0,0-16,0V32H152a8,8,0,0,0,0,16Zm88,32h-8V72a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0V96h8a8,8,0,0,0,0-16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M196.89,130.94,144.4,111.6,125.06,59.11a13.92,13.92,0,0,0-26.12,0L79.6,111.6,27.11,130.94a13.92,13.92,0,0,0,0,26.12L79.6,176.4l19.34,52.49a13.92,13.92,0,0,0,26.12,0L144.4,176.4l52.49-19.34a13.92,13.92,0,0,0,0-26.12Zm-4.15,14.86-55.08,20.3a6,6,0,0,0-3.56,3.56l-20.3,55.08a1.92,1.92,0,0,1-3.6,0L89.9,169.66a6,6,0,0,0-3.56-3.56L31.26,145.8a1.92,1.92,0,0,1,0-3.6l55.08-20.3a6,6,0,0,0,3.56-3.56l20.3-55.08a1.92,1.92,0,0,1,3.6,0l20.3,55.08a6,6,0,0,0,3.56,3.56l55.08,20.3a1.92,1.92,0,0,1,0,3.6ZM146,40a6,6,0,0,1,6-6h18V16a6,6,0,0,1,12,0V34h18a6,6,0,0,1,0,12H182V64a6,6,0,0,1-12,0V46H152A6,6,0,0,1,146,40ZM246,88a6,6,0,0,1-6,6H230v10a6,6,0,0,1-12,0V94H208a6,6,0,0,1,0-12h10V72a6,6,0,0,1,12,0V82h10A6,6,0,0,1,246,88Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M196.2,132.81l-53.36-19.65L123.19,59.8a11.93,11.93,0,0,0-22.38,0L81.16,113.16,27.8,132.81a11.93,11.93,0,0,0,0,22.38l53.36,19.65,19.65,53.36a11.93,11.93,0,0,0,22.38,0l19.65-53.36,53.36-19.65a11.93,11.93,0,0,0,0-22.38Zm-2.77,14.87L138.35,168a4,4,0,0,0-2.37,2.37l-20.3,55.08a3.92,3.92,0,0,1-7.36,0L88,170.35A4,4,0,0,0,85.65,168l-55.08-20.3a3.92,3.92,0,0,1,0-7.36L85.65,120A4,4,0,0,0,88,117.65l20.3-55.08a3.92,3.92,0,0,1,7.36,0L136,117.65a4,4,0,0,0,2.37,2.37l55.08,20.3a3.92,3.92,0,0,1,0,7.36ZM148,40a4,4,0,0,1,4-4h20V16a4,4,0,0,1,8,0V36h20a4,4,0,0,1,0,8H180V64a4,4,0,0,1-8,0V44H152A4,4,0,0,1,148,40Zm96,48a4,4,0,0,1-4,4H228v12a4,4,0,0,1-8,0V92H208a4,4,0,0,1,0-8h12V72a4,4,0,0,1,8,0V84h12A4,4,0,0,1,244,88Z`}))]]),iM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M116,36V20a12,12,0,0,1,24,0V36a12,12,0,0,1-24,0Zm80,92a68,68,0,1,1-68-68A68.07,68.07,0,0,1,196,128Zm-24,0a44,44,0,1,0-44,44A44.05,44.05,0,0,0,172,128ZM51.51,68.49a12,12,0,1,0,17-17l-12-12a12,12,0,0,0-17,17Zm0,119-12,12a12,12,0,0,0,17,17l12-12a12,12,0,1,0-17-17ZM196,72a12,12,0,0,0,8.49-3.51l12-12a12,12,0,0,0-17-17l-12,12A12,12,0,0,0,196,72Zm8.49,115.51a12,12,0,0,0-17,17l12,12a12,12,0,0,0,17-17ZM48,128a12,12,0,0,0-12-12H20a12,12,0,0,0,0,24H36A12,12,0,0,0,48,128Zm80,80a12,12,0,0,0-12,12v16a12,12,0,0,0,24,0V220A12,12,0,0,0,128,208Zm108-92H220a12,12,0,0,0,0,24h16a12,12,0,0,0,0-24Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M184,128a56,56,0,1,1-56-56A56,56,0,0,1,184,128Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm8,24a64,64,0,1,0,64,64A64.07,64.07,0,0,0,128,64ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M122,40V16a6,6,0,0,1,12,0V40a6,6,0,0,1-12,0Zm68,88a62,62,0,1,1-62-62A62.07,62.07,0,0,1,190,128Zm-12,0a50,50,0,1,0-50,50A50.06,50.06,0,0,0,178,128ZM59.76,68.24a6,6,0,1,0,8.48-8.48l-16-16a6,6,0,0,0-8.48,8.48Zm0,119.52-16,16a6,6,0,1,0,8.48,8.48l16-16a6,6,0,1,0-8.48-8.48ZM192,70a6,6,0,0,0,4.24-1.76l16-16a6,6,0,0,0-8.48-8.48l-16,16A6,6,0,0,0,192,70Zm4.24,117.76a6,6,0,0,0-8.48,8.48l16,16a6,6,0,0,0,8.48-8.48ZM46,128a6,6,0,0,0-6-6H16a6,6,0,0,0,0,12H40A6,6,0,0,0,46,128Zm82,82a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V216A6,6,0,0,0,128,210Zm112-88H216a6,6,0,0,0,0,12h24a6,6,0,0,0,0-12Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M124,40V16a4,4,0,0,1,8,0V40a4,4,0,0,1-8,0Zm64,88a60,60,0,1,1-60-60A60.07,60.07,0,0,1,188,128Zm-8,0a52,52,0,1,0-52,52A52.06,52.06,0,0,0,180,128ZM61.17,66.83a4,4,0,0,0,5.66-5.66l-16-16a4,4,0,0,0-5.66,5.66Zm0,122.34-16,16a4,4,0,0,0,5.66,5.66l16-16a4,4,0,0,0-5.66-5.66ZM192,68a4,4,0,0,0,2.83-1.17l16-16a4,4,0,1,0-5.66-5.66l-16,16A4,4,0,0,0,192,68Zm2.83,121.17a4,4,0,0,0-5.66,5.66l16,16a4,4,0,0,0,5.66-5.66ZM40,124H16a4,4,0,0,0,0,8H40a4,4,0,0,0,0-8Zm88,88a4,4,0,0,0-4,4v24a4,4,0,0,0,8,0V216A4,4,0,0,0,128,212Zm112-88H216a4,4,0,0,0,0,8h24a4,4,0,0,0,0-8Z`}))]]),aM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H180V36A28,28,0,0,0,152,8H104A28,28,0,0,0,76,36V48H40a12,12,0,0,0,0,24h4V208a20,20,0,0,0,20,20H192a20,20,0,0,0,20-20V72h4a12,12,0,0,0,0-24ZM100,36a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4V48H100Zm88,168H68V72H188ZM116,104v64a12,12,0,0,1-24,0V104a12,12,0,0,1,24,0Zm48,0v64a12,12,0,0,1-24,0V104a12,12,0,0,1,24,0Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M200,56V208a8,8,0,0,1-8,8H64a8,8,0,0,1-8-8V56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM112,168a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm0-120H96V40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,50H174V40a22,22,0,0,0-22-22H104A22,22,0,0,0,82,40V50H40a6,6,0,0,0,0,12H50V208a14,14,0,0,0,14,14H192a14,14,0,0,0,14-14V62h10a6,6,0,0,0,0-12ZM94,40a10,10,0,0,1,10-10h48a10,10,0,0,1,10,10V50H94ZM194,208a2,2,0,0,1-2,2H64a2,2,0,0,1-2-2V62H194ZM110,104v64a6,6,0,0,1-12,0V104a6,6,0,0,1,12,0Zm48,0v64a6,6,0,0,1-12,0V104a6,6,0,0,1,12,0Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,52H172V40a20,20,0,0,0-20-20H104A20,20,0,0,0,84,40V52H40a4,4,0,0,0,0,8H52V208a12,12,0,0,0,12,12H192a12,12,0,0,0,12-12V60h12a4,4,0,0,0,0-8ZM92,40a12,12,0,0,1,12-12h48a12,12,0,0,1,12,12V52H92ZM196,208a4,4,0,0,1-4,4H64a4,4,0,0,1-4-4V60H196ZM108,104v64a4,4,0,0,1-8,0V104a4,4,0,0,1,8,0Zm48,0v64a4,4,0,0,1-8,0V104a4,4,0,0,1,8,0Z`}))]]),oM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a12,12,0,0,1-12,12h-8v8a12,12,0,0,1-24,0v-8h-8a12,12,0,0,1,0-24h8v-8a12,12,0,0,1,24,0v8h8A12,12,0,0,1,256,136Zm-54.81,56.28a12,12,0,1,1-18.38,15.44C169.12,191.42,145,172,108,172c-28.89,0-55.46,12.68-74.81,35.72a12,12,0,0,1-18.38-15.44A124.08,124.08,0,0,1,63.5,156.53a72,72,0,1,1,89,0A124,124,0,0,1,201.19,192.28ZM108,148a48,48,0,1,0-48-48A48.05,48.05,0,0,0,108,148Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M168,100a60,60,0,1,1-60-60A60,60,0,0,1,168,100Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136Zm-57.87,58.85a8,8,0,0,1-12.26,10.3C165.75,181.19,138.09,168,108,168s-57.75,13.19-77.87,37.15a8,8,0,0,1-12.25-10.3c14.94-17.78,33.52-30.41,54.17-37.17a68,68,0,1,1,71.9,0C164.6,164.44,183.18,177.07,198.13,194.85ZM108,152a52,52,0,1,0-52-52A52.06,52.06,0,0,0,108,152Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136ZM144,157.68a68,68,0,1,0-71.9,0c-20.65,6.76-39.23,19.39-54.17,37.17A8,8,0,0,0,24,208H192a8,8,0,0,0,6.13-13.15C183.18,177.07,164.6,164.44,144,157.68Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M254,136a6,6,0,0,1-6,6H230v18a6,6,0,0,1-12,0V142H200a6,6,0,0,1,0-12h18V112a6,6,0,0,1,12,0v18h18A6,6,0,0,1,254,136Zm-57.41,60.14a6,6,0,1,1-9.18,7.72C166.9,179.45,138.69,166,108,166s-58.89,13.45-79.41,37.86a6,6,0,0,1-9.18-7.72C35.14,177.41,55,164.48,77,158.25a66,66,0,1,1,62,0C161,164.48,180.86,177.41,196.59,196.14ZM108,154a54,54,0,1,0-54-54A54.06,54.06,0,0,0,108,154Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136Zm-57.87,58.85a8,8,0,0,1-12.26,10.3C165.75,181.19,138.09,168,108,168s-57.75,13.19-77.87,37.15a8,8,0,0,1-12.25-10.3c14.94-17.78,33.52-30.41,54.17-37.17a68,68,0,1,1,71.9,0C164.6,164.44,183.18,177.07,198.13,194.85ZM108,152a52,52,0,1,0-52-52A52.06,52.06,0,0,0,108,152Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M252,136a4,4,0,0,1-4,4H228v20a4,4,0,0,1-8,0V140H200a4,4,0,0,1,0-8h20V112a4,4,0,0,1,8,0v20h20A4,4,0,0,1,252,136Zm-56.94,61.43a4,4,0,0,1-6.12,5.14C168,177.7,139.3,164,108,164s-60,13.7-80.94,38.57a4,4,0,1,1-6.12-5.14c16.71-19.9,38.13-33.13,61.89-38.59a64,64,0,1,1,50.34,0C156.93,164.3,178.35,177.53,195.06,197.43ZM108,156a56,56,0,1,0-56-56A56.06,56.06,0,0,0,108,156Z`}))]]),sM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:qj}));sM.displayName=`ArrowLeftIcon`;var cM=sM,lM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Jj}));lM.displayName=`ArrowRightIcon`;var uM=lM,dM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Yj}));dM.displayName=`BookOpenIcon`;var fM=dM,pM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Xj}));pM.displayName=`DotsThreeIcon`;var mM=pM,hM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Zj}));hM.displayName=`MagnifyingGlassIcon`;var gM=hM,_M=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Qj}));_M.displayName=`MoonIcon`;var vM=_M,yM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:$j}));yM.displayName=`PencilSimpleIcon`;var bM=yM,xM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:eM}));xM.displayName=`PlugsConnectedIcon`;var SM=xM,CM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:tM}));CM.displayName=`PlusIcon`;var wM=CM,TM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:nM}));TM.displayName=`SignOutIcon`;var EM=TM,DM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:rM}));DM.displayName=`SparkleIcon`;var OM=DM,kM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:iM}));kM.displayName=`SunIcon`;var AM=kM,jM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:aM}));jM.displayName=`TrashIcon`;var MM=jM,NM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:oM}));NM.displayName=`UserPlusIcon`;var PM=NM,FM=class extends Error{status;problems;code;constructor(e,t,n=[],r=``){super(e),this.status=t,this.problems=n,this.code=r}},IM=`fanout:unauthorized`;function LM(){let e=new URLSearchParams(window.location.search).get(`return_to`);if(!e)return``;let t=new URL(e,window.location.origin);return t.origin!==window.location.origin||t.pathname!==`/api/auth/oauth/authorize`?``:`${t.pathname}${t.search}`}function RM(e){return!e||typeof e!=`object`||!(`id`in e)||typeof e.id!=`string`||e.id===``?`none`:`user`}function zM(){window.dispatchEvent(new Event(IM))}async function BM(e,t={}){let n=new Headers(t.headers);n.set(`Fanout-Request`,`1`);let r=await fetch(e,{...t,headers:n,credentials:`same-origin`});if(r.status===401&&zM(),r.status===403){let e=await r.clone().json().catch(()=>({}));throw new FM(e.message??`You do not have permission to perform this action.`,r.status,[],e.code??``)}return r}async function VM(){let e=await BM(`/api/auth/logout`,{method:`POST`});if(!e.ok&&e.status!==401)throw Error(`Sign-out failed — your session is still active.`);e.status!==401&&zM(),window.location.assign(`/`)}var HM=(0,M.createContext)(null);function UM(){let e=(0,M.useContext)(HM);if(!e)throw Error(`Fanout runtime status is unavailable`);return e}var WM=(0,M.createContext)(null);function GM(){let e=(0,M.useContext)(WM);if(!e)throw Error(`Fanout viewer is unavailable`);return e}function KM(e){if(!e||typeof e!=`object`)return null;let t=e;return typeof t.id!=`string`||t.id===``||t.status!==`active`&&t.status!==`suspended`?null:{id:t.id,email:typeof t.email==`string`?t.email:``,display_name:typeof t.display_name==`string`?t.display_name:``,status:t.status,role:typeof t.role==`string`?t.role:``}}async function qM(e,t){let n=await fetch(e,{method:t===void 0?`GET`:`POST`,headers:t===void 0?void 0:{"Content-Type":`application/json`},body:t===void 0?void 0:JSON.stringify(t),credentials:`same-origin`}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(r.message??`Request failed (${n.status})`);return r}function JM({children:e,wide:t=!1}){return(0,N.jsx)(u,{mih:`100dvh`,style:{background:`radial-gradient(circle at 50% -12%, var(--mantine-color-brand-light), transparent 38%), linear-gradient(180deg, var(--mantine-color-default-hover), var(--mantine-color-body) 62%)`},children:(0,N.jsx)(je,{mih:`100dvh`,px:`md`,py:48,children:(0,N.jsx)(ve,{size:t?680:480,w:`100%`,children:(0,N.jsx)(Fe,{radius:28,p:{base:24,sm:40},style:{background:`var(--mantine-color-body)`,border:`1px solid var(--mantine-color-default-border)`,boxShadow:`var(--mantine-shadow-xl)`},children:e})})})})}function YM(){return typeof window>`u`?``:new URLSearchParams(window.location.search).get(`setup_token`)??``}function XM(){return typeof window>`u`?``:new URLSearchParams(window.location.search).get(`login_token`)??``}function ZM({children:e}){let t=ze(),[n,r]=(0,M.useState)(null),[i,a]=(0,M.useState)(!1),[o,s]=(0,M.useState)(`none`),[c,l]=(0,M.useState)(null),[d,f]=(0,M.useState)(!1),[p,m]=(0,M.useState)(``),[h,g]=(0,M.useState)(``),[_,v]=(0,M.useState)(YM),[y,b]=(0,M.useState)(XM),[x,S]=(0,M.useState)(``),[C,w]=(0,M.useState)(!1),[T,ee]=(0,M.useState)(0),[E,D]=(0,M.useState)(()=>Date.now()),[O,te]=(0,M.useState)(!1),[re,k]=(0,M.useState)(``),[ie,ae]=(0,M.useState)(null),[se,le]=(0,M.useState)(!1),de=(0,M.useRef)(null),fe=LM(),pe=o===`user`;async function he(){let e=await fetch(`/api/auth/me`,{credentials:`same-origin`});if(!e.ok){s(`none`),l(null);return}let t=await e.json().catch(()=>null);s(RM(t)),l(KM(t))}async function ge(){try{let e=await fetch(`/api/auth/me`,{credentials:`same-origin`});if(!e.ok)return;l(KM(await e.json().catch(()=>null)))}catch{}}(0,M.useEffect)(()=>{let e=new URL(window.location.href);(e.searchParams.has(`setup_token`)||e.searchParams.has(`login_token`))&&(e.searchParams.delete(`setup_token`),e.searchParams.delete(`login_token`),t({href:e.pathname+e.search+e.hash,replace:!0}))},[t]),(0,M.useEffect)(()=>{qM(`/api/auth/status`).then(r).catch(e=>k(String(e))).finally(()=>a(!0)),he().catch(()=>s(`none`)).finally(()=>f(!0));let e=()=>{s(`none`),l(null)};return window.addEventListener(IM,e),()=>window.removeEventListener(IM,e)},[]),(0,M.useEffect)(()=>{d&&o===`none`&&y&&(te(!0),k(``),qM(`/api/auth/link/verify`,{token:y}).then(()=>{s(`user`),ge()}).catch(e=>k(e instanceof Error?e.message:String(e))).finally(()=>{b(``),te(!1)}))},[y,d,o]),(0,M.useEffect)(()=>{pe&&d&&fe&&window.location.replace(fe)},[pe,fe,d]),(0,M.useEffect)(()=>{if(T<=Date.now())return;let e=setInterval(()=>{D(Date.now()),Date.now()>=T&&clearInterval(e)},1e3);return()=>clearInterval(e)},[T]);let _e=Math.max(0,Math.ceil((T-E)/1e3));(0,M.useEffect)(()=>{C&&!O&&re&&de.current?.querySelector(`input`)?.focus()},[O,C,re]);async function ve(e){try{await navigator.clipboard.writeText(e),le(!0)}catch{k(`Clipboard access failed. Select and copy the token manually.`)}}if(ie?.ingest_token)return(0,N.jsx)(JM,{wide:!0,children:(0,N.jsxs)(oe,{gap:`lg`,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(`div`,{children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Setup complete`}),(0,N.jsx)(xe,{order:1,mt:`xs`,fz:{base:28,sm:32},lh:1.08,children:`Save your ingest token`})]}),(0,N.jsx)(ue,{c:`dimmed`,children:`Fanout shows this token once. Store it with your collector secrets before continuing.`}),(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`OTLP endpoint`}),(0,N.jsx)(ss,{block:!0,children:ie.suggested_endpoint??window.location.origin})]}),(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`Header`}),(0,N.jsxs)(ss,{block:!0,children:[ie.ingest_header_name??`Authorization`,`: Bearer `,ie.ingest_token]})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),(0,N.jsxs)(ne,{grow:!0,align:`stretch`,children:[(0,N.jsx)(ce,{variant:`light`,radius:`md`,leftSection:se?(0,N.jsx)(me,{size:16,weight:`bold`}):(0,N.jsx)(Ee,{size:16}),onClick:()=>void ve(`${ie.ingest_header_name??`Authorization`}: Bearer ${ie.ingest_token}`),children:se?`Copied`:`Copy header`}),(0,N.jsx)(ce,{radius:`md`,rightSection:(0,N.jsx)(uM,{size:16,weight:`bold`}),onClick:()=>{s(`user`),ae(null),ge()},children:`Continue to Fanout`})]}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,onClick:()=>void ve(ie.ingest_token??``),children:`Copy token only`})]})});if(!d||!i||y)return(0,N.jsx)(je,{mih:`100dvh`,children:(0,N.jsx)(Ie,{size:`sm`})});if(!n)return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:`lg`,children:[(0,N.jsx)(ke,{}),(0,N.jsx)(xe,{order:1,children:`Fanout is unavailable`}),(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re||`Authentication status could not be loaded.`})]})});if(pe&&fe)return null;if(pe)return(0,N.jsx)(HM.Provider,{value:n,children:(0,N.jsx)(WM.Provider,{value:c??{id:``,email:p,display_name:h,status:`active`,role:``},children:e})});if(n&&!n.setup_required&&n.auth_mode===`oidc`){let e=fe?`/api/auth/oidc/start?return_to=${encodeURIComponent(fe)}`:`/api/auth/oidc/start`;return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:28,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(oe,{gap:10,children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Secure workspace`}),(0,N.jsx)(xe,{order:1,fz:{base:28,sm:32},lh:1.08,children:`Sign in`}),(0,N.jsx)(ue,{c:`dimmed`,size:`md`,lh:1.6,children:`Use your organization's identity provider to continue.`})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),(0,N.jsx)(ce,{component:`a`,href:e,size:`md`,radius:`md`,rightSection:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:`Continue with SSO`})]})})}async function ye(){te(!0),k(``);try{await qM(`/api/auth/code/send`,{email:p}),w(!0),S(``),ee(Date.now()+3e4),D(Date.now())}catch(e){k(e instanceof Error?e.message:String(e))}finally{te(!1)}}async function A(e){te(!0),k(``);try{await qM(`/api/auth/code/verify`,{email:p,code:e}),s(`user`),w(!1),S(``),ee(0),ge()}catch(e){S(``),k(e instanceof Error?e.message:String(e))}finally{te(!1)}}function j(){w(!1),S(``),k(``)}async function be(e){e.preventDefault(),te(!0),k(``);try{if(n?.setup_required){let e=await qM(`/api/auth/setup`,{email:p,display_name:h,setup_token:_});e.ingest_token?ae(e):(s(`user`),ge())}else if(C){await A(x);return}else{await ye();return}}catch(e){k(e instanceof Error?e.message:String(e))}finally{te(!1)}}let Se=C&&!n?.setup_required,we=n?.setup_required?`Create the first admin`:Se?`Check your email`:n?.self_signup?`Sign in or create an account`:`Sign in`,Te=n?.setup_required?`Use the one-time token printed by the Fanout process.`:n?.smtp_configured?Se?`We sent a code to ${p}.`:n?.self_signup?`Enter your email to sign in or create a viewer account. No password needed.`:`Enter your email and we’ll send a short verification code. No password needed.`:`Email delivery is not configured. Ask the operator to run fanout login-link with your email address.`;return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:28,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(oe,{gap:10,children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:n?.setup_required?`One-time setup`:`Secure workspace`}),(0,N.jsx)(xe,{order:1,fz:{base:28,sm:32},lh:1.08,children:we}),Te&&(0,N.jsx)(ue,{c:`dimmed`,size:`md`,lh:1.6,maw:390,children:Te})]}),(0,N.jsx)(`form`,{onSubmit:be,children:(0,N.jsxs)(oe,{gap:`md`,children:[(0,N.jsx)(Rc,{label:`Email`,placeholder:`you@company.com`,type:`email`,required:!0,value:p,onChange:e=>m(e.currentTarget.value),disabled:C,variant:`filled`,radius:`md`,size:`md`,autoFocus:!C}),n?.setup_required&&(0,N.jsx)(Rc,{label:`Display name`,placeholder:`Your display name`,value:h,onChange:e=>g(e.currentTarget.value),variant:`filled`,radius:`md`,size:`md`}),n?.setup_required&&(0,N.jsx)(Rc,{label:`Setup token`,placeholder:`from the setup URL printed at startup`,required:!0,value:_,onChange:e=>v(e.currentTarget.value),autoComplete:`one-time-code`,variant:`filled`,radius:`md`,size:`md`}),Se&&(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`Verification code`}),(0,N.jsx)(u,{ref:de,children:(0,N.jsx)(Lc,{length:6,type:`number`,oneTimeCode:!0,autoFocus:!0,value:x,onChange:S,onComplete:e=>void A(e),disabled:O,error:!!re,size:`md`,radius:`md`,"aria-label":`Verification code`,getInputProps:e=>({"aria-label":`Digit ${e+1}`})})}),(0,N.jsxs)(ne,{justify:`space-between`,gap:`xs`,children:[(0,N.jsxs)(ue,{c:`dimmed`,size:`xs`,children:[`Sent to `,p]}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,leftSection:(0,N.jsx)(cM,{size:12,weight:`bold`}),onClick:j,disabled:O,children:`Change email`})]}),(0,N.jsxs)(ne,{justify:`space-between`,gap:`xs`,children:[(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,children:`Codes expire in 5 minutes`}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,onClick:()=>void ye(),disabled:O||_e>0,children:_e>0?`Resend in ${_e}s`:`Resend code`})]})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),Se?(0,N.jsx)(ce,{type:`submit`,size:`md`,radius:`md`,mt:4,loading:O,disabled:O||x.length<6,rightSection:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:`Verify code`}):(0,N.jsx)(ce,{type:`submit`,size:`md`,radius:`md`,mt:4,loading:O,disabled:!n||!n.setup_required&&!n.smtp_configured,leftSection:n?.setup_required?(0,N.jsx)(PM,{size:17,weight:`bold`}):void 0,rightSection:n?.setup_required?void 0:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:n?.setup_required?`Create admin`:`Send code`})]})})]})})}var QM=[`agent-threads`];async function $M(e){let t=await BM(e);if(!t.ok)throw Error(`Request failed (${t.status})`);return t.json()}var eN=new Set([`create_dashboard`,`edit_dashboard`,`replace_dashboard`,`restore_dashboard_version`]);function tN(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function nN(e){if(typeof e==`string`)try{let t=JSON.parse(e);if(tN(t))return t}catch{}}var rN=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),iN=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;function aN(e){return tN(e)&&typeof e.id==`string`&&[`ok`,`empty`,`error`,`invalid`,`not_run`,`partial`,`stale`].includes(String(e.status))&&(e.rows===void 0||iN(e.rows))&&(e.elapsed_ms===void 0||iN(e.elapsed_ms))&&(e.diagnosis===void 0||typeof e.diagnosis==`string`)&&(e.error===void 0||typeof e.error==`string`)}function oN(e){if(!tN(e)||!Number.isInteger(e.base_version)||Number(e.base_version)<0||!Number.isInteger(e.version)||Number(e.version)<1||!Array.isArray(e.changes)||typeof e.layout_changed!=`boolean`||e.dashboard_fields!==void 0&&!rN(e.dashboard_fields)||!e.changes.every(e=>tN(e)&&typeof e.panel_id==`string`&&typeof e.title==`string`&&[`added`,`changed`,`removed`].includes(String(e.kind))&&(e.fields===void 0||rN(e.fields)&&!e.fields.includes(`grid`))&&(e.position_changed===void 0||typeof e.position_changed==`boolean`)))return!1;let t=e.save_check;return tN(t)&&typeof t.checked==`boolean`&&iN(t.elapsed_ms)&&Array.isArray(t.panels)&&t.panels.every(e=>aN(e)&&Number.isInteger(e.rows)&&Number(e.rows)>=0)&&new Set(t.panels.map(e=>e.id)).size===t.panels.length&&(t.reason===void 0||typeof t.reason==`string`)&&(!t.checked||t.panels.every(e=>e.status!==`not_run`&&e.status!==`invalid`))}function sN(e,t,n){let r=-1;n.forEach((n,i)=>{n.role===`tool`&&n.toolCallId===e&&n.content===t&&(r=i)});let i=r<0?n.length:r,a=-1;if(n.slice(0,i).forEach((e,t)=>{e.role===`user`&&(a=t)}),a<0)return null;let o=n.slice(a+1,i).flatMap(e=>e.role===`assistant`?e.toolCalls??[]:[]).filter(t=>t.id===e),s=o.length===1?o[0].function.name:void 0;if(!s||!eN.has(s))return null;let c=nN(t),l=c?.dashboard,u=c?.receipt;return!c||c.error||c.isError||!tN(l)||typeof l.id!=`string`||!l.id||typeof l.name!=`string`||!l.name||!oN(u)||l.version!==u.version||r>=0&&n[r].error?null:{id:l.id,name:l.name,version:u.version,label:s===`create_dashboard`?`Created`:s===`restore_dashboard_version`?`Restored`:`Updated`,receipt:u}}var cN={viz:`chart type`,sql:`SQL`,content:`text`,x_unit:`x-axis unit`,options:`display options`,drill:`drill-down`,click:`click action`,time:`time range`,annotations:`markers`,better:`better direction`,reduce:`summary`,min:`minimum`,max:`maximum`},lN=e=>Object.hasOwn(cN,e)?cN[e]:e.replaceAll(`_`,` `),uN=e=>e.kind===`added`?`+ ${e.title}`:e.kind===`removed`?`− ${e.title}`:`~ ${e.title}${e.fields?.length?`: `+e.fields.map(lN).join(`, `):``}${e.position_changed?` · moved`:``}`;function dN(e){return[...e.changes.map(uN),...e.layout_changed?[`Layout adjusted`]:[],...e.dashboard_fields?.map(e=>`Dashboard: ${lN(e)}`)??[]]}function fN(e,t,n){return e.filter(e=>n.has(e.panel_id)&&!t.some(t=>t.panel_id===e.panel_id&&t.path===e.path))}var pN={schema:`Telemetry`,context:`Context`,draft:`Draft`,validation:`Validation`,preview:`Preview`,save:`Save`},mN=new Set([`get_intelligence_snapshot`,`query_telemetry`,`get_observability_overview`,`get_service_topology`,`get_service_dependencies`,`get_service_performance`,`inspect_trace`,`search_logs`]),hN=(e,t)=>Array.isArray(e)?e.flatMap(e=>tN(e)&&typeof e.path==`string`&&typeof e.message==`string`?[{panel_id:t,path:e.path,message:e.message}]:[]):[],gN=e=>{let t=nN(e)?.error;return tN(t)?t.code:void 0},_N=e=>e.role===`tool`&&gN(e.content)===`interrupted`,vN=e=>![`invalid`,`not_run`].includes(e.status);function yN(e,t){let n=e.findIndex(e=>e.id===t&&e.role===`user`);if(n<0)return null;let r=e.findIndex((e,t)=>t>n&&e.role===`user`),i=e.slice(n+1,r<0?void 0:r),a=new Set(i.flatMap(e=>e.role===`tool`&&gN(e.content)===`answer_only`?[e.toolCallId]:[])),o=i.flatMap((e,t)=>e.role===`assistant`?(e.toolCalls??[]).map(e=>({call:e,index:t})):[]).filter(({call:e})=>!a.has(e.id));if(!o.some(({call:e})=>eN.has(e.function.name)||e.function.name===`preview_panels`))return null;let s={schema:{state:`unobserved`},context:{state:`unobserved`},draft:{state:`unobserved`},validation:{state:`unobserved`},preview:{state:`unobserved`},save:{state:`unobserved`}},c={turn_id:t,stages:s,panel_titles:{},panels:[],problems:[],corrections:[],save_attempts:[],explanations:[],context_counts:{deploys:0,anomalies:0}},l=new Map,u=new Map;for(let{call:e}of o)l.set(e.id,(l.get(e.id)??0)+1);i.forEach((e,t)=>{if(e.role===`tool`){let n=u.get(e.toolCallId)??[];n.push({index:t,message:e}),u.set(e.toolCallId,n)}});let d=new Map,f=new Map,p=[],m,h=!1,g=!1,_=(e,t)=>{for(let n of fN(y.get(e)??[],t,new Set([e])))p.some(e=>e.panel_id===n.panel_id&&e.path===n.path)||p.push(n);y.set(e,t)},v=new Map,y=new Map,b=new Set,x=!1,S=!1;for(let{call:t,index:n}of o){if(l.get(t.id)!==1)continue;let r=t.function.name,i=nN(t.function.arguments),a=(u.get(t.id)??[]).filter(e=>e.index>n),o=a.length===1||eN.has(r)&&a.length>1&&a.slice(0,-1).every(e=>_N(e.message))?a.at(-1).message:void 0,C=o&&nN(o.content),w=!!C&&o?.role===`tool`&&!o.error&&!C.error&&!C.isError,T=o?w?`complete`:`failed`:`incomplete`;if(r===`get_telemetry_schema`&&(s.schema={state:T}),mN.has(r)){let e=o?.role===`tool`&&!o.error&&!C?.error&&!C?.isError&&typeof o.content==`string`&&o.content.length>0;if(s.context={state:o?e?`complete`:`failed`:`incomplete`},w)for(let[e,t]of[[`deploys`,[`deploys`,`deployments`]],[`anomalies`,[`anomalies`]]])for(let n of t)Array.isArray(C[n])&&(c.context_counts[e]+=C[n].length)}if(r===`preview_panels`||r===`create_dashboard`||r===`replace_dashboard`){let e=r===`preview_panels`?i?.panels:tN(i?.dashboard)?i.dashboard.panels:void 0;if(Array.isArray(e)){c.panel_count=e.length,s.draft={state:`complete`};for(let t of e)tN(t)&&typeof t.id==`string`&&typeof t.title==`string`&&t.title.trim()&&f.set(t.id,t.title)}}if(r===`preview_panels`){x=!0;let e=Array.isArray(i?.panels)?i.panels.flatMap(e=>tN(e)&&typeof e.id==`string`?[e.id]:[]):[];for(let t of e)v.set(t,{id:t,status:`not_run`});let t=w&&Array.isArray(C.panels)&&C.panels.every(aN)?C.panels:void 0,n=typeof C?.elapsed_ms==`number`&&C.elapsed_ms>=0?C.elapsed_ms:void 0;if(s.validation={state:t?t.some(e=>e.status===`invalid`||e.status===`not_run`)||hN(C?.problems,`dashboard`).length?`failed`:`complete`:T===`complete`?`failed`:T},s.preview={state:t?t.every(vN)?`complete`:`incomplete`:T===`complete`?`failed`:T,elapsed_ms:n},!t||e.length===0||t.length!==e.length||new Set(t.map(e=>e.id)).size!==e.length||t.some(t=>!e.includes(t.id))){S=e.length===0;for(let t of e)o&&b.add(t);continue}S=!1;for(let t of e)b.delete(t);for(let e of t){let t=hN(e.problems,e.id);if(e.status!==`not_run`)_(e.id,t);else{let n=y.get(e.id)??[];y.set(e.id,[...n,...t.filter(e=>!n.some(t=>t.path===e.path))])}v.set(e.id,e)}c.problems=[...y.values()].flat().concat(hN(C?.problems,`dashboard`))}if(eN.has(r)){let n=o&&sN(t.id,o.content,e),r=!!o&&_N(o),i=!r&&o?.role===`tool`&&(!!o.error||!!C?.error||!!C?.isError);if(g=!!i,h=!!o&&!n&&!i&&!r,s.save={state:n?`complete`:r?`interrupted`:i?`failed`:`incomplete`},n)for(let e of c.save_attempts)e.state===`failed`&&(e.state=`retried`);if(c.save_attempts.push({call_id:t.id,state:s.save.state}),n){m?.id!==n.id&&(m=n,d.clear());for(let e of n.receipt.changes){e.title.trim()&&f.set(e.panel_id,e.title);let t=d.get(e.panel_id);if(t?.kind===`added`&&e.kind===`removed`){d.delete(e.panel_id);continue}if(t?.kind===`added`){d.set(e.panel_id,{panel_id:e.panel_id,title:e.title,kind:`added`});continue}if(e.kind===`removed`){d.set(e.panel_id,e);continue}t&&e.kind===`changed`?d.set(e.panel_id,{...e,fields:[...new Set([...t.fields??[],...e.fields??[]])].sort(),position_changed:t.position_changed||e.position_changed}):d.set(e.panel_id,t?.kind===`removed`&&e.kind===`added`?{...e,kind:`changed`}:e)}let e=C?.dashboard,t=tN(e)?e.spec:void 0;if(tN(t)&&Array.isArray(t.panels))for(let e of t.panels)tN(e)&&typeof e.id==`string`&&typeof e.title==`string`&&e.title.trim()&&f.set(e.id,e.title);let r=c.saved?.id===n.id?c.saved.receipt:void 0;c.saved={...n,label:m.label,receipt:{...n.receipt,base_version:m.receipt.base_version,changes:[...d.values()],layout_changed:m.receipt.base_version!==0&&(n.receipt.layout_changed||!!r?.layout_changed),dashboard_fields:m.receipt.base_version===0?void 0:[...new Set([...r?.dashboard_fields??[],...n.receipt.dashboard_fields??[]])].sort()}},c.panel_count=n.receipt.save_check.panels.length,s.draft={state:`complete`};let i=new Set(n.receipt.save_check.panels.map(e=>e.id));for(let e of n.receipt.save_check.panels)vN(e)&&(_(e.id,[]),b.delete(e.id));p=p.filter(e=>i.has(e.panel_id)),c.problems=[...y.values()].flat().filter(e=>i.has(e.panel_id))}}}if(h)return null;c.panel_titles=Object.fromEntries(f),c.corrections=p.map(e=>({...e,title:f.get(e.panel_id)??e.panel_id}));let C=c.saved?new Set(c.saved.receipt.save_check.panels.map(e=>e.id)):void 0;if(c.panels=[...v.values()].filter(e=>!C||C.has(e.id)),x){let e=S||[...b].some(e=>!C||C.has(e)),t=c.panels.some(e=>e.status===`not_run`),n=c.problems.length>0;s.validation.state=e||n?`failed`:t?`incomplete`:`complete`,s.preview.state=e?`failed`:t||n||c.panels.some(e=>e.status===`invalid`)?`incomplete`:`complete`}let w=c.saved?.receipt.save_check;w&&!w.checked&&c.explanations.push(`Save check incomplete: ${w.reason||`Panels were not checked`}`);for(let e of w?.panels??c.panels)e.status!==`ok`&&c.explanations.push(`${f.get(e.id)??e.id}: ${e.status}${e.error||e.diagnosis?` — ${e.error||e.diagnosis}`:``}`);for(let e of c.problems)c.explanations.push(`${f.get(e.panel_id)??e.panel_id}: ${e.message}`);let T=Object.entries(s).filter(([,e])=>e.state===`incomplete`||e.state===`failed`).map(([e,t])=>`${pN[e]}: ${t.state}`);return T.length&&c.explanations.push(T.join(` · `)),s.save.state===`interrupted`&&c.explanations.push(`Save interrupted · outcome unknown`),g&&c.explanations.push(c.saved?`A later change failed; v${c.saved.version} remains saved`:`Save failed · dashboard was not saved`),c}var bN=(0,M.createContext)(null);function xN(){let e=(0,M.useContext)(bN);if(!e)throw Error(`Fanout app context is unavailable`);return e}var SN=`Build me a dashboard for my services, showing request volume, latency, and errors. Ask me which services to monitor first.`,CN={query_telemetry:{activity:`Querying telemetry…`,title:`Telemetry panels`},get_observability_overview:{activity:`Checking system health…`,title:`System health`},get_service_topology:{activity:`Mapping service dependencies…`,title:`Service map`},get_service_dependencies:{activity:`Tracing service dependencies…`,title:`Service dependencies`},list_panel_exemplars:{activity:`Finding example traces…`,title:`Example traces`},resolve_panel_variables:{activity:`Reading filter choices…`,title:`Filter choices`},query_panel_fragment:{activity:`Refreshing panels…`,title:`Panel refresh`},get_service_performance:{activity:`Reading performance signals…`,title:`Performance`},inspect_trace:{activity:`Inspecting a trace…`,title:`Trace lookup`},search_logs:{activity:`Searching logs…`,title:`Logs`},get_intelligence_snapshot:{activity:`Reviewing detected anomalies…`,title:`Detected anomalies`},get_telemetry_schema:{activity:`Reading what telemetry exists…`,title:`Telemetry discovery`},preview_panels:{activity:`Checking dashboard panels…`,title:`Panel check`},list_dashboards:{activity:`Looking through your dashboards…`,title:`Dashboards`},get_dashboard:{activity:`Opening your dashboard…`,title:`Dashboard`},create_dashboard:{activity:`Building your dashboard…`,title:`Dashboard save`},edit_dashboard:{activity:`Updating your dashboard…`,title:`Dashboard save`},replace_dashboard:{activity:`Redesigning your dashboard…`,title:`Dashboard save`},list_dashboard_versions:{activity:`Reading your dashboard history…`,title:`Dashboard history`},restore_dashboard_version:{activity:`Restoring your dashboard…`,title:`Dashboard`}};function wN(e){return CN[e]?.activity??`Working on it…`}function TN(e){return CN[e]?.title??`Analysis step`}function EN(e){switch(e){case`provider_unavailable`:return`Fanout could not reach the model provider. Please try again.`;case`step_limit`:return`Fanout reached its step limit before finishing. Try a narrower question.`;case`time_limit`:return`Fanout reached its 5-minute time limit. Try a smaller request.`;default:return`Fanout could not complete this analysis. Please try again.`}}function DN(e){let t=(0,M.useRef)(new Map);return(0,M.useMemo)(()=>{let n=new Map,r=new Set,i=e.flatMap((e,t)=>e.role===`user`?[t]:[]);i.forEach((a,o)=>{let s=i[o+1]??e.length,c=e[a],l=e[s-1];r.add(c.id);let u=t.current.get(c.id),d=u&&u.last===l&&u.length===s-a?u.receipt:yN(e.slice(a,s),c.id);oe.msecs?(e.seq=IN(n),e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function FN(e,t,n,r,i=0){if(e.length<16)throw Error(`Random bytes length must be >= 16`);if(!r)r=new Uint8Array(16),i=0;else if(i<0||i+16>r.length)throw RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);return t??=Date.now(),n??=IN(e),r[i++]=t/1099511627776&255,r[i++]=t/4294967296&255,r[i++]=t/16777216&255,r[i++]=t/65536&255,r[i++]=t/256&255,r[i++]=t&255,r[i++]=112|n>>>28&15,r[i++]=n>>>20&255,r[i++]=128|n>>>14&63,r[i++]=n>>>6&255,r[i++]=n<<2&255|e[10]&3,r[i++]=e[11],r[i++]=e[12],r[i++]=e[13],r[i++]=e[14],r[i++]=e[15],r}function IN(e){return(e[6]&127)<<24|e[7]<<16|e[8]<<8|e[9]}function LN(){return NN()}var RN=[`dashboards`],zN=3e4;async function BN(e,t){let{json:n,...r}=t??{},i=new Headers(r.headers),a=r.body;n!==void 0&&(i.set(`content-type`,`application/json`),a=JSON.stringify(n));let o=await BM(e,{...r,headers:i,body:a}),s=await o.json().catch(()=>({}));if(!o.ok)throw new FM(s.message??`Request failed (${o.status})`,o.status,s.problems??[],s.code??``);return s}var VN=e=>`/api/dashboards/${encodeURIComponent(e)}`,HN=()=>BN(`/api/dashboards`).then(e=>e.dashboards),UN=(e,t)=>BN(VN(e),{signal:t}),WN=(e,t)=>BN(`${VN(e)}/versions`,{signal:t}).then(e=>e.versions),GN=(e,t,n)=>BN(`${VN(e)}/versions/${t}`,{signal:n}),KN=(e,t)=>BN(`${VN(e)}/versions/${t}/restore`,{method:`POST`}),qN=(e,t,n,r)=>BN(VN(e),{method:`PUT`,json:{spec:t,base_version:n,message:r}}),JN=(e,t,n,r)=>BN(VN(e),{method:`PATCH`,json:{operations:t,base_version:n,message:r}}),YN=(e,t)=>BN(`/api/panels/query`,{method:`POST`,json:e,signal:t}).then(e=>e.results),XN=e=>BN(`/api/telemetry/schema`,{signal:e}),ZN=(e,t)=>BN(`/api/annotations`,{method:`POST`,json:e,signal:t}),QN=(e,t)=>BN(`/api/panels/variables/resolve`,{method:`POST`,json:e,signal:t}).then(e=>e.options),$N=(e,t)=>BN(`/api/panels/exemplars`,{method:`POST`,json:e,signal:t});function eP(e,t){let n=new URLSearchParams({namespace:e.namespace??``,from:e.window_from,to:e.window_to,limit:`200`});return BN(`/api/traces/${encodeURIComponent(e.trace_id??``)}?${n}`,{signal:t})}function tP(){let{setColorScheme:e}=Nr(),t=Ir(`light`,{getInitialValueInEffect:!0}),n=t===`dark`?`light`:`dark`,[r,i]=(0,M.useState)(!1);return(0,N.jsx)(St,{label:`Switch to ${n} theme`,opened:r,children:(0,N.jsx)(Di,{variant:`subtle`,color:`gray`,"aria-label":`Switch to ${n} theme`,onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),onFocus:()=>i(!0),onBlur:()=>i(!1),onClick:()=>{i(!1),e(n)},children:t===`dark`?(0,N.jsx)(AM,{size:17,weight:`bold`}):(0,N.jsx)(vM,{size:17,weight:`bold`})})})}var nP={home:`https://fanout.run/docs`,ingest:`https://fanout.run/docs/get-started/send-telemetry`,connect:`https://fanout.run/docs/guides/mcp`};async function rP(e,t){let n=new URLSearchParams({page_size:`30`});e&&n.set(`q`,e),t&&n.set(`cursor`,t);let r=await BM(`/api/agent/threads?${n}`);if(!r.ok)throw Error(`Unable to load chats (${r.status})`);return r.json()}function iP({agentAvailable:e,activeThreadID:t,activeDashboardID:n,autoFocusSearch:r=!1,onNewChat:i,onSelectThread:a,onDeletedThread:o,onSelectDashboard:s,onCreateDashboard:c,onInvestigateService:l,ref:u}){let d=SA(),[f,p]=(0,M.useState)(``),[m]=or(f.trim(),250),[h,g]=(0,M.useState)(null),[_,v]=(0,M.useState)(null),[y,b]=(0,M.useState)(``),[x,S]=(0,M.useState)(``),[w,T]=(0,M.useState)(!1),ee=(0,M.useRef)(null);(0,M.useImperativeHandle)(u,()=>({focusSearch:()=>ee.current?.focus()}),[]),(0,M.useEffect)(()=>{r&&requestAnimationFrame(()=>ee.current?.focus())},[r]);let E=Kj({queryKey:[...QM,m],queryFn:({pageParam:e})=>rP(m,e),initialPageParam:``,getNextPageParam:e=>e.next_cursor??void 0,enabled:e}),D=Gj({queryKey:RN,queryFn:HN,refetchInterval:3e4,staleTime:zN}),O=(0,M.useMemo)(()=>E.data?.pages.flatMap(e=>e.items)??[],[E.data]),te=(0,M.useMemo)(()=>uP(O),[O]),re=Gj({queryKey:[`telemetry-schema`,`1h`],queryFn:()=>$M(`/api/telemetry/schema?window=1h`),enabled:e&&!!m&&!!l,staleTime:6e4}),k=(0,M.useMemo)(()=>{if(!m)return[];let e=m.toLowerCase();return(re.data?.services??[]).map(e=>e.value).filter(t=>t.toLowerCase().includes(e)).slice(0,6)},[re.data,m]),ie=(0,M.useMemo)(()=>{let e=D.data??[],t=m.toLowerCase();return t?e.filter(e=>e.name.toLowerCase().includes(t)):e},[D.data,m]);function ae(e){S(``),b(e.title),g(e)}async function se(){if(h&&y.trim()){T(!0),S(``);try{let e=await BM(`/api/agent/threads/${encodeURIComponent(h.id)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:y.trim()})});if(!e.ok)throw Error(`Unable to rename chat (${e.status})`);await d.invalidateQueries({queryKey:QM}),g(null)}catch(e){S(e instanceof Error?e.message:`Unable to rename this chat.`)}finally{T(!1)}}}async function le(){if(_){T(!0),S(``);try{let e=await BM(`/api/agent/threads/${encodeURIComponent(_.id)}`,{method:`DELETE`});if(!e.ok)throw Error(`Unable to delete chat (${e.status})`);let t=_.id;v(null),await d.invalidateQueries({queryKey:QM}),await d.invalidateQueries({queryKey:RN}),o(t)}catch(e){S(e instanceof Error?e.message:`Unable to delete this chat.`)}finally{T(!1)}}}return(0,N.jsxs)(oe,{gap:`sm`,h:`100%`,component:`nav`,"aria-label":`Navigation`,children:[e&&(0,N.jsx)(ce,{leftSection:(0,N.jsx)(wM,{size:16,weight:`bold`}),onClick:i,children:`New chat`}),(0,N.jsx)(vt,{type:`auto`,offsetScrollbars:!0,flex:1,mx:-4,px:4,children:(0,N.jsxs)(oe,{gap:`lg`,pb:`sm`,children:[e&&(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Chats`}),E.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),E.isError&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,p:`xs`,children:`Chats could not be loaded.`}),!E.isLoading&&!E.isError&&O.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,py:`xs`,children:m?`No matching chats`:`No chats yet`}),te.map(e=>(0,N.jsxs)(oe,{gap:2,children:[te.length>1&&(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,px:`sm`,pt:4,children:e.label}),e.threads.map(e=>(0,N.jsx)(oP,{thread:e,active:e.id===t,onSelect:()=>a(e.id),onRename:()=>ae(e),onDelete:()=>{S(``),v(e)}},e.id))]},e.label)),E.hasNextPage&&(0,N.jsx)(ce,{variant:`subtle`,color:`gray`,size:`compact-sm`,loading:E.isFetchingNextPage,onClick:()=>void E.fetchNextPage(),children:`See all`})]}),e&&m&&l&&re.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),e&&m&&l&&(re.isSuccess||re.isError)&&(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Services`}),re.isError&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,children:`Services could not be searched`}),re.isSuccess&&k.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,children:`No matching services`}),k.map(e=>(0,N.jsx)(C,{className:`rail-row`,p:`sm`,onClick:()=>l(e),children:(0,N.jsx)(ue,{size:`sm`,fw:500,truncate:!0,children:e})},e))]}),(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Dashboards`}),D.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),D.isError&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,p:`xs`,children:`Dashboards could not be loaded.`}),!D.isLoading&&!D.isError&&m&&ie.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,py:`xs`,children:`No matching dashboards`}),ie.map(t=>{let r=t.id===n;return(0,N.jsxs)(oe,{gap:0,children:[(0,N.jsx)(C,{component:`a`,href:`/dashboards/${encodeURIComponent(t.id)}`,className:`rail-row`,"data-active":r||void 0,"aria-current":r?`page`:void 0,p:`sm`,onClick:e=>{e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),s(t.id))},children:(0,N.jsxs)(ne,{justify:`space-between`,gap:`sm`,wrap:`nowrap`,children:[(0,N.jsx)(ue,{size:`sm`,fw:r?600:500,truncate:!0,children:t.name}),t.is_default&&(0,N.jsx)(ts,{size:`xs`,variant:`light`,color:`gray`,children:`Default`})]})}),e&&t.origin&&(0,N.jsx)(C,{component:`a`,href:`/chat/${encodeURIComponent(t.origin.thread_id)}`,"data-request-provenance":!0,px:`sm`,pb:`xs`,onClick:e=>{e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),a(t.origin.thread_id))},children:(0,N.jsxs)(ue,{size:`xs`,c:`dimmed`,lineClamp:2,children:[`Built from: `,t.origin.request_excerpt]})})]},t.id)}),e&&(0,N.jsx)(ce,{variant:`subtle`,color:`gray`,size:`compact-sm`,justify:`flex-start`,leftSection:(0,N.jsx)(OM,{size:14,weight:`fill`}),onClick:c,children:D.data?.length===0?`New dashboard`:`Create with AI`})]})]})}),(0,N.jsx)(Rc,{ref:ee,value:f,onChange:e=>p(e.currentTarget.value),leftSection:(0,N.jsx)(gM,{size:15}),rightSection:(0,N.jsx)(As,{size:`xs`,children:`⌘K`}),rightSectionWidth:44,placeholder:`Search`,"aria-label":`Search chats, dashboards and services`,size:`sm`}),(0,N.jsx)(jc,{opened:h!==null,onClose:()=>!w&&g(null),title:`Rename chat`,centered:!0,children:(0,N.jsx)(`form`,{onSubmit:e=>{e.preventDefault(),se()},children:(0,N.jsxs)(oe,{children:[(0,N.jsx)(Rc,{label:`Name`,value:y,onChange:e=>b(e.currentTarget.value),maxLength:120,autoFocus:!0}),x&&(0,N.jsx)(Ce,{color:`bad`,children:x}),(0,N.jsxs)(ne,{justify:`flex-end`,children:[(0,N.jsx)(ce,{variant:`default`,onClick:()=>g(null),disabled:w,children:`Cancel`}),(0,N.jsx)(ce,{type:`submit`,loading:w,disabled:!y.trim(),children:`Save`})]})]})})}),(0,N.jsx)(jc,{opened:_!==null,onClose:()=>!w&&v(null),title:`Delete chat?`,centered:!0,children:(0,N.jsxs)(oe,{children:[(0,N.jsxs)(ue,{size:`sm`,children:[`This permanently removes `,(0,N.jsx)(ue,{span:!0,fw:650,children:_?.title}),` and its saved messages.`]}),x&&(0,N.jsx)(Ce,{color:`bad`,children:x}),(0,N.jsxs)(ne,{justify:`flex-end`,children:[(0,N.jsx)(ce,{variant:`default`,onClick:()=>v(null),disabled:w,children:`Cancel`}),(0,N.jsx)(ce,{color:`bad`,loading:w,onClick:()=>void le(),children:`Delete`})]})]})})]})}function aP({children:e}){return(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,fw:700,tt:`uppercase`,lts:`0.08em`,px:`sm`,children:e})}function oP({thread:e,active:t,onSelect:n,onRename:r,onDelete:i}){return(0,N.jsx)(u,{"data-active":t||void 0,className:`rail-row`,children:(0,N.jsxs)(ne,{gap:2,wrap:`nowrap`,children:[(0,N.jsx)(C,{onClick:n,"aria-current":t?`page`:void 0,p:`sm`,flex:1,style:{minWidth:0},children:(0,N.jsxs)(oe,{gap:0,children:[(0,N.jsx)(ue,{size:`sm`,fw:t?600:500,truncate:!0,children:e.title}),(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,children:dP(e.updated_at)})]})}),(0,N.jsxs)(hc,{position:`bottom-end`,withinPortal:!0,children:[(0,N.jsx)(hc.Target,{children:(0,N.jsx)(Di,{className:`rail-row-actions`,variant:`subtle`,color:`gray`,size:`sm`,mr:4,"aria-label":`Actions for ${e.title}`,children:(0,N.jsx)(mM,{size:18,weight:`bold`})})}),(0,N.jsxs)(hc.Dropdown,{children:[(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(bM,{size:15}),onClick:r,children:`Rename`}),(0,N.jsx)(hc.Item,{color:`bad`,leftSection:(0,N.jsx)(MM,{size:15}),onClick:i,children:`Delete`})]})]})]})})}function sP(e){return e.includes(`T`)?new Date(e):new Date(`${e.replace(` `,`T`)}Z`)}function cP(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()}var lP=[`Today`,`Yesterday`,`Previous 7 days`,`Older`];function uP(e){let t=cP(new Date),n=new Map;for(let r of e){let e=Math.floor((t-cP(sP(r.updated_at)))/864e5),i=e<=0?`Today`:e===1?`Yesterday`:e<=7?`Previous 7 days`:`Older`,a=n.get(i)??[];a.push(r),n.set(i,a)}return lP.filter(e=>n.has(e)).map(e=>({label:e,threads:n.get(e)}))}function dP(e){let t=sP(e),n=cP(new Date);return Math.floor((n-cP(t))/864e5)<=1?new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`}).format(t):new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`}).format(t)}function fP({children:e}){let{agentAvailable:t,threadID:n,threadMissing:r,newThread:i,selectThread:a,openChat:o}=xN(),s=ze(),c=Un({select:e=>e.location.pathname}),{dashboardId:l}=hn({strict:!1}),u=c===`/chat`||c.startsWith(`/chat/`),[d,f]=br(!1),[p,m]=(0,M.useState)(!1),[h,g]=(0,M.useState)(``),_=(0,M.useRef)(null),v=ie(`(max-width: 62em)`),y=(0,M.useRef)(v);y.current=v,(0,M.useEffect)(()=>{f.close()},[c]),(0,M.useEffect)(()=>{let e=e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),y.current?(m(!0),f.open()):_.current?.focusSearch())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let b={agentAvailable:t,activeThreadID:u&&!r&&c!==`/chat`?n:void 0,activeDashboardID:l,onNewChat:i,onSelectThread:a,onDeletedThread:e=>{e===n&&i()},onSelectDashboard:e=>void s({to:`/dashboards/$dashboardId`,params:{dashboardId:e},search:{}}),onCreateDashboard:()=>o(SN),onInvestigateService:e=>o(`Investigate the ${e} service. Explain its errors and latency.`)};return(0,N.jsxs)(Vo,{header:{height:52},navbar:{width:256,breakpoint:`md`,collapsed:{mobile:!0}},padding:0,children:[(0,N.jsx)(Vo.Header,{children:(0,N.jsxs)(ne,{h:`100%`,px:{base:`sm`,sm:`md`},justify:`space-between`,wrap:`nowrap`,children:[(0,N.jsxs)(ne,{gap:`sm`,wrap:`nowrap`,children:[(0,N.jsx)(is,{hiddenFrom:`md`,opened:d,onClick:()=>{m(!1),f.toggle()},size:`sm`,"aria-label":d?`Close navigation`:`Open navigation`}),(0,N.jsx)(ke,{size:`small`})]}),(0,N.jsxs)(ne,{gap:`xs`,wrap:`nowrap`,children:[(0,N.jsx)(St,{label:`Documentation`,children:(0,N.jsx)(Di,{component:`a`,href:nP.home,target:`_blank`,rel:`noopener noreferrer`,variant:`subtle`,color:`gray`,"aria-label":`Documentation`,children:(0,N.jsx)(fM,{size:17,weight:`bold`})})}),(0,N.jsx)(tP,{}),(0,N.jsx)(pP,{onError:g})]})]})}),(0,N.jsx)(Vo.Navbar,{p:`sm`,children:(0,N.jsx)(iP,{ref:_,...b})}),(0,N.jsx)(Ds,{opened:d,onClose:f.close,hiddenFrom:`md`,size:288,padding:`sm`,title:(0,N.jsx)(ke,{size:`small`}),overlayProps:{backgroundOpacity:.24,blur:1},children:(0,N.jsx)(iP,{...b,autoFocusSearch:d&&p})}),(0,N.jsxs)(Vo.Main,{children:[h&&(0,N.jsx)(Ce,{color:`bad`,m:`md`,withCloseButton:!0,onClose:()=>g(``),children:h}),e]})]})}function pP({onError:e}){let t=ze(),n=GM(),r=(n.display_name.trim()||n.email.trim()||`?`).charAt(0).toUpperCase();return(0,N.jsxs)(hc,{position:`bottom-end`,withinPortal:!0,shadow:`md`,children:[(0,N.jsx)(hc.Target,{children:(0,N.jsx)(Di,{variant:`subtle`,color:`gray`,size:`lg`,radius:`xl`,"aria-label":`${r} account menu`,children:(0,N.jsx)(Qo,{size:26,radius:`xl`,color:`brand`,children:r})})}),(0,N.jsxs)(hc.Dropdown,{children:[(0,N.jsx)(hc.Label,{children:n.email||`Signed in`}),(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(SM,{size:15}),onClick:()=>void t({to:`/settings`}),children:`Connect telemetry`}),(0,N.jsx)(hc.Divider,{}),(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(EM,{size:15}),onClick:()=>void VM().catch(t=>e(t instanceof Error?t.message:`Sign-out failed — your session is still active.`)),children:`Sign out`})]})]})}function mP(){let{agent_available:e}=UM(),t=ze(),n=SA(),{threadId:r}=hn({strict:!1}),[i,a]=(0,M.useState)(LN),o=(0,M.useRef)(new Set),s=r??i,[c,l]=(0,M.useState)([]),[u,d]=(0,M.useState)({}),[f,p]=(0,M.useState)(``),[m,h]=(0,M.useState)(!1),[g,_]=(0,M.useState)(!1),[v,y]=(0,M.useState)(``),[b,x]=(0,M.useState)(!1),S=(0,M.useRef)(!1),[C,w]=(0,M.useState)(``),[T,ee]=(0,M.useState)(``),[E,D]=(0,M.useState)(0),O=(0,M.useRef)(null),te=(0,M.useRef)({}),ne=(0,M.useRef)(null),re=(0,M.useRef)(new Map),k=(0,M.useMemo)(()=>new bA({url:`/api/agent/runs`,threadId:s,fetch:(e,t)=>BM(e,t)}),[s]),ie=!e||f===s;function ae(){re.current.clear(),y(``)}function oe(e){return S.current||e instanceof Error&&e.name===`AbortError`}(0,M.useEffect)(()=>{let t=!0;if(l([]),te.current={},d({}),p(``),h(!1),_(!1),S.current=!1,x(!1),ae(),ee(``),!e){p(s);return}!r||o.current.has(s)?(k.setMessages([]),p(s)):BM(`/api/agent/threads/${encodeURIComponent(s)}`).then(async e=>{if(e.status===404)return null;if(!e.ok)throw Error(`Unable to load thread (${e.status})`);return e.json()}).then(e=>{if(t){if(e===null){h(!0),p(s);return}k.setMessages(e.messages??[]),l(e.messages??[]),p(s)}}).catch(()=>{t&&(O.current=null,ee(`This chat could not be restored. Start a new chat or try again.`))});let i=k.subscribe({onMessagesChanged:({messages:e})=>l([...e]),onRunInitialized:()=>{S.current=!1,x(!1),_(!0),ee(``)},onTextMessageContentEvent:({event:e})=>{e.delta&&y(``)},onToolCallStartEvent:({event:e})=>{re.current.set(e.toolCallId,wN(e.toolCallName)),y(wN(e.toolCallName))},onToolCallResultEvent:({event:e,messages:t})=>{re.current.delete(e.toolCallId),y([...re.current.values()].at(-1)??`Analyzing your system`);let r=sN(e.toolCallId,e.content,t);r&&(n.invalidateQueries({queryKey:RN}),n.invalidateQueries({queryKey:[`dashboard`,r.id]}),n.invalidateQueries({queryKey:[`dashboard-versions`,r.id]}))},onRunErrorEvent:({event:e})=>{e.code===`abort`||S.current?(ee(``),x(!0)):(console.warn(`Agent run error`,e.code),ee(EN(e.code))),_(!1),ae()},onRunFinalized:({messages:e})=>{let t=[...e];l(t),d(e=>{let n={...e};for(let e of t)e.role===`assistant`&&!n[e.id]&&(n[e.id]=Date.now());return n}),_(!1),ae(),o.current.delete(s),n.invalidateQueries({queryKey:QM})},onRunFailed:e=>{oe(e.error)?(ee(``),x(!0)):(console.error(`Agent run failed`,e),ee(EN())),_(!1),ae(),o.current.delete(s),n.invalidateQueries({queryKey:QM})}});return()=>{t=!1,i.unsubscribe(),k.abortRun()}},[k,e,n,E,s]),(0,M.useEffect)(()=>{if(!e)return;let n=e=>{let n=e.target,i=n?.matches(`input, textarea, [contenteditable='true']`);e.key===`/`&&!i&&(e.preventDefault(),r?requestAnimationFrame(()=>ne.current?.focus()):t({to:`/chat`}).then(()=>requestAnimationFrame(()=>ne.current?.focus()))),e.key===`Escape`&&n===ne.current&&(w(``),ne.current?.blur())};return window.addEventListener(`keydown`,n),()=>window.removeEventListener(`keydown`,n)},[e,t,r]);async function se(){_(!0),ee(``);try{let{context:e=[],...t}=te.current;await k.runAgent({context:e,forwardedProps:t})}catch(e){oe(e)?(ee(``),x(!0)):(console.error(`Agent run failed`,e),ee(EN())),_(!1),ae(),o.current.delete(s)}}async function ce(n,i){let a=n.trim();if(!e||!a||g||!ie||m)return;te.current={...i},r||(o.current.add(s),t({to:`/chat/$threadId`,params:{threadId:s},replace:!0}));let c={id:LN(),role:`user`,content:a};k.addMessage(c),l([...k.messages]),d(e=>({...e,[c.id]:Date.now()})),w(``),await se()}(0,M.useEffect)(()=>{let e=O.current;ie&&r&&e&&(O.current=null,ce(e.text,e.options))},[ie,r,s]);function le(e){e.preventDefault(),ce(C)}function ue(){S.current=!0,ee(``),x(!0),k.abortRun(),_(!1),ae(),o.current.delete(s)}function de(){!g&&k.messages.some(e=>e.role===`user`)&&se()}function fe(n,r){if(!e)return;let i=LN();o.current.add(i),O.current=n?{text:n,options:{...r}}:null,t({to:`/chat/$threadId`,params:{threadId:i}})}function pe(){k.abortRun(),O.current=null,te.current={},a(LN()),t({to:`/chat`})}function me(e){O.current=null,te.current={},t({to:`/chat/$threadId`,params:{threadId:e}})}function he(){D(e=>e+1)}return(0,N.jsx)(bN.Provider,{value:{agentAvailable:e,threadID:s,threadMissing:m,messages:c,messageTimes:u,ready:ie,running:g,activity:v,stopped:b,input:C,setInput:w,error:T,inputRef:ne,send:ce,submit:le,stop:ue,retry:de,reloadThread:he,openChat:fe,newThread:pe,selectThread:me},children:(0,N.jsx)(fP,{children:(0,N.jsx)(Nn,{})})})}function hP(){let e=(0,M.useMemo)(()=>new Mj,[]);return(0,N.jsx)(CA,{client:e,children:(0,N.jsx)(ZM,{children:(0,N.jsx)(mP,{})})})}var gP=xn({component:hP,notFoundComponent:()=>(0,N.jsx)(Ve,{to:`/`,replace:!0})}),_P=Sn(`/`)({component:Cn(()=>tt(()=>import(`./routes-D2AdaqvY.js`),__vite__mapDeps([0,1,2])),`component`)}),vP=Sn(`/settings`)({component:Cn(()=>tt(()=>import(`./settings-BolmPCiI.js`),__vite__mapDeps([3,1,4,5,6])),`component`)}),yP=Sn(`/chat/`)({component:Cn(()=>tt(()=>import(`./chat.index-CVg1vCUR.js`),__vite__mapDeps([7,8,1,4,9,5,10])),`component`)}),bP=Sn(`/chat/$threadId`)({component:Cn(()=>tt(()=>import(`./chat._threadId-CVg1vCUR.js`),__vite__mapDeps([11,8,1,4,9,5,10])),`component`)});function xP(e){try{let t=typeof e==`string`?e:JSON.stringify(e);if(!t||t.length>4096)return;let n=typeof e==`string`?JSON.parse(e):e;if(!n||typeof n!=`object`)return;let r=n;return typeof r.panel_id!=`string`||!/^([a-z][a-z0-9_]{0,39})$/.test(r.panel_id)||r.kind!==`traces`&&r.kind!==`logs`||typeof r.from!=`string`||typeof r.to!=`string`||!Number.isFinite(Date.parse(r.from))||!Number.isFinite(Date.parse(r.to))||Date.parse(r.from)>=Date.parse(r.to)||Date.parse(r.to)-Date.parse(r.from)>2592e6||typeof r.window_from!=`string`||typeof r.window_to!=`string`||!Number.isFinite(Date.parse(r.window_from))||!Number.isFinite(Date.parse(r.window_to))||Date.parse(r.window_from)>=Date.parse(r.window_to)||Date.parse(r.window_to)-Date.parse(r.window_from)>2592e6||Date.parse(r.from)Date.parse(r.window_to)||!r.dimensions||Array.isArray(r.dimensions)||typeof r.dimensions!=`object`||Object.keys(r.dimensions).length>3||Object.values(r.dimensions).some(e=>typeof e!=`string`||e.length>500)||r.trace_id!==void 0&&(typeof r.trace_id!=`string`||r.trace_id.length>128)||r.namespace!==void 0&&(typeof r.namespace!=`string`||r.namespace.length>200)||r.bucket&&(!Number.isFinite(r.bucket.lower)||r.bucket.lower<0||r.bucket.upper!==void 0&&(!Number.isFinite(r.bucket.upper)||r.bucket.upper<=r.bucket.lower))?void 0:{panel_id:r.panel_id,kind:r.kind,from:r.from,to:r.to,window_from:r.window_from,window_to:r.window_to,dimensions:r.dimensions,trace_id:r.trace_id,namespace:r.namespace,bucket:r.bucket}}catch{return}}function SP(e,t,n){if(!e.drill&&e.viz!==`service_map`&&!n.trace_id||t.from_ms===void 0||t.to_ms===void 0)return;let r=t.from_ms,i=t.to_ms;if(n.from!==void 0&&n.to!==void 0&&(r=Math.max(r,Date.parse(n.from)),i=Math.min(i,Date.parse(n.to))),n.time!==void 0&&!n.trace_id){let e=/^(\d+)(s|m|h|d)$/.exec(t.interval??``),a=e?Number(e[1])*{s:1e3,m:6e4,h:36e5,d:864e5}[e[2]]:6e4;r=Math.max(r,n.time),i=Math.min(i,n.time+a)}return xP(JSON.stringify({panel_id:e.id,kind:n.trace_id||e.viz===`service_map`?`traces`:e.drill,from:n.from&&Date.parse(n.from)===r?n.from:new Date(r).toISOString(),to:n.to&&Date.parse(n.to)===i?n.to:new Date(i).toISOString(),window_from:new Date(t.from_ms).toISOString(),window_to:new Date(t.to_ms).toISOString(),dimensions:n.dimensions,trace_id:n.trace_id,namespace:n.namespace,bucket:n.bucket}))}function CP(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))for(let e of Array.isArray(r)?r:[r]){if(e===void 0)continue;let r=typeof e==`string`&&/^[{"]/.test(e);t.append(n,r||typeof e==`object`&&e?JSON.stringify(e):String(e))}let n=t.toString();return n?`?${n}`:``}function wP(e){let t=Object.create(null),n=e=>{if(e.startsWith(`{`)||e.startsWith(`"`))try{let t=JSON.parse(e);if(typeof t==`string`)return/^[{"]/.test(t)?t:e;if(typeof t==`object`&&t&&!Array.isArray(t))return t}catch{}return e},r=new URLSearchParams(e);for(let e of new Set(r.keys())){let i=r.getAll(e).map(n);t[e]=i.length===1?i[0]:i}return t}var TP=[`5m`,`15m`,`1h`,`3h`,`6h`,`12h`,`24h`,`2d`,`7d`,`30d`],EP=[`off`,`10s`,`30s`,`1m`,`5m`],DP=e=>{if(typeof e!=`string`||!/^\d{4}-\d{2}-\d{2}[Tt](?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(e)||Number.isNaN(Date.parse(e)))return!1;let[t,n,r]=e.slice(0,10).split(`-`).map(Number),i=new Date(0);return i.setUTCFullYear(t,n-1,r),i.setUTCHours(0,0,0,0),i.getUTCFullYear()===t&&i.getUTCMonth()===n-1&&i.getUTCDate()===r},OP=e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`?String(e):void 0;function kP(e){let t={};typeof e.range==`string`&&TP.includes(e.range)?t.range=e.range:DP(e.from)&&DP(e.to)&&Date.parse(e.from)typeof e==`string`)&&(i[e]=t)}}else{let t=OP(n);t!==void 0&&(i[e]=t)}}}Object.keys(i).length>0&&(t.vars=i);let a=xP(e.drill);return a&&(t.drill=JSON.stringify(a)),t}function AP(e){let t={};e.drill&&(t.drill=JSON.parse(e.drill)),e.range&&(t.range=e.range),e.from&&e.to&&(t.from=e.from,t.to=e.to),e.compare&&(t.compare=e.compare),e.view&&(t.view=e.view),e.edit&&(t.edit=e.edit);for(let[n,r]of Object.entries(e.vars??{}))t[`var-${n}`]=Array.isArray(r)?{values:r}:r;return t}function jP(e,t){let n=new URL(e);return n.search=CP(AP({...kP(wP(n.search)),drill:JSON.stringify(t)})),n.href}function MP(e,t){let n=e.time.refresh??`30s`;return t.from&&t.to?{from:t.from,to:t.to,refresh:n}:t.range?{range:t.range,refresh:n}:{...e.time,refresh:n}}var NP=Sn(`/dashboards/`)({component:Cn(()=>tt(()=>import(`./dashboards.index-CSc2aAxM.js`),__vite__mapDeps([12,1,2,13,4,9,5,10,6])),`component`),validateSearch:e=>AP(kP(e))}),PP=Sn(`/dashboards/$dashboardId`)({component:Cn(()=>tt(()=>import(`./dashboards._dashboardId-D2ADrkcC.js`),__vite__mapDeps([14,1,2,13,4,9,5,10,6])),`component`),validateSearch:e=>AP(kP(e))}),FP=_P.update({id:`/`,path:`/`,getParentRoute:()=>gP}),IP=vP.update({id:`/settings`,path:`/settings`,getParentRoute:()=>gP}),LP=yP.update({id:`/chat/`,path:`/chat/`,getParentRoute:()=>gP}),RP=bP.update({id:`/chat/$threadId`,path:`/chat/$threadId`,getParentRoute:()=>gP}),zP=NP.update({id:`/dashboards/`,path:`/dashboards/`,getParentRoute:()=>gP}),BP={IndexRoute:FP,SettingsRoute:IP,ChatThreadIdRoute:RP,DashboardsDashboardIdRoute:PP.update({id:`/dashboards/$dashboardId`,path:`/dashboards/$dashboardId`,getParentRoute:()=>gP}),ChatIndexRoute:LP,DashboardsIndexRoute:zP},VP=zn({routeTree:gP._addFileChildren(BP)._addFileTypes(),parseSearch:wP,stringifySearch:CP,defaultPreload:`intent`,scrollRestoration:!0}),HP=[`#fafafa`,`#e6e4de`,`#bfbdb6`,`#8b8e99`,`#565b69`,`#1d2433`,`#131721`,`#0b0e14`,`#080a10`,`#05070b`],UP=[`#f3ecfd`,`#ece3fb`,`#dcc9f7`,`#d2a6ff`,`#bf94ec`,`#a97ce0`,`#9163d6`,`#7c4dcc`,`#5b32a3`,`#40236f`],WP=[`#eefbe6`,`#dcf7cc`,`#c2f0a6`,`#a5e880`,`#8fe06c`,`#7fd962`,`#66c04b`,`#4f9c3a`,`#3b7a2c`,`#2a5a1f`],GP=[`#fff5e6`,`#ffe9c9`,`#ffd79b`,`#ffc571`,`#ffbc62`,`#ffb454`,`#ef9c33`,`#c87d21`,`#9c5f16`,`#74460f`],KP=[`#fdecee`,`#fbd9dc`,`#f8b6bc`,`#f59099`,`#f37d87`,`#f26d78`,`#e04d5a`,`#c03642`,`#96262f`,`#6f1a21`],qP=[`#e8f6ff`,`#ccebff`,`#a3daff`,`#7dcbff`,`#66c5ff`,`#59c2ff`,`#33a7e6`,`#1e86bd`,`#146694`,`#0d4a6d`],JP={dark:{text:`#bfbdb6`,muted:`#8b8e99`,grid:`#1d2433`,surface:`#131721`,border:`#626777`},light:{text:`#4a5058`,muted:`#6b7280`,grid:`#eceef0`,surface:`#fcfcfc`,border:`#8c939d`}},YP={dark:[`#3987e5`,`#d95926`,`#199e70`,`#9085e9`,`#c98500`,`#d55181`],light:[`#2a78d6`,`#eb6834`,`#1baf7a`,`#4a3aa7`,`#eda100`,`#e87ba4`]},XP={micro:11,small:12,body:14,title:16,section:22,page:32},ZP={display:`"Geist Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,body:`"Geist Variable", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`},QP={brand:UP,ok:WP,warn:GP,bad:KP,info:qP},$P={light:7,dark:5};function eF(e){let t=e.replace(`#`,``),n=t.length===3?[...t].map(e=>e+e).join(``):t,r=e=>{let t=parseInt(n.slice(e,e+2),16)/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4};return .2126*r(0)+.7152*r(2)+.0722*r(4)}function tF(e){let t=eF(e),n=1.05/(t+.05);return(t+.05)/.05>n?`var(--mantine-color-black)`:`var(--mantine-color-white)`}function nF(e){return Object.fromEntries(Object.entries(QP).map(([t,n])=>[`--fanout-color-${t}-contrast`,tF(n[$P[e]])]))}function rF(e){return t=>{let n=t.color??oF.primaryColor,r=e({...t,color:n}),i=t.variant===`filled`||t.variant===void 0;return t.autoContrast===!1||!i||!Object.hasOwn(QP,n)?r:{...r,color:`var(--fanout-color-${n}-contrast)`}}}var iF=.25,aF={xs:9,sm:10,md:11,lg:13,xl:16},oF={primaryColor:`brand`,primaryShade:$P,autoContrast:!0,luminanceThreshold:iF,colors:{dark:HP,brand:UP,ok:WP,warn:GP,bad:KP,info:qP},defaultRadius:`md`,fontFamily:ZP.body,fontFamilyMonospace:ZP.display,headings:{fontFamily:ZP.body,fontWeight:`600`},cursorType:`pointer`,components:{Tabs:{styles:(e,t)=>({tab:lF(t.color,`--tabs-text-color`)})},Pagination:{styles:(e,t)=>({control:lF(t.color,`--pagination-active-color`)})},Badge:{vars:(e,t)=>({root:cF(t.size)})},Menu:{defaultProps:{withInitialFocusPlaceholder:!1}},Drawer:{defaultProps:{closeButtonProps:{"aria-label":`Close`}}},Modal:{defaultProps:{closeButtonProps:{"aria-label":`Close`}}}}},sF=()=>({variables:{"--mantine-color-error":`var(--mantine-color-bad-filled)`},light:{"--mantine-color-dimmed":JP.light.muted,...nF(`light`)},dark:nF(`dark`)});function cF(e){let t=aF[e??`md`];return t===void 0||t>=XP.micro?{}:{"--badge-fz":`${XP.micro/16}rem`}}function lF(e,t){return!e||e===oF.primaryColor?{[t]:`var(--fanout-color-${oF.primaryColor}-contrast)`}:{}}var uF=rF(ee),dF=Xr({...oF,variantColorResolver:uF});(0,Kc.createRoot)(document.getElementById(`root`)).render((0,N.jsx)(M.StrictMode,{children:(0,N.jsx)(Yr,{theme:dF,defaultColorScheme:`auto`,cssVariablesResolver:sF,children:(0,N.jsx)(Hn,{router:VP})})}));export{mM as $,Ir as $t,JN as A,U as At,xN as B,Rc as Bt,RN as C,K as Ct,GN as D,Ub as Dt,eP as E,Ob as Et,QN as F,vy as Ft,eN as G,ss as Gt,_N as H,hc as Ht,KN as I,g_ as It,GM as J,eo as Jt,tN as K,ts as Kt,SN as L,f_ as Lt,$N as M,Sb as Mt,YN as N,Yy as Nt,HN as O,px as Ot,qN as P,wy as Pt,bM as Q,Qr as Qt,TN as R,d_ as Rt,nP as S,q as St,XN as T,fb as Tt,pN as U,As as Ut,dN as V,jc as Vt,nN as W,Ds as Wt,FM as X,yi as Xt,BM as Y,Di as Yt,MM as Z,ci as Zt,TP as _,hb as _t,JP as a,ln as an,OA as at,SP as b,Pb as bt,WP as c,SA as ct,GP as d,db as dt,kr as en,Gj as et,PP as f,Rb as ft,kP as g,Eb as gt,MP as h,G as ht,UP as i,Gn as in,IA as it,ZN as j,Ab as jt,WN as k,Ib as kt,YP as l,Vy as lt,jP as m,_b as mt,eF as n,tr as nn,ij as nt,ZP as o,Qt as on,BA as ot,NP as p,yb as pt,$M as q,Ho as qt,KP as r,Xn as rn,ej as rt,qP as s,tn as sn,XA as st,tF as t,yr as tn,Oj as tt,XP as u,By as ut,EP as v,Mb as vt,UN as w,wb as wt,xP as x,cx as xt,AP as y,Gy as yt,DN as z,Zf as zt}; \ No newline at end of file +`)};function XO(e,t){return $c(t)&&ZO(`[ag-ui][legacy] The result of tool call '${e}' carries content parts the legacy protocol cannot represent; only its text parts are bridged and the rest is dropped.`),Qc(t)}var ZO=e=>{typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(e)},QO=(e,t,n)=>r=>{let i={},a=!0,o=!0,s=``,c=null,l=null,u=[],d={},f=!1,p=e=>{typeof e==`object`&&e&&(`messages`in e&&delete e.messages,i=e)};return r.pipe(xd(r=>{switch(r.type){case L.TEXT_MESSAGE_START:{let e=r;return[{type:JO.TextMessageStart,messageId:e.messageId,role:e.role}]}case L.TEXT_MESSAGE_CONTENT:{let e=r;return[{type:JO.TextMessageContent,messageId:e.messageId,content:e.delta}]}case L.TEXT_MESSAGE_END:{let e=r;return[{type:JO.TextMessageEnd,messageId:e.messageId}]}case L.TOOL_CALL_START:{let e=r;return u.push({id:e.toolCallId,type:`function`,function:{name:e.toolCallName,arguments:``}}),o=!0,d[e.toolCallId]=e.toolCallName,[{type:JO.ActionExecutionStart,actionExecutionId:e.toolCallId,actionName:e.toolCallName,parentMessageId:e.parentMessageId}]}case L.TOOL_CALL_ARGS:{let c=r,d=u.find(e=>e.id===c.toolCallId);if(!d)return ZO(`[ag-ui][legacy] TOOL_CALL_ARGS: No tool call found with ID '${c.toolCallId}'`),[];d.function.arguments+=c.delta;let f=!1;if(l){let e=l.find(e=>e.tool==d.function.name);if(e)try{let t=JSON.parse(Id(d.function.arguments));e.tool_argument&&e.tool_argument in t?(p({...i,[e.state_key]:t[e.tool_argument]}),f=!0):e.tool_argument||(p({...i,[e.state_key]:t}),f=!0)}catch{}}return[{type:JO.ActionExecutionArgs,actionExecutionId:c.toolCallId,args:c.delta},...f?[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}]:[]]}case L.TOOL_CALL_END:{let e=r;return[{type:JO.ActionExecutionEnd,actionExecutionId:e.toolCallId}]}case L.TOOL_CALL_RESULT:{let e=r,t=d[e.toolCallId];return(t===void 0||t===``)&&ZO(`[ag-ui][legacy] No usable tool name was seen for tool call '${e.toolCallId}' (${t===void 0?`no TOOL_CALL_START reached this bridge`:`its TOOL_CALL_START carried an empty toolCallName`}), so its result is being bridged with the fabricated action name "unknown". Downstream consumers route on that name.`),[{type:JO.ActionExecutionResult,actionExecutionId:e.toolCallId,result:XO(e.toolCallId,e.content),actionName:t||`unknown`}]}case L.RAW:return f||(f=!0,ZO(`[ag-ui][legacy] Dropping RAW events: the legacy runtime protocol has no equivalent, so the provider payloads they carry do not reach the legacy stream. Reported once per stream.`)),[];case L.CUSTOM:{let e=r;switch(e.name){case`Exit`:a=!1;break;case`PredictState`:l=e.value}return[{type:JO.MetaEvent,name:e.name,value:e.value}]}case L.STATE_SNAPSHOT:return p(r.snapshot),[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}];case L.STATE_DELTA:{let c=r,l;try{l=Fl.applyPatch(i,c.delta,!0,!1).newDocument}catch(e){let t=e instanceof Error?e.message:String(e);return ZO(`[ag-ui][legacy] Failed to apply state patch:\nCurrent state: ${JSON.stringify(i,null,2)}\nPatch operations: ${JSON.stringify(c.delta,null,2)}\nError: ${t}`),[]}return p(l),[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:o}]}case L.MESSAGES_SNAPSHOT:return c=r.messages,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify({...i,...c?{messages:c}:{}}),active:!0}];case L.RUN_STARTED:return[];case L.RUN_FINISHED:{if(c&&(i.messages=c),Object.keys(i).length===0)return[];let r=null;if(c)try{r=$O(c)}catch(e){return[{type:JO.RunError,message:e.message}]}return[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify({...i,...r?{messages:r}:{}}),active:!1}]}case L.RUN_ERROR:{let e=r;return[{type:JO.RunError,message:e.message,code:e.code}]}case L.STEP_STARTED:return s=r.stepName,u=[],l=null,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:!0}];case L.STEP_FINISHED:return u=[],l=null,[{type:JO.AgentStateMessage,threadId:e,agentName:n,nodeName:s,runId:t,running:a,role:`assistant`,state:JSON.stringify(i),active:!1}];default:return[]}}))};function $O(e){let t=[];for(let n of e)if(n.role===`assistant`||n.role===`user`||n.role===`system`){let e=YO(n.content);if(e){let r={id:n.id,role:n.role,content:e};t.push(r)}if(n.role===`assistant`&&n.toolCalls&&n.toolCalls.length>0)for(let e of n.toolCalls){let r;try{r=JSON.parse(e.function.arguments)}catch(t){throw Error(`Failed to parse arguments for tool call '${e.id}' (${e.function.name}): ${t.message}`)}let i={id:e.id,name:e.function.name,arguments:r,parentMessageId:n.id};t.push(i)}}else if(n.role===`tool`){let r=`unknown`;for(let t of e)if(t.role===`assistant`&&t.toolCalls?.length){for(let e of t.toolCalls)if(e.id===n.toolCallId){r=e.function.name;break}}let i={id:n.id,result:XO(n.toolCallId,n.content),actionExecutionId:n.toolCallId,actionName:r};t.push(i)}return t}var ek=e=>e.kind===`tool`?e.fields.toolCallId:e.fields.messageId,tk=e=>e===`tool`?`toolCallId`:`messageId`,nk=(e,t,n,r,i)=>{if(r!==void 0&&r!==i)throw Error(`Cannot continue ${e} '${t}': chunk ${n} '${r}' does not match the open stream's ${n} ${i===void 0?`(absent)`:`'${i}'`}.`)},rk=(e,t)=>t.metadata===void 0?e:{...e,metadata:t.metadata},ik=(e,t)=>{let n=rk(e,t);return t.rawEvent===void 0?n:{...n,rawEvent:t.rawEvent}},ak=e=>new Set(Object.keys(e.shape)),ok=ak(bx),sk=ak(wx),ck=ak(sS),lk=(e,t)=>{let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n},uk=e=>{typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`[ag-ui][transform] ${e} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`)},dk=(e,t,n,r)=>{if(t===void 0||n||e.length===0)return;let i=e[e.length-1],a=Object.keys(t).filter(e=>Object.prototype.hasOwnProperty.call(i,e));a.length>0&&uk(`A ${r} carried ${a.map(e=>`'${e}'`).join(`, `)}, which the synthesized ${String(i.type)} already describes. The synthesized value is kept and the chunk's is dropped — this stage does not judge a described field, so the producer's value cannot be substituted for its own.`),e[e.length-1]={...t,...i}},fk=e=>t=>{let n=MO(e),r=new Map,i=e=>{let t=r.get(e);if(!t)return[];switch(r.delete(e),t.kind){case`text`:{let e={type:L.TEXT_MESSAGE_END,messageId:t.fields.messageId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`TEXT_MESSAGE_END`,e,{messageId:e.messageId}),[e]}case`tool`:{let e={type:L.TOOL_CALL_END,toolCallId:t.fields.toolCallId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`TOOL_CALL_END`,e,{toolCallId:e.toolCallId}),[e]}case`reasoning`:{let e={type:L.REASONING_MESSAGE_END,messageId:t.fields.messageId,...t.fields.subagentRunId!==void 0&&{subagentRunId:t.fields.subagentRunId}};return n?.event(`TRANSFORM`,`REASONING_MESSAGE_END`,e,{messageId:e.messageId}),[e]}}},a=()=>[...r.keys()].flatMap(e=>i(e)),o=(e,t)=>{for(let[n,i]of r)if(i.kind===e&&ek(i)===t)return{owner:n}},s=(e,t,n,i,a)=>{if(t!==void 0){let r=o(e,t);if(r){if(n!==void 0&&n!==r.owner)throw Error(`Cannot continue ${a} '${t}': chunk subagentRunId '${n}' does not match the open stream's subagent '${r.owner??`(the parent agent)`}'.`);return r.owner}return n}if(n!==void 0)return n;if(r.get(void 0)?.kind===e)return;let s=[...r.entries()].filter(([,t])=>t.kind===e);if(s.length===1)return s[0][0];if(s.length>1)throw Error(`Ambiguous ${i}: it carries neither a ${tk(e)} nor a subagentRunId, but ${s.length} lanes have an open ${a}. Attribute the chunk to the subagent it belongs to.`)};return t.pipe(xd(e=>{switch(e.type){case L.TEXT_MESSAGE_START:case L.TEXT_MESSAGE_CONTENT:case L.TEXT_MESSAGE_END:case L.TOOL_CALL_START:case L.TOOL_CALL_ARGS:case L.TOOL_CALL_END:case L.TOOL_CALL_RESULT:case L.STATE_SNAPSHOT:case L.STATE_DELTA:case L.CUSTOM:case L.STEP_STARTED:case L.STEP_FINISHED:case L.REASONING_START:case L.REASONING_MESSAGE_START:case L.REASONING_MESSAGE_CONTENT:case L.REASONING_MESSAGE_END:case L.REASONING_END:return[...i(e.subagentRunId??void 0),e];case L.RUN_STARTED:case L.RUN_FINISHED:case L.RUN_ERROR:case L.MESSAGES_SNAPSHOT:return[...a(),e];case L.RAW:case L.ACTIVITY_SNAPSHOT:case L.ACTIVITY_DELTA:case L.REASONING_ENCRYPTED_VALUE:case L.SUBAGENT_STARTED:return[e];case L.SUBAGENT_FINISHED:case L.SUBAGENT_ERROR:{let t=e.subagentRunId;return t==null?[e]:[...i(t),e]}case L.TEXT_MESSAGE_CHUNK:{let t=e,a=lk(e,ok),o=s(`text`,t.messageId,t.subagentRunId??void 0,`TEXT_MESSAGE_CHUNK`,`text message`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`text`&&(t.messageId===void 0||t.messageId===c.fields.messageId))nk(`text message`,c.fields.messageId,`role`,t.role,c.fields.role),nk(`text message`,c.fields.messageId,`name`,t.name,c.fields.name),d=c.fields;else{if(l.push(...i(o)),t.messageId===void 0)throw Error(`First TEXT_MESSAGE_CHUNK must have a messageId`);d={messageId:t.messageId,role:t.role===void 0?`assistant`:t.role,name:t.name,subagentRunId:t.subagentRunId},r.set(o,{kind:`text`,fields:d});let e=rk({type:L.TEXT_MESSAGE_START,messageId:t.messageId,role:d.role,...t.name!==void 0&&{name:t.name},...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`TEXT_MESSAGE_START`,e,{messageId:t.messageId})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.TEXT_MESSAGE_CONTENT,messageId:d.messageId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`TEXT_MESSAGE_CONTENT`,r,{messageId:d.messageId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.TEXT_MESSAGE_CONTENT,messageId:d.messageId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`TEXT_MESSAGE_CHUNK`),l}case L.TOOL_CALL_CHUNK:{let t=e,a=lk(e,sk),o=s(`tool`,t.toolCallId,t.subagentRunId??void 0,`TOOL_CALL_CHUNK`,`tool call`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`tool`&&(t.toolCallId===void 0||t.toolCallId===c.fields.toolCallId))nk(`tool call`,c.fields.toolCallId,`toolCallName`,t.toolCallName,c.fields.toolCallName),nk(`tool call`,c.fields.toolCallId,`parentMessageId`,t.parentMessageId,c.fields.parentMessageId),d=c.fields;else{if(l.push(...i(o)),t.toolCallId===void 0)throw Error(`First TOOL_CALL_CHUNK must have a toolCallId`);if(t.toolCallName===void 0)throw Error(`First TOOL_CALL_CHUNK must have a toolCallName`);d={toolCallId:t.toolCallId,toolCallName:t.toolCallName,parentMessageId:t.parentMessageId,subagentRunId:t.subagentRunId},r.set(o,{kind:`tool`,fields:d});let e=rk({type:L.TOOL_CALL_START,toolCallId:t.toolCallId,toolCallName:t.toolCallName,...t.parentMessageId!==void 0&&{parentMessageId:t.parentMessageId},...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`TOOL_CALL_START`,e,{toolCallId:t.toolCallId,toolCallName:t.toolCallName})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.TOOL_CALL_ARGS,toolCallId:d.toolCallId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`TOOL_CALL_ARGS`,r,{toolCallId:d.toolCallId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.TOOL_CALL_ARGS,toolCallId:d.toolCallId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`TOOL_CALL_CHUNK`),l}case L.REASONING_MESSAGE_CHUNK:{let t=e,a=lk(e,ck),o=s(`reasoning`,t.messageId,t.subagentRunId??void 0,`REASONING_MESSAGE_CHUNK`,`reasoning message`),c=r.get(o),l=[],u=!1,d;if(c?.kind===`reasoning`&&(t.messageId===void 0||t.messageId===c.fields.messageId))d=c.fields;else{if(l.push(...i(o)),t.messageId===void 0)throw Error(`First REASONING_MESSAGE_CHUNK must have a messageId`);d={messageId:t.messageId,subagentRunId:t.subagentRunId},r.set(o,{kind:`reasoning`,fields:d});let e=rk({type:L.REASONING_MESSAGE_START,messageId:t.messageId,role:`reasoning`,...t.subagentRunId!==void 0&&{subagentRunId:t.subagentRunId}},t);l.push(e),n?.event(`TRANSFORM`,`REASONING_MESSAGE_START`,e,{messageId:t.messageId})}if(t.delta!==void 0||t.rawEvent!==void 0){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId,r=ik({...a,type:L.REASONING_MESSAGE_CONTENT,messageId:d.messageId,delta:t.delta===void 0?``:t.delta,...e!==void 0&&{subagentRunId:e}},t);l.push(r),u=!0,n?.event(`TRANSFORM`,`REASONING_MESSAGE_CONTENT`,r,{messageId:d.messageId})}if(l.length===0&&(t.metadata!==void 0||t.rawEvent!==void 0||t.subagentRunId===null||a!==void 0)){let e=t.subagentRunId===void 0?d.subagentRunId:t.subagentRunId;l.push({...a,type:L.REASONING_MESSAGE_CONTENT,messageId:d.messageId,delta:``,...t.metadata!==void 0&&{metadata:t.metadata},...t.rawEvent!==void 0&&{rawEvent:t.rawEvent},...e!==void 0&&{subagentRunId:e}}),u=!0}return dk(l,a,u,`REASONING_MESSAGE_CHUNK`),l}}return e.type,[e]}),jd(()=>{a()}))},pk=Symbol(`agui.strip.drop`);function mk(e){let t=e;for(;;){if(t instanceof tO||t instanceof rO||t instanceof aO||t instanceof hO||t instanceof dO){t=t.unwrap();continue}if(t instanceof pO){t=t.def.in;continue}if(t instanceof _O){t=t.def.getter();continue}return t}}function hk(e){let t=e.def;return typeof t?.discriminator==`string`?t.discriminator:void 0}function gk(e){let t=e,n=Array.isArray(t.def?.values)?t.def.values:t.values?Array.from(t.values):void 0;return n&&n.length===1?n[0]:t.value}function _k(e){let t=mk(e);return t instanceof QD?gk(t):void 0}function vk(e,t,n,r){let i=mk(t);if(i instanceof WD){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=i.shape,a=e,o={},s=i.meta()?.specOpen===!0;for(let e of Object.keys(a)){let i=Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;if(i===void 0){if(s){o[e]=a[e];continue}r.push(`${n}/${e}`);continue}let c=r.length,l=vk(a[e],i,`${n}/${e}`,r);if(l===pk){if(r.length=c,i.safeParse(void 0).success){r.push(`${n}/${e}`);continue}return pk}o[e]=l}return o}if(i instanceof HD){if(!Array.isArray(e))return e;let t=i.element,a=[];return e.forEach((e,i)=>{let o=r.length,s=vk(e,t,`${n}/${i}`,r);if(s===pk){r.length=o,r.push(`${n}/${i}`);return}a.push(s)}),a}if(i instanceof YD){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=i.def.valueType,a=e,o={};for(let e of Object.keys(a)){let i=r.length,s=vk(a[e],t,`${n}/${e}`,r);if(s===pk){r.length=i,r.push(`${n}/${e}`);continue}o[e]=s}return o}if(i instanceof GD){let t=i.options,a=hk(i);if(a!==void 0){if(typeof e!=`object`||!e||Array.isArray(e))return e;let i=e[a];for(let o of t){let t=mk(o);if(!(t instanceof WD))continue;let s=t.shape;if(_k(s[a])===i)return vk(e,o,n,r)}return pk}let o=t.filter(e=>mk(e)instanceof WD),s=typeof e==`object`&&!!e&&!Array.isArray(e);if(o.length>1&&s)return e;for(let i of t){let t=mk(i);if(t instanceof HD&&Array.isArray(e)||t instanceof WD&&s)return vk(e,i,n,r)}return e}return e}function yk(e,t){let n=[],r=vk(e,t,``,n);if(r===pk)throw Error(`Internal error: the stripper found the whole value unrecognisable, which the schemas are not supposed to allow — schema/stripper mismatch.`);return{value:r,stripped:n}}var bk=new Set(Object.values(L));function xk(e){return bk.has(e.type)}var Sk=new Map(pS.options.map(e=>{let t=e.shape;return[String(gk(t.type)),e]})),Ck=()=>typeof process<`u`&&!!{}.SUPPRESS_TRANSFORMATION_WARNINGS;function wk(e){Ck()||console.warn(`[ag-ui][enforce] ${e}`)}var Tk=e=>t=>{let n=MO(e);return t.pipe(xd(e=>{if(!xk(e))return wk(`Dropping unrecognised event '${String(e.type)}': no middleware translated it and the protocol does not describe it.`),n?.event(`ENFORCE`,`Unrecognised event dropped:`,e,{type:e.type}),Lu;let t=Sk.get(e.type);if(t===void 0)throw Error(`No validator for recognised event type '${String(e.type)}'`);let{value:r,stripped:i}=yk(e,t);for(let t of i)wk(`Removed unrecognised material at '${t}' on ${String(e.type)}. Nothing handled it; see the repo-root DEPRECATIONS.md if it is a retired shape.`);return gd(t.parse(r))}))};function Ek(e){let{value:t,stripped:n}=yk(Yc(e,`RunAgentInput`),qx);for(let e of n)wk(`Removed unrecognised material at '${e}' from the outgoing input.`);return qx.parse(t)}var Dk=class{runNext(e,t){return t.run(e).pipe(fk(!1))}runNextWithState(e,t){let n=wO(e.messages||[]),r=wO(e.state===void 0?{}:e.state),i=new Iu;return LO(e,i,t,[]).subscribe({next:e=>{e.messages!==void 0&&(n=e.messages),e.state!==void 0&&(r=e.state)},error:()=>{}}),this.runNext(e,t).pipe(Dd(async e=>(i.next(e),await new Promise(e=>setTimeout(e,0)),{event:e,messages:wO(n),state:wO(r)})))}},Ok=class extends Dk{constructor(e){super(),this.fn=e}run(e,t){return this.fn(e,t)}};function kk(e){return e.startsWith(`image/`)?`image`:e.startsWith(`audio/`)?`audio`:e.startsWith(`video/`)?`video`:`document`}function Ak(e){return typeof e==`object`&&!!e&&`type`in e&&e.type===`binary`&&`mimeType`in e&&typeof e.mimeType==`string`}function jk(e){let t=kk(e.mimeType);return e.data?{type:t,source:{type:`data`,value:e.data,mimeType:e.mimeType},...e.filename?{metadata:{filename:e.filename}}:{}}:e.url?{type:t,source:{type:`url`,value:e.url,mimeType:e.mimeType},...e.filename?{metadata:{filename:e.filename}}:{}}:((typeof process>`u`||!{}.SUPPRESS_TRANSFORMATION_WARNINGS)&&console.warn(`[ag-ui][compat] A binary content part carries only an id ('${e.id??``}') and cannot be converted to a modern media part; a 1.0 peer will not accept it. Provide data or a url. See the repo-root DEPRECATIONS.md.`),e)}function Mk(e,t,n){if(typeof e!=`object`||!e||!(`type`in e)||e.type!==t.type||!(`source`in e))return!1;let r=e.source;return typeof r!=`object`||!r||!(`type`in r)||r.type!==t.source.type||!(`value`in r)||r.value!==t.source.value||!(`mimeType`in r)||r.mimeType!==t.source.mimeType?!1:!n||`metadata`in e&&typeof e.metadata==`object`&&e.metadata!==null&&`filename`in e.metadata&&e.metadata.filename===n}function Nk(e){let t=e.content;if(!Array.isArray(t))return e;let n=t.flatMap(e=>{if(Ak(e)){let n=jk(e);return n.type!==`binary`&&t.some(t=>Mk(t,n,e.filename))?[]:[n]}return[e]});return{...e,content:n}}var Pk=`THINKING_START`,Fk=`THINKING_END`,Ik=`THINKING_TEXT_MESSAGE_START`,Lk=`THINKING_TEXT_MESSAGE_CONTENT`,Rk=`THINKING_TEXT_MESSAGE_END`;function zk(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var Bk={event:[`rawEvent`,`subagentRunId`],[L.RUN_STARTED]:[`parentRunId`,`input`],[L.RUN_FINISHED]:[`result`,`outcome`],[L.RUN_ERROR]:[`usage`],[L.SUBAGENT_FINISHED]:[`result`],[L.TOOL_CALL_START]:[`parentMessageId`],[L.TOOL_CALL_CHUNK]:[`parentMessageId`],[L.TOOL_CALL_RESULT]:[`role`],"RUN_FINISHED.outcome":[`pendingToolCallIds`],"RUN_FINISHED.usage[]":[`provider`,`reasoningTokens`,`cachedInputTokens`,`cacheWriteInputTokens`],RunAgentInput:[`forwardedProps`],Tool:[`parameters`],ResumeEntry:[`payload`],"input content":[`metadata`]},Vk=new Map(Object.entries(Bk).filter(([e])=>Object.values(L).includes(e))),Hk=e=>RO(e,`an absent field`);function Uk(e,t,n,r){if(!zk(e))return e;let i;for(let a of t)e[a]===null&&(r(n===void 0?`${a}: null`:`${n}.${a}: null`),i??={...e},delete i[a]);return i??e}function Wk(e,t,n){if(!zk(e)||!Array.isArray(e[t]))return e;let r=e[t],i=r.map(n);return i.some((e,t)=>e!==r[t])?{...e,[t]:i}:e}function Gk(e,t){return Wk(e,`content`,e=>{if(!zk(e))return e;switch(e.type){case`image`:case`audio`:case`video`:case`document`:return Uk(e,Bk[`input content`],`${e.type} input content`,t);default:return e}})}function Kk(e,t=Hk){let n=Uk(e,Bk.RunAgentInput,`RunAgentInput`,t);return n=Wk(n,`tools`,e=>Uk(e,Bk.Tool,`Tool`,t)),n=Wk(n,`resume`,e=>Uk(e,Bk.ResumeEntry,`ResumeEntry`,t)),Wk(n,`messages`,e=>Gk(e,t))}var qk=class extends Dk{constructor(...e){super(...e),this.currentReasoningId=null,this.currentMessageId=null,this.nullsNoticedThisRun=new Set,this.noticeNullOncePerRun=e=>{this.nullsNoticedThisRun.has(e)||(this.nullsNoticedThisRun.add(e),RO(e,`an absent field`))}}warn(e,t){RO(e,t)}mintedContinuationId(e,t){if(t!==null)return t;let n=TO();return this.warnAside(`Minting a messageId ('${n}') for ${e}: no THINKING opener preceded it, so there was no id to continue. The id is this client's invention, not the producer's, and verification will reject the translated event for naming something nothing opened.`),n}warnAside(e){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`[ag-ui][compat] ${e} Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`)}run(e,t){return this.currentReasoningId=null,this.currentMessageId=null,this.nullsNoticedThisRun.clear(),e.messages=e.messages.map(Nk),t.run(e).pipe(yd(e=>this.transformEvent(e)))}transformEvent(e){let t=this.noticeNullOncePerRun;e.type===L.RUN_STARTED&&this.nullsNoticedThisRun.clear(),e=Uk(e,Bk.event,void 0,t);let n=Vk.get(e.type);switch(n&&(e=Uk(e,n,e.type,t)),e.type){case Pk:{this.currentReasoningId=TO();let{title:t,...n}=e;return this.warn(Pk,L.REASONING_START),t!==void 0&&this.warnAside(`Dropping ${Pk}.title ${JSON.stringify(t)}: ${L.REASONING_START} has no title field, so the span's label cannot be carried and nothing downstream can recover it.`),{...n,type:L.REASONING_START,messageId:this.currentReasoningId}}case Ik:return this.currentMessageId=TO(),this.warn(Ik,L.REASONING_MESSAGE_START),{...e,type:L.REASONING_MESSAGE_START,messageId:this.currentMessageId,role:`reasoning`};case Lk:{let{delta:t,...n}=e;return this.warn(Lk,L.REASONING_MESSAGE_CONTENT),{...n,type:L.REASONING_MESSAGE_CONTENT,messageId:this.mintedContinuationId(Lk,this.currentMessageId),delta:t}}case Rk:{let t=this.mintedContinuationId(Rk,this.currentMessageId);return this.currentMessageId=null,this.warn(Rk,L.REASONING_MESSAGE_END),{...e,type:L.REASONING_MESSAGE_END,messageId:t}}case Fk:{let t=this.mintedContinuationId(Fk,this.currentReasoningId);return this.currentReasoningId=null,this.warn(Fk,L.REASONING_END),{...e,type:L.REASONING_END,messageId:t}}case L.RUN_FINISHED:{let n=e,r=Uk(n.outcome,Bk[`RUN_FINISHED.outcome`],`RUN_FINISHED.outcome`,t);return Wk(r===n.outcome?n:{...n,outcome:r},`usage`,e=>Uk(e,Bk[`RUN_FINISHED.usage[]`],`RUN_FINISHED.usage[]`,t))}case L.MESSAGES_SNAPSHOT:{let t=e;return Array.isArray(t.messages)?{...t,messages:t.messages.map(e=>this.upgradeInboundMessage(e))}:e}case L.RUN_STARTED:{let n=Kk(e.input,t),r=n===e.input?e:{...e,input:n},i=r;return!i.input||!Array.isArray(i.input.messages)?r:{...i,input:{...i.input,messages:i.input.messages.map(e=>this.upgradeInboundMessage(e))}}}default:return e}}upgradeInboundMessage(e){e=Gk(e,this.noticeNullOncePerRun);let t=e.content;return!Array.isArray(t)||!t.some(e=>typeof e==`object`&&!!e&&e.type===`binary`)?e:(this.warn(`binary input content`,`the modern media content parts`),Nk(e))}},Jk=()=>e=>wd(()=>{let t=new qk;return e.pipe(yd(e=>t.transformEvent(e)))});function Yk(e,t=new Date){return e.expiresAt!==void 0&&new Date(e.expiresAt)<=t}function Xk(){return typeof process<`u`&&!!{}.SUPPRESS_TRANSFORMATION_WARNINGS}function Zk(e){Xk()||console.warn(`[ag-ui][compat] Flattening message content for a <=0.0.39 peer DROPS non-text parts (${e.join(`, `)}). The peer cannot receive them; upgrade it to keep media content. See the repo-root DEPRECATIONS.md.`)}function Qk(e){Xk()||console.warn(`[ag-ui][compat] Not flattening message content for a <=0.0.39 peer: ${e} content part(s) claim type "text" but carry a malformed 'text' value. That is a defect in the message, not media the peer cannot represent, and a downgrade must not repair it — the content is passed on unchanged so the outgoing enforcement boundary reports it. See the repo-root DEPRECATIONS.md.`)}function $k(e){let t=e.content;if(Array.isArray(t)){let n=e=>typeof e==`object`&&!!e&&`type`in e&&e.type===`text`,r=e=>n(e)&&typeof e.text==`string`,i=t.filter(e=>n(e)&&!r(e));if(i.length>0)return Qk(i.length),e;let a=t.filter(e=>!r(e)).map(e=>typeof e==`object`&&e&&`type`in e?String(e.type):typeof e);a.length>0&&Zk(a);let o=t.filter(r).map(e=>e.text).join(``);return{...e,content:o}}return typeof t==`string`?e:t===void 0?{...e,content:``}:e}var eA=class extends Dk{run(e,t){let{parentRunId:n,...r}=e,i={...r,messages:r.messages.map($k)};return this.runNext(i,t)}},tA=`THINKING_START`,nA=`THINKING_END`,rA=`THINKING_TEXT_MESSAGE_START`,iA=`THINKING_TEXT_MESSAGE_CONTENT`,aA=`THINKING_TEXT_MESSAGE_END`,oA=class extends Dk{constructor(...e){super(...e),this.currentReasoningId=null,this.currentMessageId=null}warnAboutTransformation(e,t){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`AG-UI is converting ${e} to ${t}. To remove this warning, upgrade your AG-UI integration package (e.g. @ag-ui/langgraph). To surpress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`)}run(e,t){return this.currentReasoningId=null,this.currentMessageId=null,this.runNext(e,t).pipe(yd(e=>this.transformEvent(e)))}transformEvent(e){switch(e.type){case tA:{this.currentReasoningId=TO();let{title:t,...n}=e;return this.warnAboutTransformation(tA,L.REASONING_START),{...n,type:L.REASONING_START,messageId:this.currentReasoningId}}case rA:return this.currentMessageId=TO(),this.warnAboutTransformation(rA,L.REASONING_MESSAGE_START),{...e,type:L.REASONING_MESSAGE_START,messageId:this.currentMessageId,role:`reasoning`};case iA:{let{delta:t,...n}=e;return this.warnAboutTransformation(iA,L.REASONING_MESSAGE_CONTENT),{...n,type:L.REASONING_MESSAGE_CONTENT,messageId:this.currentMessageId??TO(),delta:t}}case aA:{let t=this.currentMessageId??TO();return this.warnAboutTransformation(aA,L.REASONING_MESSAGE_END),{...e,type:L.REASONING_MESSAGE_END,messageId:t}}case nA:{let t=this.currentReasoningId??TO();return this.warnAboutTransformation(nA,L.REASONING_END),{...e,type:L.REASONING_END,messageId:t}}default:return e}}},sA=`SUBAGENT_STARTED`,cA=`SUBAGENT_FINISHED`,lA=`SUBAGENT_ERROR`;function uA(e){if(e&&typeof e==`object`&&`subagentRunId`in e){let{subagentRunId:t,...n}=e;return n}return e}function dA(e){return e.map(e=>uA(e))}var fA=class extends Dk{warnDroppedLifecycleEvent(e){typeof process<`u`&&{}.SUPPRESS_TRANSFORMATION_WARNINGS||console.warn(`AG-UI is dropping ${e} because the target agent predates subagent support. To remove this warning, upgrade your AG-UI integration package. To suppress it, set SUPPRESS_TRANSFORMATION_WARNINGS=true in your .env file.`)}run(e,t){let n={...e,messages:(e.messages??[]).map(e=>uA(e))};return this.runNext(n,t).pipe(Pd(e=>{let t=e.type;(t===sA||t===cA||t===lA)&&this.warnDroppedLifecycleEvent(t)}),Td(e=>{let t=e.type;return t!==sA&&t!==cA&&t!==lA}),yd(e=>{let t=uA(e);if(t.type===L.MESSAGES_SNAPSHOT){let e=t;if(Array.isArray(e.messages))return{...e,messages:dA(e.messages)}}if(t.type===L.RUN_FINISHED){let e=t;if(e.outcome&&Array.isArray(e.outcome.interrupts))return{...e,outcome:{...e.outcome,interrupts:e.outcome.interrupts.map(e=>uA(e))}}}if(t.type===L.RUN_STARTED){let e=t;if(e.input&&Array.isArray(e.input.messages))return{...e,input:{...e.input,messages:dA(e.input.messages)}}}return t}))}},pA=`1.0.2`,mA=!1,hA=new WeakSet,gA=(e,t)=>/^\d+\.\d+$/.test(e)?WT(e,t)>0?`newer`:`not-newer`:`uninterpretable`,_A=e=>{let t=e.protocolVersion;if(t!==void 0&&t!==`1.0`)switch(gA(t,`1.0`)){case`uninterpretable`:console.warn(`[ag-ui] The producer declared protocol version '${t}', which this client cannot interpret.`);return;case`newer`:console.warn(`[ag-ui] The producer speaks protocol ${t}; this client speaks 1.0. Unrecognised material will be stripped with warnings.`);return;case`not-newer`:return}},vA=class e{resolvePeerCeiling(t){if(this.resolvingPeerCeiling)return pA;let n=Object.getOwnPropertyDescriptor(this,`maxVersion`),r=Object.getOwnPropertyDescriptor(this,`maxProtocolVersion`),i=Object.getPrototypeOf(this);for(;i&&i!==e.prototype;)n??=Object.getOwnPropertyDescriptor(i,`maxVersion`),r??=Object.getOwnPropertyDescriptor(i,`maxProtocolVersion`),i=Object.getPrototypeOf(i);if(t===`maxVersion`&&n)return pA;let a=t===`maxProtocolVersion`?n:r;if(!a)return pA;this.resolvingPeerCeiling=!0;try{return a.get?a.get.call(this):a.value}finally{this.resolvingPeerCeiling=!1}}get maxProtocolVersion(){return this.resolvePeerCeiling(`maxProtocolVersion`)}get maxVersion(){return!this.resolvingPeerCeiling&&!mA&&(mA=!0,console.warn(`[ag-ui] AbstractAgent.maxVersion is deprecated — use maxProtocolVersion. Same value; the new name says whose version it is and that it is a ceiling.`)),this.resolvePeerCeiling(`maxVersion`)}get debug(){return this._debug}set debug(e){this._debug=jO(e),this._debugLogger=PO(this._debug)}get debugLogger(){return this._debugLogger}set debugLogger(e){this._debugLogger=typeof e==`boolean`?e?PO(jO(!0)):void 0:e}resolvedCeilingDuringConstruction(){let e=this.maxProtocolVersion;if(typeof e!=`string`||!GT(e))throw new R(`maxProtocolVersion resolved to ${JSON.stringify(e)} during construction, which is not a version this client can compare. A ceiling read from an instance field is not available yet — return a literal from the getter.`);return e}constructor({agentId:e,description:t,threadId:n,initialMessages:r,initialState:i,debug:a}={}){this.subscribers=[],this.isRunning=!1,this.pendingInterrupts=[],this.middlewares=[],this.resolvingPeerCeiling=!1,this.agentId=e,this.description=t??``,this.threadId=n??Gc(),this.messages=wO(r??[]),this.state=wO(i??{}),this._debug=jO(a),this._debugLogger=PO(this._debug);let o=this.resolvedCeilingDuringConstruction();WT(o,`0.0.39`)<=0&&this.middlewares.unshift(new eA),WT(o,`0.0.45`)<=0&&this.middlewares.unshift(new oA),WT(o,`0.0.57`)<=0&&this.middlewares.unshift(new fA)}subscribe(e){return this.subscribers.push(e),{unsubscribe:()=>{this.subscribers=this.subscribers.filter(t=>t!==e)}}}use(...e){let t=e.map(e=>typeof e==`function`?new Ok(e):e);return this.middlewares.push(...t),this}async runAgent(e,t){try{this.isRunning=!0,this.agentId=this.agentId??Gc();let n=this.prepareRunAgentInput(e);this.debugLogger?.lifecycle(`LIFECYCLE`,`Run started:`,{agentId:this.agentId,threadId:this.threadId});let r,i=new Set(this.messages.map(e=>e.id)),a=[{onRunStartedEvent:({event:e})=>_A(e),onRunFinishedEvent:e=>{e.outcome===`success`&&(r=e.result)}},...this.subscribers,t??{}];hA.add(n),await this.onInitialize(n,a),this.activeRunDetach$=new Nu;let o;this.activeRunCompletionPromise=new Promise(e=>{o=e}),await vd(Su(()=>[...this.middlewares,new qk].reduceRight((e,t)=>({run:n=>t.run(n,e),get messages(){return e.messages},get state(){return e.state}}),this).run(n),Tk(this.debugLogger),fk(this.debugLogger),zO(this.debugLogger),e=>e.pipe(Nd(this.activeRunDetach$)),e=>this.applyBeforeSourceError(n,e,a),Ed(e=>(this.debugLogger?.lifecycle(`LIFECYCLE`,`Run errored:`,{agentId:this.agentId,error:e instanceof Error?e.message:String(e)}),this.isRunning=!1,this.onError(n,e,a))),jd(()=>{this.debugLogger?.lifecycle(`LIFECYCLE`,`Run finished:`,{agentId:this.agentId,threadId:this.threadId}),this.isRunning=!1,this.onFinalize(n,a),o?.(),o=void 0,this.activeRunCompletionPromise=void 0,this.activeRunDetach$=void 0}))(gd(null)));let s=wO(this.messages).filter(e=>!i.has(e.id));return{result:r,newMessages:s}}finally{this.isRunning=!1}}connect(e){throw new Xc}async connectAgent(e,t){try{this.isRunning=!0,this.agentId=this.agentId??Gc();let n=this.prepareRunAgentInput(e),r,i=new Set(this.messages.map(e=>e.id)),a=[{onRunStartedEvent:({event:e})=>_A(e),onRunFinishedEvent:e=>{e.outcome===`success`&&(r=e.result)}},...this.subscribers,t??{}];await this.onInitialize(n,a),this.activeRunDetach$=new Nu;let o;this.activeRunCompletionPromise=new Promise(e=>{o=e}),await vd(Su(()=>wd(()=>this.connect(n)),e=>Tk(this.debugLogger)(Jk()(e)),fk(this.debugLogger),zO(this.debugLogger),e=>e.pipe(Nd(this.activeRunDetach$)),e=>this.applyBeforeSourceError(n,e,a),Ed(e=>(this.isRunning=!1,e instanceof Xc?Lu:this.onError(n,e,a))),jd(()=>{this.isRunning=!1,this.onFinalize(n,a),o?.(),o=void 0,this.activeRunCompletionPromise=void 0,this.activeRunDetach$=void 0}))(gd(null)),{defaultValue:void 0});let s=wO(this.messages).filter(e=>!i.has(e.id));return{result:r,newMessages:s}}finally{this.isRunning=!1}}abortRun(){}async detachActiveRun(){if(!this.activeRunDetach$)return;let e=this.activeRunCompletionPromise??Promise.resolve();this.activeRunDetach$.next(),this.activeRunDetach$?.complete(),await e}applyBeforeSourceError(e,t,n){return wd(()=>{let r,i=t.pipe(Ed(e=>(r={error:e},Lu)));return this.processApplyEvents(e,this.apply(e,i,n),n).pipe(kd(wd(()=>{let e=r;return e?z(()=>e.error):Lu})))})}apply(e,t,n){return LO(e,t,this,n,this.debugLogger)}processApplyEvents(e,t,n){return t.pipe(Pd(t=>{t.messages&&(this.messages=t.messages,n.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),t.state!==void 0&&(this.state=t.state,n.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))}))}prepareRunAgentInput(e){let t=wO(this.messages);for(let e of t)e.subagentRunId===null&&delete e.subagentRunId;let n=t.filter(e=>e.role!==`activity`);return{threadId:this.threadId,runId:e?.runId||Gc(),...WT(this.maxProtocolVersion,pA)>=0&&{protocolVersion:`1.0`},tools:wO(e?.tools??[]),context:wO(e?.context??[]),forwardedProps:wO(e?.forwardedProps??{}),state:wO(this.state),messages:n,...e?.resume===void 0?{}:{resume:wO(e.resume)}}}async onInitialize(e,t){if(hA.has(e)&&this.pendingInterrupts.length>0){let t=new Set((e.resume??[]).map(e=>e.interruptId)),n=this.pendingInterrupts.map(e=>e.id).filter(e=>!t.has(e));if(n.length>0)throw new R(`Thread has ${n.length} pending interrupt(s) not addressed by resume: ${n.join(`, `)}`);for(let t of this.pendingInterrupts)if(Yk(t)&&(e.resume??[]).find(e=>e.interruptId===t.id)?.status!==`cancelled`)throw new R(`Interrupt ${t.id} expired at ${t.expiresAt} and can no longer be answered. Cancel it to continue the thread.`)}let n=await AO(t,this.messages,this.state,(t,n,r)=>t.onRunInitialized?.({messages:n,state:r,agent:this,input:e}));if(n.messages!==void 0||n.state!==void 0){if(n.messages){this.messages=n.messages;for(let e of n.messages)e.subagentRunId===null&&delete e.subagentRunId;e.messages=n.messages.filter(e=>e.role!==`activity`),t.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})}n.state!==void 0&&(this.state=n.state,e.state=n.state,t.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))}}onError(e,t,n){return hd(AO(n,this.messages,this.state,(n,r,i)=>n.onRunFailed?.({error:t,messages:r,state:i,agent:this,input:e}))).pipe(yd(r=>{let i=r;if((i.messages!==void 0||i.state!==void 0)&&(i.messages!==void 0&&(this.messages=i.messages,n.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),i.state!==void 0&&(this.state=i.state,n.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})}))),i.stopPropagation!==!0){let e=String(t);if(t.name!==`AbortError`&&t.message!==`Fetch is aborted`&&t.message!==`signal is aborted without reason`&&t.message!==`component unmounted`&&e!==`component unmounted`)throw console.error(`Agent execution failed:`,t),t}return{}}))}async onFinalize(e,t){let n=await AO(t,this.messages,this.state,(t,n,r)=>t.onRunFinalized?.({messages:n,state:r,agent:this,input:e}));(n.messages!==void 0||n.state!==void 0)&&(n.messages!==void 0&&(this.messages=n.messages,t.forEach(t=>{t.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this,input:e})})),n.state!==void 0&&(this.state=n.state,t.forEach(t=>{t.onStateChanged?.({state:this.state,messages:this.messages,agent:this,input:e})})))}clone(){let e=Object.create(Object.getPrototypeOf(this));return e.agentId=this.agentId,e.description=this.description,e.threadId=this.threadId,e.messages=wO(this.messages),e.state=wO(this.state),e._debug=this._debug,e._debugLogger=this._debugLogger,e.isRunning=this.isRunning,e.subscribers=[...this.subscribers],e.middlewares=[...this.middlewares],e.pendingInterrupts=wO(this.pendingInterrupts),e}addMessage(e){this.messages.push(e),(async()=>{for(let t of this.subscribers)await t.onNewMessage?.({message:e,messages:this.messages,state:this.state,agent:this});if(e.role===`assistant`&&e.toolCalls)for(let t of e.toolCalls)for(let e of this.subscribers)await e.onNewToolCall?.({toolCall:t,messages:this.messages,state:this.state,agent:this});for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}addMessages(e){this.messages.push(...e),(async()=>{for(let t of e){for(let e of this.subscribers)await e.onNewMessage?.({message:t,messages:this.messages,state:this.state,agent:this});if(t.role===`assistant`&&t.toolCalls)for(let e of t.toolCalls)for(let t of this.subscribers)await t.onNewToolCall?.({toolCall:e,messages:this.messages,state:this.state,agent:this})}for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}setMessages(e){this.messages=wO(e),(async()=>{for(let e of this.subscribers)await e.onMessagesChanged?.({messages:this.messages,state:this.state,agent:this})})()}setState(e){this.state=wO(e),(async()=>{for(let e of this.subscribers)await e.onStateChanged?.({messages:this.messages,state:this.state,agent:this})})()}legacy_to_be_removed_runAgentBridged(e){this.agentId=this.agentId??Gc();let t=this.prepareRunAgentInput(e);return[...this.middlewares,new qk].reduceRight((e,t)=>({run:n=>t.run(n,e),get messages(){return e.messages},get state(){return e.state}}),this).run(t).pipe(Tk(this.debugLogger),fk(this.debugLogger),zO(this.debugLogger),QO(this.threadId,t.runId,this.agentId),e=>e.pipe(yd(e=>(this.debugLogger?.event(`LEGACY`,`Event:`,e,{type:e.type}),e))))}};function yA(e){if(!Array.isArray(e.messages))return e;let t=!1,n=e.messages.map(e=>{if(e.subagentRunId===null){t=!0;let n={...e};return delete n.subagentRunId,n}return e});return t?{...e,messages:n}:e}var bA=class extends vA{requestInit(e){return{method:`POST`,headers:{...this.headers,"Content-Type":`application/json`,Accept:`text/event-stream`},body:JSON.stringify(yA(e)),signal:this.abortController.signal}}runAgent(e,t){return this.abortController=e?.abortController??new AbortController,super.runAgent(e,t)}abortRun(){this.abortController.abort(),super.abortRun()}constructor(e){super(e),this.abortController=new AbortController,this.url=e.url,this.headers=wO(e.headers??{}),this.fetch=e.fetch??((e,t)=>fetch(e,t))}run(e){return qO(VO(()=>this.fetch(this.url,this.requestInit(Ek(e)))),this.debugLogger)}clone(){let e=super.clone();e.url=this.url,e.headers=wO(this.headers??{}),e.fetch=this.fetch;let t=new AbortController,n=this.abortController.signal;return n.aborted&&t.abort(n.reason),e.abortController=t,e}},xA=M.createContext(void 0),SA=e=>{let t=M.useContext(xA);if(e)return e;if(!t)throw Error(`No QueryClient set, use QueryClientProvider to set one`);return t},CA=({client:e,children:t})=>(M.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),(0,N.jsx)(xA.Provider,{value:e,children:t})),wA={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},TA=new class{#e=wA;setTimeoutProvider(e){this.#e=e}setTimeout(e,t){return this.#e.setTimeout(e,t)}clearTimeout(e){this.#e.clearTimeout(e)}setInterval(e,t){return this.#e.setInterval(e,t)}clearInterval(e){this.#e.clearInterval(e)}};function EA(e){setTimeout(e,0)}var DA=typeof window>`u`||`Deno`in globalThis;function OA(){}function kA(e,t){return typeof e==`function`?e(t):e}function AA(e){return typeof e==`number`&&e>=0&&e!==1/0}function jA(e,t){return Math.max(e+(t||0)-Date.now(),0)}function MA(e,t){return typeof e==`function`?e(t):e}function NA(e,t){let{type:n=`all`,exact:r,fetchStatus:i,predicate:a,queryKey:o,stale:s}=e;if(o){if(r){if(t.queryHash!==FA(o,t.options))return!1}else if(!LA(t.queryKey,o))return!1}if(n!==`all`){let e=t.isActive();if(n===`active`&&!e||n===`inactive`&&e)return!1}return!(typeof s==`boolean`&&t.isStale()!==s||i&&i!==t.state.fetchStatus||a&&!a(t))}function PA(e,t){let{exact:n,status:r,predicate:i,mutationKey:a}=e;if(a){if(!t.options.mutationKey)return!1;if(n){if(IA(t.options.mutationKey)!==IA(a))return!1}else if(!LA(t.options.mutationKey,a))return!1}return!(r&&t.state.status!==r||i&&!i(t))}function FA(e,t){return(t?.queryKeyHashFn||IA)(e)}function IA(e){return JSON.stringify(e,(e,t)=>HA(t)?Object.keys(t).sort().reduce((e,n)=>(e[n]=t[n],e),{}):t)}function LA(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(Array.isArray(e)&&Array.isArray(t)){if(t.length>e.length)return!1;for(let n=0;n500)return t;let r=VA(e)&&VA(t);if(!r&&!(HA(e)&&HA(t)))return t;let i=(r?e:Object.keys(e)).length,a=r?t:Object.keys(t),o=a.length,s=r?Array(o):{},c=0;for(let l=0;l{TA.setTimeout(t,e)})}function GA(e,t,n){return typeof n.structuralSharing==`function`?n.structuralSharing(e,t):n.structuralSharing===!1?t:zA(e,t)}function KA(e,t,n=0){let r=[...e,t];return n&&r.length>n?r.slice(1):r}function qA(e,t,n=0){let r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var JA=Symbol();function YA(e,t){return!e.queryFn&&t?.initialPromise?()=>t.initialPromise:!e.queryFn||e.queryFn===JA?()=>Promise.reject(Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}function XA(e,t){return typeof e==`function`?e(...t):!!e}function ZA(e,t,n){let r=!1,i;return Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(i??=t(),r?i:(r=!0,i.aborted?n():i.addEventListener(`abort`,n,{once:!0}),i))}),e}var QA=()=>DA,$A=()=>QA(),ej=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},tj=new class extends ej{#e;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e();return window.addEventListener(`visibilitychange`,t,!1),()=>{window.removeEventListener(`visibilitychange`,t)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(e=>{typeof e==`boolean`?this.setFocused(e):this.onFocus()})}setFocused(e){this.#e!==e&&(this.#e=e,this.onFocus())}onFocus(){let e=this.isFocused();this.listeners.forEach(t=>{t(e)})}isFocused(){return typeof this.#e==`boolean`?this.#e:globalThis.document?.visibilityState!==`hidden`}},nj=EA;function rj(){let e=[],t=0,n=e=>{e()},r=e=>{e()},i=nj,a=r=>{t?e.push(r):i(()=>{n(r)})},o=()=>{let t=e;e=[],t.length&&i(()=>{r(()=>{t.forEach(e=>{n(e)})})})};return{batch:e=>{let n;t++;try{n=e()}finally{t--,t||o()}return n},batchCalls:e=>(...t)=>{a(()=>{e(...t)})},schedule:a,setNotifyFunction:e=>{n=e},setBatchNotifyFunction:e=>{r=e},setScheduler:e=>{i=e}}}var ij=rj(),aj=new class extends ej{#e=!0;#t;#n;constructor(){super(),this.#n=e=>{if(typeof window<`u`&&window.addEventListener){let t=()=>e(!0),n=()=>e(!1);return window.addEventListener(`online`,t,!1),window.addEventListener(`offline`,n,!1),()=>{window.removeEventListener(`online`,t),window.removeEventListener(`offline`,n)}}}}onSubscribe(){this.#t||this.setEventListener(this.#n)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#n=e,this.#t?.(),this.#t=e(this.setOnline.bind(this))}setOnline(e){this.#e!==e&&(this.#e=e,this.listeners.forEach(t=>{t(e)}))}isOnline(){return this.#e}};function oj(e){return Math.min(1e3*2**e,3e4)}function sj(e){return(e??`online`)!==`online`||aj.isOnline()}var cj=class extends Error{constructor(e){super(`CancelledError`),this.revert=e?.revert,this.silent=e?.silent}};function lj(e){let t=!1,n=0,r,i=`pending`,a,o,s=new Promise((e,t)=>{a=e,o=t});s.catch(OA);let c=()=>i!==`pending`,l=t=>{if(!c()){let n=new cj(t);h(n),e.onCancel?.(n)}},u=()=>{t=!0},d=()=>{t=!1},f=()=>tj.isFocused()&&(e.networkMode===`always`||aj.isOnline())&&e.canRun(),p=()=>sj(e.networkMode)&&e.canRun(),m=e=>{c()||(r?.(),i=`resolved`,a(e))},h=e=>{c()||(r?.(),i=`rejected`,o(e))},g=t=>new Promise(n=>{r=e=>{(c()||t())&&n(e)},e.onPause?.()}).then(()=>{r=void 0,c()||e.onContinue?.()}),_=()=>{if(c())return;let r,i=n===0?e.initialPromise:void 0;try{r=i??e.fn()}catch(e){r=Promise.reject(e)}Promise.resolve(r).then(m).catch(r=>{if(c())return;let i=e.retry??($A()?0:3),a=e.retryDelay??oj,o=typeof a==`function`?a(n,r):a,s=i===!0||typeof i==`number`&&nf()?void 0:g(f)).then(()=>{t?h(r):_()})})};return{promise:s,status:()=>i,cancel:l,continue:()=>(r?.(),s),cancelRetry:u,continueRetry:d,canStart:p,start:()=>(p()?_():g(p).then(_),s)}}var uj=class{#e;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),AA(this.gcTime)&&(this.#e=TA.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??($A()?1/0:3e5))}clearGcTimeout(){this.#e!==void 0&&(TA.clearTimeout(this.#e),this.#e=void 0)}};function dj(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,l=async()=>{let n=!1,l=e=>{ZA(e,()=>t.signal,()=>n=!0)},u=YA(t.options,t.fetchOptions),d=async(e,r,i)=>{if(n)return Promise.reject(t.signal.reason);if(r==null&&e.pages.length)return Promise.resolve(e);let a=(()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return l(e),e})(),o=await u(a),{maxPages:s}=t.options,c=i?qA:KA;return{pages:c(e.pages,o,s),pageParams:c(e.pageParams,r,s)}};if(i&&a.length){let e=i===`backward`,t=e?pj:fj,n={pages:a,pageParams:o};s=await d(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:fj(r,s);if(c>0&&e==null)break;s=await d(s,e),c++}while(ct.options.persister?.(l,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):l}}}function fj(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function pj(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}function mj(e,t){return t?fj(e,t)!=null:!1}function hj(e,t){return!t||!e.getPreviousPageParam?!1:pj(e,t)!=null}var gj=class extends uj{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e){super(),this.#s=!1,this.#o=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#i=e.client,this.#r=this.#i.getQueryCache(),this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#t=yj(this.options),this.state=e.state??this.#t,this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return this.#e}get promise(){return this.#a?.promise}setOptions(e){if(this.options={...this.#o,...e},e?._type&&(this.#e=e._type),this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){let e=yj(this.options);e.data!==void 0&&(this.setState(vj(e.data,e.dataUpdatedAt)),this.#t=e)}}optionalRemove(){!this.observers.length&&this.state.fetchStatus===`idle`&&this.#r.remove(this)}setData(e,t){let n=GA(this.state.data,e,this.options);return this.#c({data:n,type:`success`,dataUpdatedAt:t?.updatedAt,manual:t?.manual}),n}setState(e){this.#c({type:`setState`,state:e})}cancel(e){let t=this.#a?.promise;return this.#a?.cancel(e),t?t.then(OA).catch(OA):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return this.#t}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(e=>MA(e.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===JA||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0&&this.observers.some(e=>MA(e.options.staleTime,this)===`static`)}isStale(){return this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(e=0){return this.state.data===void 0?!0:e===`static`?!1:this.state.isInvalidated?!0:!jA(this.state.dataUpdatedAt,e)}onFocus(){this.observers.find(e=>e.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#a?.continue()}onOnline(){this.observers.find(e=>e.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#a?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#r.notify({type:`observerAdded`,query:this,observer:e}))}removeObserver(e){let t=this.observers.indexOf(e);t!==-1&&(this.observers.splice(t,1),this.observers.length||(this.#a&&(this.#s||this.state.fetchStatus===`paused`&&this.state.status===`pending`?this.#a.cancel({revert:!0}):this.#a.cancelRetry()),this.scheduleGc()),this.#r.notify({type:`observerRemoved`,query:this,observer:e}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||this.#c({type:`invalidate`})}async fetch(e,t){if(this.state.fetchStatus!==`idle`&&this.#a?.status()!==`rejected`){if(this.state.data!==void 0&&t?.cancelRefetch)this.cancel({silent:!0});else if(this.#a)return this.#a.continueRetry(),this.#a.promise}if(e&&this.setOptions(e),!this.options.queryFn){let e=this.observers.find(e=>e.options.queryFn);e&&this.setOptions(e.options)}let n=new AbortController,r=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(this.#s=!0,n.signal)})},i=()=>{let e=YA(this.options,t),n=(()=>{let e={client:this.#i,queryKey:this.queryKey,meta:this.meta};return r(e),e})();return this.#s=!1,this.options.persister?this.options.persister(e,n,this):e(n)},a=(()=>{let e={fetchOptions:t,options:this.options,queryKey:this.queryKey,client:this.#i,state:this.state,fetchFn:i};return r(e),e})();(this.#e===`infinite`?dj(this.options.pages):this.options.behavior)?.onFetch(a,this),this.#n=this.state,(this.state.fetchStatus===`idle`||this.state.fetchMeta!==a.fetchOptions?.meta)&&this.#c({type:`fetch`,meta:a.fetchOptions?.meta});let o=this.#a=lj({initialPromise:t?.initialPromise,fn:a.fetchFn,onCancel:e=>{e instanceof cj&&e.revert&&this.setState({...this.#n,fetchStatus:`idle`}),n.abort()},onFail:(e,t)=>{this.#c({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#c({type:`pause`})},onContinue:()=>{this.#c({type:`continue`})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0});try{let e=await o.start();if(e===void 0)throw Error(`${this.queryHash} data is undefined`);return this.setData(e),this.#r.config.onSuccess?.(e,this),this.#r.config.onSettled?.(e,this.state.error,this),e}catch(e){if(e instanceof cj){if(e.silent)return this.#a.promise;if(e.revert){if(this.state.data===void 0)throw e;return this.state.data}}throw this.#c({type:`error`,error:e}),this.#r.config.onError?.(e,this),this.#r.config.onSettled?.(this.state.data,e,this),e}finally{this.#a===o&&(this.#a=void 0),this.scheduleGc()}}#c(e){let t=t=>{switch(e.type){case`failed`:return{...t,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case`pause`:return{...t,fetchStatus:`paused`};case`continue`:return{...t,fetchStatus:`fetching`};case`fetch`:return{...t,..._j(t.data,this.options),fetchMeta:e.meta??null};case`success`:let n={...t,...vj(e.data,e.dataUpdatedAt),dataUpdateCount:t.dataUpdateCount+1,...!e.manual&&{fetchStatus:`idle`,fetchFailureCount:0,fetchFailureReason:null}};return this.#n=e.manual?n:void 0,n;case`error`:let r=e.error;return{...t,error:r,errorUpdateCount:t.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:t.fetchFailureCount+1,fetchFailureReason:r,fetchStatus:`idle`,status:`error`,isInvalidated:!0};case`invalidate`:return{...t,isInvalidated:!0};case`setState`:return{...t,...e.state}}};this.state=t(this.state),ij.batch(()=>{this.observers.slice().forEach(e=>{e.onQueryUpdate()}),this.#r.notify({query:this,type:`updated`,action:e})})}};function _j(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:sj(t.networkMode)?`fetching`:`paused`,...e===void 0&&{error:null,status:`pending`}}}function vj(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:`success`}}function yj(e){let t=typeof e.initialData==`function`?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt==`function`?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?`success`:`pending`,fetchStatus:`idle`}}var bj=class extends ej{#e;#t=void 0;#n=void 0;#r=void 0;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p=new Set;constructor(e,t){super(),this.options=t,this.#e=e,this.#o=null,this.bindMethods(),this.setOptions(t)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.#t.addObserver(this),Sj(this.#t,this.options)?this.#m():this.updateResult(),this.#y())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return Cj(this.#t,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return Cj(this.#t,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#b(),this.#x(),this.#t.removeObserver(this)}setOptions(e){let t=this.options,n=this.#t;if(this.options=this.#e.defaultQueryOptions(e),this.options.enabled!==void 0&&typeof this.options.enabled!=`boolean`&&typeof this.options.enabled!=`function`&&typeof MA(this.options.enabled,this.#t)!=`boolean`)throw Error(`Expected enabled to be a boolean or a callback that returns a boolean`);this.#S(),this.#t.setOptions(this.options),t._defaulted&&!BA(this.options,t)&&this.#e.getQueryCache().notify({type:`observerOptionsUpdated`,query:this.#t,observer:this});let r=this.hasListeners();r&&wj(this.#t,n,this.options,t)&&this.#m(),this.updateResult(),r&&(this.#t!==n||MA(this.options.enabled,this.#t)!==MA(t.enabled,this.#t)||MA(this.options.staleTime,this.#t)!==MA(t.staleTime,this.#t))&&this.#g();let i=this.#_();r&&(this.#t!==n||MA(this.options.enabled,this.#t)!==MA(t.enabled,this.#t)||i!==this.#f)&&this.#v(i)}getOptimisticResult(e){let t=this.#e.getQueryCache().build(this.#e,e),n=this.createResult(t,e);return BA(this.getCurrentResult(),n)||(this.#r=n,this.#a=this.options,this.#i=this.#t.state),n}getCurrentResult(){return this.#r}trackResult(e,t){return new Proxy(e,{get:(e,n)=>(this.trackProp(n),t?.(n),Reflect.get(e,n))})}trackProp(e){this.#p.add(e)}getCurrentQuery(){return this.#t}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),n=this.#e.getQueryCache().build(this.#e,t),r=()=>{},i,a=new Promise(e=>{i=e,r=this.#e.getQueryCache().subscribe(i=>{i.type===`updated`&&i.query.queryHash===n.queryHash&&n.state.data!==void 0&&(r(),e(this.createResult(n,t)))})});return Promise.race([n.fetch().then(()=>{let e=this.createResult(n,t);return i?.(e),e}).finally(()=>{r()}),a])}fetch(e){return this.#m({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#r))}#m(e){this.#S();let t=this.#t.fetch(this.options,e);return e?.throwOnError||(t=t.catch(OA)),t}#h(e){return!$A()&&MA(this.options.enabled,this.#t)!==!1&&AA(e)}#g(){this.#b();let e=MA(this.options.staleTime,this.#t);if(this.#r.isStale||!this.#h(e))return;let t=jA(this.#r.dataUpdatedAt,e)+1;this.#u=TA.setTimeout(()=>{this.#r.isStale||this.updateResult()},t)}#_(){return MA(this.options.refetchInterval,this.#t)??!1}#v(e){this.#x(),this.#f=e,this.#f!==0&&this.#h(this.#f)&&(this.#d=TA.setInterval(()=>{(this.options.refetchIntervalInBackground||tj.isFocused())&&this.#m()},this.#f))}#y(){this.#g(),this.#v(this.#_())}#b(){this.#u!==void 0&&(TA.clearTimeout(this.#u),this.#u=void 0)}#x(){this.#d!==void 0&&(TA.clearInterval(this.#d),this.#d=void 0)}createResult(e,t){let n=this.#t,r=this.options,i=this.#r,a=this.#i,o=this.#a,s=e===n?this.#n:e.state,{state:c}=e,l={...c},u=!1,d;if(t._optimisticResults){let i=this.hasListeners(),a=!i&&Sj(e,t),o=i&&wj(e,n,t,r);(a||o)&&(l={...l,..._j(c.data,e.options)}),t._optimisticResults===`isRestoring`&&(l.fetchStatus=`idle`)}let{error:f,errorUpdatedAt:p,status:m}=l;d=l.data;let h=!1;if(t.placeholderData!==void 0&&d===void 0&&m===`pending`){let e;i?.isPlaceholderData&&t.placeholderData===o?.placeholderData?(e=i.data,h=!0):e=typeof t.placeholderData==`function`?t.placeholderData(this.#l?.state.data,this.#l):t.placeholderData,e!==void 0&&(m=`success`,d=GA(i?.data,e,t),u=!0)}if(t.select&&d!==void 0&&!h){if(i&&d===a?.data&&t.select===this.#s)d=this.#c;else try{this.#s=t.select,d=t.select(d),d=GA(i?.data,d,t),this.#c=d,this.#o=null}catch(e){this.#o=e}}else d===void 0&&(this.#o=null);this.#o&&(f=this.#o,d=this.#c,p=Date.now(),m=`error`,u=!1);let g=l.fetchStatus===`fetching`,_=m===`pending`,v=m===`error`,y=_&&g,b=d!==void 0;return{status:m,fetchStatus:l.fetchStatus,isPending:_,isSuccess:m===`success`,isError:v,isInitialLoading:y,isLoading:y,data:d,dataUpdatedAt:l.dataUpdatedAt,error:f,errorUpdatedAt:p,failureCount:l.fetchFailureCount,failureReason:l.fetchFailureReason,errorUpdateCount:l.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:l.dataUpdateCount>s.dataUpdateCount||l.errorUpdateCount>s.errorUpdateCount,isFetching:g,isRefetching:g&&!_,isLoadingError:v&&!b,isPaused:l.fetchStatus===`paused`,isPlaceholderData:u,isRefetchError:v&&b,isStale:Tj(e,t),refetch:this.refetch,isEnabled:MA(t.enabled,e)!==!1}}updateResult(){let e=this.#r,t=this.createResult(this.#t,this.options);if(this.#i=this.#t.state,this.#a=this.options,this.#i.data!==void 0&&(this.#l=this.#t),BA(t,e))return;this.#r=t;let n=(()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,n=typeof t==`function`?t():t;if(n===`all`||!n&&!this.#p.size)return!0;let r=new Set(n??this.#p);return this.options.throwOnError&&r.add(`error`),Object.keys(this.#r).some(t=>{let n=t;return this.#r[n]!==e[n]&&r.has(n)})})();ij.batch(()=>{n&&this.listeners.forEach(e=>{e(this.#r)}),this.#e.getQueryCache().notify({query:this.#t,type:`observerResultsUpdated`})})}#S(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#t)return;let t=this.#t;this.#t=e,this.#n=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()}};function xj(e,t){return MA(t.enabled,e)!==!1&&e.state.data===void 0&&(e.state.status!==`error`||MA(t.retryOnMount,e)!==!1)}function Sj(e,t){return xj(e,t)||e.state.data!==void 0&&Cj(e,t,t.refetchOnMount)}function Cj(e,t,n){if(MA(t.enabled,e)!==!1&&MA(t.staleTime,e)!==`static`){let r=MA(n,e);return r===`always`||r!==!1&&Tj(e,t)}return!1}function wj(e,t,n,r){return(e!==t||MA(r.enabled,e)===!1)&&(!n.suspense||e.state.status!==`error`)&&Tj(e,n)}function Tj(e,t){return MA(t.enabled,e)!==!1&&e.isStaleByTime(MA(t.staleTime,e))}var Ej=class extends bj{constructor(e,t){super(e,t)}bindMethods(){super.bindMethods(),this.fetchNextPage=this.fetchNextPage.bind(this),this.fetchPreviousPage=this.fetchPreviousPage.bind(this)}setOptions(e){e._type=`infinite`,super.setOptions(e)}getOptimisticResult(e){return e._type=`infinite`,super.getOptimisticResult(e)}fetchNextPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`forward`}}})}fetchPreviousPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`backward`}}})}createResult(e,t){let{state:n}=e,r=super.createResult(e,t),{isFetching:i,isRefetching:a,isError:o,isRefetchError:s}=r,c=n.fetchMeta?.fetchMore?.direction,l=o&&c===`forward`,u=i&&c===`forward`,d=o&&c===`backward`,f=i&&c===`backward`;return{...r,fetchNextPage:this.fetchNextPage,fetchPreviousPage:this.fetchPreviousPage,hasNextPage:mj(t,n.data),hasPreviousPage:hj(t,n.data),isFetchNextPageError:l,isFetchingNextPage:u,isFetchPreviousPageError:d,isFetchingPreviousPage:f,isRefetchError:s&&!l&&!d,isRefetching:a&&!u&&!f}}},Dj=class extends uj{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||Oj(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:`observerAdded`,mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:`observerRemoved`,mutation:this,observer:e})}optionalRemove(){this.#t.length||(this.state.status===`pending`?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??(this.state.status===`pending`?this.execute(this.state.variables):Promise.resolve())}async execute(e){let t=()=>{this.#i({type:`continue`})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey},r=this.#r=lj({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error(`No mutationFn found`)),onFail:(e,t)=>{this.#i({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#i({type:`pause`})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)}),i=this.state.status===`pending`,a=!r.canStart();try{if(i)t();else{this.#i({type:`pending`,variables:e,isPaused:a}),this.#n.config.onMutate&&await this.#n.config.onMutate(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#i({type:`pending`,context:t,variables:e,isPaused:a})}let o=await r.start();return await this.#n.config.onSuccess?.(o,e,this.state.context,this,n),await this.options.onSuccess?.(o,e,this.state.context,n),await this.#n.config.onSettled?.(o,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(o,null,e,this.state.context,n),this.#i({type:`success`,data:o}),o}catch(t){try{await this.#n.config.onError?.(t,e,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,n)}catch(e){Promise.reject(e)}try{await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,n)}catch(e){Promise.reject(e)}throw this.#i({type:`error`,error:t}),t}finally{this.#r===r&&(this.#r=void 0),this.#n.runNext(this)}}#i(e){let t=t=>{switch(e.type){case`failed`:return{...t,failureCount:e.failureCount,failureReason:e.error};case`pause`:return{...t,isPaused:!0};case`continue`:return{...t,isPaused:!1};case`pending`:return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:`pending`,variables:e.variables,submittedAt:Date.now()};case`success`:return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:`success`,isPaused:!1};case`error`:return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:`error`}}};this.state=t(this.state),ij.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:`updated`,action:e})})}};function Oj(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:`idle`,variables:void 0,submittedAt:0}}var kj=class extends ej{#e;#t;#n;constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}build(e,t,n){let r=new Dj({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t);if(n){if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=Aj(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}return!0}runNext(e){let t=Aj(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){ij.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>PA(t,e))}findAll(e={}){return this.getAll().filter(t=>PA(e,t))}notify(e){ij.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return ij.batch(()=>Promise.all(e.map(e=>e.continue().catch(OA))))}};function Aj(e){return e.options.scope?.id}var jj=class extends ej{#e;constructor(e={}){super(),this.config=e,this.#e=new Map}build(e,t,n){let r=t.queryKey,i=t.queryHash??FA(r,t),a=this.get(i);return a||(a=new gj({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){this.#e.get(e.queryHash)===e&&(e.destroy(),this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){ij.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>NA(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>NA(e,t)):t}notify(e){ij.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){ij.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){ij.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},Mj=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new jj,this.#t=e.mutationCache||new kj,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=tj.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=aj.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(MA(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=kA(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return ij.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;ij.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return ij.batch(()=>{let r=n.findAll(e),i=new Set(r);return r.forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,predicate:e=>i.has(e)},t)})}cancelQueries(e,t={}){let n={revert:!0,...t},r=ij.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(OA).catch(OA)}invalidateQueries(e,t={}){return ij.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=ij.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(OA)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(OA)}async query(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t),r=n.isStaleByTime(MA(t.staleTime,n))?await n.fetch(t):n.state.data,i=t.select;return i?i(r):r}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(MA(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(OA).catch(OA)}infiniteQuery(e){return e._type=`infinite`,this.query(e)}fetchInfiniteQuery(e){return e._type=`infinite`,this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(OA).catch(OA)}ensureInfiniteQueryData(e){return e._type=`infinite`,this.ensureQueryData(e)}resumePausedMutations(){return aj.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(IA(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{LA(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(IA(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{LA(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=FA(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===JA&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},Nj=M.createContext(!1),Pj=()=>M.useContext(Nj);Nj.Provider;function Fj(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var Ij=M.createContext(Fj()),Lj=()=>M.useContext(Ij),Rj=(e,t,n)=>{let r=n?.state.error&&typeof e.throwOnError==`function`?XA(e.throwOnError,[n.state.error,n]):e.throwOnError;(e.suspense||r)&&(t.isReset()||(e.retryOnMount=!1))},zj=e=>{M.useEffect(()=>{e.clearReset()},[e])},Bj=({result:e,errorResetBoundary:t,throwOnError:n,query:r,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&(i&&e.data===void 0||XA(n,[e.error,r])),Vj=e=>{if(e.suspense){let t=1e3,n=e=>e===`static`?e:Math.max(e??t,t),r=e.staleTime;e.staleTime=typeof r==`function`?(...e)=>n(r(...e)):n(r),typeof e.gcTime==`number`&&(e.gcTime=Math.max(e.gcTime,t))}},Hj=(e,t)=>e?.suspense&&t.isPending,Uj=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function Wj(e,t,n){let r=Pj(),i=Lj(),a=SA(n),o=a.defaultQueryOptions(e),s=a.getQueryCache().get(o.queryHash),c=e.subscribed!==!1;o._optimisticResults=r?`isRestoring`:c?`optimistic`:void 0,Vj(o),Rj(o,i,s),zj(i);let[l]=M.useState(()=>new t(a,o)),u=l.getOptimisticResult(o),d=!r&&c;if(M.useSyncExternalStore(M.useCallback(e=>{let t=d?l.subscribe(ij.batchCalls(e)):OA;return l.updateResult(),t},[l,d]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),M.useEffect(()=>{l.setOptions(o)},[o,l]),Hj(o,u))throw Uj(o,l,i);if(Bj({result:u,errorResetBoundary:i,throwOnError:o.throwOnError,query:s,suspense:o.suspense}))throw u.error;return o.notifyOnChangeProps?u:l.trackResult(u)}function Gj(e,t){return Wj(e,bj,t)}function Kj(e,t){return Wj(e,Ej,t)}var qj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H69l51.52,51.51a12,12,0,0,1-17,17l-72-72a12,12,0,0,1,0-17l72-72a12,12,0,0,1,17,17L69,116H216A12,12,0,0,1,228,128Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M112,56V200L40,128Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M216,120H120V56a8,8,0,0,0-13.66-5.66l-72,72a8,8,0,0,0,0,11.32l72,72A8,8,0,0,0,120,200V136h96a8,8,0,0,0,0-16ZM104,180.69,51.31,128,104,75.31Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H120v64a8,8,0,0,1-13.66,5.66l-72-72a8,8,0,0,1,0-11.32l72-72A8,8,0,0,1,120,56v64h96A8,8,0,0,1,224,128Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H54.49l61.75,61.76a6,6,0,1,1-8.48,8.48l-72-72a6,6,0,0,1,0-8.48l72-72a6,6,0,0,1,8.48,8.48L54.49,122H216A6,6,0,0,1,222,128Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H49.66l65.17,65.17a4,4,0,0,1-5.66,5.66l-72-72a4,4,0,0,1,0-5.66l72-72a4,4,0,0,1,5.66,5.66L49.66,124H216A4,4,0,0,1,220,128Z`}))]]),Jj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,128l-72,72V56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,133.66l-72,72A8,8,0,0,1,136,200V136H40a8,8,0,0,1,0-16h96V56a8,8,0,0,1,13.66-5.66l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220.24,132.24l-72,72a6,6,0,0,1-8.48-8.48L201.51,134H40a6,6,0,0,1,0-12H201.51L139.76,60.24a6,6,0,0,1,8.48-8.48l72,72A6,6,0,0,1,220.24,132.24Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M218.83,130.83l-72,72a4,4,0,0,1-5.66-5.66L206.34,132H40a4,4,0,0,1,0-8H206.34L141.17,58.83a4,4,0,0,1,5.66-5.66l72,72A4,4,0,0,1,218.83,130.83Z`}))]]),Yj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,44H160a43.86,43.86,0,0,0-32,13.85A43.86,43.86,0,0,0,96,44H24A12,12,0,0,0,12,56V200a12,12,0,0,0,12,12H96a20,20,0,0,1,20,20,12,12,0,0,0,24,0,20,20,0,0,1,20-20h72a12,12,0,0,0,12-12V56A12,12,0,0,0,232,44ZM96,188H36V68H96a20,20,0,0,1,20,20V192.81A43.79,43.79,0,0,0,96,188Zm124,0H160a43.71,43.71,0,0,0-20,4.83V88a20,20,0,0,1,20-20h60Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,56V200H160a32,32,0,0,0-32,32,32,32,0,0,0-32-32H24V56H96a32,32,0,0,1,32,32,32,32,0,0,1,32-32Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240,56V200a8,8,0,0,1-8,8H160a24,24,0,0,0-24,23.94,7.9,7.9,0,0,1-5.12,7.55A8,8,0,0,1,120,232a24,24,0,0,0-24-24H24a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8H88a32,32,0,0,1,32,32v87.73a8.17,8.17,0,0,0,7.47,8.25,8,8,0,0,0,8.53-8V80a32,32,0,0,1,32-32h64A8,8,0,0,1,240,56Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,50H160a38,38,0,0,0-32,17.55A38,38,0,0,0,96,50H24a6,6,0,0,0-6,6V200a6,6,0,0,0,6,6H96a26,26,0,0,1,26,26,6,6,0,0,0,12,0,26,26,0,0,1,26-26h72a6,6,0,0,0,6-6V56A6,6,0,0,0,232,50ZM96,194H30V62H96a26,26,0,0,1,26,26V204.31A37.86,37.86,0,0,0,96,194Zm130,0H160a37.87,37.87,0,0,0-26,10.32V88a26,26,0,0,1,26-26h66Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232,52H160a36,36,0,0,0-32,19.54A36,36,0,0,0,96,52H24a4,4,0,0,0-4,4V200a4,4,0,0,0,4,4H96a28,28,0,0,1,28,28,4,4,0,0,0,8,0,28,28,0,0,1,28-28h72a4,4,0,0,0,4-4V56A4,4,0,0,0,232,52ZM96,196H28V60H96a28,28,0,0,1,28,28V209.4A35.93,35.93,0,0,0,96,196Zm132,0H160a35.94,35.94,0,0,0-28,13.41V88a28,28,0,0,1,28-28h68Z`}))]]),Xj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M144,128a16,16,0,1,1-16-16A16,16,0,0,1,144,128ZM60,112a16,16,0,1,0,16,16A16,16,0,0,0,60,112Zm136,0a16,16,0,1,0,16,16A16,16,0,0,0,196,112Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240,96v64a16,16,0,0,1-16,16H32a16,16,0,0,1-16-16V96A16,16,0,0,1,32,80H224A16,16,0,0,1,240,96Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm56-12a12,12,0,1,0,12,12A12,12,0,0,0,196,116ZM60,116a12,12,0,1,0,12,12A12,12,0,0,0,60,116Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,80H32A16,16,0,0,0,16,96v64a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V96A16,16,0,0,0,224,80ZM60,140a12,12,0,1,1,12-12A12,12,0,0,1,60,140Zm68,0a12,12,0,1,1,12-12A12,12,0,0,1,128,140Zm68,0a12,12,0,1,1,12-12A12,12,0,0,1,196,140Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M138,128a10,10,0,1,1-10-10A10,10,0,0,1,138,128ZM60,118a10,10,0,1,0,10,10A10,10,0,0,0,60,118Zm136,0a10,10,0,1,0,10,10A10,10,0,0,0,196,118Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M140,128a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm56-12a12,12,0,1,0,12,12A12,12,0,0,0,196,116ZM60,116a12,12,0,1,0,12,12A12,12,0,0,0,60,116Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M136,128a8,8,0,1,1-8-8A8,8,0,0,1,136,128Zm-76-8a8,8,0,1,0,8,8A8,8,0,0,0,60,120Zm136,0a8,8,0,1,0,8,8A8,8,0,0,0,196,120Z`}))]]),Zj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232.49,215.51,185,168a92.12,92.12,0,1,0-17,17l47.53,47.54a12,12,0,0,0,17-17ZM44,112a68,68,0,1,1,68,68A68.07,68.07,0,0,1,44,112Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M168,112a56,56,0,1,1-56-56A56,56,0,0,1,168,112Zm61.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88,88,0,1,1,11.32-11.31l50.06,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228.24,219.76l-51.38-51.38a86.15,86.15,0,1,0-8.48,8.48l51.38,51.38a6,6,0,0,0,8.48-8.48ZM38,112a74,74,0,1,1,74,74A74.09,74.09,0,0,1,38,112Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M226.83,221.17l-52.7-52.7a84.1,84.1,0,1,0-5.66,5.66l52.7,52.7a4,4,0,0,0,5.66-5.66ZM36,112a76,76,0,1,1,76,76A76.08,76.08,0,0,1,36,112Z`}))]]),Qj=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M236.37,139.4a12,12,0,0,0-12-3A84.07,84.07,0,0,1,119.6,31.59a12,12,0,0,0-15-15A108.86,108.86,0,0,0,49.69,55.07,108,108,0,0,0,136,228a107.09,107.09,0,0,0,64.93-21.69,108.86,108.86,0,0,0,38.44-54.94A12,12,0,0,0,236.37,139.4Zm-49.88,47.74A84,84,0,0,1,68.86,69.51,84.93,84.93,0,0,1,92.27,48.29Q92,52.13,92,56A108.12,108.12,0,0,0,200,164q3.87,0,7.71-.27A84.79,84.79,0,0,1,186.49,187.14Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.89,147.89A96,96,0,1,1,108.11,28.11,96.09,96.09,0,0,0,227.89,147.89Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M235.54,150.21a104.84,104.84,0,0,1-37,52.91A104,104,0,0,1,32,120,103.09,103.09,0,0,1,52.88,57.48a104.84,104.84,0,0,1,52.91-37,8,8,0,0,1,10,10,88.08,88.08,0,0,0,109.8,109.8,8,8,0,0,1,10,10Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M232.13,143.64a6,6,0,0,0-6-1.49A90.07,90.07,0,0,1,113.86,29.85a6,6,0,0,0-7.49-7.48A102.88,102.88,0,0,0,54.48,58.68,102,102,0,0,0,197.32,201.52a102.88,102.88,0,0,0,36.31-51.89A6,6,0,0,0,232.13,143.64Zm-42,48.29a90,90,0,0,1-126-126A90.9,90.9,0,0,1,99.65,37.66,102.06,102.06,0,0,0,218.34,156.35,90.9,90.9,0,0,1,190.1,191.93Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M230.72,145.06a4,4,0,0,0-4-1A92.08,92.08,0,0,1,111.94,29.27a4,4,0,0,0-5-5A100.78,100.78,0,0,0,56.08,59.88a100,100,0,0,0,140,140,100.78,100.78,0,0,0,35.59-50.87A4,4,0,0,0,230.72,145.06ZM191.3,193.53A92,92,0,0,1,62.47,64.7a93,93,0,0,1,39.88-30.35,100.09,100.09,0,0,0,119.3,119.3A93,93,0,0,1,191.3,193.53Z`}))]]),$j=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M230.14,70.54,185.46,25.85a20,20,0,0,0-28.29,0L33.86,149.17A19.85,19.85,0,0,0,28,163.31V208a20,20,0,0,0,20,20H92.69a19.86,19.86,0,0,0,14.14-5.86L230.14,98.82a20,20,0,0,0,0-28.28ZM91,204H52V165l84-84,39,39ZM192,103,153,64l18.34-18.34,39,39Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M221.66,90.34,192,120,136,64l29.66-29.66a8,8,0,0,1,11.31,0L221.66,79A8,8,0,0,1,221.66,90.34Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M225.9,74.78,181.21,30.09a14,14,0,0,0-19.8,0L38.1,153.41a13.94,13.94,0,0,0-4.1,9.9V208a14,14,0,0,0,14,14H92.69a13.94,13.94,0,0,0,9.9-4.1L225.9,94.58a14,14,0,0,0,0-19.8ZM94.1,209.41a2,2,0,0,1-1.41.59H48a2,2,0,0,1-2-2V163.31a2,2,0,0,1,.59-1.41L136,72.48,183.51,120ZM217.41,86.1,192,111.51,144.49,64,169.9,38.58a2,2,0,0,1,2.83,0l44.68,44.69a2,2,0,0,1,0,2.83Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224.49,76.2,179.8,31.51a12,12,0,0,0-17,0L133.17,61.17h0L39.52,154.83A11.9,11.9,0,0,0,36,163.31V208a12,12,0,0,0,12,12H92.69a12,12,0,0,0,8.48-3.51L224.48,93.17a12,12,0,0,0,0-17Zm-129,134.63A4,4,0,0,1,92.69,212H48a4,4,0,0,1-4-4V163.31a4,4,0,0,1,1.17-2.83L136,69.65,186.34,120ZM218.83,87.51,192,114.34,141.66,64l26.82-26.83a4,4,0,0,1,5.66,0l44.69,44.68a4,4,0,0,1,0,5.66Z`}))]]),eM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M240.49,15.51a12,12,0,0,0-17,0L173.94,65.09l-2.54-2.55a36.05,36.05,0,0,0-50.91,0L100,83l-3.51-3.52a12,12,0,0,0-17,17L83,100,62.54,120.49a36,36,0,0,0,0,50.91l2.55,2.54L15.51,223.51a12,12,0,0,0,17,17l49.57-49.58,2.54,2.55a36.06,36.06,0,0,0,50.91,0L156,173l3.51,3.52a12,12,0,0,0,17-17L173,156l20.49-20.49a36,36,0,0,0,0-50.91l-2.55-2.54,49.58-49.57A12,12,0,0,0,240.49,15.51Zm-121.95,161a12,12,0,0,1-17,0L79.51,154.43a12,12,0,0,1,0-17L100,117l39,39Zm58-57.95h0L156,139l-39-39,20.49-20.49a12,12,0,0,1,17,0l22.06,22.06a12,12,0,0,1,0,17ZM85.27,33.37a12,12,0,0,1,21.46-10.74l8,16A12,12,0,1,1,93.27,49.37Zm-68,57.26a12,12,0,0,1,16.1-5.36l16,8a12,12,0,1,1-10.74,21.46l-16-8A12,12,0,0,1,17.27,90.63Zm221.46,74.74a12,12,0,0,1-16.1,5.36l-16-8a12,12,0,0,1,10.74-21.46l16,8A12,12,0,0,1,238.73,165.37Zm-68,57.26a12,12,0,1,1-21.46,10.74l-8-16a12,12,0,0,1,21.46-10.74Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M185,127,127,185a24,24,0,0,1-33.94,0L71,162.91A24,24,0,0,1,71,129L129,71a24,24,0,0,1,33.94,0L185,93.09A24,24,0,0,1,185,127Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M237.66,18.34a8,8,0,0,0-11.32,0l-52.4,52.41-5.37-5.38a32.05,32.05,0,0,0-45.26,0L100,88.69l-6.34-6.35A8,8,0,0,0,82.34,93.66L88.69,100,65.37,123.31a32,32,0,0,0,0,45.26l5.38,5.37-52.41,52.4a8,8,0,0,0,11.32,11.32l52.4-52.41,5.37,5.38a32.06,32.06,0,0,0,45.26,0L156,167.31l6.34,6.35a8,8,0,0,0,11.32-11.32L167.31,156l23.32-23.31a32,32,0,0,0,0-45.26l-5.38-5.37,52.41-52.4A8,8,0,0,0,237.66,18.34Zm-116.29,161a16,16,0,0,1-22.62,0L76.69,157.25a16,16,0,0,1,0-22.62L100,111.31,144.69,156Zm57.94-57.94h0L156,144.69,111.31,100l23.32-23.31a16,16,0,0,1,22.62,0l22.06,22a16,16,0,0,1,0,22.63ZM88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM24.57,93A8,8,0,0,1,35,88.57l20,8A8,8,0,0,1,49,111.43l-20-8A8,8,0,0,1,24.57,93ZM231.43,163a8,8,0,0,1-10.4,4.46l-20-8A8,8,0,1,1,207,144.57l20,8A8,8,0,0,1,231.43,163Zm-64,58.06A8,8,0,0,1,152.57,227l-8-20A8,8,0,0,1,159.43,201Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM29,103.43l20,8A8,8,0,1,0,55,96.57l-20-8A8,8,0,0,0,29,103.43ZM227,152.57l-20-8A8,8,0,1,0,201,159.43l20,8A8,8,0,0,0,227,152.57ZM159.43,201A8,8,0,0,0,144.57,207l8,20A8,8,0,1,0,167.43,221ZM237.91,18.52a8,8,0,0,0-11.5-.18L174,70.75l-5.38-5.38a32,32,0,0,0-45.28,0L106.14,82.54a4,4,0,0,0,0,5.66l61.7,61.66a4,4,0,0,0,5.66,0l16.74-16.74a32.76,32.76,0,0,0,9.81-22.52,31.82,31.82,0,0,0-9.37-23.17l-5.38-5.37,52.2-52.17A8.22,8.22,0,0,0,237.91,18.52ZM85.64,90.34a8,8,0,0,0-11.49.18,8.22,8.22,0,0,0,.41,11.37L80.67,108,65.34,123.31A31.82,31.82,0,0,0,56,146.47,32.75,32.75,0,0,0,65.77,169l5,4.94L18.49,226.13a8.21,8.21,0,0,0-.61,11.1,8,8,0,0,0,11.72.43L82,185.25l5.37,5.38a32.1,32.1,0,0,0,45.29,0L148,175.31l6.34,6.35a8,8,0,0,0,11.32-11.32Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M236.24,19.76a6,6,0,0,0-8.48,0L173.94,73.57l-6.79-6.78a30,30,0,0,0-42.42,0L100,91.51l-7.76-7.75a6,6,0,0,0-8.48,8.48L91.51,100,66.79,124.73a30,30,0,0,0,0,42.42l6.78,6.79L19.76,227.76a6,6,0,1,0,8.48,8.48l53.82-53.81,6.79,6.78a30,30,0,0,0,42.42,0L156,164.49l7.76,7.75a6,6,0,0,0,8.48-8.48L164.49,156l24.72-24.73a30,30,0,0,0,0-42.42l-6.78-6.79,53.81-53.82A6,6,0,0,0,236.24,19.76Zm-113.45,161a18,18,0,0,1-25.46,0L75.27,158.67a18,18,0,0,1,0-25.46L100,108.49,147.51,156Zm57.94-57.94L156,147.51,108.49,100l24.72-24.73a18,18,0,0,1,25.46,0l22.06,22.06a18,18,0,0,1,0,25.46ZM90.43,34.23a6,6,0,0,1,11.14-4.46l8,20a6,6,0,1,1-11.14,4.46Zm-64,59.54a6,6,0,0,1,7.8-3.34l20,8a6,6,0,1,1-4.46,11.14l-20-8A6,6,0,0,1,26.43,93.77Zm203.14,68.46a6,6,0,0,1-7.8,3.34l-20-8a6,6,0,0,1,4.46-11.14l20,8A6,6,0,0,1,229.57,162.23Zm-64,59.54a6,6,0,1,1-11.14,4.46l-8-20a6,6,0,0,1,11.14-4.46Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M237.66,18.34a8,8,0,0,0-11.32,0l-52.4,52.41-5.37-5.38a32.05,32.05,0,0,0-45.26,0L100,88.69l-6.34-6.35A8,8,0,0,0,82.34,93.66L88.69,100,65.37,123.31a32,32,0,0,0,0,45.26l5.38,5.37-52.41,52.4a8,8,0,0,0,11.32,11.32l52.4-52.41,5.37,5.38a32,32,0,0,0,45.26,0L156,167.31l6.34,6.35a8,8,0,0,0,11.32-11.32L167.31,156l23.32-23.31a32,32,0,0,0,0-45.26l-5.38-5.37,52.41-52.4A8,8,0,0,0,237.66,18.34Zm-116.29,161a16,16,0,0,1-22.62,0L76.69,157.25a16,16,0,0,1,0-22.62L100,111.31,144.69,156Zm57.94-57.94L156,144.69,111.31,100l23.32-23.31a16,16,0,0,1,22.62,0l22.06,22A16,16,0,0,1,179.31,121.37ZM88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM24.57,93A8,8,0,0,1,35,88.57l20,8A8,8,0,0,1,49,111.43l-20-8A8,8,0,0,1,24.57,93ZM231.43,163a8,8,0,0,1-10.4,4.46l-20-8A8,8,0,1,1,207,144.57l20,8A8,8,0,0,1,231.43,163Zm-64,58.06A8,8,0,0,1,152.57,227l-8-20A8,8,0,0,1,159.43,201Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M234.83,21.17a4,4,0,0,0-5.66,0L173.94,76.4l-8.2-8.2a28,28,0,0,0-39.6,0L100,94.34l-9.17-9.17a4,4,0,0,0-5.66,5.66L94.34,100,68.2,126.14a28,28,0,0,0,0,39.6l8.2,8.2L21.17,229.17a4,4,0,0,0,5.66,5.66L82.06,179.6l8.2,8.2a28,28,0,0,0,39.6,0L156,161.66l9.17,9.17a4,4,0,0,0,5.66-5.66L161.66,156l26.14-26.14a28,28,0,0,0,0-39.6l-8.2-8.2,55.23-55.23A4,4,0,0,0,234.83,21.17Zm-110.63,161a20,20,0,0,1-28.28,0L73.86,160.08a20,20,0,0,1,0-28.28L100,105.66,150.34,156Zm57.94-57.94L156,150.34,105.66,100,131.8,73.86a20,20,0,0,1,28.28,0l22.06,22.06A20,20,0,0,1,182.14,124.2ZM92.29,33.49a4,4,0,1,1,7.42-3l8,20a4,4,0,0,1-2.22,5.2A3.91,3.91,0,0,1,104,56a4,4,0,0,1-3.71-2.51Zm-64,61a4,4,0,0,1,5.2-2.22l20,8A4,4,0,0,1,52,108a3.91,3.91,0,0,1-1.49-.29l-20-8A4,4,0,0,1,28.29,94.51Zm199.42,67A4,4,0,0,1,224,164a3.91,3.91,0,0,1-1.49-.29l-20-8a4,4,0,1,1,3-7.42l20,8A4,4,0,0,1,227.71,161.49Zm-64,61a4,4,0,0,1-2.22,5.2A3.91,3.91,0,0,1,160,228a4,4,0,0,1-3.71-2.51l-8-20a4,4,0,0,1,7.42-3Z`}))]]),tM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H140v76a12,12,0,0,1-24,0V140H40a12,12,0,0,1,0-24h76V40a12,12,0,0,1,24,0v76h76A12,12,0,0,1,228,128Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H136v48a8,8,0,0,1-16,0V136H72a8,8,0,0,1,0-16h48V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H134v82a6,6,0,0,1-12,0V134H40a6,6,0,0,1,0-12h82V40a6,6,0,0,1,12,0v82h82A6,6,0,0,1,222,128Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H132v84a4,4,0,0,1-8,0V132H40a4,4,0,0,1,0-8h84V40a4,4,0,0,1,8,0v84h84A4,4,0,0,1,220,128Z`}))]]),nM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M124,216a12,12,0,0,1-12,12H48a12,12,0,0,1-12-12V40A12,12,0,0,1,48,28h64a12,12,0,0,1,0,24H60V204h52A12,12,0,0,1,124,216Zm108.49-96.49-40-40a12,12,0,0,0-17,17L195,116H112a12,12,0,0,0,0,24h83l-19.52,19.51a12,12,0,0,0,17,17l40-40A12,12,0,0,0,232.49,119.51Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M224,56V200a16,16,0,0,1-16,16H48V40H208A16,16,0,0,1,224,56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40A8,8,0,0,0,176,88v32H112a8,8,0,0,0,0,16h64v32a8,8,0,0,0,13.66,5.66l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M118,216a6,6,0,0,1-6,6H48a6,6,0,0,1-6-6V40a6,6,0,0,1,6-6h64a6,6,0,0,1,0,12H54V210h58A6,6,0,0,1,118,216Zm110.24-92.24-40-40a6,6,0,0,0-8.48,8.48L209.51,122H112a6,6,0,0,0,0,12h97.51l-29.75,29.76a6,6,0,1,0,8.48,8.48l40-40A6,6,0,0,0,228.24,123.76Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M116,216a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V40a4,4,0,0,1,4-4h64a4,4,0,0,1,0,8H52V212h60A4,4,0,0,1,116,216Zm110.83-90.83-40-40a4,4,0,0,0-5.66,5.66L214.34,124H112a4,4,0,0,0,0,8H214.34l-33.17,33.17a4,4,0,0,0,5.66,5.66l40-40A4,4,0,0,0,226.83,125.17Z`}))]]),rM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M199,125.31l-49.88-18.39L130.69,57a19.92,19.92,0,0,0-37.38,0L74.92,106.92,25,125.31a19.92,19.92,0,0,0,0,37.38l49.88,18.39L93.31,231a19.92,19.92,0,0,0,37.38,0l18.39-49.88L199,162.69a19.92,19.92,0,0,0,0-37.38Zm-63.38,35.16a12,12,0,0,0-7.11,7.11L112,212.28l-16.47-44.7a12,12,0,0,0-7.11-7.11L43.72,144l44.7-16.47a12,12,0,0,0,7.11-7.11L112,75.72l16.47,44.7a12,12,0,0,0,7.11,7.11L180.28,144ZM140,40a12,12,0,0,1,12-12h12V16a12,12,0,0,1,24,0V28h12a12,12,0,0,1,0,24H188V64a12,12,0,0,1-24,0V52H152A12,12,0,0,1,140,40ZM252,88a12,12,0,0,1-12,12h-4v4a12,12,0,0,1-24,0v-4h-4a12,12,0,0,1,0-24h4V72a12,12,0,0,1,24,0v4h4A12,12,0,0,1,252,88Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M194.82,151.43l-55.09,20.3-20.3,55.09a7.92,7.92,0,0,1-14.86,0l-20.3-55.09-55.09-20.3a7.92,7.92,0,0,1,0-14.86l55.09-20.3,20.3-55.09a7.92,7.92,0,0,1,14.86,0l20.3,55.09,55.09,20.3A7.92,7.92,0,0,1,194.82,151.43Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M208,144a15.78,15.78,0,0,1-10.42,14.94L146,178l-19,51.62a15.92,15.92,0,0,1-29.88,0L78,178l-51.62-19a15.92,15.92,0,0,1,0-29.88L78,110l19-51.62a15.92,15.92,0,0,1,29.88,0L146,110l51.62,19A15.78,15.78,0,0,1,208,144ZM152,48h16V64a8,8,0,0,0,16,0V48h16a8,8,0,0,0,0-16H184V16a8,8,0,0,0-16,0V32H152a8,8,0,0,0,0,16Zm88,32h-8V72a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0V96h8a8,8,0,0,0,0-16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M196.89,130.94,144.4,111.6,125.06,59.11a13.92,13.92,0,0,0-26.12,0L79.6,111.6,27.11,130.94a13.92,13.92,0,0,0,0,26.12L79.6,176.4l19.34,52.49a13.92,13.92,0,0,0,26.12,0L144.4,176.4l52.49-19.34a13.92,13.92,0,0,0,0-26.12Zm-4.15,14.86-55.08,20.3a6,6,0,0,0-3.56,3.56l-20.3,55.08a1.92,1.92,0,0,1-3.6,0L89.9,169.66a6,6,0,0,0-3.56-3.56L31.26,145.8a1.92,1.92,0,0,1,0-3.6l55.08-20.3a6,6,0,0,0,3.56-3.56l20.3-55.08a1.92,1.92,0,0,1,3.6,0l20.3,55.08a6,6,0,0,0,3.56,3.56l55.08,20.3a1.92,1.92,0,0,1,0,3.6ZM146,40a6,6,0,0,1,6-6h18V16a6,6,0,0,1,12,0V34h18a6,6,0,0,1,0,12H182V64a6,6,0,0,1-12,0V46H152A6,6,0,0,1,146,40ZM246,88a6,6,0,0,1-6,6H230v10a6,6,0,0,1-12,0V94H208a6,6,0,0,1,0-12h10V72a6,6,0,0,1,12,0V82h10A6,6,0,0,1,246,88Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M196.2,132.81l-53.36-19.65L123.19,59.8a11.93,11.93,0,0,0-22.38,0L81.16,113.16,27.8,132.81a11.93,11.93,0,0,0,0,22.38l53.36,19.65,19.65,53.36a11.93,11.93,0,0,0,22.38,0l19.65-53.36,53.36-19.65a11.93,11.93,0,0,0,0-22.38Zm-2.77,14.87L138.35,168a4,4,0,0,0-2.37,2.37l-20.3,55.08a3.92,3.92,0,0,1-7.36,0L88,170.35A4,4,0,0,0,85.65,168l-55.08-20.3a3.92,3.92,0,0,1,0-7.36L85.65,120A4,4,0,0,0,88,117.65l20.3-55.08a3.92,3.92,0,0,1,7.36,0L136,117.65a4,4,0,0,0,2.37,2.37l55.08,20.3a3.92,3.92,0,0,1,0,7.36ZM148,40a4,4,0,0,1,4-4h20V16a4,4,0,0,1,8,0V36h20a4,4,0,0,1,0,8H180V64a4,4,0,0,1-8,0V44H152A4,4,0,0,1,148,40Zm96,48a4,4,0,0,1-4,4H228v12a4,4,0,0,1-8,0V92H208a4,4,0,0,1,0-8h12V72a4,4,0,0,1,8,0V84h12A4,4,0,0,1,244,88Z`}))]]),iM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M116,36V20a12,12,0,0,1,24,0V36a12,12,0,0,1-24,0Zm80,92a68,68,0,1,1-68-68A68.07,68.07,0,0,1,196,128Zm-24,0a44,44,0,1,0-44,44A44.05,44.05,0,0,0,172,128ZM51.51,68.49a12,12,0,1,0,17-17l-12-12a12,12,0,0,0-17,17Zm0,119-12,12a12,12,0,0,0,17,17l12-12a12,12,0,1,0-17-17ZM196,72a12,12,0,0,0,8.49-3.51l12-12a12,12,0,0,0-17-17l-12,12A12,12,0,0,0,196,72Zm8.49,115.51a12,12,0,0,0-17,17l12,12a12,12,0,0,0,17-17ZM48,128a12,12,0,0,0-12-12H20a12,12,0,0,0,0,24H36A12,12,0,0,0,48,128Zm80,80a12,12,0,0,0-12,12v16a12,12,0,0,0,24,0V220A12,12,0,0,0,128,208Zm108-92H220a12,12,0,0,0,0,24h16a12,12,0,0,0,0-24Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M184,128a56,56,0,1,1-56-56A56,56,0,0,1,184,128Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm8,24a64,64,0,1,0,64,64A64.07,64.07,0,0,0,128,64ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M122,40V16a6,6,0,0,1,12,0V40a6,6,0,0,1-12,0Zm68,88a62,62,0,1,1-62-62A62.07,62.07,0,0,1,190,128Zm-12,0a50,50,0,1,0-50,50A50.06,50.06,0,0,0,178,128ZM59.76,68.24a6,6,0,1,0,8.48-8.48l-16-16a6,6,0,0,0-8.48,8.48Zm0,119.52-16,16a6,6,0,1,0,8.48,8.48l16-16a6,6,0,1,0-8.48-8.48ZM192,70a6,6,0,0,0,4.24-1.76l16-16a6,6,0,0,0-8.48-8.48l-16,16A6,6,0,0,0,192,70Zm4.24,117.76a6,6,0,0,0-8.48,8.48l16,16a6,6,0,0,0,8.48-8.48ZM46,128a6,6,0,0,0-6-6H16a6,6,0,0,0,0,12H40A6,6,0,0,0,46,128Zm82,82a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V216A6,6,0,0,0,128,210Zm112-88H216a6,6,0,0,0,0,12h24a6,6,0,0,0,0-12Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M124,40V16a4,4,0,0,1,8,0V40a4,4,0,0,1-8,0Zm64,88a60,60,0,1,1-60-60A60.07,60.07,0,0,1,188,128Zm-8,0a52,52,0,1,0-52,52A52.06,52.06,0,0,0,180,128ZM61.17,66.83a4,4,0,0,0,5.66-5.66l-16-16a4,4,0,0,0-5.66,5.66Zm0,122.34-16,16a4,4,0,0,0,5.66,5.66l16-16a4,4,0,0,0-5.66-5.66ZM192,68a4,4,0,0,0,2.83-1.17l16-16a4,4,0,1,0-5.66-5.66l-16,16A4,4,0,0,0,192,68Zm2.83,121.17a4,4,0,0,0-5.66,5.66l16,16a4,4,0,0,0,5.66-5.66ZM40,124H16a4,4,0,0,0,0,8H40a4,4,0,0,0,0-8Zm88,88a4,4,0,0,0-4,4v24a4,4,0,0,0,8,0V216A4,4,0,0,0,128,212Zm112-88H216a4,4,0,0,0,0,8h24a4,4,0,0,0,0-8Z`}))]]),aM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H180V36A28,28,0,0,0,152,8H104A28,28,0,0,0,76,36V48H40a12,12,0,0,0,0,24h4V208a20,20,0,0,0,20,20H192a20,20,0,0,0,20-20V72h4a12,12,0,0,0,0-24ZM100,36a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4V48H100Zm88,168H68V72H188ZM116,104v64a12,12,0,0,1-24,0V104a12,12,0,0,1,24,0Zm48,0v64a12,12,0,0,1-24,0V104a12,12,0,0,1,24,0Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M200,56V208a8,8,0,0,1-8,8H64a8,8,0,0,1-8-8V56Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM112,168a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm0-120H96V40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,50H174V40a22,22,0,0,0-22-22H104A22,22,0,0,0,82,40V50H40a6,6,0,0,0,0,12H50V208a14,14,0,0,0,14,14H192a14,14,0,0,0,14-14V62h10a6,6,0,0,0,0-12ZM94,40a10,10,0,0,1,10-10h48a10,10,0,0,1,10,10V50H94ZM194,208a2,2,0,0,1-2,2H64a2,2,0,0,1-2-2V62H194ZM110,104v64a6,6,0,0,1-12,0V104a6,6,0,0,1,12,0Zm48,0v64a6,6,0,0,1-12,0V104a6,6,0,0,1,12,0Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M216,52H172V40a20,20,0,0,0-20-20H104A20,20,0,0,0,84,40V52H40a4,4,0,0,0,0,8H52V208a12,12,0,0,0,12,12H192a12,12,0,0,0,12-12V60h12a4,4,0,0,0,0-8ZM92,40a12,12,0,0,1,12-12h48a12,12,0,0,1,12,12V52H92ZM196,208a4,4,0,0,1-4,4H64a4,4,0,0,1-4-4V60H196ZM108,104v64a4,4,0,0,1-8,0V104a4,4,0,0,1,8,0Zm48,0v64a4,4,0,0,1-8,0V104a4,4,0,0,1,8,0Z`}))]]),oM=new Map([[`bold`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a12,12,0,0,1-12,12h-8v8a12,12,0,0,1-24,0v-8h-8a12,12,0,0,1,0-24h8v-8a12,12,0,0,1,24,0v8h8A12,12,0,0,1,256,136Zm-54.81,56.28a12,12,0,1,1-18.38,15.44C169.12,191.42,145,172,108,172c-28.89,0-55.46,12.68-74.81,35.72a12,12,0,0,1-18.38-15.44A124.08,124.08,0,0,1,63.5,156.53a72,72,0,1,1,89,0A124,124,0,0,1,201.19,192.28ZM108,148a48,48,0,1,0-48-48A48.05,48.05,0,0,0,108,148Z`}))],[`duotone`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M168,100a60,60,0,1,1-60-60A60,60,0,0,1,168,100Z`,opacity:`0.2`}),M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136Zm-57.87,58.85a8,8,0,0,1-12.26,10.3C165.75,181.19,138.09,168,108,168s-57.75,13.19-77.87,37.15a8,8,0,0,1-12.25-10.3c14.94-17.78,33.52-30.41,54.17-37.17a68,68,0,1,1,71.9,0C164.6,164.44,183.18,177.07,198.13,194.85ZM108,152a52,52,0,1,0-52-52A52.06,52.06,0,0,0,108,152Z`}))],[`fill`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136ZM144,157.68a68,68,0,1,0-71.9,0c-20.65,6.76-39.23,19.39-54.17,37.17A8,8,0,0,0,24,208H192a8,8,0,0,0,6.13-13.15C183.18,177.07,164.6,164.44,144,157.68Z`}))],[`light`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M254,136a6,6,0,0,1-6,6H230v18a6,6,0,0,1-12,0V142H200a6,6,0,0,1,0-12h18V112a6,6,0,0,1,12,0v18h18A6,6,0,0,1,254,136Zm-57.41,60.14a6,6,0,1,1-9.18,7.72C166.9,179.45,138.69,166,108,166s-58.89,13.45-79.41,37.86a6,6,0,0,1-9.18-7.72C35.14,177.41,55,164.48,77,158.25a66,66,0,1,1,62,0C161,164.48,180.86,177.41,196.59,196.14ZM108,154a54,54,0,1,0-54-54A54.06,54.06,0,0,0,108,154Z`}))],[`regular`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M256,136a8,8,0,0,1-8,8H232v16a8,8,0,0,1-16,0V144H200a8,8,0,0,1,0-16h16V112a8,8,0,0,1,16,0v16h16A8,8,0,0,1,256,136Zm-57.87,58.85a8,8,0,0,1-12.26,10.3C165.75,181.19,138.09,168,108,168s-57.75,13.19-77.87,37.15a8,8,0,0,1-12.25-10.3c14.94-17.78,33.52-30.41,54.17-37.17a68,68,0,1,1,71.9,0C164.6,164.44,183.18,177.07,198.13,194.85ZM108,152a52,52,0,1,0-52-52A52.06,52.06,0,0,0,108,152Z`}))],[`thin`,M.createElement(M.Fragment,null,M.createElement(`path`,{d:`M252,136a4,4,0,0,1-4,4H228v20a4,4,0,0,1-8,0V140H200a4,4,0,0,1,0-8h20V112a4,4,0,0,1,8,0v20h20A4,4,0,0,1,252,136Zm-56.94,61.43a4,4,0,0,1-6.12,5.14C168,177.7,139.3,164,108,164s-60,13.7-80.94,38.57a4,4,0,1,1-6.12-5.14c16.71-19.9,38.13-33.13,61.89-38.59a64,64,0,1,1,50.34,0C156.93,164.3,178.35,177.53,195.06,197.43ZM108,156a56,56,0,1,0-56-56A56.06,56.06,0,0,0,108,156Z`}))]]),sM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:qj}));sM.displayName=`ArrowLeftIcon`;var cM=sM,lM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Jj}));lM.displayName=`ArrowRightIcon`;var uM=lM,dM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Yj}));dM.displayName=`BookOpenIcon`;var fM=dM,pM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Xj}));pM.displayName=`DotsThreeIcon`;var mM=pM,hM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Zj}));hM.displayName=`MagnifyingGlassIcon`;var gM=hM,_M=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:Qj}));_M.displayName=`MoonIcon`;var vM=_M,yM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:$j}));yM.displayName=`PencilSimpleIcon`;var bM=yM,xM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:eM}));xM.displayName=`PlugsConnectedIcon`;var SM=xM,CM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:tM}));CM.displayName=`PlusIcon`;var wM=CM,TM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:nM}));TM.displayName=`SignOutIcon`;var EM=TM,DM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:rM}));DM.displayName=`SparkleIcon`;var OM=DM,kM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:iM}));kM.displayName=`SunIcon`;var AM=kM,jM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:aM}));jM.displayName=`TrashIcon`;var MM=jM,NM=M.forwardRef((e,t)=>M.createElement(k,{ref:t,...e,weights:oM}));NM.displayName=`UserPlusIcon`;var PM=NM,FM=class extends Error{status;problems;code;constructor(e,t,n=[],r=``){super(e),this.status=t,this.problems=n,this.code=r}},IM=`fanout:unauthorized`;function LM(){let e=new URLSearchParams(window.location.search).get(`return_to`);if(!e)return``;let t=new URL(e,window.location.origin);return t.origin!==window.location.origin||t.pathname!==`/api/auth/oauth/authorize`?``:`${t.pathname}${t.search}`}function RM(e){return!e||typeof e!=`object`||!(`id`in e)||typeof e.id!=`string`||e.id===``?`none`:`user`}function zM(){window.dispatchEvent(new Event(IM))}async function BM(e,t={}){let n=new Headers(t.headers);n.set(`Fanout-Request`,`1`);let r=await fetch(e,{...t,headers:n,credentials:`same-origin`});if(r.status===401&&zM(),r.status===403){let e=await r.clone().json().catch(()=>({}));throw new FM(e.message??`You do not have permission to perform this action.`,r.status,[],e.code??``)}return r}async function VM(){let e=await BM(`/api/auth/logout`,{method:`POST`});if(!e.ok&&e.status!==401)throw Error(`Sign-out failed — your session is still active.`);e.status!==401&&zM(),window.location.assign(`/`)}var HM=(0,M.createContext)(null);function UM(){let e=(0,M.useContext)(HM);if(!e)throw Error(`Fanout runtime status is unavailable`);return e}var WM=(0,M.createContext)(null);function GM(){let e=(0,M.useContext)(WM);if(!e)throw Error(`Fanout viewer is unavailable`);return e}function KM(e){if(!e||typeof e!=`object`)return null;let t=e;return typeof t.id!=`string`||t.id===``||t.status!==`active`&&t.status!==`suspended`?null:{id:t.id,email:typeof t.email==`string`?t.email:``,display_name:typeof t.display_name==`string`?t.display_name:``,status:t.status,role:typeof t.role==`string`?t.role:``}}async function qM(e,t){let n=await fetch(e,{method:t===void 0?`GET`:`POST`,headers:t===void 0?void 0:{"Content-Type":`application/json`},body:t===void 0?void 0:JSON.stringify(t),credentials:`same-origin`}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(r.message??`Request failed (${n.status})`);return r}function JM({children:e,wide:t=!1}){return(0,N.jsx)(u,{mih:`100dvh`,style:{background:`radial-gradient(circle at 50% -12%, var(--mantine-color-brand-light), transparent 38%), linear-gradient(180deg, var(--mantine-color-default-hover), var(--mantine-color-body) 62%)`},children:(0,N.jsx)(je,{mih:`100dvh`,px:`md`,py:48,children:(0,N.jsx)(ve,{size:t?680:480,w:`100%`,children:(0,N.jsx)(Fe,{radius:28,p:{base:24,sm:40},style:{background:`var(--mantine-color-body)`,border:`1px solid var(--mantine-color-default-border)`,boxShadow:`var(--mantine-shadow-xl)`},children:e})})})})}function YM(){return typeof window>`u`?``:new URLSearchParams(window.location.search).get(`setup_token`)??``}function XM(){return typeof window>`u`?``:new URLSearchParams(window.location.search).get(`login_token`)??``}function ZM({children:e}){let t=ze(),[n,r]=(0,M.useState)(null),[i,a]=(0,M.useState)(!1),[o,s]=(0,M.useState)(`none`),[c,l]=(0,M.useState)(null),[d,f]=(0,M.useState)(!1),[p,m]=(0,M.useState)(``),[h,g]=(0,M.useState)(``),[_,v]=(0,M.useState)(YM),[y,b]=(0,M.useState)(XM),[x,S]=(0,M.useState)(``),[C,w]=(0,M.useState)(!1),[T,ee]=(0,M.useState)(0),[E,D]=(0,M.useState)(()=>Date.now()),[O,te]=(0,M.useState)(!1),[re,k]=(0,M.useState)(``),[ie,ae]=(0,M.useState)(null),[se,le]=(0,M.useState)(!1),de=(0,M.useRef)(null),fe=LM(),pe=o===`user`;async function he(){let e=await fetch(`/api/auth/me`,{credentials:`same-origin`});if(!e.ok){s(`none`),l(null);return}let t=await e.json().catch(()=>null);s(RM(t)),l(KM(t))}async function ge(){try{let e=await fetch(`/api/auth/me`,{credentials:`same-origin`});if(!e.ok)return;l(KM(await e.json().catch(()=>null)))}catch{}}(0,M.useEffect)(()=>{let e=new URL(window.location.href);(e.searchParams.has(`setup_token`)||e.searchParams.has(`login_token`))&&(e.searchParams.delete(`setup_token`),e.searchParams.delete(`login_token`),t({href:e.pathname+e.search+e.hash,replace:!0}))},[t]),(0,M.useEffect)(()=>{qM(`/api/auth/status`).then(r).catch(e=>k(String(e))).finally(()=>a(!0)),he().catch(()=>s(`none`)).finally(()=>f(!0));let e=()=>{s(`none`),l(null)};return window.addEventListener(IM,e),()=>window.removeEventListener(IM,e)},[]),(0,M.useEffect)(()=>{d&&o===`none`&&y&&(te(!0),k(``),qM(`/api/auth/link/verify`,{token:y}).then(()=>{s(`user`),ge()}).catch(e=>k(e instanceof Error?e.message:String(e))).finally(()=>{b(``),te(!1)}))},[y,d,o]),(0,M.useEffect)(()=>{pe&&d&&fe&&window.location.replace(fe)},[pe,fe,d]),(0,M.useEffect)(()=>{if(T<=Date.now())return;let e=setInterval(()=>{D(Date.now()),Date.now()>=T&&clearInterval(e)},1e3);return()=>clearInterval(e)},[T]);let _e=Math.max(0,Math.ceil((T-E)/1e3));(0,M.useEffect)(()=>{C&&!O&&re&&de.current?.querySelector(`input`)?.focus()},[O,C,re]);async function ve(e){try{await navigator.clipboard.writeText(e),le(!0)}catch{k(`Clipboard access failed. Select and copy the token manually.`)}}if(ie?.ingest_token)return(0,N.jsx)(JM,{wide:!0,children:(0,N.jsxs)(oe,{gap:`lg`,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(`div`,{children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Setup complete`}),(0,N.jsx)(xe,{order:1,mt:`xs`,fz:{base:28,sm:32},lh:1.08,children:`Save your ingest token`})]}),(0,N.jsx)(ue,{c:`dimmed`,children:`Fanout shows this token once. Store it with your collector secrets before continuing.`}),(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`OTLP endpoint`}),(0,N.jsx)(ss,{block:!0,children:ie.suggested_endpoint??window.location.origin})]}),(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`Header`}),(0,N.jsxs)(ss,{block:!0,children:[ie.ingest_header_name??`Authorization`,`: Bearer `,ie.ingest_token]})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),(0,N.jsxs)(ne,{grow:!0,align:`stretch`,children:[(0,N.jsx)(ce,{variant:`light`,radius:`md`,leftSection:se?(0,N.jsx)(me,{size:16,weight:`bold`}):(0,N.jsx)(Ee,{size:16}),onClick:()=>void ve(`${ie.ingest_header_name??`Authorization`}: Bearer ${ie.ingest_token}`),children:se?`Copied`:`Copy header`}),(0,N.jsx)(ce,{radius:`md`,rightSection:(0,N.jsx)(uM,{size:16,weight:`bold`}),onClick:()=>{s(`user`),ae(null),ge()},children:`Continue to Fanout`})]}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,onClick:()=>void ve(ie.ingest_token??``),children:`Copy token only`})]})});if(!d||!i||y)return(0,N.jsx)(je,{mih:`100dvh`,children:(0,N.jsx)(Ie,{size:`sm`})});if(!n)return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:`lg`,children:[(0,N.jsx)(ke,{}),(0,N.jsx)(xe,{order:1,children:`Fanout is unavailable`}),(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re||`Authentication status could not be loaded.`})]})});if(pe&&fe)return null;if(pe)return(0,N.jsx)(HM.Provider,{value:n,children:(0,N.jsx)(WM.Provider,{value:c??{id:``,email:p,display_name:h,status:`active`,role:``},children:e})});if(n&&!n.setup_required&&n.auth_mode===`oidc`){let e=fe?`/api/auth/oidc/start?return_to=${encodeURIComponent(fe)}`:`/api/auth/oidc/start`;return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:28,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(oe,{gap:10,children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:`Secure workspace`}),(0,N.jsx)(xe,{order:1,fz:{base:28,sm:32},lh:1.08,children:`Sign in`}),(0,N.jsx)(ue,{c:`dimmed`,size:`md`,lh:1.6,children:`Use your organization's identity provider to continue.`})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),(0,N.jsx)(ce,{component:`a`,href:e,size:`md`,radius:`md`,rightSection:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:`Continue with SSO`})]})})}async function ye(){te(!0),k(``);try{await qM(`/api/auth/code/send`,{email:p}),w(!0),S(``),ee(Date.now()+3e4),D(Date.now())}catch(e){k(e instanceof Error?e.message:String(e))}finally{te(!1)}}async function A(e){te(!0),k(``);try{await qM(`/api/auth/code/verify`,{email:p,code:e}),s(`user`),w(!1),S(``),ee(0),ge()}catch(e){S(``),k(e instanceof Error?e.message:String(e))}finally{te(!1)}}function j(){w(!1),S(``),k(``)}async function be(e){e.preventDefault(),te(!0),k(``);try{if(n?.setup_required){let e=await qM(`/api/auth/setup`,{email:p,display_name:h,setup_token:_});e.ingest_token?ae(e):(s(`user`),ge())}else if(C){await A(x);return}else{await ye();return}}catch(e){k(e instanceof Error?e.message:String(e))}finally{te(!1)}}let Se=C&&!n?.setup_required,we=n?.setup_required?`Create the first admin`:Se?`Check your email`:n?.self_signup?`Sign in or create an account`:`Sign in`,Te=n?.setup_required?`Use the one-time token printed by the Fanout process.`:n?.smtp_configured?Se?`We sent a code to ${p}.`:n?.self_signup?`Enter your email to sign in or create a viewer account. No password needed.`:`Enter your email and we’ll send a short verification code. No password needed.`:`Email delivery is not configured. Ask the operator to run fanout login-link with your email address.`;return(0,N.jsx)(JM,{children:(0,N.jsxs)(oe,{gap:28,children:[(0,N.jsx)(ke,{}),(0,N.jsxs)(oe,{gap:10,children:[(0,N.jsx)(ue,{c:`brand`,fw:700,size:`xs`,tt:`uppercase`,lts:`0.12em`,children:n?.setup_required?`One-time setup`:`Secure workspace`}),(0,N.jsx)(xe,{order:1,fz:{base:28,sm:32},lh:1.08,children:we}),Te&&(0,N.jsx)(ue,{c:`dimmed`,size:`md`,lh:1.6,maw:390,children:Te})]}),(0,N.jsx)(`form`,{onSubmit:be,children:(0,N.jsxs)(oe,{gap:`md`,children:[(0,N.jsx)(Rc,{label:`Email`,placeholder:`you@company.com`,type:`email`,required:!0,value:p,onChange:e=>m(e.currentTarget.value),disabled:C,variant:`filled`,radius:`md`,size:`md`,autoFocus:!C}),n?.setup_required&&(0,N.jsx)(Rc,{label:`Display name`,placeholder:`Your display name`,value:h,onChange:e=>g(e.currentTarget.value),variant:`filled`,radius:`md`,size:`md`}),n?.setup_required&&(0,N.jsx)(Rc,{label:`Setup token`,placeholder:`from the setup URL printed at startup`,required:!0,value:_,onChange:e=>v(e.currentTarget.value),autoComplete:`one-time-code`,variant:`filled`,radius:`md`,size:`md`}),Se&&(0,N.jsxs)(oe,{gap:`xs`,children:[(0,N.jsx)(ue,{size:`sm`,fw:600,children:`Verification code`}),(0,N.jsx)(u,{ref:de,children:(0,N.jsx)(Lc,{length:6,type:`number`,oneTimeCode:!0,autoFocus:!0,value:x,onChange:S,onComplete:e=>void A(e),disabled:O,error:!!re,size:`md`,radius:`md`,"aria-label":`Verification code`,getInputProps:e=>({"aria-label":`Digit ${e+1}`})})}),(0,N.jsxs)(ne,{justify:`space-between`,gap:`xs`,children:[(0,N.jsxs)(ue,{c:`dimmed`,size:`xs`,children:[`Sent to `,p]}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,leftSection:(0,N.jsx)(cM,{size:12,weight:`bold`}),onClick:j,disabled:O,children:`Change email`})]}),(0,N.jsxs)(ne,{justify:`space-between`,gap:`xs`,children:[(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,children:`Codes expire in 5 minutes`}),(0,N.jsx)(ce,{variant:`subtle`,size:`compact-xs`,onClick:()=>void ye(),disabled:O||_e>0,children:_e>0?`Resend in ${_e}s`:`Resend code`})]})]}),re&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,children:re}),Se?(0,N.jsx)(ce,{type:`submit`,size:`md`,radius:`md`,mt:4,loading:O,disabled:O||x.length<6,rightSection:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:`Verify code`}):(0,N.jsx)(ce,{type:`submit`,size:`md`,radius:`md`,mt:4,loading:O,disabled:!n||!n.setup_required&&!n.smtp_configured,leftSection:n?.setup_required?(0,N.jsx)(PM,{size:17,weight:`bold`}):void 0,rightSection:n?.setup_required?void 0:(0,N.jsx)(uM,{size:17,weight:`bold`}),children:n?.setup_required?`Create admin`:`Send code`})]})})]})})}var QM=[`agent-threads`];async function $M(e){let t=await BM(e);if(!t.ok)throw Error(`Request failed (${t.status})`);return t.json()}var eN=new Set([`create_dashboard`,`edit_dashboard`,`replace_dashboard`,`restore_dashboard_version`]);function tN(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function nN(e){if(typeof e==`string`)try{let t=JSON.parse(e);if(tN(t))return t}catch{}}var rN=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),iN=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;function aN(e){return tN(e)&&typeof e.id==`string`&&[`ok`,`empty`,`error`,`invalid`,`not_run`,`partial`,`stale`].includes(String(e.status))&&(e.rows===void 0||iN(e.rows))&&(e.elapsed_ms===void 0||iN(e.elapsed_ms))&&(e.diagnosis===void 0||typeof e.diagnosis==`string`)&&(e.error===void 0||typeof e.error==`string`)}function oN(e){if(!tN(e)||!Number.isInteger(e.base_version)||Number(e.base_version)<0||!Number.isInteger(e.version)||Number(e.version)<1||!Array.isArray(e.changes)||typeof e.layout_changed!=`boolean`||e.dashboard_fields!==void 0&&!rN(e.dashboard_fields)||!e.changes.every(e=>tN(e)&&typeof e.panel_id==`string`&&typeof e.title==`string`&&[`added`,`changed`,`removed`].includes(String(e.kind))&&(e.fields===void 0||rN(e.fields)&&!e.fields.includes(`grid`))&&(e.position_changed===void 0||typeof e.position_changed==`boolean`)))return!1;let t=e.save_check;return tN(t)&&typeof t.checked==`boolean`&&iN(t.elapsed_ms)&&Array.isArray(t.panels)&&t.panels.every(e=>aN(e)&&Number.isInteger(e.rows)&&Number(e.rows)>=0)&&new Set(t.panels.map(e=>e.id)).size===t.panels.length&&(t.reason===void 0||typeof t.reason==`string`)&&(!t.checked||t.panels.every(e=>e.status!==`not_run`&&e.status!==`invalid`))}function sN(e,t,n){let r=-1;n.forEach((n,i)=>{n.role===`tool`&&n.toolCallId===e&&n.content===t&&(r=i)});let i=r<0?n.length:r,a=-1;if(n.slice(0,i).forEach((e,t)=>{e.role===`user`&&(a=t)}),a<0)return null;let o=n.slice(a+1,i).flatMap(e=>e.role===`assistant`?e.toolCalls??[]:[]).filter(t=>t.id===e),s=o.length===1?o[0].function.name:void 0;if(!s||!eN.has(s))return null;let c=nN(t),l=c?.dashboard,u=c?.receipt;return!c||c.error||c.isError||!tN(l)||typeof l.id!=`string`||!l.id||typeof l.name!=`string`||!l.name||!oN(u)||l.version!==u.version||r>=0&&n[r].error?null:{id:l.id,name:l.name,version:u.version,label:s===`create_dashboard`?`Created`:s===`restore_dashboard_version`?`Restored`:`Updated`,receipt:u}}var cN={viz:`chart type`,sql:`SQL`,content:`text`,x_unit:`x-axis unit`,options:`display options`,drill:`drill-down`,click:`click action`,time:`time range`,annotations:`markers`,better:`better direction`,reduce:`summary`,min:`minimum`,max:`maximum`},lN=e=>Object.hasOwn(cN,e)?cN[e]:e.replaceAll(`_`,` `),uN=e=>e.kind===`added`?`+ ${e.title}`:e.kind===`removed`?`− ${e.title}`:`~ ${e.title}${e.fields?.length?`: `+e.fields.map(lN).join(`, `):``}${e.position_changed?` · moved`:``}`;function dN(e){return[...e.changes.map(uN),...e.layout_changed?[`Layout adjusted`]:[],...e.dashboard_fields?.map(e=>`Dashboard: ${lN(e)}`)??[]]}function fN(e,t,n){return e.filter(e=>n.has(e.panel_id)&&!t.some(t=>t.panel_id===e.panel_id&&t.path===e.path))}var pN={schema:`Telemetry`,context:`Context`,draft:`Draft`,validation:`Validation`,preview:`Preview`,save:`Save`},mN=new Set([`get_intelligence_snapshot`,`query_telemetry`,`get_observability_overview`,`get_service_topology`,`get_service_dependencies`,`get_service_performance`,`inspect_trace`,`search_logs`]),hN=(e,t)=>Array.isArray(e)?e.flatMap(e=>tN(e)&&typeof e.path==`string`&&typeof e.message==`string`?[{panel_id:t,path:e.path,message:e.message}]:[]):[],gN=e=>{let t=nN(e)?.error;return tN(t)?t.code:void 0},_N=e=>e.role===`tool`&&gN(e.content)===`interrupted`,vN=e=>![`invalid`,`not_run`].includes(e.status);function yN(e,t){let n=e.findIndex(e=>e.id===t&&e.role===`user`);if(n<0)return null;let r=e.findIndex((e,t)=>t>n&&e.role===`user`),i=e.slice(n+1,r<0?void 0:r),a=new Set(i.flatMap(e=>e.role===`tool`&&gN(e.content)===`answer_only`?[e.toolCallId]:[])),o=i.flatMap((e,t)=>e.role===`assistant`?(e.toolCalls??[]).map(e=>({call:e,index:t})):[]).filter(({call:e})=>!a.has(e.id));if(!o.some(({call:e})=>eN.has(e.function.name)||e.function.name===`preview_panels`))return null;let s={schema:{state:`unobserved`},context:{state:`unobserved`},draft:{state:`unobserved`},validation:{state:`unobserved`},preview:{state:`unobserved`},save:{state:`unobserved`}},c={turn_id:t,stages:s,panel_titles:{},panels:[],problems:[],corrections:[],save_attempts:[],explanations:[],context_counts:{deploys:0,anomalies:0}},l=new Map,u=new Map;for(let{call:e}of o)l.set(e.id,(l.get(e.id)??0)+1);i.forEach((e,t)=>{if(e.role===`tool`){let n=u.get(e.toolCallId)??[];n.push({index:t,message:e}),u.set(e.toolCallId,n)}});let d=new Map,f=new Map,p=[],m,h=!1,g=!1,_=(e,t)=>{for(let n of fN(y.get(e)??[],t,new Set([e])))p.some(e=>e.panel_id===n.panel_id&&e.path===n.path)||p.push(n);y.set(e,t)},v=new Map,y=new Map,b=new Set,x=!1,S=!1;for(let{call:t,index:n}of o){if(l.get(t.id)!==1)continue;let r=t.function.name,i=nN(t.function.arguments),a=(u.get(t.id)??[]).filter(e=>e.index>n),o=a.length===1||eN.has(r)&&a.length>1&&a.slice(0,-1).every(e=>_N(e.message))?a.at(-1).message:void 0,C=o&&nN(o.content),w=!!C&&o?.role===`tool`&&!o.error&&!C.error&&!C.isError,T=o?w?`complete`:`failed`:`incomplete`;if(r===`get_telemetry_schema`&&(s.schema={state:T}),mN.has(r)){let e=o?.role===`tool`&&!o.error&&!C?.error&&!C?.isError&&typeof o.content==`string`&&o.content.length>0;if(s.context={state:o?e?`complete`:`failed`:`incomplete`},w)for(let[e,t]of[[`deploys`,[`deploys`,`deployments`]],[`anomalies`,[`anomalies`]]])for(let n of t)Array.isArray(C[n])&&(c.context_counts[e]+=C[n].length)}if(r===`preview_panels`||r===`create_dashboard`||r===`replace_dashboard`){let e=r===`preview_panels`?i?.panels:tN(i?.dashboard)?i.dashboard.panels:void 0;if(Array.isArray(e)){c.panel_count=e.length,s.draft={state:`complete`};for(let t of e)tN(t)&&typeof t.id==`string`&&typeof t.title==`string`&&t.title.trim()&&f.set(t.id,t.title)}}if(r===`preview_panels`){x=!0;let e=Array.isArray(i?.panels)?i.panels.flatMap(e=>tN(e)&&typeof e.id==`string`?[e.id]:[]):[];for(let t of e)v.set(t,{id:t,status:`not_run`});let t=w&&Array.isArray(C.panels)&&C.panels.every(aN)?C.panels:void 0,n=typeof C?.elapsed_ms==`number`&&C.elapsed_ms>=0?C.elapsed_ms:void 0;if(s.validation={state:t?t.some(e=>e.status===`invalid`||e.status===`not_run`)||hN(C?.problems,`dashboard`).length?`failed`:`complete`:T===`complete`?`failed`:T},s.preview={state:t?t.every(vN)?`complete`:`incomplete`:T===`complete`?`failed`:T,elapsed_ms:n},!t||e.length===0||t.length!==e.length||new Set(t.map(e=>e.id)).size!==e.length||t.some(t=>!e.includes(t.id))){S=e.length===0;for(let t of e)o&&b.add(t);continue}S=!1;for(let t of e)b.delete(t);for(let e of t){let t=hN(e.problems,e.id);if(e.status!==`not_run`)_(e.id,t);else{let n=y.get(e.id)??[];y.set(e.id,[...n,...t.filter(e=>!n.some(t=>t.path===e.path))])}v.set(e.id,e)}c.problems=[...y.values()].flat().concat(hN(C?.problems,`dashboard`))}if(eN.has(r)){let n=o&&sN(t.id,o.content,e),r=!!o&&_N(o),i=!r&&o?.role===`tool`&&(!!o.error||!!C?.error||!!C?.isError);if(g=!!i,h=!!o&&!n&&!i&&!r,s.save={state:n?`complete`:r?`interrupted`:i?`failed`:`incomplete`},n)for(let e of c.save_attempts)e.state===`failed`&&(e.state=`retried`);if(c.save_attempts.push({call_id:t.id,state:s.save.state}),n){m?.id!==n.id&&(m=n,d.clear());for(let e of n.receipt.changes){e.title.trim()&&f.set(e.panel_id,e.title);let t=d.get(e.panel_id);if(t?.kind===`added`&&e.kind===`removed`){d.delete(e.panel_id);continue}if(t?.kind===`added`){d.set(e.panel_id,{panel_id:e.panel_id,title:e.title,kind:`added`});continue}if(e.kind===`removed`){d.set(e.panel_id,e);continue}t&&e.kind===`changed`?d.set(e.panel_id,{...e,fields:[...new Set([...t.fields??[],...e.fields??[]])].sort(),position_changed:t.position_changed||e.position_changed}):d.set(e.panel_id,t?.kind===`removed`&&e.kind===`added`?{...e,kind:`changed`}:e)}let e=C?.dashboard,t=tN(e)?e.spec:void 0;if(tN(t)&&Array.isArray(t.panels))for(let e of t.panels)tN(e)&&typeof e.id==`string`&&typeof e.title==`string`&&e.title.trim()&&f.set(e.id,e.title);let r=c.saved?.id===n.id?c.saved.receipt:void 0;c.saved={...n,label:m.label,receipt:{...n.receipt,base_version:m.receipt.base_version,changes:[...d.values()],layout_changed:m.receipt.base_version!==0&&(n.receipt.layout_changed||!!r?.layout_changed),dashboard_fields:m.receipt.base_version===0?void 0:[...new Set([...r?.dashboard_fields??[],...n.receipt.dashboard_fields??[]])].sort()}},c.panel_count=n.receipt.save_check.panels.length,s.draft={state:`complete`};let i=new Set(n.receipt.save_check.panels.map(e=>e.id));for(let e of n.receipt.save_check.panels)vN(e)&&(_(e.id,[]),b.delete(e.id));p=p.filter(e=>i.has(e.panel_id)),c.problems=[...y.values()].flat().filter(e=>i.has(e.panel_id))}}}if(h)return null;c.panel_titles=Object.fromEntries(f),c.corrections=p.map(e=>({...e,title:f.get(e.panel_id)??e.panel_id}));let C=c.saved?new Set(c.saved.receipt.save_check.panels.map(e=>e.id)):void 0;if(c.panels=[...v.values()].filter(e=>!C||C.has(e.id)),x){let e=S||[...b].some(e=>!C||C.has(e)),t=c.panels.some(e=>e.status===`not_run`),n=c.problems.length>0;s.validation.state=e||n?`failed`:t?`incomplete`:`complete`,s.preview.state=e?`failed`:t||n||c.panels.some(e=>e.status===`invalid`)?`incomplete`:`complete`}let w=c.saved?.receipt.save_check;w&&!w.checked&&c.explanations.push(`Save check incomplete: ${w.reason||`Panels were not checked`}`);for(let e of w?.panels??c.panels)e.status!==`ok`&&c.explanations.push(`${f.get(e.id)??e.id}: ${e.status}${e.error||e.diagnosis?` — ${e.error||e.diagnosis}`:``}`);for(let e of c.problems)c.explanations.push(`${f.get(e.panel_id)??e.panel_id}: ${e.message}`);let T=Object.entries(s).filter(([,e])=>e.state===`incomplete`||e.state===`failed`).map(([e,t])=>`${pN[e]}: ${t.state}`);return T.length&&c.explanations.push(T.join(` · `)),s.save.state===`interrupted`&&c.explanations.push(`Save interrupted · outcome unknown`),g&&c.explanations.push(c.saved?`A later change failed; v${c.saved.version} remains saved`:`Save failed · dashboard was not saved`),c}var bN=(0,M.createContext)(null);function xN(){let e=(0,M.useContext)(bN);if(!e)throw Error(`Fanout app context is unavailable`);return e}var SN=`Build me a dashboard for my services, showing request volume, latency, and errors. Ask me which services to monitor first.`,CN={query_telemetry:{activity:`Querying telemetry…`,title:`Telemetry panels`},get_observability_overview:{activity:`Checking system health…`,title:`System health`},get_service_topology:{activity:`Mapping service dependencies…`,title:`Service map`},get_service_dependencies:{activity:`Tracing service dependencies…`,title:`Service dependencies`},list_panel_exemplars:{activity:`Finding example traces…`,title:`Example traces`},resolve_panel_variables:{activity:`Reading filter choices…`,title:`Filter choices`},query_panel_fragment:{activity:`Refreshing panels…`,title:`Panel refresh`},get_service_performance:{activity:`Reading performance signals…`,title:`Performance`},inspect_trace:{activity:`Inspecting a trace…`,title:`Trace lookup`},search_logs:{activity:`Searching logs…`,title:`Logs`},get_intelligence_snapshot:{activity:`Reviewing detected anomalies…`,title:`Detected anomalies`},get_telemetry_schema:{activity:`Reading what telemetry exists…`,title:`Telemetry discovery`},preview_panels:{activity:`Checking dashboard panels…`,title:`Panel check`},list_dashboards:{activity:`Looking through your dashboards…`,title:`Dashboards`},get_dashboard:{activity:`Opening your dashboard…`,title:`Dashboard`},create_dashboard:{activity:`Building your dashboard…`,title:`Dashboard save`},edit_dashboard:{activity:`Updating your dashboard…`,title:`Dashboard save`},replace_dashboard:{activity:`Redesigning your dashboard…`,title:`Dashboard save`},list_dashboard_versions:{activity:`Reading your dashboard history…`,title:`Dashboard history`},restore_dashboard_version:{activity:`Restoring your dashboard…`,title:`Dashboard`}};function wN(e){return CN[e]?.activity??`Working on it…`}function TN(e){return CN[e]?.title??`Analysis step`}function EN(e){switch(e){case`provider_unavailable`:return`Fanout could not reach the model provider. Please try again.`;case`step_limit`:return`Fanout reached its step limit before finishing. Try a narrower question.`;case`time_limit`:return`Fanout reached its 5-minute time limit. Try a smaller request.`;default:return`Fanout could not complete this analysis. Please try again.`}}function DN(e){let t=(0,M.useRef)(new Map);return(0,M.useMemo)(()=>{let n=new Map,r=new Set,i=e.flatMap((e,t)=>e.role===`user`?[t]:[]);i.forEach((a,o)=>{let s=i[o+1]??e.length,c=e[a],l=e[s-1];r.add(c.id);let u=t.current.get(c.id),d=u&&u.last===l&&u.length===s-a?u.receipt:yN(e.slice(a,s),c.id);oe.msecs?(e.seq=IN(n),e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function FN(e,t,n,r,i=0){if(e.length<16)throw Error(`Random bytes length must be >= 16`);if(!r)r=new Uint8Array(16),i=0;else if(i<0||i+16>r.length)throw RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);return t??=Date.now(),n??=IN(e),r[i++]=t/1099511627776&255,r[i++]=t/4294967296&255,r[i++]=t/16777216&255,r[i++]=t/65536&255,r[i++]=t/256&255,r[i++]=t&255,r[i++]=112|n>>>28&15,r[i++]=n>>>20&255,r[i++]=128|n>>>14&63,r[i++]=n>>>6&255,r[i++]=n<<2&255|e[10]&3,r[i++]=e[11],r[i++]=e[12],r[i++]=e[13],r[i++]=e[14],r[i++]=e[15],r}function IN(e){return(e[6]&127)<<24|e[7]<<16|e[8]<<8|e[9]}function LN(){return NN()}var RN=[`dashboards`],zN=3e4;async function BN(e,t){let{json:n,...r}=t??{},i=new Headers(r.headers),a=r.body;n!==void 0&&(i.set(`content-type`,`application/json`),a=JSON.stringify(n));let o=await BM(e,{...r,headers:i,body:a}),s=await o.json().catch(()=>({}));if(!o.ok)throw new FM(s.message??`Request failed (${o.status})`,o.status,s.problems??[],s.code??``);return s}var VN=e=>`/api/dashboards/${encodeURIComponent(e)}`,HN=()=>BN(`/api/dashboards`).then(e=>e.dashboards),UN=(e,t)=>BN(VN(e),{signal:t}),WN=(e,t)=>BN(`${VN(e)}/versions`,{signal:t}).then(e=>e.versions),GN=(e,t,n)=>BN(`${VN(e)}/versions/${t}`,{signal:n}),KN=(e,t)=>BN(`${VN(e)}/versions/${t}/restore`,{method:`POST`}),qN=(e,t,n,r)=>BN(VN(e),{method:`PUT`,json:{spec:t,base_version:n,message:r}}),JN=(e,t,n,r)=>BN(VN(e),{method:`PATCH`,json:{operations:t,base_version:n,message:r}}),YN=(e,t)=>BN(`/api/queries/run`,{method:`POST`,json:e,signal:t}).then(e=>e.results),XN=e=>BN(`/api/telemetry/schema`,{signal:e}),ZN=(e,t)=>BN(`/api/annotations`,{method:`POST`,json:e,signal:t}),QN=(e,t)=>BN(`/api/queries/variables/resolve`,{method:`POST`,json:e,signal:t}).then(e=>e.options),$N=(e,t)=>BN(`/api/queries/exemplars`,{method:`POST`,json:e,signal:t});function eP(e,t){let n=new URLSearchParams({namespace:e.namespace??``,from:e.window_from,to:e.window_to,limit:`200`});return BN(`/api/traces/${encodeURIComponent(e.trace_id??``)}?${n}`,{signal:t})}function tP(){let{setColorScheme:e}=Nr(),t=Ir(`light`,{getInitialValueInEffect:!0}),n=t===`dark`?`light`:`dark`,[r,i]=(0,M.useState)(!1);return(0,N.jsx)(St,{label:`Switch to ${n} theme`,opened:r,children:(0,N.jsx)(Di,{variant:`subtle`,color:`gray`,"aria-label":`Switch to ${n} theme`,onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),onFocus:()=>i(!0),onBlur:()=>i(!1),onClick:()=>{i(!1),e(n)},children:t===`dark`?(0,N.jsx)(AM,{size:17,weight:`bold`}):(0,N.jsx)(vM,{size:17,weight:`bold`})})})}var nP={home:`https://fanout.run/docs`,ingest:`https://fanout.run/docs/get-started/send-telemetry`,connect:`https://fanout.run/docs/guides/mcp`};async function rP(e,t){let n=new URLSearchParams({page_size:`30`});e&&n.set(`q`,e),t&&n.set(`cursor`,t);let r=await BM(`/api/agent/threads?${n}`);if(!r.ok)throw Error(`Unable to load chats (${r.status})`);return r.json()}function iP({agentAvailable:e,activeThreadID:t,activeDashboardID:n,autoFocusSearch:r=!1,onNewChat:i,onSelectThread:a,onDeletedThread:o,onSelectDashboard:s,onCreateDashboard:c,onInvestigateService:l,ref:u}){let d=SA(),[f,p]=(0,M.useState)(``),[m]=or(f.trim(),250),[h,g]=(0,M.useState)(null),[_,v]=(0,M.useState)(null),[y,b]=(0,M.useState)(``),[x,S]=(0,M.useState)(``),[w,T]=(0,M.useState)(!1),ee=(0,M.useRef)(null);(0,M.useImperativeHandle)(u,()=>({focusSearch:()=>ee.current?.focus()}),[]),(0,M.useEffect)(()=>{r&&requestAnimationFrame(()=>ee.current?.focus())},[r]);let E=Kj({queryKey:[...QM,m],queryFn:({pageParam:e})=>rP(m,e),initialPageParam:``,getNextPageParam:e=>e.next_cursor??void 0,enabled:e}),D=Gj({queryKey:RN,queryFn:HN,refetchInterval:3e4,staleTime:zN}),O=(0,M.useMemo)(()=>E.data?.pages.flatMap(e=>e.items)??[],[E.data]),te=(0,M.useMemo)(()=>uP(O),[O]),re=Gj({queryKey:[`telemetry-schema`,`1h`],queryFn:()=>$M(`/api/telemetry/schema?window=1h`),enabled:e&&!!m&&!!l,staleTime:6e4}),k=(0,M.useMemo)(()=>{if(!m)return[];let e=m.toLowerCase();return(re.data?.services??[]).map(e=>e.value).filter(t=>t.toLowerCase().includes(e)).slice(0,6)},[re.data,m]),ie=(0,M.useMemo)(()=>{let e=D.data??[],t=m.toLowerCase();return t?e.filter(e=>e.name.toLowerCase().includes(t)):e},[D.data,m]);function ae(e){S(``),b(e.title),g(e)}async function se(){if(h&&y.trim()){T(!0),S(``);try{let e=await BM(`/api/agent/threads/${encodeURIComponent(h.id)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:y.trim()})});if(!e.ok)throw Error(`Unable to rename chat (${e.status})`);await d.invalidateQueries({queryKey:QM}),g(null)}catch(e){S(e instanceof Error?e.message:`Unable to rename this chat.`)}finally{T(!1)}}}async function le(){if(_){T(!0),S(``);try{let e=await BM(`/api/agent/threads/${encodeURIComponent(_.id)}`,{method:`DELETE`});if(!e.ok)throw Error(`Unable to delete chat (${e.status})`);let t=_.id;v(null),await d.invalidateQueries({queryKey:QM}),await d.invalidateQueries({queryKey:RN}),o(t)}catch(e){S(e instanceof Error?e.message:`Unable to delete this chat.`)}finally{T(!1)}}}return(0,N.jsxs)(oe,{gap:`sm`,h:`100%`,component:`nav`,"aria-label":`Navigation`,children:[e&&(0,N.jsx)(ce,{leftSection:(0,N.jsx)(wM,{size:16,weight:`bold`}),onClick:i,children:`New chat`}),(0,N.jsx)(vt,{type:`auto`,offsetScrollbars:!0,flex:1,mx:-4,px:4,children:(0,N.jsxs)(oe,{gap:`lg`,pb:`sm`,children:[e&&(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Chats`}),E.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),E.isError&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,p:`xs`,children:`Chats could not be loaded.`}),!E.isLoading&&!E.isError&&O.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,py:`xs`,children:m?`No matching chats`:`No chats yet`}),te.map(e=>(0,N.jsxs)(oe,{gap:2,children:[te.length>1&&(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,px:`sm`,pt:4,children:e.label}),e.threads.map(e=>(0,N.jsx)(oP,{thread:e,active:e.id===t,onSelect:()=>a(e.id),onRename:()=>ae(e),onDelete:()=>{S(``),v(e)}},e.id))]},e.label)),E.hasNextPage&&(0,N.jsx)(ce,{variant:`subtle`,color:`gray`,size:`compact-sm`,loading:E.isFetchingNextPage,onClick:()=>void E.fetchNextPage(),children:`See all`})]}),e&&m&&l&&re.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),e&&m&&l&&(re.isSuccess||re.isError)&&(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Services`}),re.isError&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,children:`Services could not be searched`}),re.isSuccess&&k.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,children:`No matching services`}),k.map(e=>(0,N.jsx)(C,{className:`rail-row`,p:`sm`,onClick:()=>l(e),children:(0,N.jsx)(ue,{size:`sm`,fw:500,truncate:!0,children:e})},e))]}),(0,N.jsxs)(oe,{gap:4,children:[(0,N.jsx)(aP,{children:`Dashboards`}),D.isLoading&&(0,N.jsx)(je,{py:`md`,children:(0,N.jsx)(Ie,{size:`xs`})}),D.isError&&(0,N.jsx)(Ce,{color:`bad`,radius:`md`,p:`xs`,children:`Dashboards could not be loaded.`}),!D.isLoading&&!D.isError&&m&&ie.length===0&&(0,N.jsx)(ue,{c:`dimmed`,size:`sm`,px:`sm`,py:`xs`,children:`No matching dashboards`}),ie.map(t=>{let r=t.id===n;return(0,N.jsxs)(oe,{gap:0,children:[(0,N.jsx)(C,{component:`a`,href:`/dashboards/${encodeURIComponent(t.id)}`,className:`rail-row`,"data-active":r||void 0,"aria-current":r?`page`:void 0,p:`sm`,onClick:e=>{e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),s(t.id))},children:(0,N.jsxs)(ne,{justify:`space-between`,gap:`sm`,wrap:`nowrap`,children:[(0,N.jsx)(ue,{size:`sm`,fw:r?600:500,truncate:!0,children:t.name}),t.is_default&&(0,N.jsx)(ts,{size:`xs`,variant:`light`,color:`gray`,children:`Default`})]})}),e&&t.origin&&(0,N.jsx)(C,{component:`a`,href:`/chat/${encodeURIComponent(t.origin.thread_id)}`,"data-request-provenance":!0,px:`sm`,pb:`xs`,onClick:e=>{e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),a(t.origin.thread_id))},children:(0,N.jsxs)(ue,{size:`xs`,c:`dimmed`,lineClamp:2,children:[`Built from: `,t.origin.request_excerpt]})})]},t.id)}),e&&(0,N.jsx)(ce,{variant:`subtle`,color:`gray`,size:`compact-sm`,justify:`flex-start`,leftSection:(0,N.jsx)(OM,{size:14,weight:`fill`}),onClick:c,children:D.data?.length===0?`New dashboard`:`Create with AI`})]})]})}),(0,N.jsx)(Rc,{ref:ee,value:f,onChange:e=>p(e.currentTarget.value),leftSection:(0,N.jsx)(gM,{size:15}),rightSection:(0,N.jsx)(As,{size:`xs`,children:`⌘K`}),rightSectionWidth:44,placeholder:`Search`,"aria-label":`Search chats, dashboards and services`,size:`sm`}),(0,N.jsx)(jc,{opened:h!==null,onClose:()=>!w&&g(null),title:`Rename chat`,centered:!0,children:(0,N.jsx)(`form`,{onSubmit:e=>{e.preventDefault(),se()},children:(0,N.jsxs)(oe,{children:[(0,N.jsx)(Rc,{label:`Name`,value:y,onChange:e=>b(e.currentTarget.value),maxLength:120,autoFocus:!0}),x&&(0,N.jsx)(Ce,{color:`bad`,children:x}),(0,N.jsxs)(ne,{justify:`flex-end`,children:[(0,N.jsx)(ce,{variant:`default`,onClick:()=>g(null),disabled:w,children:`Cancel`}),(0,N.jsx)(ce,{type:`submit`,loading:w,disabled:!y.trim(),children:`Save`})]})]})})}),(0,N.jsx)(jc,{opened:_!==null,onClose:()=>!w&&v(null),title:`Delete chat?`,centered:!0,children:(0,N.jsxs)(oe,{children:[(0,N.jsxs)(ue,{size:`sm`,children:[`This permanently removes `,(0,N.jsx)(ue,{span:!0,fw:650,children:_?.title}),` and its saved messages.`]}),x&&(0,N.jsx)(Ce,{color:`bad`,children:x}),(0,N.jsxs)(ne,{justify:`flex-end`,children:[(0,N.jsx)(ce,{variant:`default`,onClick:()=>v(null),disabled:w,children:`Cancel`}),(0,N.jsx)(ce,{color:`bad`,loading:w,onClick:()=>void le(),children:`Delete`})]})]})})]})}function aP({children:e}){return(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,fw:700,tt:`uppercase`,lts:`0.08em`,px:`sm`,children:e})}function oP({thread:e,active:t,onSelect:n,onRename:r,onDelete:i}){return(0,N.jsx)(u,{"data-active":t||void 0,className:`rail-row`,children:(0,N.jsxs)(ne,{gap:2,wrap:`nowrap`,children:[(0,N.jsx)(C,{onClick:n,"aria-current":t?`page`:void 0,p:`sm`,flex:1,style:{minWidth:0},children:(0,N.jsxs)(oe,{gap:0,children:[(0,N.jsx)(ue,{size:`sm`,fw:t?600:500,truncate:!0,children:e.title}),(0,N.jsx)(ue,{c:`dimmed`,size:`xs`,children:dP(e.updated_at)})]})}),(0,N.jsxs)(hc,{position:`bottom-end`,withinPortal:!0,children:[(0,N.jsx)(hc.Target,{children:(0,N.jsx)(Di,{className:`rail-row-actions`,variant:`subtle`,color:`gray`,size:`sm`,mr:4,"aria-label":`Actions for ${e.title}`,children:(0,N.jsx)(mM,{size:18,weight:`bold`})})}),(0,N.jsxs)(hc.Dropdown,{children:[(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(bM,{size:15}),onClick:r,children:`Rename`}),(0,N.jsx)(hc.Item,{color:`bad`,leftSection:(0,N.jsx)(MM,{size:15}),onClick:i,children:`Delete`})]})]})]})})}function sP(e){return e.includes(`T`)?new Date(e):new Date(`${e.replace(` `,`T`)}Z`)}function cP(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()}var lP=[`Today`,`Yesterday`,`Previous 7 days`,`Older`];function uP(e){let t=cP(new Date),n=new Map;for(let r of e){let e=Math.floor((t-cP(sP(r.updated_at)))/864e5),i=e<=0?`Today`:e===1?`Yesterday`:e<=7?`Previous 7 days`:`Older`,a=n.get(i)??[];a.push(r),n.set(i,a)}return lP.filter(e=>n.has(e)).map(e=>({label:e,threads:n.get(e)}))}function dP(e){let t=sP(e),n=cP(new Date);return Math.floor((n-cP(t))/864e5)<=1?new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`}).format(t):new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`}).format(t)}function fP({children:e}){let{agentAvailable:t,threadID:n,threadMissing:r,newThread:i,selectThread:a,openChat:o}=xN(),s=ze(),c=Un({select:e=>e.location.pathname}),{dashboardId:l}=hn({strict:!1}),u=c===`/chat`||c.startsWith(`/chat/`),[d,f]=br(!1),[p,m]=(0,M.useState)(!1),[h,g]=(0,M.useState)(``),_=(0,M.useRef)(null),v=ie(`(max-width: 62em)`),y=(0,M.useRef)(v);y.current=v,(0,M.useEffect)(()=>{f.close()},[c]),(0,M.useEffect)(()=>{let e=e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),y.current?(m(!0),f.open()):_.current?.focusSearch())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let b={agentAvailable:t,activeThreadID:u&&!r&&c!==`/chat`?n:void 0,activeDashboardID:l,onNewChat:i,onSelectThread:a,onDeletedThread:e=>{e===n&&i()},onSelectDashboard:e=>void s({to:`/dashboards/$dashboardId`,params:{dashboardId:e},search:{}}),onCreateDashboard:()=>o(SN),onInvestigateService:e=>o(`Investigate the ${e} service. Explain its errors and latency.`)};return(0,N.jsxs)(Vo,{header:{height:52},navbar:{width:256,breakpoint:`md`,collapsed:{mobile:!0}},padding:0,children:[(0,N.jsx)(Vo.Header,{children:(0,N.jsxs)(ne,{h:`100%`,px:{base:`sm`,sm:`md`},justify:`space-between`,wrap:`nowrap`,children:[(0,N.jsxs)(ne,{gap:`sm`,wrap:`nowrap`,children:[(0,N.jsx)(is,{hiddenFrom:`md`,opened:d,onClick:()=>{m(!1),f.toggle()},size:`sm`,"aria-label":d?`Close navigation`:`Open navigation`}),(0,N.jsx)(ke,{size:`small`})]}),(0,N.jsxs)(ne,{gap:`xs`,wrap:`nowrap`,children:[(0,N.jsx)(St,{label:`Documentation`,children:(0,N.jsx)(Di,{component:`a`,href:nP.home,target:`_blank`,rel:`noopener noreferrer`,variant:`subtle`,color:`gray`,"aria-label":`Documentation`,children:(0,N.jsx)(fM,{size:17,weight:`bold`})})}),(0,N.jsx)(tP,{}),(0,N.jsx)(pP,{onError:g})]})]})}),(0,N.jsx)(Vo.Navbar,{p:`sm`,children:(0,N.jsx)(iP,{ref:_,...b})}),(0,N.jsx)(Ds,{opened:d,onClose:f.close,hiddenFrom:`md`,size:288,padding:`sm`,title:(0,N.jsx)(ke,{size:`small`}),overlayProps:{backgroundOpacity:.24,blur:1},children:(0,N.jsx)(iP,{...b,autoFocusSearch:d&&p})}),(0,N.jsxs)(Vo.Main,{children:[h&&(0,N.jsx)(Ce,{color:`bad`,m:`md`,withCloseButton:!0,onClose:()=>g(``),children:h}),e]})]})}function pP({onError:e}){let t=ze(),n=GM(),r=(n.display_name.trim()||n.email.trim()||`?`).charAt(0).toUpperCase();return(0,N.jsxs)(hc,{position:`bottom-end`,withinPortal:!0,shadow:`md`,children:[(0,N.jsx)(hc.Target,{children:(0,N.jsx)(Di,{variant:`subtle`,color:`gray`,size:`lg`,radius:`xl`,"aria-label":`${r} account menu`,children:(0,N.jsx)(Qo,{size:26,radius:`xl`,color:`brand`,children:r})})}),(0,N.jsxs)(hc.Dropdown,{children:[(0,N.jsx)(hc.Label,{children:n.email||`Signed in`}),(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(SM,{size:15}),onClick:()=>void t({to:`/settings`}),children:`Connect telemetry`}),(0,N.jsx)(hc.Divider,{}),(0,N.jsx)(hc.Item,{leftSection:(0,N.jsx)(EM,{size:15}),onClick:()=>void VM().catch(t=>e(t instanceof Error?t.message:`Sign-out failed — your session is still active.`)),children:`Sign out`})]})]})}function mP(){let{agent_available:e}=UM(),t=ze(),n=SA(),{threadId:r}=hn({strict:!1}),[i,a]=(0,M.useState)(LN),o=(0,M.useRef)(new Set),s=r??i,[c,l]=(0,M.useState)([]),[u,d]=(0,M.useState)({}),[f,p]=(0,M.useState)(``),[m,h]=(0,M.useState)(!1),[g,_]=(0,M.useState)(!1),[v,y]=(0,M.useState)(``),[b,x]=(0,M.useState)(!1),S=(0,M.useRef)(!1),[C,w]=(0,M.useState)(``),[T,ee]=(0,M.useState)(``),[E,D]=(0,M.useState)(0),O=(0,M.useRef)(null),te=(0,M.useRef)({}),ne=(0,M.useRef)(null),re=(0,M.useRef)(new Map),k=(0,M.useMemo)(()=>new bA({url:`/api/agent/runs`,threadId:s,fetch:(e,t)=>BM(e,t)}),[s]),ie=!e||f===s;function ae(){re.current.clear(),y(``)}function oe(e){return S.current||e instanceof Error&&e.name===`AbortError`}(0,M.useEffect)(()=>{let t=!0;if(l([]),te.current={},d({}),p(``),h(!1),_(!1),S.current=!1,x(!1),ae(),ee(``),!e){p(s);return}!r||o.current.has(s)?(k.setMessages([]),p(s)):BM(`/api/agent/threads/${encodeURIComponent(s)}`).then(async e=>{if(e.status===404)return null;if(!e.ok)throw Error(`Unable to load thread (${e.status})`);return e.json()}).then(e=>{if(t){if(e===null){h(!0),p(s);return}k.setMessages(e.messages??[]),l(e.messages??[]),p(s)}}).catch(()=>{t&&(O.current=null,ee(`This chat could not be restored. Start a new chat or try again.`))});let i=k.subscribe({onMessagesChanged:({messages:e})=>l([...e]),onRunInitialized:()=>{S.current=!1,x(!1),_(!0),ee(``)},onTextMessageContentEvent:({event:e})=>{e.delta&&y(``)},onToolCallStartEvent:({event:e})=>{re.current.set(e.toolCallId,wN(e.toolCallName)),y(wN(e.toolCallName))},onToolCallResultEvent:({event:e,messages:t})=>{re.current.delete(e.toolCallId),y([...re.current.values()].at(-1)??`Analyzing your system`);let r=sN(e.toolCallId,e.content,t);r&&(n.invalidateQueries({queryKey:RN}),n.invalidateQueries({queryKey:[`dashboard`,r.id]}),n.invalidateQueries({queryKey:[`dashboard-versions`,r.id]}))},onRunErrorEvent:({event:e})=>{e.code===`abort`||S.current?(ee(``),x(!0)):(console.warn(`Agent run error`,e.code),ee(EN(e.code))),_(!1),ae()},onRunFinalized:({messages:e})=>{let t=[...e];l(t),d(e=>{let n={...e};for(let e of t)e.role===`assistant`&&!n[e.id]&&(n[e.id]=Date.now());return n}),_(!1),ae(),o.current.delete(s),n.invalidateQueries({queryKey:QM})},onRunFailed:e=>{oe(e.error)?(ee(``),x(!0)):(console.error(`Agent run failed`,e),ee(EN())),_(!1),ae(),o.current.delete(s),n.invalidateQueries({queryKey:QM})}});return()=>{t=!1,i.unsubscribe(),k.abortRun()}},[k,e,n,E,s]),(0,M.useEffect)(()=>{if(!e)return;let n=e=>{let n=e.target,i=n?.matches(`input, textarea, [contenteditable='true']`);e.key===`/`&&!i&&(e.preventDefault(),r?requestAnimationFrame(()=>ne.current?.focus()):t({to:`/chat`}).then(()=>requestAnimationFrame(()=>ne.current?.focus()))),e.key===`Escape`&&n===ne.current&&(w(``),ne.current?.blur())};return window.addEventListener(`keydown`,n),()=>window.removeEventListener(`keydown`,n)},[e,t,r]);async function se(){_(!0),ee(``);try{let{context:e=[],...t}=te.current;await k.runAgent({context:e,forwardedProps:t})}catch(e){oe(e)?(ee(``),x(!0)):(console.error(`Agent run failed`,e),ee(EN())),_(!1),ae(),o.current.delete(s)}}async function ce(n,i){let a=n.trim();if(!e||!a||g||!ie||m)return;te.current={...i},r||(o.current.add(s),t({to:`/chat/$threadId`,params:{threadId:s},replace:!0}));let c={id:LN(),role:`user`,content:a};k.addMessage(c),l([...k.messages]),d(e=>({...e,[c.id]:Date.now()})),w(``),await se()}(0,M.useEffect)(()=>{let e=O.current;ie&&r&&e&&(O.current=null,ce(e.text,e.options))},[ie,r,s]);function le(e){e.preventDefault(),ce(C)}function ue(){S.current=!0,ee(``),x(!0),k.abortRun(),_(!1),ae(),o.current.delete(s)}function de(){!g&&k.messages.some(e=>e.role===`user`)&&se()}function fe(n,r){if(!e)return;let i=LN();o.current.add(i),O.current=n?{text:n,options:{...r}}:null,t({to:`/chat/$threadId`,params:{threadId:i}})}function pe(){k.abortRun(),O.current=null,te.current={},a(LN()),t({to:`/chat`})}function me(e){O.current=null,te.current={},t({to:`/chat/$threadId`,params:{threadId:e}})}function he(){D(e=>e+1)}return(0,N.jsx)(bN.Provider,{value:{agentAvailable:e,threadID:s,threadMissing:m,messages:c,messageTimes:u,ready:ie,running:g,activity:v,stopped:b,input:C,setInput:w,error:T,inputRef:ne,send:ce,submit:le,stop:ue,retry:de,reloadThread:he,openChat:fe,newThread:pe,selectThread:me},children:(0,N.jsx)(fP,{children:(0,N.jsx)(Nn,{})})})}function hP(){let e=(0,M.useMemo)(()=>new Mj,[]);return(0,N.jsx)(CA,{client:e,children:(0,N.jsx)(ZM,{children:(0,N.jsx)(mP,{})})})}var gP=xn({component:hP,notFoundComponent:()=>(0,N.jsx)(Ve,{to:`/`,replace:!0})}),_P=Sn(`/`)({component:Cn(()=>tt(()=>import(`./routes-D2AdaqvY.js`),__vite__mapDeps([0,1,2])),`component`)}),vP=Sn(`/settings`)({component:Cn(()=>tt(()=>import(`./settings-D2EYPvK1.js`),__vite__mapDeps([3,1,4,5,6])),`component`)}),yP=Sn(`/chat/`)({component:Cn(()=>tt(()=>import(`./chat.index-COFCWU9S.js`),__vite__mapDeps([7,8,1,4,9,5,10])),`component`)}),bP=Sn(`/chat/$threadId`)({component:Cn(()=>tt(()=>import(`./chat._threadId-COFCWU9S.js`),__vite__mapDeps([11,8,1,4,9,5,10])),`component`)});function xP(e){try{let t=typeof e==`string`?e:JSON.stringify(e);if(!t||t.length>4096)return;let n=typeof e==`string`?JSON.parse(e):e;if(!n||typeof n!=`object`)return;let r=n;return typeof r.panel_id!=`string`||!/^([a-z][a-z0-9_]{0,39})$/.test(r.panel_id)||r.kind!==`traces`&&r.kind!==`logs`||typeof r.from!=`string`||typeof r.to!=`string`||!Number.isFinite(Date.parse(r.from))||!Number.isFinite(Date.parse(r.to))||Date.parse(r.from)>=Date.parse(r.to)||Date.parse(r.to)-Date.parse(r.from)>2592e6||typeof r.window_from!=`string`||typeof r.window_to!=`string`||!Number.isFinite(Date.parse(r.window_from))||!Number.isFinite(Date.parse(r.window_to))||Date.parse(r.window_from)>=Date.parse(r.window_to)||Date.parse(r.window_to)-Date.parse(r.window_from)>2592e6||Date.parse(r.from)Date.parse(r.window_to)||!r.dimensions||Array.isArray(r.dimensions)||typeof r.dimensions!=`object`||Object.keys(r.dimensions).length>3||Object.values(r.dimensions).some(e=>typeof e!=`string`||e.length>500)||r.trace_id!==void 0&&(typeof r.trace_id!=`string`||r.trace_id.length>128)||r.namespace!==void 0&&(typeof r.namespace!=`string`||r.namespace.length>200)||r.bucket&&(!Number.isFinite(r.bucket.lower)||r.bucket.lower<0||r.bucket.upper!==void 0&&(!Number.isFinite(r.bucket.upper)||r.bucket.upper<=r.bucket.lower))?void 0:{panel_id:r.panel_id,kind:r.kind,from:r.from,to:r.to,window_from:r.window_from,window_to:r.window_to,dimensions:r.dimensions,trace_id:r.trace_id,namespace:r.namespace,bucket:r.bucket}}catch{return}}function SP(e,t,n){if(!e.drill&&e.viz!==`service_map`&&!n.trace_id||t.from_ms===void 0||t.to_ms===void 0)return;let r=t.from_ms,i=t.to_ms;if(n.from!==void 0&&n.to!==void 0&&(r=Math.max(r,Date.parse(n.from)),i=Math.min(i,Date.parse(n.to))),n.time!==void 0&&!n.trace_id){let e=/^(\d+)(s|m|h|d)$/.exec(t.interval??``),a=e?Number(e[1])*{s:1e3,m:6e4,h:36e5,d:864e5}[e[2]]:6e4;r=Math.max(r,n.time),i=Math.min(i,n.time+a)}return xP(JSON.stringify({panel_id:e.id,kind:n.trace_id||e.viz===`service_map`?`traces`:e.drill,from:n.from&&Date.parse(n.from)===r?n.from:new Date(r).toISOString(),to:n.to&&Date.parse(n.to)===i?n.to:new Date(i).toISOString(),window_from:new Date(t.from_ms).toISOString(),window_to:new Date(t.to_ms).toISOString(),dimensions:n.dimensions,trace_id:n.trace_id,namespace:n.namespace,bucket:n.bucket}))}function CP(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))for(let e of Array.isArray(r)?r:[r]){if(e===void 0)continue;let r=typeof e==`string`&&/^[{"]/.test(e);t.append(n,r||typeof e==`object`&&e?JSON.stringify(e):String(e))}let n=t.toString();return n?`?${n}`:``}function wP(e){let t=Object.create(null),n=e=>{if(e.startsWith(`{`)||e.startsWith(`"`))try{let t=JSON.parse(e);if(typeof t==`string`)return/^[{"]/.test(t)?t:e;if(typeof t==`object`&&t&&!Array.isArray(t))return t}catch{}return e},r=new URLSearchParams(e);for(let e of new Set(r.keys())){let i=r.getAll(e).map(n);t[e]=i.length===1?i[0]:i}return t}var TP=[`5m`,`15m`,`1h`,`3h`,`6h`,`12h`,`24h`,`2d`,`7d`,`30d`],EP=[`off`,`10s`,`30s`,`1m`,`5m`],DP=e=>{if(typeof e!=`string`||!/^\d{4}-\d{2}-\d{2}[Tt](?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(e)||Number.isNaN(Date.parse(e)))return!1;let[t,n,r]=e.slice(0,10).split(`-`).map(Number),i=new Date(0);return i.setUTCFullYear(t,n-1,r),i.setUTCHours(0,0,0,0),i.getUTCFullYear()===t&&i.getUTCMonth()===n-1&&i.getUTCDate()===r},OP=e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`?String(e):void 0;function kP(e){let t={};typeof e.range==`string`&&TP.includes(e.range)?t.range=e.range:DP(e.from)&&DP(e.to)&&Date.parse(e.from)typeof e==`string`)&&(i[e]=t)}}else{let t=OP(n);t!==void 0&&(i[e]=t)}}}Object.keys(i).length>0&&(t.vars=i);let a=xP(e.drill);return a&&(t.drill=JSON.stringify(a)),t}function AP(e){let t={};e.drill&&(t.drill=JSON.parse(e.drill)),e.range&&(t.range=e.range),e.from&&e.to&&(t.from=e.from,t.to=e.to),e.compare&&(t.compare=e.compare),e.view&&(t.view=e.view),e.edit&&(t.edit=e.edit);for(let[n,r]of Object.entries(e.vars??{}))t[`var-${n}`]=Array.isArray(r)?{values:r}:r;return t}function jP(e,t){let n=new URL(e);return n.search=CP(AP({...kP(wP(n.search)),drill:JSON.stringify(t)})),n.href}function MP(e,t){let n=e.time.refresh??`30s`;return t.from&&t.to?{from:t.from,to:t.to,refresh:n}:t.range?{range:t.range,refresh:n}:{...e.time,refresh:n}}var NP=Sn(`/dashboards/`)({component:Cn(()=>tt(()=>import(`./dashboards.index-CZW2eWRj.js`),__vite__mapDeps([12,1,2,13,4,9,5,10,6])),`component`),validateSearch:e=>AP(kP(e))}),PP=Sn(`/dashboards/$dashboardId`)({component:Cn(()=>tt(()=>import(`./dashboards._dashboardId-BMU7vUrs.js`),__vite__mapDeps([14,1,2,13,4,9,5,10,6])),`component`),validateSearch:e=>AP(kP(e))}),FP=_P.update({id:`/`,path:`/`,getParentRoute:()=>gP}),IP=vP.update({id:`/settings`,path:`/settings`,getParentRoute:()=>gP}),LP=yP.update({id:`/chat/`,path:`/chat/`,getParentRoute:()=>gP}),RP=bP.update({id:`/chat/$threadId`,path:`/chat/$threadId`,getParentRoute:()=>gP}),zP=NP.update({id:`/dashboards/`,path:`/dashboards/`,getParentRoute:()=>gP}),BP={IndexRoute:FP,SettingsRoute:IP,ChatThreadIdRoute:RP,DashboardsDashboardIdRoute:PP.update({id:`/dashboards/$dashboardId`,path:`/dashboards/$dashboardId`,getParentRoute:()=>gP}),ChatIndexRoute:LP,DashboardsIndexRoute:zP},VP=zn({routeTree:gP._addFileChildren(BP)._addFileTypes(),parseSearch:wP,stringifySearch:CP,defaultPreload:`intent`,scrollRestoration:!0}),HP=[`#fafafa`,`#e6e4de`,`#bfbdb6`,`#8b8e99`,`#565b69`,`#1d2433`,`#131721`,`#0b0e14`,`#080a10`,`#05070b`],UP=[`#f3ecfd`,`#ece3fb`,`#dcc9f7`,`#d2a6ff`,`#bf94ec`,`#a97ce0`,`#9163d6`,`#7c4dcc`,`#5b32a3`,`#40236f`],WP=[`#eefbe6`,`#dcf7cc`,`#c2f0a6`,`#a5e880`,`#8fe06c`,`#7fd962`,`#66c04b`,`#4f9c3a`,`#3b7a2c`,`#2a5a1f`],GP=[`#fff5e6`,`#ffe9c9`,`#ffd79b`,`#ffc571`,`#ffbc62`,`#ffb454`,`#ef9c33`,`#c87d21`,`#9c5f16`,`#74460f`],KP=[`#fdecee`,`#fbd9dc`,`#f8b6bc`,`#f59099`,`#f37d87`,`#f26d78`,`#e04d5a`,`#c03642`,`#96262f`,`#6f1a21`],qP=[`#e8f6ff`,`#ccebff`,`#a3daff`,`#7dcbff`,`#66c5ff`,`#59c2ff`,`#33a7e6`,`#1e86bd`,`#146694`,`#0d4a6d`],JP={dark:{text:`#bfbdb6`,muted:`#8b8e99`,grid:`#1d2433`,surface:`#131721`,border:`#626777`},light:{text:`#4a5058`,muted:`#6b7280`,grid:`#eceef0`,surface:`#fcfcfc`,border:`#8c939d`}},YP={dark:[`#3987e5`,`#d95926`,`#199e70`,`#9085e9`,`#c98500`,`#d55181`],light:[`#2a78d6`,`#eb6834`,`#1baf7a`,`#4a3aa7`,`#eda100`,`#e87ba4`]},XP={micro:11,small:12,body:14,title:16,section:22,page:32},ZP={display:`"Geist Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,body:`"Geist Variable", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`},QP={brand:UP,ok:WP,warn:GP,bad:KP,info:qP},$P={light:7,dark:5};function eF(e){let t=e.replace(`#`,``),n=t.length===3?[...t].map(e=>e+e).join(``):t,r=e=>{let t=parseInt(n.slice(e,e+2),16)/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4};return .2126*r(0)+.7152*r(2)+.0722*r(4)}function tF(e){let t=eF(e),n=1.05/(t+.05);return(t+.05)/.05>n?`var(--mantine-color-black)`:`var(--mantine-color-white)`}function nF(e){return Object.fromEntries(Object.entries(QP).map(([t,n])=>[`--fanout-color-${t}-contrast`,tF(n[$P[e]])]))}function rF(e){return t=>{let n=t.color??oF.primaryColor,r=e({...t,color:n}),i=t.variant===`filled`||t.variant===void 0;return t.autoContrast===!1||!i||!Object.hasOwn(QP,n)?r:{...r,color:`var(--fanout-color-${n}-contrast)`}}}var iF=.25,aF={xs:9,sm:10,md:11,lg:13,xl:16},oF={primaryColor:`brand`,primaryShade:$P,autoContrast:!0,luminanceThreshold:iF,colors:{dark:HP,brand:UP,ok:WP,warn:GP,bad:KP,info:qP},defaultRadius:`md`,fontFamily:ZP.body,fontFamilyMonospace:ZP.display,headings:{fontFamily:ZP.body,fontWeight:`600`},cursorType:`pointer`,components:{Tabs:{styles:(e,t)=>({tab:lF(t.color,`--tabs-text-color`)})},Pagination:{styles:(e,t)=>({control:lF(t.color,`--pagination-active-color`)})},Badge:{vars:(e,t)=>({root:cF(t.size)})},Menu:{defaultProps:{withInitialFocusPlaceholder:!1}},Drawer:{defaultProps:{closeButtonProps:{"aria-label":`Close`}}},Modal:{defaultProps:{closeButtonProps:{"aria-label":`Close`}}}}},sF=()=>({variables:{"--mantine-color-error":`var(--mantine-color-bad-filled)`},light:{"--mantine-color-dimmed":JP.light.muted,...nF(`light`)},dark:nF(`dark`)});function cF(e){let t=aF[e??`md`];return t===void 0||t>=XP.micro?{}:{"--badge-fz":`${XP.micro/16}rem`}}function lF(e,t){return!e||e===oF.primaryColor?{[t]:`var(--fanout-color-${oF.primaryColor}-contrast)`}:{}}var uF=rF(ee),dF=Xr({...oF,variantColorResolver:uF});(0,Kc.createRoot)(document.getElementById(`root`)).render((0,N.jsx)(M.StrictMode,{children:(0,N.jsx)(Yr,{theme:dF,defaultColorScheme:`auto`,cssVariablesResolver:sF,children:(0,N.jsx)(Hn,{router:VP})})}));export{mM as $,Ir as $t,JN as A,U as At,xN as B,Rc as Bt,RN as C,K as Ct,GN as D,Ub as Dt,eP as E,Ob as Et,QN as F,vy as Ft,eN as G,ss as Gt,_N as H,hc as Ht,KN as I,g_ as It,GM as J,eo as Jt,tN as K,ts as Kt,SN as L,f_ as Lt,$N as M,Sb as Mt,YN as N,Yy as Nt,HN as O,px as Ot,qN as P,wy as Pt,bM as Q,Qr as Qt,TN as R,d_ as Rt,nP as S,q as St,XN as T,fb as Tt,pN as U,As as Ut,dN as V,jc as Vt,nN as W,Ds as Wt,FM as X,yi as Xt,BM as Y,Di as Yt,MM as Z,ci as Zt,TP as _,hb as _t,JP as a,ln as an,OA as at,SP as b,Pb as bt,WP as c,SA as ct,GP as d,db as dt,kr as en,Gj as et,PP as f,Rb as ft,kP as g,Eb as gt,MP as h,G as ht,UP as i,Gn as in,IA as it,ZN as j,Ab as jt,WN as k,Ib as kt,YP as l,Vy as lt,jP as m,_b as mt,eF as n,tr as nn,ij as nt,ZP as o,Qt as on,BA as ot,NP as p,yb as pt,$M as q,Ho as qt,KP as r,Xn as rn,ej as rt,qP as s,tn as sn,XA as st,tF as t,yr as tn,Oj as tt,XP as u,By as ut,EP as v,Mb as vt,UN as w,wb as wt,xP as x,cx as xt,AP as y,Gy as yt,DN as z,Zf as zt}; \ No newline at end of file diff --git a/internal/ui/dist/assets/mcp-app-frame-RnhKpud9.js b/internal/ui/dist/assets/mcp-app-frame-BzM2b2mm.js similarity index 99% rename from internal/ui/dist/assets/mcp-app-frame-RnhKpud9.js rename to internal/ui/dist/assets/mcp-app-frame-BzM2b2mm.js index b590cb80..22518301 100644 --- a/internal/ui/dist/assets/mcp-app-frame-RnhKpud9.js +++ b/internal/ui/dist/assets/mcp-app-frame-BzM2b2mm.js @@ -1,4 +1,4 @@ -import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{C as r,d as i,f as a,p as o,u as s,y as c}from"./brand-DUaZkIz1.js";import{n as l}from"./chat-0Bi74QKL.js";import{$t as u,At as d,Ct as f,Dt as p,Et as m,Ft as h,It as g,Lt as _,Mt as v,Nt as y,Ot as b,Pt as ee,Rt as x,St as S,Tt as C,Y as w,Zt as T,_t as E,bt as te,dt as ne,ft as D,gt as O,ht as re,jt as k,kt as A,lt as ie,mt as ae,pt as oe,ut as se,vt as ce,wt as le,xt as ue,yt as de,zt as fe}from"./index-eh4vL-r5.js";var pe={invalid_type:`invalid_type`,too_big:`too_big`,too_small:`too_small`,invalid_format:`invalid_format`,not_multiple_of:`not_multiple_of`,unrecognized_keys:`unrecognized_keys`,invalid_union:`invalid_union`,invalid_key:`invalid_key`,invalid_element:`invalid_element`,invalid_value:`invalid_value`,custom:`custom`},me;me||={};function he(e){return x(se,e)}function ge(e){return _(ie,e)}function _e(e){return g(ne,e)}function j(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:void 0}function M(e,t){if(!Array.isArray(e))return[];let n=new Set(t);return e.filter(e=>{if(typeof e!=`string`||/[\s;'\"]/.test(e))return!1;let t=e.match(/^([a-z]+):\/\/([^/]+)$/i);return!!(t&&n.has(t[1].toLowerCase()))})}function ve(e){let t=j(j(j(e)?.ui)?.csp),n=M(t?.connectDomains,[`http`,`https`,`ws`,`wss`]),r=M(t?.resourceDomains,[`http`,`https`]),i=M(t?.frameDomains,[`http`,`https`]),a=M(t?.baseUriDomains,[`http`,`https`]),o=r.length?` ${r.join(` `)}`:``,s=[`default-src 'none'`,`worker-src blob:`,`script-src 'self' 'unsafe-inline'${o}`,`style-src 'self' 'unsafe-inline'${o}`,`img-src 'self' data:${o}`,`media-src 'self' data:${o}`,`font-src 'self' data:${o}`,`connect-src ${n.length?n.join(` `):`'none'`}`];return i.length&&s.push(`frame-src ${i.join(` `)}`),a.length&&s.push(`base-uri ${a.join(` `)}`),`${s.join(`; `)};`}var ye=Object.create,be=Object.defineProperty,N=Object.getOwnPropertyDescriptor,xe=Object.getOwnPropertyNames,P=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty,Ce=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),we=(e,t)=>{let n={};for(var r in e)be(n,r,{get:e[r],enumerable:!0});return t&&be(n,Symbol.toStringTag,{value:`Module`}),n},Te=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=xe(t),a=0,o=i.length,s;at[e]).bind(null,s),enumerable:!(r=N(t,s))||r.enumerable});return e},Ee=(e,t,n)=>(n=e==null?{}:ye(P(e)),Te(t||!e||!e.__esModule?be(n,`default`,{value:e,enumerable:!0}):n,e)),De=new Set([`https://json-schema.org/draft/2020-12/schema`,`http://json-schema.org/draft/2020-12/schema`]),Oe=new Set([`https://json-schema.org/draft/2019-09/schema`,`http://json-schema.org/draft/2019-09/schema`]),ke=new Set([`https://json-schema.org/draft-07/schema`,`http://json-schema.org/draft-07/schema`]),Ae=new Set([`https://json-schema.org/draft-06/schema`,`http://json-schema.org/draft-06/schema`]);function je(e){return typeof e==`string`&&Oe.has(e.replace(/#$/,``))}function Me(e,t){if(!(`$schema`in e)||typeof e.$schema!=`string`)return`2020-12`;let n=e.$schema.replace(/#$/,``);if(De.has(n))return`2020-12`;if(Oe.has(n))return`2019-09`;if(ke.has(n)||Ae.has(n))return`draft-7`;throw Error(`JSON Schema declares an unsupported dialect ("$schema": "${e.$schema.slice(0,200)}"). The default validator supports JSON Schema 2020-12, 2019-09, draft-07, and draft-06; ${t}`)}var Ne=`2025-11-25`,Pe=[Ne,`2025-06-18`,`2025-03-26`,`2024-11-05`,`2024-10-07`],Fe=`io.modelcontextprotocol/related-task`,Ie=`io.modelcontextprotocol/protocolVersion`,Le=`io.modelcontextprotocol/clientInfo`,Re=`io.modelcontextprotocol/serverInfo`,ze=`io.modelcontextprotocol/clientCapabilities`,Be=`io.modelcontextprotocol/subscriptionId`,Ve=`io.modelcontextprotocol/logLevel`,He=ue(()=>k([d(),C(),E(),oe(),A(d(),He),O(He)])),F=A(d(),He),Ue=O(He),We=k([d(),C().int()]),Ge=d(),Ke=m({ttl:C().optional()}),qe=m({taskId:d()}),Je=f({progressToken:We.optional(),[Fe]:qe.optional()}),I=m({_meta:Je.optional()}),Ye=I.extend({task:Ke.optional()}),L=m({method:d(),params:I.loose().optional()}),R=m({_meta:Je.optional()}),z=m({method:d(),params:R.loose().optional()}),Xe=f({get[Re](){return H.optional().catch(void 0)}}),B=f({_meta:Xe.optional()}),Ze=k([d(),C().int()]),Qe=m({jsonrpc:S(`2.0`),id:Ze,...L.shape}).strict(),$e=m({jsonrpc:S(`2.0`),...z.shape}).strict(),V=m({jsonrpc:S(`2.0`),id:Ze,result:B}).strict(),et=m({jsonrpc:S(`2.0`),id:Ze.optional(),error:m({code:C().int(),message:d(),data:v().optional()})}).strict(),tt=k([Qe,$e,V,et]),nt=k([V,et]),rt=B.strict(),it=R.extend({requestId:Ze.optional(),reason:d().optional()}),at=z.extend({method:S(`notifications/cancelled`),params:it}),ot=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),st=m({icons:O(ot).optional()}),ct=m({name:d(),title:d().optional()}),H=ct.extend({...ct.shape,...st.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),lt=te(m({applyDefaults:E().optional()}),F),ut=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:lt.optional(),url:F.optional()}),F.optional())),dt=f({list:F.optional(),cancel:F.optional(),requests:f({sampling:f({createMessage:F.optional()}).optional(),elicitation:f({create:F.optional()}).optional()}).optional()}),ft=f({list:F.optional(),cancel:F.optional(),requests:f({tools:f({call:F.optional()}).optional()}).optional()}),pt=m({experimental:A(d(),F).optional(),sampling:m({context:F.optional(),tools:F.optional()}).optional(),elicitation:ut.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:dt.optional(),extensions:A(d(),F).optional()}),mt=I.extend({protocolVersion:d(),capabilities:pt,clientInfo:H}),ht=L.extend({method:S(`initialize`),params:mt}),gt=m({experimental:A(d(),F).optional(),logging:F.optional(),completions:F.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:ft.optional(),extensions:A(d(),F).optional()}),_t=B.extend({protocolVersion:d(),capabilities:gt,serverInfo:H,instructions:d().optional()}),vt=z.extend({method:S(`notifications/initialized`),params:R.optional()}),yt=L.extend({method:S(`server/discover`),params:I.optional()}),bt=B.extend({supportedVersions:O(d()),capabilities:gt,instructions:d().optional()}),xt=L.extend({method:S(`ping`),params:I.optional()}),St=m({progress:C(),total:p(C()),message:p(d())}),Ct=m({...R.shape,...St.shape,progressToken:We}),wt=z.extend({method:S(`notifications/progress`),params:Ct}),Tt=I.extend({cursor:Ge.optional()}),Et=L.extend({params:Tt.optional()}),Dt=B.extend({nextCursor:Ge.optional()}),Ot=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),kt=Ot.extend({text:d()}),At=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),jt=Ot.extend({blob:At}),Mt=D([`user`,`assistant`]),Nt=m({audience:O(Mt).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),Pt=m({...ct.shape,...st.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:Nt.optional(),_meta:p(f({}))}),Ft=m({...ct.shape,...st.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:Nt.optional(),_meta:p(f({}))}),It=Et.extend({method:S(`resources/list`)}),Lt=Dt.extend({resources:O(Pt)}),U=Et.extend({method:S(`resources/templates/list`)}),W=Dt.extend({resourceTemplates:O(Ft)}),Rt=I.extend({uri:d()}),zt=Rt,Bt=L.extend({method:S(`resources/read`),params:zt}),Vt=B.extend({contents:O(k([kt,jt]))}),Ht=z.extend({method:S(`notifications/resources/list_changed`),params:R.optional()}),Ut=Rt,Wt=L.extend({method:S(`resources/subscribe`),params:Ut}),Gt=Rt,Kt=L.extend({method:S(`resources/unsubscribe`),params:Gt}),qt=m({toolsListChanged:E().optional(),promptsListChanged:E().optional(),resourcesListChanged:E().optional(),resourceSubscriptions:O(d()).optional()}),Jt=I.extend({notifications:qt}),Yt=L.extend({method:S(`subscriptions/listen`),params:Jt}),Xt=R.extend({notifications:qt}),Zt=z.extend({method:S(`notifications/subscriptions/acknowledged`),params:Xt}),Qt=Xe.extend({[Be]:Ze}),$t=B.extend({_meta:Qt}),en=R.extend({uri:d()}),tn=z.extend({method:S(`notifications/resources/updated`),params:en}),G=m({name:d(),description:p(d()),required:p(E())}),nn=m({...ct.shape,...st.shape,description:p(d()),arguments:p(O(G)),_meta:p(f({}))}),rn=Et.extend({method:S(`prompts/list`)}),an=Dt.extend({prompts:O(nn)}),on=I.extend({name:d(),arguments:A(d(),d()).optional()}),sn=L.extend({method:S(`prompts/get`),params:on}),cn=m({type:S(`text`),text:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),K=m({type:S(`image`),data:At,mimeType:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),ln=m({type:S(`audio`),data:At,mimeType:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),un=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),dn=m({type:S(`resource`),resource:k([kt,jt]),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),fn=Pt.extend({type:S(`resource_link`)}),pn=k([cn,K,ln,fn,dn]),mn=m({role:Mt,content:pn}),hn=B.extend({description:d().optional(),messages:O(mn)}),gn=z.extend({method:S(`notifications/prompts/list_changed`),params:R.optional()}),_n=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),vn=m({taskSupport:D([`required`,`optional`,`forbidden`]).optional()}),yn=m({...ct.shape,...st.shape,description:d().optional(),inputSchema:m({type:S(`object`),properties:A(d(),He).optional(),required:O(d()).optional()}).catchall(v()),outputSchema:f({$schema:d().optional()}).optional(),annotations:_n.optional(),execution:vn.optional(),_meta:A(d(),v()).optional()}),bn=Et.extend({method:S(`tools/list`)}),xn=Dt.extend({tools:O(yn)}),Sn=B.extend({content:O(pn).default([]),structuredContent:v().optional(),isError:E().optional()}),Cn=Sn.or(B.extend({toolResult:v()})),wn=Ye.extend({name:d(),arguments:A(d(),v()).optional()}),Tn=L.extend({method:S(`tools/call`),params:wn}),En=z.extend({method:S(`notifications/tools/list_changed`),params:R.optional()}),Dn=m({autoRefresh:E().default(!0),debounceMs:C().int().nonnegative().default(300)}),On=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),kn=I.extend({level:On}),An=L.extend({method:S(`logging/setLevel`),params:kn}),jn=R.extend({level:On,logger:d().optional(),data:v()}),Mn=z.extend({method:S(`notifications/message`),params:jn}),Nn=m({name:d().optional()}),Pn=m({hints:O(Nn).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),Fn=m({mode:D([`auto`,`required`,`none`]).optional()}),In=m({type:S(`tool_result`),toolUseId:d().describe(`The unique identifier for the corresponding tool call.`),content:O(pn),structuredContent:v().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),Ln=ce(`type`,[cn,K,ln]),Rn=ce(`type`,[cn,K,ln,un,In]),zn=m({role:Mt,content:k([Rn,O(Rn)]),_meta:A(d(),v()).optional()}),Bn=Ye.extend({messages:O(zn),modelPreferences:Pn.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:F.optional(),tools:O(yn).optional(),toolChoice:Fn.optional()}),Vn=L.extend({method:S(`sampling/createMessage`),params:Bn}),Hn=B.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`]).or(d())),role:Mt,content:Ln}),Un=B.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`,`toolUse`]).or(d())),role:Mt,content:k([Rn,O(Rn)])}),Wn=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),Gn=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Kn=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),qn=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Jn=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Yn=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),Xn=k([qn,Jn]),Zn=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),Qn=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),$n=k([Zn,Qn]),er=k([Yn,Xn,$n]),tr=k([er,Wn,Gn,Kn]),nr=Ye.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),tr),required:O(d()).optional()}).catchall(v())}),rr=Ye.extend({mode:S(`url`),message:d(),elicitationId:d(),url:d().url()}),ir=k([nr,rr]),ar=L.extend({method:S(`elicitation/create`),params:ir}),or=R.extend({elicitationId:d()}),sr=z.extend({method:S(`notifications/elicitation/complete`),params:or}),cr=B.extend({action:D([`accept`,`decline`,`cancel`]),content:b(e=>e===null?void 0:e,A(d(),k([d(),C(),E(),O(d())])).optional())}),lr=m({type:S(`ref/resource`),uri:d()}),ur=m({type:S(`ref/prompt`),name:d()}),dr=I.extend({ref:k([ur,lr]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()}),fr=L.extend({method:S(`completion/complete`),params:dr}),pr=B.extend({completion:f({values:O(d()).max(100),total:p(C().int()),hasMore:p(E())})}),mr=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),hr=L.extend({method:S(`roots/list`),params:I.optional()}),gr=B.extend({roots:O(mr)}),_r=z.extend({method:S(`notifications/roots/list_changed`),params:R.optional()}),vr=f({ttl:C().optional(),pollInterval:C().optional()}),yr=D([`working`,`input_required`,`completed`,`failed`,`cancelled`]),br=m({taskId:d(),status:yr,ttl:k([C(),oe()]),createdAt:d(),lastUpdatedAt:d(),pollInterval:p(C()),statusMessage:p(d())}),xr=B.extend({task:br}),Sr=R.merge(br),Cr=z.extend({method:S(`notifications/tasks/status`),params:Sr}),wr=L.extend({method:S(`tasks/get`),params:I.extend({taskId:d()})}),Tr=B.merge(br),Er=L.extend({method:S(`tasks/result`),params:I.extend({taskId:d()})}),Dr=B.loose(),Or=Et.extend({method:S(`tasks/list`)}),kr=Dt.extend({tasks:O(br)}),Ar=L.extend({method:S(`tasks/cancel`),params:I.extend({taskId:d()})}),jr=B.merge(br),Mr=k([xt,ht,yt,fr,An,sn,rn,It,U,Bt,Wt,Kt,Yt,Tn,bn]),Nr=k([at,wt,vt,_r]),Pr=k([rt,Hn,Un,cr,gr]),Fr=k([xt,Vn,ar,hr]),Ir=k([at,wt,Mn,tn,Ht,En,gn,Zt,sr]),Lr=k([rt,_t,bt,pr,hn,an,Lt,W,Vt,Sn,xn,$t]),q=y().superRefine((e,t)=>{if(!URL.canParse(e))return t.addIssue({code:pe.custom,message:`URL must be parseable`,fatal:!0}),fe}).refine(e=>{let t=new URL(e);return t.protocol!==`javascript:`&&t.protocol!==`data:`&&t.protocol!==`vbscript:`},{message:`URL cannot use javascript:, data:, or vbscript: scheme`}),Rr=f({resource:d().url(),authorization_servers:O(q).optional(),jwks_uri:d().url().optional(),scopes_supported:O(d()).optional(),bearer_methods_supported:O(d()).optional(),resource_signing_alg_values_supported:O(d()).optional(),resource_name:d().optional(),resource_documentation:d().optional(),resource_policy_uri:d().url().optional(),resource_tos_uri:d().url().optional(),tls_client_certificate_bound_access_tokens:E().optional(),authorization_details_types_supported:O(d()).optional(),dpop_signing_alg_values_supported:O(d()).optional(),dpop_bound_access_tokens_required:E().optional()}),zr=f({issuer:d(),authorization_endpoint:q,token_endpoint:q,registration_endpoint:q.optional(),scopes_supported:O(d()).optional(),response_types_supported:O(d()),response_modes_supported:O(d()).optional(),grant_types_supported:O(d()).optional(),token_endpoint_auth_methods_supported:O(d()).optional(),token_endpoint_auth_signing_alg_values_supported:O(d()).optional(),service_documentation:q.optional(),revocation_endpoint:q.optional(),revocation_endpoint_auth_methods_supported:O(d()).optional(),revocation_endpoint_auth_signing_alg_values_supported:O(d()).optional(),introspection_endpoint:d().optional(),introspection_endpoint_auth_methods_supported:O(d()).optional(),introspection_endpoint_auth_signing_alg_values_supported:O(d()).optional(),code_challenge_methods_supported:O(d()).optional(),client_id_metadata_document_supported:E().optional(),authorization_response_iss_parameter_supported:E().optional().catch(void 0),dpop_signing_alg_values_supported:O(d()).optional()}),Br=f({issuer:d(),authorization_endpoint:q,token_endpoint:q,userinfo_endpoint:q.optional(),jwks_uri:q,registration_endpoint:q.optional(),scopes_supported:O(d()).optional(),response_types_supported:O(d()),response_modes_supported:O(d()).optional(),grant_types_supported:O(d()).optional(),acr_values_supported:O(d()).optional(),subject_types_supported:O(d()),id_token_signing_alg_values_supported:O(d()),id_token_encryption_alg_values_supported:O(d()).optional(),id_token_encryption_enc_values_supported:O(d()).optional(),userinfo_signing_alg_values_supported:O(d()).optional(),userinfo_encryption_alg_values_supported:O(d()).optional(),userinfo_encryption_enc_values_supported:O(d()).optional(),request_object_signing_alg_values_supported:O(d()).optional(),request_object_encryption_alg_values_supported:O(d()).optional(),request_object_encryption_enc_values_supported:O(d()).optional(),token_endpoint_auth_methods_supported:O(d()).optional(),token_endpoint_auth_signing_alg_values_supported:O(d()).optional(),display_values_supported:O(d()).optional(),claim_types_supported:O(d()).optional(),claims_supported:O(d()).optional(),service_documentation:d().optional(),claims_locales_supported:O(d()).optional(),ui_locales_supported:O(d()).optional(),claims_parameter_supported:E().optional(),request_parameter_supported:E().optional(),request_uri_parameter_supported:E().optional(),require_request_uri_registration:E().optional(),op_policy_uri:q.optional(),op_tos_uri:q.optional(),client_id_metadata_document_supported:E().optional(),authorization_response_iss_parameter_supported:E().optional().catch(void 0)}),Vr=m({...Br.shape,...zr.pick({code_challenge_methods_supported:!0}).shape}),Hr=m({access_token:d(),id_token:d().optional(),token_type:d(),expires_in:_e().optional(),scope:d().optional(),refresh_token:d().optional(),issuer:d().optional().catch(void 0)}).strip(),Ur=m({issued_token_type:S(`urn:ietf:params:oauth:token-type:id-jag`),access_token:d(),token_type:d().optional(),expires_in:C().optional(),scope:d().optional()}).strip(),Wr=m({error:d(),error_description:d().optional(),error_uri:d().optional()}),Gr=q.optional().or(S(``).transform(()=>void 0)),Kr=m({redirect_uris:O(q),token_endpoint_auth_method:d().optional(),grant_types:O(d()).optional(),response_types:O(d()).optional(),application_type:d().optional(),client_name:d().optional(),client_uri:q.optional(),logo_uri:Gr,scope:d().optional(),contacts:O(d()).optional(),tos_uri:Gr,policy_uri:d().optional(),jwks_uri:q.optional(),jwks:re().optional(),software_id:d().optional(),software_version:d().optional(),software_statement:d().optional()}).strip(),qr=m({client_id:d(),client_secret:d().optional(),client_id_issued_at:C().optional(),client_secret_expires_at:C().optional(),issuer:d().optional().catch(void 0)}).strip(),Jr=Kr.merge(qr),Yr=m({error:d(),error_description:d().optional()}).strip(),Xr=m({token:d(),token_type_hint:d().optional()}).strip(),Zr=Symbol.for(`mcp.sdk.errorBrands`);function Qr(e,t){let n=new Set,r=t;for(;typeof r==`function`;){let e=r.mcpBrand;Object.prototype.hasOwnProperty.call(r,`mcpBrand`)&&typeof e==`string`&&n.add(e),r=Object.getPrototypeOf(r)}n.size!==0&&Object.defineProperty(e,Zr,{value:n,enumerable:!1,configurable:!0})}function $r(e,t){try{if(typeof t==`object`&&t&&Object.prototype.hasOwnProperty.call(e,`mcpBrand`)&&typeof e.mcpBrand==`string`&&Object.prototype.hasOwnProperty.call(t,Zr)){let n=t[Zr];if(n&&typeof n.has==`function`&&n.has(e.mcpBrand))return!0}}catch{}return Function.prototype[Symbol.hasInstance].call(e,t)}var ei=function(e){return e.InvalidRequest=`invalid_request`,e.InvalidClient=`invalid_client`,e.InvalidGrant=`invalid_grant`,e.UnauthorizedClient=`unauthorized_client`,e.UnsupportedGrantType=`unsupported_grant_type`,e.InvalidScope=`invalid_scope`,e.AccessDenied=`access_denied`,e.ServerError=`server_error`,e.TemporarilyUnavailable=`temporarily_unavailable`,e.UnsupportedResponseType=`unsupported_response_type`,e.UnsupportedTokenType=`unsupported_token_type`,e.InvalidToken=`invalid_token`,e.MethodNotAllowed=`method_not_allowed`,e.TooManyRequests=`too_many_requests`,e.InvalidClientMetadata=`invalid_client_metadata`,e.InvalidRedirectUri=`invalid_redirect_uri`,e.InsufficientScope=`insufficient_scope`,e.InvalidTarget=`invalid_target`,e.InvalidDpopProof=`invalid_dpop_proof`,e.UseDpopNonce=`use_dpop_nonce`,e}({}),ti=class e extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.OAuthError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n){super(t),this.code=e,this.errorUri=n,this.name=`OAuthError`,Qr(this,new.target)}toResponseObject(){let e={error:this.code,error_description:this.message};return this.errorUri&&(e.error_uri=this.errorUri),e}static fromResponse(t){return new e(t.error,t.error_description??t.error,t.error_uri)}},J=function(e){return e.NotConnected=`NOT_CONNECTED`,e.AlreadyConnected=`ALREADY_CONNECTED`,e.NotInitialized=`NOT_INITIALIZED`,e.CapabilityNotSupported=`CAPABILITY_NOT_SUPPORTED`,e.RequestTimeout=`REQUEST_TIMEOUT`,e.ConnectionClosed=`CONNECTION_CLOSED`,e.SendFailed=`SEND_FAILED`,e.InvalidResult=`INVALID_RESULT`,e.UnsupportedResultType=`UNSUPPORTED_RESULT_TYPE`,e.InputRequiredRoundsExceeded=`INPUT_REQUIRED_ROUNDS_EXCEEDED`,e.ListPaginationExceeded=`LIST_PAGINATION_EXCEEDED`,e.MethodNotSupportedByProtocolVersion=`METHOD_NOT_SUPPORTED_BY_PROTOCOL_VERSION`,e.EraNegotiationFailed=`ERA_NEGOTIATION_FAILED`,e.ClientHttpNotImplemented=`CLIENT_HTTP_NOT_IMPLEMENTED`,e.ClientHttpAuthentication=`CLIENT_HTTP_AUTHENTICATION`,e.ClientHttpForbidden=`CLIENT_HTTP_FORBIDDEN`,e.ClientHttpUnexpectedContent=`CLIENT_HTTP_UNEXPECTED_CONTENT`,e.ClientHttpFailedToOpenStream=`CLIENT_HTTP_FAILED_TO_OPEN_STREAM`,e.ClientHttpFailedToTerminateSession=`CLIENT_HTTP_FAILED_TO_TERMINATE_SESSION`,e}({}),Y=class extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.SdkError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n,r){super(t,r),this.code=e,this.data=n,this.name=`SdkError`,Qr(this,new.target)}},ni=class extends Y{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.SdkHttpError`})}constructor(e,t,n,r){super(e,t,n,r),this.name=`SdkHttpError`}get status(){return this.data.status}get statusText(){return this.data.statusText}};function ri(e){let t=typeof e==`string`?new URL(e):new URL(e.href);return t.hash=``,t}function ii(e){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t={...e};return delete t.issuer,t}function ai({requestedResource:e,configuredResource:t}){let n=typeof e==`string`?new URL(e):new URL(e.href),r=typeof t==`string`?new URL(t):new URL(t.href);if(n.origin!==r.origin||n.pathname.length=oi}function li(e){return e.filter(e=>!ci(e))}function ui(e){return e.filter(e=>ci(e))}function di(e){let t=e.structuredContent;return t===void 0||typeof t==`object`&&t&&!Array.isArray(t)||(e.content?.some(e=>e.type===`text`)??!1)?e:{...e,content:[...e.content??[],{type:`text`,text:JSON.stringify(t)}]}}var fi=[`task`,`inputRequests`,`requestState`];function pi(e){return typeof e!=`object`||!e||Array.isArray(e)||e.content!==void 0||fi.some(t=>t in e)?e:{...e,content:[]}}function mi(){let e=ue(()=>k([d(),C(),E(),oe(),A(d(),e),O(e)])),t=A(d(),e),n=k([d(),C().int()]),r=d(),i=m({ttl:C().optional()}),a=m({taskId:d()}),o=f({progressToken:n.optional(),"io.modelcontextprotocol/related-task":a.optional()}),s=m({_meta:o.optional()}),c=s.extend({task:i.optional()}),l=m({method:d(),params:s.loose().optional()}),u=m({_meta:o.optional()}),h=m({method:d(),params:u.loose().optional()}),g=f({_meta:o.optional()}),_=k([d(),C().int()]),y=g.strict(),ee=u.extend({requestId:_.optional(),reason:d().optional()}),x=h.extend({method:S(`notifications/cancelled`),params:ee}),w=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),T=m({icons:O(w).optional()}),ne=m({name:d(),title:d().optional()}),re=ne.extend({...ne.shape,...T.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),ie=te(m({applyDefaults:E().optional()}),t),ae=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:ie.optional(),url:t.optional()}),t.optional())),se=f({list:t.optional(),cancel:t.optional(),requests:f({sampling:f({createMessage:t.optional()}).optional(),elicitation:f({create:t.optional()}).optional()}).optional()}),le=f({list:t.optional(),cancel:t.optional(),requests:f({tools:f({call:t.optional()}).optional()}).optional()}),de=m({experimental:A(d(),t).optional(),sampling:m({context:t.optional(),tools:t.optional()}).optional(),elicitation:ae.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:se.optional(),extensions:A(d(),t).optional()}),fe=s.extend({protocolVersion:d(),capabilities:de,clientInfo:re}),pe=l.extend({method:S(`initialize`),params:fe}),me=m({experimental:A(d(),t).optional(),logging:t.optional(),completions:t.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:le.optional(),extensions:A(d(),t).optional()}),ge=g.extend({protocolVersion:d(),capabilities:me,serverInfo:re,instructions:d().optional()}),_e=h.extend({method:S(`notifications/initialized`),params:u.optional()}),j=l.extend({method:S(`ping`),params:s.optional()}),M=m({progress:C(),total:p(C()),message:p(d())}),ve=m({...u.shape,...M.shape,progressToken:n}),ye=h.extend({method:S(`notifications/progress`),params:ve}),be=s.extend({cursor:r.optional()}),N=l.extend({params:be.optional()}),xe=g.extend({nextCursor:r.optional()}),P=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),Se=P.extend({text:d()}),Ce=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),we=P.extend({blob:Ce}),Te=D([`user`,`assistant`]),Ee=m({audience:O(Te).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),De=m({...ne.shape,...T.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:Ee.optional(),_meta:p(f({}))}),Oe=m({...ne.shape,...T.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:Ee.optional(),_meta:p(f({}))}),ke=N.extend({method:S(`resources/list`)}),Ae=xe.extend({resources:O(De)}),je=N.extend({method:S(`resources/templates/list`)}),Me=xe.extend({resourceTemplates:O(Oe)}),Ne=s.extend({uri:d()}),Pe=Ne,Fe=l.extend({method:S(`resources/read`),params:Pe}),Ie=g.extend({contents:O(k([Se,we]))}),Le=h.extend({method:S(`notifications/resources/list_changed`),params:u.optional()}),Re=Ne,ze=l.extend({method:S(`resources/subscribe`),params:Re}),Be=Ne,Ve=l.extend({method:S(`resources/unsubscribe`),params:Be}),He=u.extend({uri:d()}),F=h.extend({method:S(`notifications/resources/updated`),params:He}),Ue=m({name:d(),description:p(d()),required:p(E())}),We=m({...ne.shape,...T.shape,description:p(d()),arguments:p(O(Ue)),_meta:p(f({}))}),Ge=N.extend({method:S(`prompts/list`)}),Ke=xe.extend({prompts:O(We)}),qe=s.extend({name:d(),arguments:A(d(),d()).optional()}),Je=l.extend({method:S(`prompts/get`),params:qe}),I=m({type:S(`text`),text:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),Ye=m({type:S(`image`),data:Ce,mimeType:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),L=m({type:S(`audio`),data:Ce,mimeType:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),R=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),z=m({type:S(`resource`),resource:k([Se,we]),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),Xe=De.extend({type:S(`resource_link`)}),B=k([I,Ye,L,Xe,z]),Ze=m({role:Te,content:B}),Qe=g.extend({description:d().optional(),messages:O(Ze)}),$e=h.extend({method:S(`notifications/prompts/list_changed`),params:u.optional()}),V=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),et=m({taskSupport:D([`required`,`optional`,`forbidden`]).optional()}),tt=m({...ne.shape,...T.shape,description:d().optional(),inputSchema:m({type:S(`object`),properties:A(d(),e).optional(),required:O(d()).optional()}).catchall(v()),outputSchema:m({type:S(`object`),properties:A(d(),e).optional(),required:O(d()).optional()}).catchall(v()).optional(),annotations:V.optional(),execution:et.optional(),_meta:A(d(),v()).optional()}),nt=N.extend({method:S(`tools/list`)}),rt=xe.extend({tools:O(tt)}),it=g.extend({content:O(B),structuredContent:A(d(),v()).optional(),isError:E().optional()}),at=c.extend({name:d(),arguments:A(d(),v()).optional()}),ot=l.extend({method:S(`tools/call`),params:at}),st=h.extend({method:S(`notifications/tools/list_changed`),params:u.optional()}),ct=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),H=s.extend({level:ct}),lt=l.extend({method:S(`logging/setLevel`),params:H}),ut=u.extend({level:ct,logger:d().optional(),data:v()}),dt=h.extend({method:S(`notifications/message`),params:ut}),ft=m({name:d().optional()}),pt=m({hints:O(ft).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),mt=m({mode:D([`auto`,`required`,`none`]).optional()}),ht=m({type:S(`tool_result`),toolUseId:d().describe(`The unique identifier for the corresponding tool call.`),content:O(B),structuredContent:m({}).loose().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),gt=ce(`type`,[I,Ye,L]),_t=ce(`type`,[I,Ye,L,R,ht]),vt=m({role:Te,content:k([_t,O(_t)]),_meta:A(d(),v()).optional()}),yt=c.extend({messages:O(vt),modelPreferences:pt.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:t.optional(),tools:O(tt).optional(),toolChoice:mt.optional()}),bt=l.extend({method:S(`sampling/createMessage`),params:yt}),xt=g.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`]).or(d())),role:Te,content:gt}),St=g.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`,`toolUse`]).or(d())),role:Te,content:k([_t,O(_t)])}),Ct=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),wt=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Tt=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),Et=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Dt=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Ot=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),kt=k([Et,Dt]),At=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),jt=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),Mt=k([At,jt]),Nt=k([Ot,kt,Mt]),Pt=k([Nt,Ct,wt,Tt]),Ft=c.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),Pt),required:O(d()).optional()}).catchall(v())}),It=c.extend({mode:S(`url`),message:d(),elicitationId:d(),url:d().url()}),Lt=k([Ft,It]),U=l.extend({method:S(`elicitation/create`),params:Lt}),W=u.extend({elicitationId:d()}),Rt=h.extend({method:S(`notifications/elicitation/complete`),params:W}),zt=g.extend({action:D([`accept`,`decline`,`cancel`]),content:b(e=>e===null?void 0:e,A(d(),k([d(),C(),E(),O(d())])).optional())}),Bt=m({type:S(`ref/resource`),uri:d()}),Vt=m({type:S(`ref/prompt`),name:d()}),Ht=s.extend({ref:k([Vt,Bt]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()}),Ut=l.extend({method:S(`completion/complete`),params:Ht}),Wt=g.extend({completion:f({values:O(d()).max(100),total:p(C().int()),hasMore:p(E())})}),Gt=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),Kt=l.extend({method:S(`roots/list`),params:s.optional()}),qt=g.extend({roots:O(Gt)}),Jt=h.extend({method:S(`notifications/roots/list_changed`),params:u.optional()}),Yt=f({ttl:C().optional(),pollInterval:C().optional()}),Xt=D([`working`,`input_required`,`completed`,`failed`,`cancelled`]),Zt=m({taskId:d(),status:Xt,ttl:k([C(),oe()]),createdAt:d(),lastUpdatedAt:d(),pollInterval:p(C()),statusMessage:p(d())}),Qt=g.extend({task:Zt}),$t=u.merge(Zt),en=h.extend({method:S(`notifications/tasks/status`),params:$t}),tn=l.extend({method:S(`tasks/get`),params:s.extend({taskId:d()})}),G=g.merge(Zt),nn=l.extend({method:S(`tasks/result`),params:s.extend({taskId:d()})}),rn=g.loose(),an=N.extend({method:S(`tasks/list`)}),on=xe.extend({tasks:O(Zt)}),sn=l.extend({method:S(`tasks/cancel`),params:s.extend({taskId:d()})});return{JSONValueSchema:e,JSONObjectSchema:t,ProgressTokenSchema:n,CursorSchema:r,TaskMetadataSchema:i,RelatedTaskMetadataSchema:a,RequestMetaSchema:o,BaseRequestParamsSchema:s,TaskAugmentedRequestParamsSchema:c,RequestSchema:l,NotificationsParamsSchema:u,NotificationSchema:h,ResultSchema:g,RequestIdSchema:_,EmptyResultSchema:y,CancelledNotificationParamsSchema:ee,CancelledNotificationSchema:x,IconSchema:w,IconsSchema:T,BaseMetadataSchema:ne,ImplementationSchema:re,ClientTasksCapabilitySchema:se,ServerTasksCapabilitySchema:le,ClientCapabilitiesSchema:de,InitializeRequestParamsSchema:fe,InitializeRequestSchema:pe,ServerCapabilitiesSchema:me,InitializeResultSchema:ge,InitializedNotificationSchema:_e,PingRequestSchema:j,ProgressSchema:M,ProgressNotificationParamsSchema:ve,ProgressNotificationSchema:ye,PaginatedRequestParamsSchema:be,PaginatedRequestSchema:N,PaginatedResultSchema:xe,ResourceContentsSchema:P,TextResourceContentsSchema:Se,BlobResourceContentsSchema:we,RoleSchema:Te,AnnotationsSchema:Ee,ResourceSchema:De,ResourceTemplateSchema:Oe,ListResourcesRequestSchema:ke,ListResourcesResultSchema:Ae,ListResourceTemplatesRequestSchema:je,ListResourceTemplatesResultSchema:Me,ResourceRequestParamsSchema:Ne,ReadResourceRequestParamsSchema:Pe,ReadResourceRequestSchema:Fe,ReadResourceResultSchema:Ie,ResourceListChangedNotificationSchema:Le,SubscribeRequestParamsSchema:Re,SubscribeRequestSchema:ze,UnsubscribeRequestParamsSchema:Be,UnsubscribeRequestSchema:Ve,ResourceUpdatedNotificationParamsSchema:He,ResourceUpdatedNotificationSchema:F,PromptArgumentSchema:Ue,PromptSchema:We,ListPromptsRequestSchema:Ge,ListPromptsResultSchema:Ke,GetPromptRequestParamsSchema:qe,GetPromptRequestSchema:Je,TextContentSchema:I,ImageContentSchema:Ye,AudioContentSchema:L,ToolUseContentSchema:R,EmbeddedResourceSchema:z,ResourceLinkSchema:Xe,ContentBlockSchema:B,PromptMessageSchema:Ze,GetPromptResultSchema:Qe,PromptListChangedNotificationSchema:$e,ToolAnnotationsSchema:V,ToolExecutionSchema:et,ToolSchema:tt,ListToolsRequestSchema:nt,ListToolsResultSchema:rt,CallToolResultSchema:it,CallToolRequestParamsSchema:at,CallToolRequestSchema:ot,ToolListChangedNotificationSchema:st,LoggingLevelSchema:ct,SetLevelRequestParamsSchema:H,SetLevelRequestSchema:lt,LoggingMessageNotificationParamsSchema:ut,LoggingMessageNotificationSchema:dt,ModelHintSchema:ft,ModelPreferencesSchema:pt,ToolChoiceSchema:mt,ToolResultContentSchema:ht,SamplingContentSchema:gt,SamplingMessageContentBlockSchema:_t,SamplingMessageSchema:vt,CreateMessageRequestParamsSchema:yt,CreateMessageRequestSchema:bt,CreateMessageResultSchema:xt,CreateMessageResultWithToolsSchema:St,BooleanSchemaSchema:Ct,StringSchemaSchema:wt,NumberSchemaSchema:Tt,UntitledSingleSelectEnumSchemaSchema:Et,TitledSingleSelectEnumSchemaSchema:Dt,LegacyTitledEnumSchemaSchema:Ot,SingleSelectEnumSchemaSchema:kt,UntitledMultiSelectEnumSchemaSchema:At,TitledMultiSelectEnumSchemaSchema:jt,MultiSelectEnumSchemaSchema:Mt,EnumSchemaSchema:Nt,PrimitiveSchemaDefinitionSchema:Pt,ElicitRequestFormParamsSchema:Ft,ElicitRequestURLParamsSchema:It,ElicitRequestParamsSchema:Lt,ElicitRequestSchema:U,ElicitationCompleteNotificationParamsSchema:W,ElicitationCompleteNotificationSchema:Rt,ElicitResultSchema:zt,ResourceTemplateReferenceSchema:Bt,PromptReferenceSchema:Vt,CompleteRequestParamsSchema:Ht,CompleteRequestSchema:Ut,CompleteResultSchema:Wt,RootSchema:Gt,ListRootsRequestSchema:Kt,ListRootsResultSchema:qt,RootsListChangedNotificationSchema:Jt,TaskCreationParamsSchema:Yt,TaskStatusSchema:Xt,TaskSchema:Zt,CreateTaskResultSchema:Qt,TaskStatusNotificationParamsSchema:$t,TaskStatusNotificationSchema:en,GetTaskRequestSchema:tn,GetTaskResultSchema:G,GetTaskPayloadRequestSchema:nn,GetTaskPayloadResultSchema:rn,ListTasksRequestSchema:an,ListTasksResultSchema:on,CancelTaskRequestSchema:sn,CancelTaskResultSchema:g.merge(Zt),ClientRequestSchema:k([j,pe,Ut,lt,Je,Ge,ke,je,Fe,ze,Ve,ot,nt,tn,nn,an,sn]),ClientNotificationSchema:k([x,ye,_e,Jt,en]),ClientResultSchema:k([y,xt,St,zt,qt,G,on,Qt]),ServerRequestSchema:k([j,bt,U,Kt,tn,nn,an,sn]),ServerNotificationSchema:k([x,ye,dt,F,Le,st,$e,en,Rt]),ServerResultSchema:k([y,ge,Wt,Qe,Ke,Ae,Me,Ie,it,rt,G,on,Qt]),CallToolResultWireSchema:v().superRefine((e,t)=>{if(typeof e==`object`&&e&&!Array.isArray(e)&&e.content===void 0){for(let n of fi)if(n in e){t.addIssue({code:`custom`,message:`content is required when the body carries '${n}' — another result family cannot default into an empty tools/call success`});return}}}).transform(pi).pipe(it)}}var hi;function gi(){return hi??=mi()}function _i(e){return e.type!==`object`}var vi=new Set([`const`,`enum`,`default`,`examples`]),yi=new Set([`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`,`dependencies`]);function bi(e){return e!==void 0&&!(typeof e==`string`&&e.startsWith(`#`))}function xi(e){let t=typeof e.$schema==`string`?e.$schema:void 0;if(bi(e.$id))return{...t!==void 0&&{$schema:t},type:`object`,properties:{result:e},required:[`result`]};let n=je(e.$schema)&&e.$recursiveAnchor!==!0,r=(e,t)=>{if(Array.isArray(e))return e.map(e=>r(e,!1));if(typeof e!=`object`||!e||!t&&bi(e.$id))return e;let i={},a=!1;for(let[o,s]of Object.entries(e))t?i[o]=r(s,!1):(o===`$ref`||o===`$dynamicRef`)&&typeof s==`string`?i[o]=s===`#`?`#/properties/result`:s.startsWith(`#/`)?`#/properties/result${s.slice(1)}`:s:o===`$recursiveRef`&&s===`#`&&n?a=!0:i[o]=vi.has(o)?s:yi.has(o)?r(s,!0):r(s,!1);return a&&(`$ref`in i?i.allOf=[...Array.isArray(i.allOf)?i.allOf:[],{$ref:`#/properties/result`}]:i.$ref=`#/properties/result`),i};return{...t!==void 0&&{$schema:t},type:`object`,properties:{result:r(e,!1)},required:[`result`]}}var Si={ping:null,initialize:null,"completion/complete":null,"logging/setLevel":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"resources/subscribe":null,"resources/unsubscribe":null,"tools/call":null,"tools/list":null,"tasks/get":null,"tasks/result":null,"tasks/list":null,"tasks/cancel":null,"sampling/createMessage":null,"elicitation/create":null,"roots/list":null},Ci={"notifications/cancelled":null,"notifications/progress":null,"notifications/initialized":null,"notifications/roots/list_changed":null,"notifications/tasks/status":null,"notifications/message":null,"notifications/resources/updated":null,"notifications/resources/list_changed":null,"notifications/tools/list_changed":null,"notifications/prompts/list_changed":null,"notifications/elicitation/complete":null},wi={ping:null,initialize:null,"completion/complete":null,"logging/setLevel":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"resources/subscribe":null,"resources/unsubscribe":null,"tools/call":null,"tools/list":null,"sampling/createMessage":null,"elicitation/create":null,"roots/list":null},Ti;function Ei(){if(Ti)return Ti;let e=gi();return Ti={requestSchemas:{ping:e.PingRequestSchema,initialize:e.InitializeRequestSchema,"completion/complete":e.CompleteRequestSchema,"logging/setLevel":e.SetLevelRequestSchema,"prompts/get":e.GetPromptRequestSchema,"prompts/list":e.ListPromptsRequestSchema,"resources/list":e.ListResourcesRequestSchema,"resources/templates/list":e.ListResourceTemplatesRequestSchema,"resources/read":e.ReadResourceRequestSchema,"resources/subscribe":e.SubscribeRequestSchema,"resources/unsubscribe":e.UnsubscribeRequestSchema,"tools/call":e.CallToolRequestSchema,"tools/list":e.ListToolsRequestSchema,"tasks/get":e.GetTaskRequestSchema,"tasks/result":e.GetTaskPayloadRequestSchema,"tasks/list":e.ListTasksRequestSchema,"tasks/cancel":e.CancelTaskRequestSchema,"sampling/createMessage":e.CreateMessageRequestSchema,"elicitation/create":e.ElicitRequestSchema,"roots/list":e.ListRootsRequestSchema},notificationSchemas:{"notifications/cancelled":e.CancelledNotificationSchema,"notifications/progress":e.ProgressNotificationSchema,"notifications/initialized":e.InitializedNotificationSchema,"notifications/roots/list_changed":e.RootsListChangedNotificationSchema,"notifications/tasks/status":e.TaskStatusNotificationSchema,"notifications/message":e.LoggingMessageNotificationSchema,"notifications/resources/updated":e.ResourceUpdatedNotificationSchema,"notifications/resources/list_changed":e.ResourceListChangedNotificationSchema,"notifications/tools/list_changed":e.ToolListChangedNotificationSchema,"notifications/prompts/list_changed":e.PromptListChangedNotificationSchema,"notifications/elicitation/complete":e.ElicitationCompleteNotificationSchema},resultSchemas:{ping:e.EmptyResultSchema,initialize:e.InitializeResultSchema,"completion/complete":e.CompleteResultSchema,"logging/setLevel":e.EmptyResultSchema,"prompts/get":e.GetPromptResultSchema,"prompts/list":e.ListPromptsResultSchema,"resources/list":e.ListResourcesResultSchema,"resources/templates/list":e.ListResourceTemplatesResultSchema,"resources/read":e.ReadResourceResultSchema,"resources/subscribe":e.EmptyResultSchema,"resources/unsubscribe":e.EmptyResultSchema,"tools/call":e.CallToolResultWireSchema,"tools/list":e.ListToolsResultSchema,"sampling/createMessage":e.CreateMessageResultWithToolsSchema,"elicitation/create":e.ElicitResultSchema,"roots/list":e.ListRootsResultSchema}},Ti}function Di(e){return Object.prototype.hasOwnProperty.call(Si,e)}function Oi(e){return Object.prototype.hasOwnProperty.call(Ci,e)}function ki(e){return Object.prototype.hasOwnProperty.call(wi,e)}function Ai(e){return ki(e)?Ei().resultSchemas[e]:void 0}function ji(e){return Di(e)?Ei().requestSchemas[e]:void 0}function Mi(e){return Oi(e)?Ei().notificationSchemas[e]:void 0}Object.keys(Si),Object.keys(Ci);function Ni(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pi(e,t){if(e===void 0)return{ok:!1,reason:`not-in-era`};let n=e.safeParse(t);return n.success?{ok:!0,value:n.data}:{ok:!1,reason:`invalid`,message:String(n.error)}}var Fi={ok:!1,reason:`not-in-era`};function Ii(e){return Ni(e)&&Ni(e.outputSchema)&&_i(e.outputSchema)}function Li(e){return e}var Ri={era:`2025-11-25`,hasRequestMethod:Di,hasNotificationMethod:Oi,validateRequest:(e,t)=>Pi(ji(e),t),validateResult:(e,t)=>Pi(Ai(e),t),validateNotification:(e,t)=>Pi(Mi(e),t),hasInputRequestMethod:()=>!1,validateInputRequest:()=>Fi,validateInputResponse:()=>Fi,samplingResultVariant:((e,t)=>{let n=gi();return Pi(e?n.CreateMessageResultWithToolsSchema:n.CreateMessageResultSchema,t)}),outboundEnvelope:e=>void 0,validateEnvelopeMeta:e=>[],projectCallToolResult(e,t){let n=di(e),r=n.structuredContent;if(r===void 0)return n;let i=typeof r!=`object`||!r||Array.isArray(r),a=t!==void 0&&_i(t);return!i&&!a?n:{...n,structuredContent:{result:r}}},decodeResult(e,t){if(Ni(t)&&`resultType`in t){let e={...t};return delete e.resultType,{kind:`complete`,result:Li(e)}}return{kind:`complete`,result:Li(t)}},encodeResult(e,t){if(e!==`tools/list`)return t;let n=t.tools;return!Array.isArray(n)||!n.some(e=>Ii(e))?t:{...t,tools:n.map(e=>Ii(e)?{...e,outputSchema:xi(e.outputSchema)}:e)}},encodeErrorCode:e=>e===-32002?-32602:e,checkInboundEnvelope:e=>void 0};function zi(){let e=ue(()=>k([d(),C(),E(),oe(),A(d(),e),O(e)])),t=A(d(),e),n=k([d(),C().int()]),r=d(),i=k([d(),C().int()]),a=D([`user`,`assistant`]),o=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),s=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),c=m({ttl:C().optional()}),l=m({taskId:d()}),u=f({progressToken:n.optional(),"io.modelcontextprotocol/related-task":l.optional()}),h=m({_meta:u.optional()}),g=h.extend({task:c.optional()}),_=m({_meta:u.optional()}),y=m({method:d(),params:_.loose().optional()}),ee=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),x=m({icons:O(ee).optional()}),w=m({name:d(),title:d().optional()}),T=w.extend({...w.shape,...x.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),ne=te(m({applyDefaults:E().optional()}),t),re=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:ne.optional(),url:t.optional()}),t.optional())),ie=f({list:t.optional(),cancel:t.optional(),requests:f({sampling:f({createMessage:t.optional()}).optional(),elicitation:f({create:t.optional()}).optional()}).optional()}),ae=f({list:t.optional(),cancel:t.optional(),requests:f({tools:f({call:t.optional()}).optional()}).optional()}),se=m({experimental:A(d(),t).optional(),sampling:m({context:t.optional(),tools:t.optional()}).optional(),elicitation:re.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:ie.optional(),extensions:A(d(),t).optional()}),ce=m({experimental:A(d(),t).optional(),logging:t.optional(),completions:t.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:ae.optional(),extensions:A(d(),t).optional()}),le=m({progress:C(),total:p(C()),message:p(d())}),de=m({..._.shape,...le.shape,progressToken:n}),fe=y.extend({method:S(`notifications/progress`),params:de}),pe=_.extend({level:o,logger:d().optional(),data:v()}),me=y.extend({method:S(`notifications/message`),params:pe}),ge=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),_e=ge.extend({text:d()}),j=ge.extend({blob:s}),M=m({audience:O(a).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),ve=m({...w.shape,...x.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:M.optional(),_meta:p(f({}))}),ye=m({...w.shape,...x.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:M.optional(),_meta:p(f({}))}),be=y.extend({method:S(`notifications/resources/list_changed`),params:_.optional()}),N=_.extend({uri:d()}),xe=y.extend({method:S(`notifications/resources/updated`),params:N}),P=m({name:d(),description:p(d()),required:p(E())}),Se=m({...w.shape,...x.shape,description:p(d()),arguments:p(O(P)),_meta:p(f({}))}),Ce=y.extend({method:S(`notifications/prompts/list_changed`),params:_.optional()}),we=m({type:S(`text`),text:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),Te=m({type:S(`image`),data:s,mimeType:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),Ee=m({type:S(`audio`),data:s,mimeType:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),De=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),Oe=m({type:S(`resource`),resource:k([_e,j]),annotations:M.optional(),_meta:A(d(),v()).optional()}),ke=ve.extend({type:S(`resource_link`)}),Ae=k([we,Te,Ee,ke,Oe]),je=m({role:a,content:Ae}),Me=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),Ne=y.extend({method:S(`notifications/tools/list_changed`),params:_.optional()}),Pe=m({name:d().optional()}),Fe=m({hints:O(Pe).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),Be=m({mode:D([`auto`,`required`,`none`]).optional()}),He=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),F=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Ue=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),We=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Ge=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Ke=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),qe=k([We,Ge]),Je=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),I=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),Ye=k([Je,I]),L=k([Ke,qe,Ye]),R=k([L,He,F,Ue]),z=g.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),R),required:O(d()).optional()}).catchall(v())}),Xe=m({type:S(`ref/resource`),uri:d()}),B=m({type:S(`ref/prompt`),name:d()}),Ze=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),Qe=se.shape,$e=m({experimental:Qe.experimental,sampling:Qe.sampling,elicitation:Qe.elicitation,roots:Qe.roots,extensions:Qe.extensions}),V=ce.shape,et=m({experimental:V.experimental,logging:V.logging,completions:V.completions,prompts:V.prompts,resources:V.resources,tools:V.tools,extensions:V.extensions}),tt=f({progressToken:n.optional(),[Ie]:d(),[Le]:T.optional(),[ze]:$e,[Ve]:o.optional()}),nt=m({...w.shape,...x.shape,description:d().optional(),inputSchema:f({$schema:d().optional(),type:S(`object`)}),outputSchema:f({$schema:d().optional()}).optional(),annotations:Me.optional(),_meta:A(d(),v()).optional()}),rt=m({type:S(`tool_result`),toolUseId:d(),content:O(Ae),structuredContent:v().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),it=k([we,Te,Ee,De,rt]),at=m({role:a,content:k([it,O(it)]),_meta:A(d(),v()).optional()}),ot=d(),st=f({[Re]:T.optional().catch(void 0)}),ct=st.optional();function H(e){return f({_meta:ct,resultType:ot.default(`complete`),...e})}let lt=H({}),ut=H({nextCursor:r.optional()}),dt=H({content:O(Ae),structuredContent:v().optional(),isError:E().optional()}),ft=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),tools:O(nt),nextCursor:r.optional()}),pt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),prompts:O(Se),nextCursor:r.optional()}),mt=H({description:d().optional(),messages:O(je)}),ht=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resources:O(ve),nextCursor:r.optional()}),gt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resourceTemplates:O(ye),nextCursor:r.optional()}),_t=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),contents:O(k([_e,j]))}),vt=H({completion:m({values:O(d()).max(100),total:C().int().optional(),hasMore:E().optional()}).loose()}),yt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`])}),bt=H({ttlMs:C().int().min(0).catch(0),cacheScope:D([`public`,`private`]).catch(`private`),supportedVersions:O(d()),capabilities:et,instructions:d().optional()}),xt=m({messages:O(at),modelPreferences:Fe.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:t.optional(),tools:O(nt).optional(),toolChoice:Be.optional()}),St=m({method:S(`sampling/createMessage`),params:xt}),Ct=m({method:S(`roots/list`),params:m({_meta:A(d(),v()).optional()}).optional()}),wt=m({...at.shape,model:d(),stopReason:d().optional()}),Tt=m({roots:O(Ze)}),Et=m({action:D([`accept`,`decline`,`cancel`]),content:A(d(),k([d(),C(),E(),O(d())])).optional()}),Dt=m({mode:S(`url`),message:d(),url:d().url()}),Ot=k([z,Dt]),kt=m({method:S(`elicitation/create`),params:Ot}),At=k([St,Ct,kt]),jt=k([wt,Tt,Et]),Mt=A(d(),At),Nt=A(d(),jt),Pt=H({inputRequests:Mt.optional(),requestState:d().optional()}),Ft={inputResponses:Nt.optional(),requestState:d().optional()},It=m({_meta:tt,...Ft}),Lt=f({progressToken:n.optional()});function U(e,t){return m({method:S(e),params:m({_meta:tt,...t})})}function W(e,t){return m({method:S(e),params:m({_meta:Lt.optional(),...t}).optional()})}let Rt={name:d(),arguments:A(d(),v()).optional(),...Ft},zt={cursor:r.optional()},Bt=U(`tools/call`,Rt),Vt=U(`tools/list`,zt),Ht=U(`prompts/list`,zt),Ut=U(`prompts/get`,{name:d(),arguments:A(d(),d()).optional(),...Ft}),Wt=U(`resources/list`,zt),Gt=U(`resources/templates/list`,zt),Kt=U(`resources/read`,{uri:d(),...Ft}),qt={ref:k([B,Xe]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()},Jt=U(`completion/complete`,qt),Yt=U(`server/discover`,{}),Xt=m({toolsListChanged:E().optional(),promptsListChanged:E().optional(),resourcesListChanged:E().optional(),resourceSubscriptions:O(d()).optional()}),Zt={notifications:Xt},Qt=U(`subscriptions/listen`,Zt),$t=st.extend({"io.modelcontextprotocol/subscriptionId":i}),en=f({_meta:$t,resultType:ot.default(`complete`)}),tn={"tools/call":W(`tools/call`,Rt),"tools/list":W(`tools/list`,zt),"prompts/get":W(`prompts/get`,{name:d(),arguments:A(d(),d()).optional()}),"prompts/list":W(`prompts/list`,zt),"resources/list":W(`resources/list`,zt),"resources/templates/list":W(`resources/templates/list`,zt),"resources/read":W(`resources/read`,{uri:d()}),"completion/complete":W(`completion/complete`,qt),"server/discover":W(`server/discover`,{}),"subscriptions/listen":W(`subscriptions/listen`,Zt)};function G(e){return f({_meta:ct,...e})}let nn={"tools/call":G({content:O(Ae),structuredContent:v().optional(),isError:E().optional()}),"tools/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),tools:O(nt),nextCursor:r.optional()}),"prompts/get":G({description:d().optional(),messages:O(je)}),"prompts/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),prompts:O(Se),nextCursor:r.optional()}),"resources/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resources:O(ve),nextCursor:r.optional()}),"resources/templates/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resourceTemplates:O(ye),nextCursor:r.optional()}),"resources/read":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),contents:O(k([_e,j]))}),"completion/complete":G({completion:m({values:O(d()).max(100),total:C().int().optional(),hasMore:E().optional()}).loose()}),"server/discover":G({ttlMs:C().int().min(0).catch(0),cacheScope:D([`public`,`private`]).catch(`private`),supportedVersions:O(d()),capabilities:et,instructions:d().optional()}),"subscriptions/listen":G({})},rn=f({"io.modelcontextprotocol/subscriptionId":i.optional()}),an=m({method:S(`notifications/subscriptions/acknowledged`),params:m({_meta:rn.optional(),notifications:Xt})}),on=m({_meta:rn.optional(),requestId:i,reason:d().optional()}),sn=m({method:S(`notifications/cancelled`),params:on}),cn={"notifications/cancelled":sn,"notifications/progress":fe,"notifications/message":me,"notifications/resources/updated":xe,"notifications/resources/list_changed":be,"notifications/tools/list_changed":Ne,"notifications/prompts/list_changed":Ce,"notifications/subscriptions/acknowledged":an},K=e=>m({jsonrpc:S(`2.0`),id:k([d(),C().int()]),result:e}).strict();return{JSONValueSchema:e,JSONObjectSchema:t,ProgressTokenSchema:n,CursorSchema:r,RequestIdSchema:i,RoleSchema:a,LoggingLevelSchema:o,TaskMetadataSchema:c,RelatedTaskMetadataSchema:l,RequestMetaSchema:u,BaseRequestParamsSchema:h,TaskAugmentedRequestParamsSchema:g,NotificationsParamsSchema:_,NotificationSchema:y,IconSchema:ee,IconsSchema:x,BaseMetadataSchema:w,ImplementationSchema:T,ClientTasksCapabilitySchema:ie,ServerTasksCapabilitySchema:ae,ClientCapabilitiesSchema:se,ServerCapabilitiesSchema:ce,ProgressSchema:le,ProgressNotificationParamsSchema:de,ProgressNotificationSchema:fe,LoggingMessageNotificationParamsSchema:pe,LoggingMessageNotificationSchema:me,ResourceContentsSchema:ge,TextResourceContentsSchema:_e,BlobResourceContentsSchema:j,AnnotationsSchema:M,ResourceSchema:ve,ResourceTemplateSchema:ye,ResourceListChangedNotificationSchema:be,ResourceUpdatedNotificationParamsSchema:N,ResourceUpdatedNotificationSchema:xe,PromptArgumentSchema:P,PromptSchema:Se,PromptListChangedNotificationSchema:Ce,TextContentSchema:we,ImageContentSchema:Te,AudioContentSchema:Ee,ToolUseContentSchema:De,EmbeddedResourceSchema:Oe,ResourceLinkSchema:ke,ContentBlockSchema:Ae,PromptMessageSchema:je,ToolAnnotationsSchema:Me,ToolListChangedNotificationSchema:Ne,ModelHintSchema:Pe,ModelPreferencesSchema:Fe,ToolChoiceSchema:Be,BooleanSchemaSchema:He,StringSchemaSchema:F,NumberSchemaSchema:Ue,UntitledSingleSelectEnumSchemaSchema:We,TitledSingleSelectEnumSchemaSchema:Ge,LegacyTitledEnumSchemaSchema:Ke,SingleSelectEnumSchemaSchema:qe,UntitledMultiSelectEnumSchemaSchema:Je,TitledMultiSelectEnumSchemaSchema:I,MultiSelectEnumSchemaSchema:Ye,EnumSchemaSchema:L,PrimitiveSchemaDefinitionSchema:R,ElicitRequestFormParamsSchema:z,ResourceTemplateReferenceSchema:Xe,PromptReferenceSchema:B,RootSchema:Ze,ClientCapabilities2026Schema:$e,ServerCapabilities2026Schema:et,RequestMetaEnvelopeSchema:tt,ToolSchema:nt,ToolResultContentSchema:rt,SamplingMessageContentBlockSchema:it,SamplingMessageSchema:at,ResultTypeSchema:ot,ResultMetaSchema:st,ResultSchema:lt,PaginatedResultSchema:ut,CallToolResultSchema:dt,ListToolsResultSchema:ft,ListPromptsResultSchema:pt,GetPromptResultSchema:mt,ListResourcesResultSchema:ht,ListResourceTemplatesResultSchema:gt,ReadResourceResultSchema:_t,CompleteResultSchema:vt,CacheableResultSchema:yt,DiscoverResultSchema:bt,CreateMessageRequestParamsSchema:xt,CreateMessageRequestSchema:St,ListRootsRequestSchema:Ct,CreateMessageResultSchema:wt,ListRootsResultSchema:Tt,ElicitResultSchema:Et,ElicitRequestURLParamsSchema:Dt,ElicitRequestParamsSchema:Ot,ElicitRequestSchema:kt,InputRequestSchema:At,InputResponseSchema:jt,InputRequestsSchema:Mt,InputResponsesSchema:Nt,InputRequiredResultSchema:Pt,InputResponseRequestParamsSchema:It,CallToolRequestSchema:Bt,ListToolsRequestSchema:Vt,ListPromptsRequestSchema:Ht,GetPromptRequestSchema:Ut,ListResourcesRequestSchema:Wt,ListResourceTemplatesRequestSchema:Gt,ReadResourceRequestSchema:Kt,CompleteRequestSchema:Jt,DiscoverRequestSchema:Yt,SubscriptionFilterSchema:Xt,SubscriptionsListenRequestSchema:Qt,SubscriptionsListenResultMetaSchema:$t,SubscriptionsListenResultSchema:en,dispatchRequestSchemas:tn,dispatchResultSchemas:nn,NotificationMetaSchema:rn,SubscriptionsAcknowledgedNotificationSchema:an,CancelledNotificationParamsSchema:on,CancelledNotificationSchema:sn,notificationSchemas2026:cn,JSONRPCResultResponseSchema:K(lt),CallToolResultResponseSchema:K(k([dt,Pt])),ListToolsResultResponseSchema:K(ft),ListPromptsResultResponseSchema:K(pt),GetPromptResultResponseSchema:K(k([mt,Pt])),ListResourcesResultResponseSchema:K(ht),ListResourceTemplatesResultResponseSchema:K(gt),ReadResourceResultResponseSchema:K(k([_t,Pt])),CompleteResultResponseSchema:K(vt),DiscoverResultResponseSchema:K(bt),SubscriptionsListenResultResponseSchema:K(en)}}var Bi;function Vi(){return Bi??=zi()}var Hi=[`tools/list`,`prompts/list`,`resources/list`,`resources/templates/list`,`resources/read`,`server/discover`];function Ui(e){return Hi.includes(e)}var Wi=Symbol(`modelcontextprotocol.resultCacheHintFallback`);function Gi(e){return e[Wi]}function Ki(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function qi(e){return e===`public`||e===`private`}var X=function(e){return e[e.ParseError=-32700]=`ParseError`,e[e.InvalidRequest=-32600]=`InvalidRequest`,e[e.MethodNotFound=-32601]=`MethodNotFound`,e[e.InvalidParams=-32602]=`InvalidParams`,e[e.InternalError=-32603]=`InternalError`,e[e.ResourceNotFound=-32002]=`ResourceNotFound`,e[e.MissingRequiredClientCapability=-32021]=`MissingRequiredClientCapability`,e[e.UnsupportedProtocolVersion=-32022]=`UnsupportedProtocolVersion`,e[e.UrlElicitationRequired=-32042]=`UrlElicitationRequired`,e}({}),Z=class e extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.ProtocolError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n){super(t),this.code=e,this.data=n,this.name=`ProtocolError`,Qr(this,new.target)}static fromError(t,n,r){if(t===X.UrlElicitationRequired&&r){let e=r;if(e.elicitations)return new Yi(e.elicitations,n)}if(t===X.UnsupportedProtocolVersion&&r){let e=r;if(Array.isArray(e.supported)&&typeof e.requested==`string`)return new Xi({supported:e.supported,requested:e.requested},n)}if(t===X.InvalidParams||t===X.ResourceNotFound){let e=r;if(typeof e?.uri==`string`&&(t===X.ResourceNotFound||Object.keys(e).length===1))return new Ji(e.uri,n)}if(t===X.MissingRequiredClientCapability&&r){let e=r;if(e.requiredCapabilities!==null&&typeof e.requiredCapabilities==`object`&&!Array.isArray(e.requiredCapabilities))return new Zi({requiredCapabilities:e.requiredCapabilities},n)}return new e(t,n,r)}},Ji=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.ResourceNotFoundError`})}constructor(e,t=`Resource not found: ${e}`){super(X.InvalidParams,t,{uri:e})}get uri(){return this.data.uri}},Yi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.UrlElicitationRequiredError`})}constructor(e,t=`URL elicitation${e.length>1?`s`:``} required`){super(X.UrlElicitationRequired,t,{elicitations:e})}get elicitations(){return this.data?.elicitations??[]}},Xi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.UnsupportedProtocolVersionError`})}constructor(e,t=`Unsupported protocol version: ${e.requested}`){super(X.UnsupportedProtocolVersion,t,e)}get supported(){return this.data.supported}get requested(){return this.data.requested}},Zi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.MissingRequiredClientCapabilityError`})}constructor(e,t=`Missing required client capabilities: ${Object.keys(e.requiredCapabilities).join(`, `)}`){super(X.MissingRequiredClientCapability,t,e)}get requiredCapabilities(){return this.data.requiredCapabilities}},Qi=0,$i=`private`,ea=[`tools/call`,`prompts/get`,`resources/read`];function ta(e,t){let n=t.resultType;if(n===void 0)return{...t,resultType:`complete`};if(n===`complete`||ea.includes(e))return t;throw new Z(X.InternalError,`Handler for ${e} returned resultType '${String(n)}', but results of ${e} only support 'complete' on protocol revision 2026-07-28`)}function na(e,t){let n=Gi(t);if(t.resultType!==`complete`||!Ui(e))return n===void 0?t:sa(t);let r=t,i=Ki(r.ttlMs)?r.ttlMs:aa(n),a=qi(r.cacheScope)?r.cacheScope:oa(n),o={...r,ttlMs:i,cacheScope:a};return delete o[Wi],o}function ra(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ia(e,t){if(t===void 0)return e;let n=e._meta;return n===void 0?{...e,_meta:{[Re]:t}}:!ra(n)||n[`io.modelcontextprotocol/serverInfo`]!==void 0?e:{...e,_meta:{...n,[Re]:t}}}function aa(e){return e!==void 0&&Ki(e.ttlMs)?e.ttlMs:Qi}function oa(e){return e!==void 0&&qi(e.cacheScope)?e.cacheScope:$i}function sa(e){let t={...e};return delete t[Wi],t}var ca=[`elicitation/create`,`sampling/createMessage`,`roots/list`],la;function ua(){if(la)return la;let e=Vi();return la={request:{"elicitation/create":m({method:S(`elicitation/create`),params:e.ElicitRequestParamsSchema}),"sampling/createMessage":m({method:S(`sampling/createMessage`),params:e.CreateMessageRequestParamsSchema}),"roots/list":m({method:S(`roots/list`),params:f({}).optional()})},response:{"elicitation/create":e.ElicitResultSchema,"sampling/createMessage":e.CreateMessageResultSchema,"roots/list":e.ListRootsResultSchema}},la}function da(e){return ca.includes(e)}function fa(e){return da(e)?ua().request[e]:void 0}function pa(e){return da(e)?ua().response[e]:void 0}var ma={"tools/call":null,"tools/list":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"completion/complete":null,"server/discover":null,"subscriptions/listen":null},ha={"notifications/cancelled":null,"notifications/progress":null,"notifications/message":null,"notifications/resources/updated":null,"notifications/resources/list_changed":null,"notifications/tools/list_changed":null,"notifications/prompts/list_changed":null,"notifications/subscriptions/acknowledged":null};function ga(e){return Object.prototype.hasOwnProperty.call(ma,e)}function _a(e){return Object.prototype.hasOwnProperty.call(ha,e)}function va(e){return Object.prototype.hasOwnProperty.call(ma,e)}function ya(e){return ga(e)?Vi().dispatchRequestSchemas[e]:void 0}function ba(e){return va(e)?Vi().dispatchResultSchemas[e]:void 0}function xa(e){return _a(e)?Vi().notificationSchemas2026[e]:void 0}Object.keys(ma),Object.keys(ha);function Sa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ca(e,t){if(e===void 0)return{ok:!1,reason:`not-in-era`};let n=e.safeParse(t);return n.success?{ok:!0,value:n.data}:{ok:!1,reason:`invalid`,message:String(n.error)}}var wa={ok:!1,reason:`not-in-era`},Ta=[Ie,ze];function Ea(e,t){let n=t,r=!1,i=()=>(r||=(n={...n},!0),n),a=t.tools;e===`tools/list`&&Array.isArray(a)&&a.some(e=>Sa(e)&&`execution`in e)&&(i().tools=a.map(e=>{if(!Sa(e)||!(`execution`in e))return e;let t={...e};return delete t.execution,t}));let o=t.capabilities;if(Sa(o)&&`tasks`in o){let e={...o};delete e.tasks,i().capabilities=e}return n}var Da={era:`2026-07-28`,hasRequestMethod:ga,hasNotificationMethod:_a,hasInputRequestMethod:e=>fa(e)!==void 0,validateRequest:(e,t)=>Ca(ya(e),t),validateResult:(e,t)=>Ca(ba(e),t),validateNotification:(e,t)=>Ca(xa(e),t),validateInputRequest:(e,t)=>Ca(fa(e),t),validateInputResponse:(e,t)=>Ca(pa(e),t),samplingResultVariant:()=>wa,outboundEnvelope(e){return{[Ie]:e.protocolVersion,[Le]:e.clientInfo,[ze]:e.clientCapabilities,...e.logLevel!==void 0&&{"io.modelcontextprotocol/logLevel":e.logLevel}}},validateEnvelopeMeta(e){let t=[];for(let n of Ta)n in e||t.push({key:n,problem:`missing`});let n=Vi().RequestMetaEnvelopeSchema.safeParse(e);if(!n.success)for(let e of n.error.issues){let n=e.path.map(String),r=n.length>0?n.join(`.`):`_meta`;n.length===1&&t.some(e=>e.key===r&&e.problem===`missing`)||t.push({key:r,problem:e.message})}return t},projectCallToolResult:e=>di(e),inputRequestSchema:fa,decodeResult(e,t){if(!Sa(t))return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: not an object`,{method:e})};let n=t.resultType;if(n===void 0)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: missing required resultType — servers implementing protocol revision 2026-07-28 MUST include it (the absent-means-complete bridge applies only to earlier-revision servers)`,{method:e,violation:`missing-resultType`})};if(typeof n!=`string`)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: non-string resultType`,{method:e,resultType:n})};if(n===`input_required`){let n=t.inputRequests,r=Sa(n)?n:{},i=t.requestState,a=t._meta===void 0?void 0:Vi().ResultMetaSchema.safeParse(t._meta),o=a?.success?a.data:void 0;return Object.keys(r).length===0&&typeof i!=`string`?{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: input_required carries neither inputRequests nor requestState (every input_required result must include at least one of the two)`,{method:e,violation:`input-required-missing-both`})}:{kind:`input_required`,inputRequests:r,...typeof i==`string`&&{requestState:i},...o!==void 0&&{_meta:o}}}if(n!==`complete`)return{kind:`invalid`,error:new Y(J.UnsupportedResultType,`Unsupported result type '${n}' for ${e}`,{resultType:n,method:e})};let r=ka(),i=Object.hasOwn(r,e)?r[e]:void 0;if(i!==void 0){let n=i.safeParse(t);if(!n.success)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: ${n.error}`,{method:e})}}let a={...t};return delete a.resultType,{kind:`complete`,result:a}},encodeResult(e,t,n){return ia(na(e,ta(e,Ea(e,t))),n)},encodeErrorCode:e=>e===-32002?-32602:e,checkInboundEnvelope(e){if(e.envelope===void 0)return`Request is missing the required _meta envelope for protocol revision 2026-07-28 (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities)`;let t=Vi().RequestMetaEnvelopeSchema.safeParse(e.envelope);if(!t.success)return`Invalid _meta envelope for protocol revision 2026-07-28: ${t.error.issues.map(e=>e.message).join(`; `)}`}},Oa;function ka(){if(Oa)return Oa;let e=Vi();return Oa={"tools/call":e.CallToolResultSchema,"tools/list":e.ListToolsResultSchema,"prompts/get":e.GetPromptResultSchema,"prompts/list":e.ListPromptsResultSchema,"resources/list":e.ListResourcesResultSchema,"resources/templates/list":e.ListResourceTemplatesResultSchema,"resources/read":e.ReadResourceResultSchema,"completion/complete":e.CompleteResultSchema,"server/discover":e.DiscoverResultSchema},Oa}var Aa=`2026-07-28`;function ja(e){return e!==void 0&&ci(e)?Da:Ri}function Ma(e){return e.revision===void 0?e.era===`modern`?Da.era:Ri.era:ja(e.revision).era}function Na(e){return Ia.some(t=>t.hasRequestMethod(e))}function Pa(e){return Ia.some(t=>t.hasNotificationMethod(e))}function Fa(e){return e===`tasks/get`||e===`tasks/cancel`}var Ia=[Ri,Da],La=we({AnnotationsSchema:()=>Nt,AudioContentSchema:()=>ln,BaseMetadataSchema:()=>ct,BaseRequestParamsSchema:()=>I,BlobResourceContentsSchema:()=>jt,BooleanSchemaSchema:()=>Wn,CallToolRequestParamsSchema:()=>wn,CallToolRequestSchema:()=>Tn,CallToolResultSchema:()=>Sn,CancelTaskRequestSchema:()=>Ar,CancelTaskResultSchema:()=>jr,CancelledNotificationParamsSchema:()=>it,CancelledNotificationSchema:()=>at,ClientCapabilitiesSchema:()=>pt,ClientNotificationSchema:()=>Nr,ClientRequestSchema:()=>Mr,ClientResultSchema:()=>Pr,ClientTasksCapabilitySchema:()=>dt,CompatibilityCallToolResultSchema:()=>Cn,CompleteRequestParamsSchema:()=>dr,CompleteRequestSchema:()=>fr,CompleteResultSchema:()=>pr,ContentBlockSchema:()=>pn,CreateMessageRequestParamsSchema:()=>Bn,CreateMessageRequestSchema:()=>Vn,CreateMessageResultSchema:()=>Hn,CreateMessageResultWithToolsSchema:()=>Un,CreateTaskResultSchema:()=>xr,CursorSchema:()=>Ge,DiscoverRequestSchema:()=>yt,DiscoverResultSchema:()=>bt,ElicitRequestFormParamsSchema:()=>nr,ElicitRequestParamsSchema:()=>ir,ElicitRequestSchema:()=>ar,ElicitRequestURLParamsSchema:()=>rr,ElicitResultSchema:()=>cr,ElicitationCompleteNotificationParamsSchema:()=>or,ElicitationCompleteNotificationSchema:()=>sr,EmbeddedResourceSchema:()=>dn,EmptyResultSchema:()=>rt,EnumSchemaSchema:()=>er,GetPromptRequestParamsSchema:()=>on,GetPromptRequestSchema:()=>sn,GetPromptResultSchema:()=>hn,GetTaskPayloadRequestSchema:()=>Er,GetTaskPayloadResultSchema:()=>Dr,GetTaskRequestSchema:()=>wr,GetTaskResultSchema:()=>Tr,IconSchema:()=>ot,IconsSchema:()=>st,ImageContentSchema:()=>K,ImplementationSchema:()=>H,InitializeRequestParamsSchema:()=>mt,InitializeRequestSchema:()=>ht,InitializeResultSchema:()=>_t,InitializedNotificationSchema:()=>vt,JSONArraySchema:()=>Ue,JSONObjectSchema:()=>F,JSONRPCErrorResponseSchema:()=>et,JSONRPCMessageSchema:()=>tt,JSONRPCNotificationSchema:()=>$e,JSONRPCRequestSchema:()=>Qe,JSONRPCResponseSchema:()=>nt,JSONRPCResultResponseSchema:()=>V,JSONValueSchema:()=>He,LegacyTitledEnumSchemaSchema:()=>Yn,ListChangedOptionsBaseSchema:()=>Dn,ListPromptsRequestSchema:()=>rn,ListPromptsResultSchema:()=>an,ListResourceTemplatesRequestSchema:()=>U,ListResourceTemplatesResultSchema:()=>W,ListResourcesRequestSchema:()=>It,ListResourcesResultSchema:()=>Lt,ListRootsRequestSchema:()=>hr,ListRootsResultSchema:()=>gr,ListTasksRequestSchema:()=>Or,ListTasksResultSchema:()=>kr,ListToolsRequestSchema:()=>bn,ListToolsResultSchema:()=>xn,LoggingLevelSchema:()=>On,LoggingMessageNotificationParamsSchema:()=>jn,LoggingMessageNotificationSchema:()=>Mn,ModelHintSchema:()=>Nn,ModelPreferencesSchema:()=>Pn,MultiSelectEnumSchemaSchema:()=>$n,NotificationSchema:()=>z,NotificationsParamsSchema:()=>R,NumberSchemaSchema:()=>Kn,PaginatedRequestParamsSchema:()=>Tt,PaginatedRequestSchema:()=>Et,PaginatedResultSchema:()=>Dt,PingRequestSchema:()=>xt,PrimitiveSchemaDefinitionSchema:()=>tr,ProgressNotificationParamsSchema:()=>Ct,ProgressNotificationSchema:()=>wt,ProgressSchema:()=>St,ProgressTokenSchema:()=>We,PromptArgumentSchema:()=>G,PromptListChangedNotificationSchema:()=>gn,PromptMessageSchema:()=>mn,PromptReferenceSchema:()=>ur,PromptSchema:()=>nn,ReadResourceRequestParamsSchema:()=>zt,ReadResourceRequestSchema:()=>Bt,ReadResourceResultSchema:()=>Vt,RelatedTaskMetadataSchema:()=>qe,RequestIdSchema:()=>Ze,RequestMetaSchema:()=>Je,RequestSchema:()=>L,ResourceContentsSchema:()=>Ot,ResourceLinkSchema:()=>fn,ResourceListChangedNotificationSchema:()=>Ht,ResourceRequestParamsSchema:()=>Rt,ResourceSchema:()=>Pt,ResourceTemplateReferenceSchema:()=>lr,ResourceTemplateSchema:()=>Ft,ResourceUpdatedNotificationParamsSchema:()=>en,ResourceUpdatedNotificationSchema:()=>tn,ResultMetaObjectSchema:()=>Xe,ResultSchema:()=>B,RoleSchema:()=>Mt,RootSchema:()=>mr,RootsListChangedNotificationSchema:()=>_r,SamplingContentSchema:()=>Ln,SamplingMessageContentBlockSchema:()=>Rn,SamplingMessageSchema:()=>zn,ServerCapabilitiesSchema:()=>gt,ServerNotificationSchema:()=>Ir,ServerRequestSchema:()=>Fr,ServerResultSchema:()=>Lr,ServerTasksCapabilitySchema:()=>ft,SetLevelRequestParamsSchema:()=>kn,SetLevelRequestSchema:()=>An,SingleSelectEnumSchemaSchema:()=>Xn,StringSchemaSchema:()=>Gn,SubscribeRequestParamsSchema:()=>Ut,SubscribeRequestSchema:()=>Wt,SubscriptionFilterSchema:()=>qt,SubscriptionsAcknowledgedNotificationParamsSchema:()=>Xt,SubscriptionsAcknowledgedNotificationSchema:()=>Zt,SubscriptionsListenRequestParamsSchema:()=>Jt,SubscriptionsListenRequestSchema:()=>Yt,SubscriptionsListenResultMetaSchema:()=>Qt,SubscriptionsListenResultSchema:()=>$t,TaskAugmentedRequestParamsSchema:()=>Ye,TaskCreationParamsSchema:()=>vr,TaskMetadataSchema:()=>Ke,TaskSchema:()=>br,TaskStatusNotificationParamsSchema:()=>Sr,TaskStatusNotificationSchema:()=>Cr,TaskStatusSchema:()=>yr,TextContentSchema:()=>cn,TextResourceContentsSchema:()=>kt,TitledMultiSelectEnumSchemaSchema:()=>Qn,TitledSingleSelectEnumSchemaSchema:()=>Jn,ToolAnnotationsSchema:()=>_n,ToolChoiceSchema:()=>Fn,ToolExecutionSchema:()=>vn,ToolListChangedNotificationSchema:()=>En,ToolResultContentSchema:()=>In,ToolSchema:()=>yn,ToolUseContentSchema:()=>un,UnsubscribeRequestParamsSchema:()=>Gt,UnsubscribeRequestSchema:()=>Kt,UntitledMultiSelectEnumSchemaSchema:()=>Zn,UntitledSingleSelectEnumSchemaSchema:()=>qn}),Ra=e=>Qe.safeParse(e).success,za=e=>$e.safeParse(e).success,Ba=e=>V.safeParse(e).success,Va=e=>et.safeParse(e).success,Ha=e=>typeof e==`object`&&!!e&&!Array.isArray(e)&&e.resultType===`input_required`,Ua=e=>ht.safeParse(e).success,Wa=e=>vt.safeParse(e).success,Ga=`Mcp-Param-`,Ka=`x-mcp-header`,qa=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,Ja=new Set([`string`,`integer`,`boolean`,`number`]);function Ya(e){let t=[],n=new Map,r=(e,i,a)=>{if(typeof e!=`object`||!e)return;let o=e;if(Ka in o){if(!a||i.length===0)return`${Qa(i)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;let e=o[Ka];if(typeof e!=`string`||e.length===0)return`${Qa(i)}: x-mcp-header MUST be a non-empty string`;if(!qa.test(e))return`${Qa(i)}: x-mcp-header '${e}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;let r=typeof o.type==`string`?o.type:void 0;if(r===void 0||!Ja.has(r))return`${Qa(i)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${r??``}`;let s=e.toLowerCase(),c=n.get(s);if(c!==void 0)return`x-mcp-header '${e}' is not case-insensitively unique (also declared as '${c}')`;n.set(s,e),t.push({path:i,headerName:e,type:r})}let s=o.properties;if(typeof s==`object`&&s)for(let[e,t]of Object.entries(s)){let n=r(t,[...i,e],a);if(n!==void 0)return n}for(let e of Xa){let t=o[e];if(t===void 0)continue;let n=Array.isArray(t)?t:typeof t==`object`&&t&&Za.has(e)?Object.values(t):[t];for(let t of n){let n=r(t,[...i,`<${e}>`],!1);if(n!==void 0)return n}}},i=r(e,[],!0);return i===void 0?{valid:!0,declarations:t}:{valid:!1,reason:i}}var Xa=[`items`,`prefixItems`,`contains`,`additionalProperties`,`unevaluatedProperties`,`unevaluatedItems`,`propertyNames`,`patternProperties`,`dependentSchemas`,`oneOf`,`anyOf`,`allOf`,`not`,`if`,`then`,`else`,`$defs`,`definitions`],Za=new Set([`patternProperties`,`dependentSchemas`,`$defs`,`definitions`]);function Qa(e){return e.length===0?``:e.join(`.`)}var $a=`=?base64?`,eo=`?=`;function to(e){if(typeof e==`string`)return e;if(typeof e==`boolean`)return e?`true`:`false`;if(typeof e==`number`)return!Number.isFinite(e)||Number.isInteger(e)&&!Number.isSafeInteger(e)?void 0:String(e)}function no(e){if(e.length===0||e.startsWith($a)&&e.endsWith(eo)||e!==e.trim())return!0;for(let t=0;t=32&&n<=126))return!0}return!1}function ro(e){let t=new TextEncoder().encode(e),n=``;for(let e of t)n+=String.fromCodePoint(e);return btoa(n)}function io(e){return no(e)?`${$a}${ro(e)}${eo}`:e}function ao(e,t){let n=e;for(let e of t){if(typeof n!=`object`||!n)return;n=n[e]}return n}function oo(e,t){let n={};for(let r of e){let e=ao(t,r.path);if(e==null)continue;let i=to(e);i!==void 0&&(n[`${Ga}${r.headerName}`]=io(i))}return n}X.InvalidRequest,X.UnsupportedProtocolVersion,X.InvalidParams,X.MethodNotFound,X.InvalidParams,X.MissingRequiredClientCapability,X.ParseError,X.InvalidRequest,X.MethodNotFound,X.UnsupportedProtocolVersion,X.MissingRequiredClientCapability;var so={"tools/call":`name`,"prompts/get":`name`,"resources/read":`uri`,"tasks/get":`taskId`,"tasks/update":`taskId`,"tasks/cancel":`taskId`};function co(e,t){let n=Object.hasOwn(so,e)?so[e]:void 0;if(n===void 0)return;let r=lo(t)?t[n]:void 0;return{field:n,value:typeof r==`string`?r:void 0}}function lo(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function uo(e,t){return ee(e,t)}function fo(e){return new Set(e.flatMap(e=>Object.keys(e.shape)))}function po(e){if(e==null)return!1;let t=typeof e;return t!==`object`&&t!==`function`||!(`~standard`in e)?!1:typeof e[`~standard`]?.validate==`function`}var mo=!1,ho=`draft-2020-12`;function go(e,t=`input`){let n=e[`~standard`],r;if(n.jsonSchema)r=n.jsonSchema[t]({target:ho});else if(n.vendor===`zod`){if(!(`_zod`in e))throw Error(`Schema appears to be from zod 3, which the SDK cannot convert to JSON Schema. Upgrade to zod >=4.2.0, or wrap your JSON Schema with fromJsonSchema().`);mo||(mo=!0,console.warn("[mcp-sdk] Your zod version does not implement `~standard.jsonSchema` (added in zod 4.2.0). Falling back to z.toJSONSchema(). Upgrade to zod >=4.2.0 to silence this warning.")),r=h(e,{target:ho,io:t})}else throw Error(`Schema library "${n.vendor}" does not implement StandardJSONSchemaV1 (\`~standard.jsonSchema\`). Upgrade to a version that does, or wrap your JSON Schema with fromJsonSchema().`);if(t===`output`)return r.type===void 0&&_o(r)?{type:`object`,...r}:r;if(r.type!==void 0&&r.type!==`object`)throw Error(`MCP tool and prompt schemas must describe objects (got type: ${JSON.stringify(r.type)}). Wrap your schema in z.object({...}) or equivalent.`);return{type:`object`,...r}}function _o(e){if(`properties`in e||`patternProperties`in e||`additionalProperties`in e||`required`in e)return!0;for(let t of[`oneOf`,`anyOf`,`allOf`]){let n=e[t];if(Array.isArray(n)&&n.length>0)return n.every(e=>typeof e==`object`&&!!e&&(e.type===`object`||_o(e)))}return!1}function vo(e){return e.path?.length?`${e.path.map(e=>String(typeof e==`object`?e.key:e)).join(`.`)}: ${e.message}`:e.message}async function yo(e,t){let n=await e[`~standard`].validate(t);return n.issues&&n.issues.length>0?{success:!1,error:n.issues.map(e=>vo(e)).join(`, `)}:{success:!0,data:n.value}}function bo(e){let t=h(e,{target:ho,io:`input`});return typeof t.pattern==`string`?t.pattern:void 0}var xo=/\\\.\\d\{(\d+)\}/;function So(e){let t=xo.exec(e),n=[void 0,-1,0];return t&&n.push(Number(t[1])),[!1,!0].flatMap(e=>[!1,!0].flatMap(t=>n.map(n=>he({local:e,offset:t,precision:n}))))}function Co(e,t){let n;switch(e){case`email`:n=[de()];break;case`uri`:n=[y()];break;case`date`:n=[ge()];break;case`date-time`:n=So(t)}return new Set(n.map(e=>bo(e)).filter(e=>e!==void 0))}function wo(e,t,n){return n!==`zod`||Co(e,t).has(t)}function To(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Eo(e){try{return go(e,`input`)}catch(e){let t=e instanceof Error?e.message:String(e);throw new Z(X.InvalidParams,`Elicitation requestedSchema must describe an object with flat primitive properties: ${t}`)}}var Do=new Set([`$comment`,`deprecated`,`description`,`examples`,`readOnly`,`title`,`writeOnly`]);function Oo(e){return Do.has(e)||e.startsWith(`x-`)}var ko=new Set([`$schema`,...Object.keys(nr.shape.requestedSchema.shape)]),Ao={string:fo([Gn,qn,Jn,Yn]),number:fo([Kn]),integer:fo([Kn]),boolean:fo([Wn]),array:fo([Zn,Qn])},jo=new Set(Gn.shape.format.unwrap().options);function Mo(e,t,n,r){if(!To(e))return e;let i=typeof e.type==`string`&&Object.hasOwn(Ao,e.type)?Ao[e.type]:void 0;if(i===void 0)return e;let a={};for(let[o,s]of Object.entries(e))i.has(o)||Oo(o)?a[o]=s:o===`pattern`&&e.type===`string`&&typeof e.format==`string`?jo.has(e.format)?(typeof s!=`string`||!wo(e.format,s,n))&&r.push(`${t}.${o}`):a[o]=s:r.push(`${t}.${o}`);return a}function No(e,t){let n={},r=[];for(let[i,a]of Object.entries(e))i===`properties`&&To(a)?n[i]=Object.fromEntries(Object.entries(a).map(([e,n])=>[e,Mo(n,`properties.${e}`,t,r)])):ko.has(i)?n[i]=a:Oo(i)||r.push(i);if(r.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema contains unsupported JSON Schema constraint(s) after Standard Schema conversion: ${r.join(`, `)}`);return n}function Po(e,t){if(!To(e.properties))return t;let n=Object.entries(e.properties).filter(([,e])=>!uo(tr,e).success).map(([e])=>`properties.${e}`);return n.length>0?n.join(`, `):t}function Fo(e,t,n=``){return Array.isArray(e)&&Array.isArray(t)?e.flatMap((e,r)=>Fo(e,t[r],`${n}[${r}]`)):!To(e)||!To(t)?[]:Object.entries(e).flatMap(([e,r])=>{let i=n?`${n}.${e}`:e;return Object.prototype.hasOwnProperty.call(t,e)?Fo(r,t[e],i):Oo(e)?[]:[i]})}function Io(e){if(!po(e.requestedSchema))return{...e,mode:`form`,requestedSchema:e.requestedSchema};let t=e.requestedSchema[`~standard`].vendor,n=No(Eo(e.requestedSchema),t),r=uo(nr.shape.requestedSchema,n);if(!r.success)throw new Z(X.InvalidParams,`Elicitation requestedSchema only supports flat primitive properties (string, number, integer, boolean, and string enums): ${Po(n,r.error.message)}`);let i=Fo(n,r.data);if(i.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema contains unsupported JSON Schema constraint(s) after Standard Schema conversion: ${i.join(`, `)}`);let a=(r.data.required??[]).filter(e=>!Object.prototype.hasOwnProperty.call(r.data.properties,e));if(a.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema lists required properties that are not defined in properties: ${a.join(`, `)}`);return{...e,mode:`form`,requestedSchema:r.data}}function Lo(e){let t=e.inputRequests!==void 0&&Object.keys(e.inputRequests).length>0,n=typeof e.requestState==`string`;if(!t&&!n)throw TypeError(`inputRequired() requires at least one of inputRequests (with at least one entry) or requestState (spec: every InputRequiredResult MUST include at least one of the two)`);return{resultType:`input_required`,...e.inputRequests!==void 0&&{inputRequests:e.inputRequests},...e.requestState!==void 0&&{requestState:e.requestState}}}Object.assign(Lo,{elicit(e){try{return{method:`elicitation/create`,params:Io(e)}}catch(e){throw e instanceof Z?TypeError(e.message,{cause:e}):e}},elicitUrl(e){return{method:`elicitation/create`,params:{...e,mode:`url`}}},createMessage(e){return{method:`sampling/createMessage`,params:e}},listRoots(){return{method:`roots/list`}}});var Ro=!0,zo=10,Bo=250;function Vo(e){return{autoFulfill:e?.autoFulfill??Ro,maxRounds:e?.maxRounds??zo}}function Ho(e,t,n){let r=t!==void 0&&Object.keys(t).length>0;return!r&&n===void 0?e:{...e,...r&&{inputResponses:t},...n!==void 0&&{requestState:n}}}function Uo(e,t){return`Multi-round-trip request '${e}' still required input after ${t} rounds (inputRequired.maxRounds)`}function Wo(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason instanceof Y?t.reason:new Y(J.RequestTimeout,String(t.reason)));return}let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason instanceof Y?t.reason:new Y(J.RequestTimeout,String(t?.reason)))};t?.addEventListener(`abort`,a,{once:!0})})}function Go(e){let t=new AbortController,n=()=>t.abort(e?.reason);return e?.addEventListener(`abort`,n,{once:!0}),e?.aborted&&t.abort(e.reason),{signal:t.signal,abort:e=>t.abort(e),dispose:()=>e?.removeEventListener(`abort`,n)}}async function Ko(e){let{config:t,method:n,originalParams:r,requestOptions:i,hooks:a,signal:o}=e,s=e.flowStartedAt??Date.now(),c=e.firstPayload,l=0;for(;;){if(l+=1,l>t.maxRounds)throw new Y(J.InputRequiredRoundsExceeded,Uo(n,t.maxRounds),{rounds:t.maxRounds,lastResult:{inputRequests:c.inputRequests,...c.requestState!==void 0&&{requestState:c.requestState}}});i.onprogress?.({progress:l,message:`Fulfilling input required by '${n}' (round ${l})`});let e=Object.entries(c.inputRequests??{}),u;if(e.length>0){let t=Go(o);try{let n=await Promise.all(e.map(async([e,n])=>{try{return[e,await a.dispatchInputRequest(e,n,t.signal)]}catch(e){throw t.abort(e),e}}));u=Object.fromEntries(n)}finally{t.dispose()}}else await Wo(Bo,o);let d={...i.timeout!==void 0&&{timeout:i.timeout}};if(i.maxTotalTimeout!==void 0){let e=Date.now()-s,t=i.maxTotalTimeout-e;if(t<=0)throw new Y(J.RequestTimeout,`Maximum total timeout exceeded`,{maxTotalTimeout:i.maxTotalTimeout,totalElapsed:e});d.maxTotalTimeout=t}let f=await a.retry(Ho(r,u,c.requestState),d);if(Ha(f)){c={inputRequests:f.inputRequests??{},...f.requestState!==void 0&&{requestState:f.requestState}};continue}return f}}var qo=`AnnotationsSchema.AudioContentSchema.BaseMetadataSchema.BlobResourceContentsSchema.BooleanSchemaSchema.CallToolRequestSchema.CallToolRequestParamsSchema.CallToolResultSchema.CancelledNotificationSchema.CancelledNotificationParamsSchema.CancelTaskRequestSchema.CancelTaskResultSchema.ClientCapabilitiesSchema.ClientNotificationSchema.ClientRequestSchema.ClientResultSchema.CompatibilityCallToolResultSchema.CompleteRequestSchema.CompleteRequestParamsSchema.CompleteResultSchema.ContentBlockSchema.CreateMessageRequestSchema.CreateMessageRequestParamsSchema.CreateMessageResultSchema.CreateMessageResultWithToolsSchema.CreateTaskResultSchema.CursorSchema.DiscoverRequestSchema.DiscoverResultSchema.ElicitationCompleteNotificationSchema.ElicitationCompleteNotificationParamsSchema.ElicitRequestSchema.ElicitRequestFormParamsSchema.ElicitRequestParamsSchema.ElicitRequestURLParamsSchema.ElicitResultSchema.EmbeddedResourceSchema.EmptyResultSchema.EnumSchemaSchema.GetPromptRequestSchema.GetPromptRequestParamsSchema.GetPromptResultSchema.GetTaskPayloadRequestSchema.GetTaskPayloadResultSchema.GetTaskRequestSchema.GetTaskResultSchema.IconSchema.IconsSchema.ImageContentSchema.ImplementationSchema.InitializedNotificationSchema.InitializeRequestSchema.InitializeRequestParamsSchema.InitializeResultSchema.JSONArraySchema.JSONObjectSchema.JSONRPCErrorResponseSchema.JSONRPCMessageSchema.JSONRPCNotificationSchema.JSONRPCRequestSchema.JSONRPCResponseSchema.JSONRPCResultResponseSchema.JSONValueSchema.LegacyTitledEnumSchemaSchema.ListPromptsRequestSchema.ListPromptsResultSchema.ListResourcesRequestSchema.ListResourcesResultSchema.ListResourceTemplatesRequestSchema.ListResourceTemplatesResultSchema.ListRootsRequestSchema.ListRootsResultSchema.ListTasksRequestSchema.ListTasksResultSchema.ListToolsRequestSchema.ListToolsResultSchema.LoggingLevelSchema.LoggingMessageNotificationSchema.LoggingMessageNotificationParamsSchema.ModelHintSchema.ModelPreferencesSchema.MultiSelectEnumSchemaSchema.NotificationSchema.NumberSchemaSchema.PaginatedRequestSchema.PaginatedRequestParamsSchema.PaginatedResultSchema.PingRequestSchema.PrimitiveSchemaDefinitionSchema.ProgressSchema.ProgressNotificationSchema.ProgressNotificationParamsSchema.ProgressTokenSchema.PromptSchema.PromptArgumentSchema.PromptListChangedNotificationSchema.PromptMessageSchema.PromptReferenceSchema.ReadResourceRequestSchema.ReadResourceRequestParamsSchema.ReadResourceResultSchema.RelatedTaskMetadataSchema.RequestSchema.RequestIdSchema.RequestMetaSchema.ResourceSchema.ResourceContentsSchema.ResourceLinkSchema.ResourceListChangedNotificationSchema.ResourceRequestParamsSchema.ResourceTemplateSchema.ResourceTemplateReferenceSchema.ResourceUpdatedNotificationSchema.ResourceUpdatedNotificationParamsSchema.ResultMetaObjectSchema.ResultSchema.RoleSchema.RootSchema.RootsListChangedNotificationSchema.SamplingContentSchema.SamplingMessageSchema.SamplingMessageContentBlockSchema.ServerCapabilitiesSchema.ServerNotificationSchema.ServerRequestSchema.ServerResultSchema.SetLevelRequestSchema.SetLevelRequestParamsSchema.SingleSelectEnumSchemaSchema.StringSchemaSchema.SubscribeRequestSchema.SubscribeRequestParamsSchema.SubscriptionFilterSchema.SubscriptionsAcknowledgedNotificationSchema.SubscriptionsAcknowledgedNotificationParamsSchema.SubscriptionsListenRequestSchema.SubscriptionsListenRequestParamsSchema.SubscriptionsListenResultSchema.SubscriptionsListenResultMetaSchema.TaskAugmentedRequestParamsSchema.TaskCreationParamsSchema.TaskMetadataSchema.TaskSchema.TaskStatusSchema.TaskStatusNotificationSchema.TaskStatusNotificationParamsSchema.TextContentSchema.TextResourceContentsSchema.TitledMultiSelectEnumSchemaSchema.TitledSingleSelectEnumSchemaSchema.ToolSchema.ToolAnnotationsSchema.ToolChoiceSchema.ToolExecutionSchema.ToolListChangedNotificationSchema.ToolResultContentSchema.ToolUseContentSchema.UnsubscribeRequestSchema.UnsubscribeRequestParamsSchema.UntitledMultiSelectEnumSchemaSchema.UntitledSingleSelectEnumSchemaSchema`.split(`.`),Jo={IdJagTokenExchangeResponseSchema:Ur,OAuthClientInformationFullSchema:Jr,OAuthClientInformationSchema:qr,OAuthClientMetadataSchema:Kr,OAuthClientRegistrationErrorSchema:Yr,OAuthErrorResponseSchema:Wr,OAuthMetadataSchema:zr,OAuthProtectedResourceMetadataSchema:Rr,OAuthTokenRevocationRequestSchema:Xr,OAuthTokensSchema:Hr,OpenIdProviderDiscoveryMetadataSchema:Vr,OpenIdProviderMetadataSchema:Br},Yo={},Xo={};function Zo(e,t){let n=e.slice(0,-6);Yo[n]=t,Xo[n]=e=>t.safeParse(e).success}for(let e of qo)Zo(e,La[e]);for(let[e,t]of Object.entries(Jo))Zo(e,t);Object.freeze(Yo);var Qo=Object.freeze(Xo);function $o(e){switch(e){case`initialize`:case`notifications/initialized`:return ja(void 0);case`server/discover`:return ja(Aa);default:return}}var es=[Ie,Le,ze,Ve],ts=[`inputResponses`,`requestState`];function ns(e,t){let n=e.params;if(!ss(n))return{message:e,lifted:{}};let r=n._meta,i=ss(r)?es.filter(e=>e in r):[],a=t===`request`?ts.filter(e=>e in n):[];if(i.length===0&&a.length===0)return{message:e,lifted:{}};let o={},s={...n};if(i.length>0&&ss(r)){let e={},t={...r};for(let n of i)e[n]=r[n],delete t[n];o.envelope=e,Object.keys(t).length>0?s._meta=t:delete s._meta}for(let e of a)e===`inputResponses`&&(o.inputResponses=s[e]),e===`requestState`&&(o.requestState=s[e]),delete s[e];return{message:{...e,params:s},lifted:o}}function rs(e,t){let n=e.validateResult(t,void 0);if(n.ok||n.reason!==`not-in-era`)return{"~standard":{version:1,vendor:`mcp-wire-codec`,validate(n){let r=e.validateResult(t,n);return r.ok?{value:r.value}:{issues:[{message:r.reason===`invalid`?r.message:`not-in-era: ${t}`}]}}}}}function is(e){return()=>e}var as=is(void 0),os=class{_transport;_requestMessageId=0;_requestHandlers=new Map;_customSchemaRequestMethods=new Set;_requestHandlerAbortControllers=new Map;_notificationHandlers=new Map;_responseHandlers=new Map;_progressHandlers=new Map;_timeoutInfo=new Map;_pendingDebouncedNotifications=new Set;_negotiatedProtocolVersion;_supportedProtocolVersions;onclose;onerror;fallbackRequestHandler;fallbackNotificationHandler;constructor(e){this._options=e,this._supportedProtocolVersions=e?.supportedProtocolVersions??Pe,this.setNotificationHandler(`notifications/cancelled`,e=>{this._oncancel(e)}),this.setNotificationHandler(`notifications/progress`,e=>{this._onprogress(e)}),this.setRequestHandler(`ping`,e=>({}))}_shouldDropInbound(e){}_outboundMetaEnvelope(){}_envelopeOutbound(e){let t=this._outboundMetaEnvelope();if(t===void 0)return e;let n=e.params??{};return{...e,params:{...n,_meta:{...t,...n._meta}}}}_resolveNonCompleteResult(e,t){return Promise.reject(new Y(J.UnsupportedResultType,`Unsupported result type '${e.kind}' for ${t.request.method}`,{resultType:e.kind,method:t.request.method}))}_getRequestHandler(e){return this._requestHandlers.get(e)}async _oncancel(e){e.params.requestId!==void 0&&this._requestHandlerAbortControllers.get(e.params.requestId)?.abort(e.params.reason)}_setupTimeout(e,t,n,r,i=!1){this._timeoutInfo.set(e,{timeoutId:setTimeout(r,t),startTime:Date.now(),timeout:t,maxTotalTimeout:n,resetTimeoutOnProgress:i,onTimeout:r})}_resetTimeout(e){let t=this._timeoutInfo.get(e);if(!t)return!1;let n=Date.now()-t.startTime;if(t.maxTotalTimeout&&n>=t.maxTotalTimeout)throw this._timeoutInfo.delete(e),new Y(J.RequestTimeout,`Maximum total timeout exceeded`,{maxTotalTimeout:t.maxTotalTimeout,totalElapsed:n});return clearTimeout(t.timeoutId),t.timeoutId=setTimeout(t.onTimeout,t.timeout),!0}_cleanupTimeout(e){let t=this._timeoutInfo.get(e);t&&(clearTimeout(t.timeoutId),this._timeoutInfo.delete(e))}async connect(e){this._transport=e;let t=this.transport?.onclose;this._transport.onclose=()=>{try{t?.()}finally{this._onclose()}};let n=this.transport?.onerror;this._transport.onerror=e=>{n?.(e),this._onerror(e)};let r=this._transport?.onmessage;this._transport.onmessage=(e,t)=>{r?.(e,t),Ba(e)||Va(e)?this._onresponse(e):Ra(e)?this._onrequest(e,t):za(e)?this._onnotification(e,t):this._onerror(Error(`Unknown message type: ${JSON.stringify(e)}`))},e.setSupportedProtocolVersions?.(this._supportedProtocolVersions),await this._transport.start()}_onclose(){let e=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._pendingDebouncedNotifications.clear();for(let e of this._timeoutInfo.values())clearTimeout(e.timeoutId);this._timeoutInfo.clear();let t=this._requestHandlerAbortControllers;this._requestHandlerAbortControllers=new Map;let n=new Y(J.ConnectionClosed,`Connection closed`);this._transport=void 0;try{this.onclose?.()}finally{for(let t of e.values())t(n);for(let e of t.values())e.abort(n)}}_onerror(e){this.onerror?.(e)}_onnotification(e,t){let{message:n}=ns(e,`notification`),r=this._negotiatedWireCodec();if(t?.classification===void 0&&this._shouldDropInbound(e)===`drop`)return;if(t?.classification!==void 0){let e=Ma(t.classification);if(e!==r.era){this._onerror(Error(`Era mismatch on inbound notification '${n.method}': classified as ${e} but this instance serves ${r.era}`));return}}if(Pa(n.method)&&!r.hasNotificationMethod(n.method))return;let i=this._notificationHandlers.get(n.method),a=this.fallbackNotificationHandler;(i!==void 0||a!==void 0)&&Promise.resolve().then(()=>i===void 0?a(n):i(n,r)).catch(e=>this._onerror(Error(`Uncaught error in notification handler: ${e}`)))}_onrequest(e,t){let{message:n,lifted:r}=ns(e,`request`),i=this._negotiatedWireCodec();if(t?.classification===void 0&&this._shouldDropInbound(e)===`drop`){this._onerror(Error(`Dropped inbound request '${e.method}': not servable on this connection's protocol era`));return}let a=this._transport,o=(e,t,r)=>{let i={jsonrpc:`2.0`,id:n.id,error:{code:e,message:t,...r!==void 0&&{data:r}}};a?.send(i).catch(e=>this._onerror(Error(`Failed to send an error response: ${e}`)))};if(t?.classification!==void 0){let e=Ma(t.classification);if(e!==i.era){this._onerror(Error(`Era mismatch on inbound request '${n.method}': classified as ${e} but this instance serves ${i.era}`));let r=t.classification.revision??e;o(X.UnsupportedProtocolVersion,`Unsupported protocol version: ${r}`,{supported:this._supportedProtocolVersions,requested:r});return}}if(Na(n.method)&&!i.hasRequestMethod(n.method)&&!(Fa(n.method)&&this._customSchemaRequestMethods.has(n.method))){o(X.MethodNotFound,`Method not found`);return}let s=this._requestHandlers.get(n.method)??this.fallbackRequestHandler;if(s===void 0){o(X.MethodNotFound,`Method not found`);return}let c=i.checkInboundEnvelope(r);if(c!==void 0){o(X.InvalidParams,c);return}let l=(e,t)=>this._notificationViaCodec(this._resolveOutboundCodec(e.method),e,{...t,relatedRequestId:n.id}),u=(e,t,r)=>this._requestWithSchemaViaCodec(this._resolveOutboundCodec(e.method),e,t,{...r,relatedRequestId:n.id}),d=new AbortController;this._requestHandlerAbortControllers.set(n.id,d);let f=r.inputResponses===void 0?void 0:us(r.inputResponses),p={sessionId:a?.sessionId,mcpReq:{id:n.id,method:n.method,_meta:n.params?._meta,...r.envelope!==void 0&&{envelope:r.envelope},...f!==void 0&&{inputResponses:f.accepted},...f!==void 0&&f.droppedKeys.length>0&&{droppedInputResponseKeys:f.droppedKeys},requestState:r.requestState===void 0?as:is(r.requestState),signal:d.signal,send:((e,t,n)=>{let r=this._resolveOutboundCodec(e.method);if(this._assertOutboundRequestInEra(r,e.method),po(t))return u(e,t,n);let i=rs(r,e.method);if(i===void 0)throw TypeError(`'${e.method}' is not a spec method; pass a result schema as the second argument to ctx.mcpReq.send().`);return u(e,i,t)}),notify:l},http:t?.authInfo?{authInfo:t.authInfo}:void 0},m=this.buildContext(p,t);Promise.resolve().then(()=>s(n,m)).then(async e=>{if(d.signal.aborted)return;let t;try{t=i.encodeResult(n.method,e,this._outboundServerInfo())}catch(e){this._onerror(Error(`Failed to encode result for ${n.method}: ${e}`)),o(X.InternalError,`Internal error`);return}let r={result:t,jsonrpc:`2.0`,id:n.id};await a?.send(r)},async e=>{if(d.signal.aborted)return;let t=Number.isSafeInteger(e.code)?e.code:X.InternalError,r={jsonrpc:`2.0`,id:n.id,error:{code:i.encodeErrorCode(t),message:e.message??`Internal error`,...e.data!==void 0&&{data:e.data}}};await a?.send(r)}).catch(e=>this._onerror(Error(`Failed to send response: ${e}`))).finally(()=>{this._requestHandlerAbortControllers.get(n.id)===d&&this._requestHandlerAbortControllers.delete(n.id)})}_onprogress(e){let{progressToken:t,...n}=e.params,r=Number(t),i=this._progressHandlers.get(r);if(!i){this._onerror(Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}let a=this._responseHandlers.get(r),o=this._timeoutInfo.get(r);if(o&&a&&o.resetTimeoutOnProgress)try{this._resetTimeout(r)}catch(e){this._responseHandlers.delete(r),this._progressHandlers.delete(r),this._cleanupTimeout(r),a(e);return}i(n)}_onresponse(e){let t=Number(e.id),n=this._responseHandlers.get(t);if(n===void 0){this._onerror(Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}this._responseHandlers.delete(t),this._cleanupTimeout(t),this._progressHandlers.delete(t),Ba(e)?n(e):n(Z.fromError(e.error.code,e.error.message,e.error.data))}get transport(){return this._transport}async close(){await this._transport?.close()}request(e,t,n){let r=this._resolveOutboundCodec(e.method);if(po(t))return Fa(e.method)||this._assertOutboundRequestInEra(r,e.method),this._requestWithSchemaViaCodec(r,e,t,n);this._assertOutboundRequestInEra(r,e.method);let i=rs(r,e.method);if(i===void 0)throw TypeError(`'${e.method}' is not a spec method; pass a result schema as the second argument to request().`);return this._requestWithSchemaViaCodec(r,e,i,t)}_negotiatedWireCodec(){return ja(this._negotiatedProtocolVersion)}_wireCodec(){return this._negotiatedWireCodec()}_resolveOutboundCodec(e){if(this._negotiatedProtocolVersion===void 0){let t=$o(e);if(t)return t}return this._negotiatedWireCodec()}_assertOutboundRequestInEra(e,t){if(Na(t)&&!e.hasRequestMethod(t))throw new Y(J.MethodNotSupportedByProtocolVersion,`Method '${t}' is not supported by the negotiated protocol version (wire era ${e.era})`,{method:t,era:e.era})}_requestWithSchema(e,t,n){let r=this._resolveOutboundCodec(e.method);return this._assertOutboundRequestInEra(r,e.method),this._requestWithSchemaViaCodec(r,e,t,n)}_requestWithSchemaViaCodec(e,t,n,r){let{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o,headers:s}=r??{},c=Date.now(),l,u;return new Promise((d,f)=>{let p=e=>{f(e)};if(!this._transport){p(Error(`Not connected`));return}if(this._options?.enforceStrictCapabilities===!0)try{this.assertCapabilityForMethod(t.method)}catch(e){p(e);return}if(r?.signal?.aborted){let e=r.signal.reason;throw e instanceof Y?e:new Y(J.RequestTimeout,String(e))}let m=e.era===`2026-07-28`&&this._transport.hasPerRequestStream===!0?new AbortController:void 0,h=this._requestMessageId++;u=h;let g={...t,jsonrpc:`2.0`,id:h};r?.onprogress&&(this._progressHandlers.set(h,r.onprogress),g.params={...t.params,_meta:{...t.params?._meta,progressToken:h}});let _=this._envelopeOutbound(g),v=!1,y=e=>{v||(this._progressHandlers.delete(h),m===void 0?t.method!==`initialize`&&this._transport?.send(this._envelopeOutbound({jsonrpc:`2.0`,method:`notifications/cancelled`,params:{requestId:h,reason:String(e)}}),{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o}).catch(e=>this._onerror(Error(`Failed to send cancellation: ${e}`))):m.abort(),f(e instanceof Y?e:new Y(J.RequestTimeout,String(e))))};this._responseHandlers.set(h,i=>{if(r?.signal?.aborted)return;if(v=!0,i instanceof Error)return f(i);let a;try{a=e.decodeResult(t.method,i.result)}catch(e){return f(e instanceof Error?e:Error(String(e)))}if(a.kind===`invalid`)return f(a.error);if(a.kind===`input_required`){if(r?.allowInputRequired===!0)return d(gs(a));let i={codec:e,request:t,resultSchema:n,options:r,flowStartedAt:c,retry:(r,i)=>this._requestWithSchemaViaCodec(e,r===void 0?{method:t.method}:{method:t.method,params:r},n,i)};return d(this._resolveNonCompleteResult(a,i))}let o=a.result;yo(n,o).then(e=>{e.success?d(e.data):f(new Y(J.InvalidResult,`Invalid result for ${t.method}: ${e.error}`))},f)}),l=()=>y(r?.signal?.reason),r?.signal?.addEventListener(`abort`,l,{once:!0});let b=r?.timeout??6e4;this._setupTimeout(h,b,r?.maxTotalTimeout,()=>y(new Y(J.RequestTimeout,`Request timed out`,{timeout:b})),r?.resetTimeoutOnProgress??!1),this._transport.send(_,{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o,headers:s,requestSignal:m?.signal}).catch(e=>{this._progressHandlers.delete(h),f(e)})}).finally(()=>{l&&r?.signal?.removeEventListener(`abort`,l),u!==void 0&&(this._responseHandlers.delete(u),this._cleanupTimeout(u))})}async notification(e,t){return await this._notificationViaCodec(this._resolveOutboundCodec(e.method),e,t)}async _notificationViaCodec(e,t,n){if(!this._transport)throw new Y(J.NotConnected,`Not connected`);if(Pa(t.method)&&!e.hasNotificationMethod(t.method))throw new Y(J.MethodNotSupportedByProtocolVersion,`Notification '${t.method}' is not supported by the negotiated protocol version (wire era ${e.era})`,{method:t.method,era:e.era});this.assertNotificationCapability(t.method);let r=this._envelopeOutbound({jsonrpc:`2.0`,...t});if((this._options?.debouncedNotificationMethods??[]).includes(t.method)&&!t.params&&n?.relatedRequestId===void 0){if(this._pendingDebouncedNotifications.has(t.method))return;this._pendingDebouncedNotifications.add(t.method),Promise.resolve().then(()=>{this._pendingDebouncedNotifications.delete(t.method),this._transport&&this._transport?.send(r,n).catch(e=>this._onerror(e))});return}await this._transport.send(r,n)}setRequestHandler(e,t,n){this.assertRequestHandlerCapability(e);let r;if(typeof t==`function`){if(!Na(e))throw TypeError(`'${e}' is not a spec request method; pass schemas as the second argument to setRequestHandler().`);r=(n,r)=>{let i=this._negotiatedWireCodec(),a=i.validateRequest(e,n);if(!a.ok&&a.reason===`not-in-era`&&(a=i.validateInputRequest(e,n)),!a.ok)throw a.reason===`not-in-era`?new Z(X.InternalError,`No wire schema for ${e} in the resolved era`):Error(a.message);return Promise.resolve(t(a.value,r))}}else if(n)r=async(r,i)=>{let a=await yo(t.params,{...r.params});if(!a.success)throw new Z(X.InvalidParams,`Invalid params for ${e}: ${a.error}`);return n(a.data,i)};else throw TypeError(`setRequestHandler: handler is required`);typeof t==`function`?this._customSchemaRequestMethods.delete(e):this._customSchemaRequestMethods.add(e),this._requestHandlers.set(e,this._wrapHandler(e,r))}_wrapHandler(e,t){return t}_outboundServerInfo(){}removeRequestHandler(e){this._requestHandlers.delete(e),this._customSchemaRequestMethods.delete(e)}assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw Error(`A request handler for ${e} already exists, which would be overridden`)}setNotificationHandler(e,t,n){if(typeof t==`function`){if(!Pa(e))throw TypeError(`'${e}' is not a spec notification method; pass schemas as the second argument to setNotificationHandler().`);this._notificationHandlers.set(e,(n,r)=>{let i=r.validateNotification(e,n);if(!i.ok)throw i.reason===`not-in-era`?new Z(X.InternalError,`No wire schema for ${e} in the resolved era`):Error(i.message);return Promise.resolve(t(i.value))});return}if(!n)throw TypeError(`setNotificationHandler: handler is required`);this._notificationHandlers.set(e,async r=>{let i=await yo(t.params,{...r.params});if(!i.success)throw new Z(X.InvalidParams,`Invalid params for notification ${e}: ${i.error}`);await n(i.data,r)})}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};function ss(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function cs(e,t){let n={...e};for(let e in t){let r=e,i=t[r];if(i===void 0)continue;let a=n[r];n[r]=ss(a)&&ss(i)?{...a,...i}:i}return n}function ls(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function us(e){let t={},n=[];if(!ls(e))return{accepted:t,droppedKeys:n};for(let[r,i]of Object.entries(e)){if(!ls(i)||`method`in i||`result`in i){n.push(r);continue}t[r]=i}return{accepted:t,droppedKeys:n}}function ds(e){throw new Y(J.SendFailed,`ctx.mcpReq.${e} is not available while fulfilling an embedded input request: the request is fulfilled locally and has no related peer request`)}function fs(e,t,n,r,i){return{sessionId:i,mcpReq:{id:e,method:t,_meta:n?._meta,requestState:is(void 0),signal:r,send:(()=>ds(`send`)),notify:()=>ds(`notify`)}}}async function ps(e,t,n,r,i){if(!ls(r)||typeof r.method!=`string`)throw new Y(J.InvalidResult,`Invalid input request '${n}': each inputRequests entry must be an embedded request object with a method`,{key:n});let a=r.method;if(!t.hasInputRequestMethod(a))throw new Y(J.InvalidResult,`Invalid input request '${n}': '${a}' is not an embedded request the ${t.era} revision defines (expected elicitation/create, sampling/createMessage, or roots/list)`,{key:n,method:a});let o=e.getRequestHandler(a);if(o===void 0)throw new Y(J.CapabilityNotSupported,`Cannot fulfil input request '${n}': no handler is registered for '${a}' on this client. Declare the corresponding capability and register a handler, or handle input_required results manually.`,{key:n,method:a});let s=ls(r.params)?r.params:void 0;return await o({jsonrpc:`2.0`,id:n,method:a,...s!==void 0&&{params:s}},e.buildContext(fs(n,a,s,i,e.sessionId)))}function ms(e,t){return{...e?.signal!==void 0&&{signal:e.signal},...e?.onprogress!==void 0&&{onprogress:e.onprogress},...e?.resetTimeoutOnProgress!==void 0&&{resetTimeoutOnProgress:e.resetTimeoutOnProgress},...e?.headers!==void 0&&{headers:e.headers},...t.timeout!==void 0&&{timeout:t.timeout},...t.maxTotalTimeout!==void 0&&{maxTotalTimeout:t.maxTotalTimeout},allowInputRequired:!0}}function hs(e,t,n,r){let{codec:i,request:a,options:o,flowStartedAt:s}=r,c={inputRequests:n.inputRequests,...n.requestState!==void 0&&{requestState:n.requestState}},l={dispatchInputRequest:(t,n,r)=>ps(e,i,t,n,r),retry:(e,t)=>r.retry(e,ms(o,t))};return Ko({config:t,method:a.method,originalParams:a.params,firstPayload:c,flowStartedAt:s,signal:o?.signal,requestOptions:{...o?.timeout!==void 0&&{timeout:o.timeout},...o?.maxTotalTimeout!==void 0&&{maxTotalTimeout:o.maxTotalTimeout},...o?.onprogress!==void 0&&{onprogress:o.onprogress}},hooks:l})}function gs(e){return{resultType:`input_required`,inputRequests:e.inputRequests,...e.requestState!==void 0&&{requestState:e.requestState},...e._meta!==void 0&&{_meta:e._meta}}}var _s=Ee(Ce((e=>{var t=/; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g,n=/\\([\u000b\u0020-\u00ff])/g,r=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;e.parse=i;function i(e){if(!e)throw TypeError(`argument string is required`);var i=typeof e==`object`?a(e):e;if(typeof i!=`string`)throw TypeError(`argument string is required to be a string`);var s=i.indexOf(`;`),c=s===-1?i.trim():i.slice(0,s).trim();if(!r.test(c))throw TypeError(`invalid media type`);var l=new o(c.toLowerCase());if(s!==-1){var u,d,f;for(t.lastIndex=s;d=t.exec(i);){if(d.index!==s)throw TypeError(`invalid parameter format`);s+=d[0].length,u=d[1].toLowerCase(),f=d[2],f.charCodeAt(0)===34&&(f=f.slice(1,-1),f.indexOf(`\\`)!==-1&&(f=f.replace(n,`$1`))),l.parameters[u]=f}if(s!==i.length)throw TypeError(`invalid parameter format`)}return l}function a(e){var t;if(typeof e.getHeader==`function`?t=e.getHeader(`content-type`):typeof e.headers==`object`&&(t=e.headers&&e.headers[`content-type`]),typeof t!=`string`)throw TypeError(`content-type header is missing from object`);return t}function o(e){this.parameters=Object.create(null),this.type=e}}))(),1);function vs(e){if(e)try{return _s.parse(e).type}catch{let t=(e.split(`;`,1)[0]??``).trim().toLowerCase();return t===``||e.slice(t.length).includes(`,`)?void 0:t}}function ys(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e):{...e}:{}}function bs(e=fetch,t){return t?async(n,r)=>e(n,{...t,...r,headers:r?.headers?{...ys(t.headers),...ys(r.headers)}:t.headers}):e}var xs=new Set([301,302,303,307,308]),Ss=5;function Cs(e,t){return e.protocol===t.protocol&&e.host===t.host||e.protocol===`http:`&&t.protocol===`https:`&&e.hostname===t.hostname&&!e.port&&!t.port}function ws(e,t){let n=xs.has(t.status)?t.headers?.get(`location`):void 0;if(n)try{return new URL(n,e)}catch{return}}var Ts=new WeakSet;function Es(e){let t=(t,n)=>e(t,n);return Ts.add(t),t}function Ds(e){return Ts.has(e)?e:async(t,n)=>{if(n?.redirect===`error`||n?.redirect===`manual`)return e(t,n);let r=(n?.method??`GET`).toUpperCase(),i=t;for(let t=0;;t++){let a=await e(i,{...n,redirect:`manual`}),o=ws(i,a);if(!o||t===Ss)return a;let s=new URL(i),c=r===`GET`||a.status===307||a.status===308,l=!(o.username||o.password)||o.username===s.username&&o.password===s.password;if(!c||!l||!Cs(s,o))return a;await a.text?.().catch(()=>{}),i=o}}}function Os(e,t){if(t.type===`opaqueredirect`)return`Redirect not followed: this runtime does not expose where it points`;let n=ws(t.url||e,t);if(n)return n.username=n.password=n.search=n.hash=``,n.protocol===`http:`&&new URL(t.url||e).protocol===`https:`?(n.protocol=`https:`,`Redirect from https to plain http not followed; try ${n.href} as the endpoint`):`Redirect to ${n.href} not followed; use that URL as the endpoint if it is the intended server`}function ks(e,t){let n=typeof e;if(n!==typeof t)return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=e.length;if(n!==t.length)return!1;for(let r=0;r1?t[a.href]=e:(a.hash=``,r===``?n=a:Is(e,t,n))}}else if(e!==!0&&e!==!1)return t;let i=n.href+(r?`#`+r:``);if(t[i]!==void 0)throw Error(`Duplicate schema URI "${i}".`);if(t[i]=e,e===!0||e===!1)return t;if(e.__absolute_uri__===void 0&&Object.defineProperty(e,"__absolute_uri__",{enumerable:!1,value:i}),e.$ref&&e.__absolute_ref__===void 0){let t=new URL(e.$ref,n.href);t.hash=t.hash,Object.defineProperty(e,"__absolute_ref__",{enumerable:!1,value:t.href})}if(e.$recursiveRef&&e.__absolute_recursive_ref__===void 0){let t=new URL(e.$recursiveRef,n.href);t.hash=t.hash,Object.defineProperty(e,"__absolute_recursive_ref__",{enumerable:!1,value:t.href})}if(e.$anchor){let r=new URL(`#`+e.$anchor,n.href);t[r.href]=e}for(let i in e){if(Ps[i])continue;let a=`${r}/${As(i)}`,o=e[i];if(Array.isArray(o)){if(Ms[i]){let e=o.length;for(let r=0;r%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,Us=/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,Ws=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,Gs=/^(?:\/(?:[^~/]|~0|~1)*)*$/,Ks=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,qs=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,Js=e=>{if(e[0]===`"`)return!1;let[t,n,...r]=e.split(`@`);return!t||!n||r.length!==0||t.length>64||n.length>253||t[0]===`.`||t.endsWith(`.`)||t.includes(`..`)||!/^[a-z0-9.-]+$/i.test(n)||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(t)?!1:n.split(`.`).every(e=>/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(e))},Ys=/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,Xs=/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,Zs=e=>e.length>1&&e.length<80&&(/^P\d+([.,]\d+)?W$/.test(e)||/^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(e)&&/^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(e));function Qs(e){return e.test.bind(e)}var $s={date:tc,time:nc.bind(void 0,!1),"date-time":ic,duration:Zs,uri:sc,"uri-reference":Qs(Vs),"uri-template":Qs(Hs),url:Qs(Us),email:Js,hostname:Qs(Bs),ipv4:Qs(Ys),ipv6:Qs(Xs),regex:lc,uuid:Qs(Ws),"json-pointer":Qs(Gs),"json-pointer-uri-fragment":Qs(Ks),"relative-json-pointer":Qs(qs)};function ec(e){return e%4==0&&(e%100!=0||e%400==0)}function tc(e){let t=e.match(Ls);if(!t)return!1;let n=+t[1],r=+t[2],i=+t[3];return r>=1&&r<=12&&i>=1&&i<=(r==2&&ec(n)?29:Rs[r])}function nc(e,t){let n=t.match(zs);if(!n)return!1;let r=+n[1],i=+n[2],a=+n[3],o=!!n[5];return(r<=23&&i<=59&&a<=59||r==23&&i==59&&a==60)&&(!e||o)}var rc=/t|\s/i;function ic(e){let t=e.split(rc);return t.length==2&&tc(t[0])&&nc(!0,t[1])}var ac=/\/|:/,oc=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;function sc(e){return ac.test(e)&&oc.test(e)}var cc=/[^\\]\\Z/;function lc(e){if(cc.test(e))return!1;try{return new RegExp(e,`u`),!0}catch{return!1}}function uc(e){let t=0,n=e.length,r=0,i;for(;r=55296&&i<=56319&&r{if(typeof e!=`string`||/[\s;'\"]/.test(e))return!1;let t=e.match(/^([a-z]+):\/\/([^/]+)$/i);return!!(t&&n.has(t[1].toLowerCase()))})}function ve(e){let t=j(j(j(e)?.ui)?.csp),n=M(t?.connectDomains,[`http`,`https`,`ws`,`wss`]),r=M(t?.resourceDomains,[`http`,`https`]),i=M(t?.frameDomains,[`http`,`https`]),a=M(t?.baseUriDomains,[`http`,`https`]),o=r.length?` ${r.join(` `)}`:``,s=[`default-src 'none'`,`worker-src blob:`,`script-src 'self' 'unsafe-inline'${o}`,`style-src 'self' 'unsafe-inline'${o}`,`img-src 'self' data:${o}`,`media-src 'self' data:${o}`,`font-src 'self' data:${o}`,`connect-src ${n.length?n.join(` `):`'none'`}`];return i.length&&s.push(`frame-src ${i.join(` `)}`),a.length&&s.push(`base-uri ${a.join(` `)}`),`${s.join(`; `)};`}var ye=Object.create,be=Object.defineProperty,N=Object.getOwnPropertyDescriptor,xe=Object.getOwnPropertyNames,P=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty,Ce=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),we=(e,t)=>{let n={};for(var r in e)be(n,r,{get:e[r],enumerable:!0});return t&&be(n,Symbol.toStringTag,{value:`Module`}),n},Te=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=xe(t),a=0,o=i.length,s;at[e]).bind(null,s),enumerable:!(r=N(t,s))||r.enumerable});return e},Ee=(e,t,n)=>(n=e==null?{}:ye(P(e)),Te(t||!e||!e.__esModule?be(n,`default`,{value:e,enumerable:!0}):n,e)),De=new Set([`https://json-schema.org/draft/2020-12/schema`,`http://json-schema.org/draft/2020-12/schema`]),Oe=new Set([`https://json-schema.org/draft/2019-09/schema`,`http://json-schema.org/draft/2019-09/schema`]),ke=new Set([`https://json-schema.org/draft-07/schema`,`http://json-schema.org/draft-07/schema`]),Ae=new Set([`https://json-schema.org/draft-06/schema`,`http://json-schema.org/draft-06/schema`]);function je(e){return typeof e==`string`&&Oe.has(e.replace(/#$/,``))}function Me(e,t){if(!(`$schema`in e)||typeof e.$schema!=`string`)return`2020-12`;let n=e.$schema.replace(/#$/,``);if(De.has(n))return`2020-12`;if(Oe.has(n))return`2019-09`;if(ke.has(n)||Ae.has(n))return`draft-7`;throw Error(`JSON Schema declares an unsupported dialect ("$schema": "${e.$schema.slice(0,200)}"). The default validator supports JSON Schema 2020-12, 2019-09, draft-07, and draft-06; ${t}`)}var Ne=`2025-11-25`,Pe=[Ne,`2025-06-18`,`2025-03-26`,`2024-11-05`,`2024-10-07`],Fe=`io.modelcontextprotocol/related-task`,Ie=`io.modelcontextprotocol/protocolVersion`,Le=`io.modelcontextprotocol/clientInfo`,Re=`io.modelcontextprotocol/serverInfo`,ze=`io.modelcontextprotocol/clientCapabilities`,Be=`io.modelcontextprotocol/subscriptionId`,Ve=`io.modelcontextprotocol/logLevel`,He=ue(()=>k([d(),C(),E(),oe(),A(d(),He),O(He)])),F=A(d(),He),Ue=O(He),We=k([d(),C().int()]),Ge=d(),Ke=m({ttl:C().optional()}),qe=m({taskId:d()}),Je=f({progressToken:We.optional(),[Fe]:qe.optional()}),I=m({_meta:Je.optional()}),Ye=I.extend({task:Ke.optional()}),L=m({method:d(),params:I.loose().optional()}),R=m({_meta:Je.optional()}),z=m({method:d(),params:R.loose().optional()}),Xe=f({get[Re](){return H.optional().catch(void 0)}}),B=f({_meta:Xe.optional()}),Ze=k([d(),C().int()]),Qe=m({jsonrpc:S(`2.0`),id:Ze,...L.shape}).strict(),$e=m({jsonrpc:S(`2.0`),...z.shape}).strict(),V=m({jsonrpc:S(`2.0`),id:Ze,result:B}).strict(),et=m({jsonrpc:S(`2.0`),id:Ze.optional(),error:m({code:C().int(),message:d(),data:v().optional()})}).strict(),tt=k([Qe,$e,V,et]),nt=k([V,et]),rt=B.strict(),it=R.extend({requestId:Ze.optional(),reason:d().optional()}),at=z.extend({method:S(`notifications/cancelled`),params:it}),ot=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),st=m({icons:O(ot).optional()}),ct=m({name:d(),title:d().optional()}),H=ct.extend({...ct.shape,...st.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),lt=te(m({applyDefaults:E().optional()}),F),ut=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:lt.optional(),url:F.optional()}),F.optional())),dt=f({list:F.optional(),cancel:F.optional(),requests:f({sampling:f({createMessage:F.optional()}).optional(),elicitation:f({create:F.optional()}).optional()}).optional()}),ft=f({list:F.optional(),cancel:F.optional(),requests:f({tools:f({call:F.optional()}).optional()}).optional()}),pt=m({experimental:A(d(),F).optional(),sampling:m({context:F.optional(),tools:F.optional()}).optional(),elicitation:ut.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:dt.optional(),extensions:A(d(),F).optional()}),mt=I.extend({protocolVersion:d(),capabilities:pt,clientInfo:H}),ht=L.extend({method:S(`initialize`),params:mt}),gt=m({experimental:A(d(),F).optional(),logging:F.optional(),completions:F.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:ft.optional(),extensions:A(d(),F).optional()}),_t=B.extend({protocolVersion:d(),capabilities:gt,serverInfo:H,instructions:d().optional()}),vt=z.extend({method:S(`notifications/initialized`),params:R.optional()}),yt=L.extend({method:S(`server/discover`),params:I.optional()}),bt=B.extend({supportedVersions:O(d()),capabilities:gt,instructions:d().optional()}),xt=L.extend({method:S(`ping`),params:I.optional()}),St=m({progress:C(),total:p(C()),message:p(d())}),Ct=m({...R.shape,...St.shape,progressToken:We}),wt=z.extend({method:S(`notifications/progress`),params:Ct}),Tt=I.extend({cursor:Ge.optional()}),Et=L.extend({params:Tt.optional()}),Dt=B.extend({nextCursor:Ge.optional()}),Ot=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),kt=Ot.extend({text:d()}),At=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),jt=Ot.extend({blob:At}),Mt=D([`user`,`assistant`]),Nt=m({audience:O(Mt).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),Pt=m({...ct.shape,...st.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:Nt.optional(),_meta:p(f({}))}),Ft=m({...ct.shape,...st.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:Nt.optional(),_meta:p(f({}))}),It=Et.extend({method:S(`resources/list`)}),Lt=Dt.extend({resources:O(Pt)}),U=Et.extend({method:S(`resources/templates/list`)}),W=Dt.extend({resourceTemplates:O(Ft)}),Rt=I.extend({uri:d()}),zt=Rt,Bt=L.extend({method:S(`resources/read`),params:zt}),Vt=B.extend({contents:O(k([kt,jt]))}),Ht=z.extend({method:S(`notifications/resources/list_changed`),params:R.optional()}),Ut=Rt,Wt=L.extend({method:S(`resources/subscribe`),params:Ut}),Gt=Rt,Kt=L.extend({method:S(`resources/unsubscribe`),params:Gt}),qt=m({toolsListChanged:E().optional(),promptsListChanged:E().optional(),resourcesListChanged:E().optional(),resourceSubscriptions:O(d()).optional()}),Jt=I.extend({notifications:qt}),Yt=L.extend({method:S(`subscriptions/listen`),params:Jt}),Xt=R.extend({notifications:qt}),Zt=z.extend({method:S(`notifications/subscriptions/acknowledged`),params:Xt}),Qt=Xe.extend({[Be]:Ze}),$t=B.extend({_meta:Qt}),en=R.extend({uri:d()}),tn=z.extend({method:S(`notifications/resources/updated`),params:en}),G=m({name:d(),description:p(d()),required:p(E())}),nn=m({...ct.shape,...st.shape,description:p(d()),arguments:p(O(G)),_meta:p(f({}))}),rn=Et.extend({method:S(`prompts/list`)}),an=Dt.extend({prompts:O(nn)}),on=I.extend({name:d(),arguments:A(d(),d()).optional()}),sn=L.extend({method:S(`prompts/get`),params:on}),cn=m({type:S(`text`),text:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),K=m({type:S(`image`),data:At,mimeType:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),ln=m({type:S(`audio`),data:At,mimeType:d(),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),un=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),dn=m({type:S(`resource`),resource:k([kt,jt]),annotations:Nt.optional(),_meta:A(d(),v()).optional()}),fn=Pt.extend({type:S(`resource_link`)}),pn=k([cn,K,ln,fn,dn]),mn=m({role:Mt,content:pn}),hn=B.extend({description:d().optional(),messages:O(mn)}),gn=z.extend({method:S(`notifications/prompts/list_changed`),params:R.optional()}),_n=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),vn=m({taskSupport:D([`required`,`optional`,`forbidden`]).optional()}),yn=m({...ct.shape,...st.shape,description:d().optional(),inputSchema:m({type:S(`object`),properties:A(d(),He).optional(),required:O(d()).optional()}).catchall(v()),outputSchema:f({$schema:d().optional()}).optional(),annotations:_n.optional(),execution:vn.optional(),_meta:A(d(),v()).optional()}),bn=Et.extend({method:S(`tools/list`)}),xn=Dt.extend({tools:O(yn)}),Sn=B.extend({content:O(pn).default([]),structuredContent:v().optional(),isError:E().optional()}),Cn=Sn.or(B.extend({toolResult:v()})),wn=Ye.extend({name:d(),arguments:A(d(),v()).optional()}),Tn=L.extend({method:S(`tools/call`),params:wn}),En=z.extend({method:S(`notifications/tools/list_changed`),params:R.optional()}),Dn=m({autoRefresh:E().default(!0),debounceMs:C().int().nonnegative().default(300)}),On=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),kn=I.extend({level:On}),An=L.extend({method:S(`logging/setLevel`),params:kn}),jn=R.extend({level:On,logger:d().optional(),data:v()}),Mn=z.extend({method:S(`notifications/message`),params:jn}),Nn=m({name:d().optional()}),Pn=m({hints:O(Nn).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),Fn=m({mode:D([`auto`,`required`,`none`]).optional()}),In=m({type:S(`tool_result`),toolUseId:d().describe(`The unique identifier for the corresponding tool call.`),content:O(pn),structuredContent:v().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),Ln=ce(`type`,[cn,K,ln]),Rn=ce(`type`,[cn,K,ln,un,In]),zn=m({role:Mt,content:k([Rn,O(Rn)]),_meta:A(d(),v()).optional()}),Bn=Ye.extend({messages:O(zn),modelPreferences:Pn.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:F.optional(),tools:O(yn).optional(),toolChoice:Fn.optional()}),Vn=L.extend({method:S(`sampling/createMessage`),params:Bn}),Hn=B.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`]).or(d())),role:Mt,content:Ln}),Un=B.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`,`toolUse`]).or(d())),role:Mt,content:k([Rn,O(Rn)])}),Wn=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),Gn=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Kn=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),qn=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Jn=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Yn=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),Xn=k([qn,Jn]),Zn=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),Qn=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),$n=k([Zn,Qn]),er=k([Yn,Xn,$n]),tr=k([er,Wn,Gn,Kn]),nr=Ye.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),tr),required:O(d()).optional()}).catchall(v())}),rr=Ye.extend({mode:S(`url`),message:d(),elicitationId:d(),url:d().url()}),ir=k([nr,rr]),ar=L.extend({method:S(`elicitation/create`),params:ir}),or=R.extend({elicitationId:d()}),sr=z.extend({method:S(`notifications/elicitation/complete`),params:or}),cr=B.extend({action:D([`accept`,`decline`,`cancel`]),content:b(e=>e===null?void 0:e,A(d(),k([d(),C(),E(),O(d())])).optional())}),lr=m({type:S(`ref/resource`),uri:d()}),ur=m({type:S(`ref/prompt`),name:d()}),dr=I.extend({ref:k([ur,lr]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()}),fr=L.extend({method:S(`completion/complete`),params:dr}),pr=B.extend({completion:f({values:O(d()).max(100),total:p(C().int()),hasMore:p(E())})}),mr=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),hr=L.extend({method:S(`roots/list`),params:I.optional()}),gr=B.extend({roots:O(mr)}),_r=z.extend({method:S(`notifications/roots/list_changed`),params:R.optional()}),vr=f({ttl:C().optional(),pollInterval:C().optional()}),yr=D([`working`,`input_required`,`completed`,`failed`,`cancelled`]),br=m({taskId:d(),status:yr,ttl:k([C(),oe()]),createdAt:d(),lastUpdatedAt:d(),pollInterval:p(C()),statusMessage:p(d())}),xr=B.extend({task:br}),Sr=R.merge(br),Cr=z.extend({method:S(`notifications/tasks/status`),params:Sr}),wr=L.extend({method:S(`tasks/get`),params:I.extend({taskId:d()})}),Tr=B.merge(br),Er=L.extend({method:S(`tasks/result`),params:I.extend({taskId:d()})}),Dr=B.loose(),Or=Et.extend({method:S(`tasks/list`)}),kr=Dt.extend({tasks:O(br)}),Ar=L.extend({method:S(`tasks/cancel`),params:I.extend({taskId:d()})}),jr=B.merge(br),Mr=k([xt,ht,yt,fr,An,sn,rn,It,U,Bt,Wt,Kt,Yt,Tn,bn]),Nr=k([at,wt,vt,_r]),Pr=k([rt,Hn,Un,cr,gr]),Fr=k([xt,Vn,ar,hr]),Ir=k([at,wt,Mn,tn,Ht,En,gn,Zt,sr]),Lr=k([rt,_t,bt,pr,hn,an,Lt,W,Vt,Sn,xn,$t]),q=y().superRefine((e,t)=>{if(!URL.canParse(e))return t.addIssue({code:pe.custom,message:`URL must be parseable`,fatal:!0}),fe}).refine(e=>{let t=new URL(e);return t.protocol!==`javascript:`&&t.protocol!==`data:`&&t.protocol!==`vbscript:`},{message:`URL cannot use javascript:, data:, or vbscript: scheme`}),Rr=f({resource:d().url(),authorization_servers:O(q).optional(),jwks_uri:d().url().optional(),scopes_supported:O(d()).optional(),bearer_methods_supported:O(d()).optional(),resource_signing_alg_values_supported:O(d()).optional(),resource_name:d().optional(),resource_documentation:d().optional(),resource_policy_uri:d().url().optional(),resource_tos_uri:d().url().optional(),tls_client_certificate_bound_access_tokens:E().optional(),authorization_details_types_supported:O(d()).optional(),dpop_signing_alg_values_supported:O(d()).optional(),dpop_bound_access_tokens_required:E().optional()}),zr=f({issuer:d(),authorization_endpoint:q,token_endpoint:q,registration_endpoint:q.optional(),scopes_supported:O(d()).optional(),response_types_supported:O(d()),response_modes_supported:O(d()).optional(),grant_types_supported:O(d()).optional(),token_endpoint_auth_methods_supported:O(d()).optional(),token_endpoint_auth_signing_alg_values_supported:O(d()).optional(),service_documentation:q.optional(),revocation_endpoint:q.optional(),revocation_endpoint_auth_methods_supported:O(d()).optional(),revocation_endpoint_auth_signing_alg_values_supported:O(d()).optional(),introspection_endpoint:d().optional(),introspection_endpoint_auth_methods_supported:O(d()).optional(),introspection_endpoint_auth_signing_alg_values_supported:O(d()).optional(),code_challenge_methods_supported:O(d()).optional(),client_id_metadata_document_supported:E().optional(),authorization_response_iss_parameter_supported:E().optional().catch(void 0),dpop_signing_alg_values_supported:O(d()).optional()}),Br=f({issuer:d(),authorization_endpoint:q,token_endpoint:q,userinfo_endpoint:q.optional(),jwks_uri:q,registration_endpoint:q.optional(),scopes_supported:O(d()).optional(),response_types_supported:O(d()),response_modes_supported:O(d()).optional(),grant_types_supported:O(d()).optional(),acr_values_supported:O(d()).optional(),subject_types_supported:O(d()),id_token_signing_alg_values_supported:O(d()),id_token_encryption_alg_values_supported:O(d()).optional(),id_token_encryption_enc_values_supported:O(d()).optional(),userinfo_signing_alg_values_supported:O(d()).optional(),userinfo_encryption_alg_values_supported:O(d()).optional(),userinfo_encryption_enc_values_supported:O(d()).optional(),request_object_signing_alg_values_supported:O(d()).optional(),request_object_encryption_alg_values_supported:O(d()).optional(),request_object_encryption_enc_values_supported:O(d()).optional(),token_endpoint_auth_methods_supported:O(d()).optional(),token_endpoint_auth_signing_alg_values_supported:O(d()).optional(),display_values_supported:O(d()).optional(),claim_types_supported:O(d()).optional(),claims_supported:O(d()).optional(),service_documentation:d().optional(),claims_locales_supported:O(d()).optional(),ui_locales_supported:O(d()).optional(),claims_parameter_supported:E().optional(),request_parameter_supported:E().optional(),request_uri_parameter_supported:E().optional(),require_request_uri_registration:E().optional(),op_policy_uri:q.optional(),op_tos_uri:q.optional(),client_id_metadata_document_supported:E().optional(),authorization_response_iss_parameter_supported:E().optional().catch(void 0)}),Vr=m({...Br.shape,...zr.pick({code_challenge_methods_supported:!0}).shape}),Hr=m({access_token:d(),id_token:d().optional(),token_type:d(),expires_in:_e().optional(),scope:d().optional(),refresh_token:d().optional(),issuer:d().optional().catch(void 0)}).strip(),Ur=m({issued_token_type:S(`urn:ietf:params:oauth:token-type:id-jag`),access_token:d(),token_type:d().optional(),expires_in:C().optional(),scope:d().optional()}).strip(),Wr=m({error:d(),error_description:d().optional(),error_uri:d().optional()}),Gr=q.optional().or(S(``).transform(()=>void 0)),Kr=m({redirect_uris:O(q),token_endpoint_auth_method:d().optional(),grant_types:O(d()).optional(),response_types:O(d()).optional(),application_type:d().optional(),client_name:d().optional(),client_uri:q.optional(),logo_uri:Gr,scope:d().optional(),contacts:O(d()).optional(),tos_uri:Gr,policy_uri:d().optional(),jwks_uri:q.optional(),jwks:re().optional(),software_id:d().optional(),software_version:d().optional(),software_statement:d().optional()}).strip(),qr=m({client_id:d(),client_secret:d().optional(),client_id_issued_at:C().optional(),client_secret_expires_at:C().optional(),issuer:d().optional().catch(void 0)}).strip(),Jr=Kr.merge(qr),Yr=m({error:d(),error_description:d().optional()}).strip(),Xr=m({token:d(),token_type_hint:d().optional()}).strip(),Zr=Symbol.for(`mcp.sdk.errorBrands`);function Qr(e,t){let n=new Set,r=t;for(;typeof r==`function`;){let e=r.mcpBrand;Object.prototype.hasOwnProperty.call(r,`mcpBrand`)&&typeof e==`string`&&n.add(e),r=Object.getPrototypeOf(r)}n.size!==0&&Object.defineProperty(e,Zr,{value:n,enumerable:!1,configurable:!0})}function $r(e,t){try{if(typeof t==`object`&&t&&Object.prototype.hasOwnProperty.call(e,`mcpBrand`)&&typeof e.mcpBrand==`string`&&Object.prototype.hasOwnProperty.call(t,Zr)){let n=t[Zr];if(n&&typeof n.has==`function`&&n.has(e.mcpBrand))return!0}}catch{}return Function.prototype[Symbol.hasInstance].call(e,t)}var ei=function(e){return e.InvalidRequest=`invalid_request`,e.InvalidClient=`invalid_client`,e.InvalidGrant=`invalid_grant`,e.UnauthorizedClient=`unauthorized_client`,e.UnsupportedGrantType=`unsupported_grant_type`,e.InvalidScope=`invalid_scope`,e.AccessDenied=`access_denied`,e.ServerError=`server_error`,e.TemporarilyUnavailable=`temporarily_unavailable`,e.UnsupportedResponseType=`unsupported_response_type`,e.UnsupportedTokenType=`unsupported_token_type`,e.InvalidToken=`invalid_token`,e.MethodNotAllowed=`method_not_allowed`,e.TooManyRequests=`too_many_requests`,e.InvalidClientMetadata=`invalid_client_metadata`,e.InvalidRedirectUri=`invalid_redirect_uri`,e.InsufficientScope=`insufficient_scope`,e.InvalidTarget=`invalid_target`,e.InvalidDpopProof=`invalid_dpop_proof`,e.UseDpopNonce=`use_dpop_nonce`,e}({}),ti=class e extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.OAuthError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n){super(t),this.code=e,this.errorUri=n,this.name=`OAuthError`,Qr(this,new.target)}toResponseObject(){let e={error:this.code,error_description:this.message};return this.errorUri&&(e.error_uri=this.errorUri),e}static fromResponse(t){return new e(t.error,t.error_description??t.error,t.error_uri)}},J=function(e){return e.NotConnected=`NOT_CONNECTED`,e.AlreadyConnected=`ALREADY_CONNECTED`,e.NotInitialized=`NOT_INITIALIZED`,e.CapabilityNotSupported=`CAPABILITY_NOT_SUPPORTED`,e.RequestTimeout=`REQUEST_TIMEOUT`,e.ConnectionClosed=`CONNECTION_CLOSED`,e.SendFailed=`SEND_FAILED`,e.InvalidResult=`INVALID_RESULT`,e.UnsupportedResultType=`UNSUPPORTED_RESULT_TYPE`,e.InputRequiredRoundsExceeded=`INPUT_REQUIRED_ROUNDS_EXCEEDED`,e.ListPaginationExceeded=`LIST_PAGINATION_EXCEEDED`,e.MethodNotSupportedByProtocolVersion=`METHOD_NOT_SUPPORTED_BY_PROTOCOL_VERSION`,e.EraNegotiationFailed=`ERA_NEGOTIATION_FAILED`,e.ClientHttpNotImplemented=`CLIENT_HTTP_NOT_IMPLEMENTED`,e.ClientHttpAuthentication=`CLIENT_HTTP_AUTHENTICATION`,e.ClientHttpForbidden=`CLIENT_HTTP_FORBIDDEN`,e.ClientHttpUnexpectedContent=`CLIENT_HTTP_UNEXPECTED_CONTENT`,e.ClientHttpFailedToOpenStream=`CLIENT_HTTP_FAILED_TO_OPEN_STREAM`,e.ClientHttpFailedToTerminateSession=`CLIENT_HTTP_FAILED_TO_TERMINATE_SESSION`,e}({}),Y=class extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.SdkError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n,r){super(t,r),this.code=e,this.data=n,this.name=`SdkError`,Qr(this,new.target)}},ni=class extends Y{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.SdkHttpError`})}constructor(e,t,n,r){super(e,t,n,r),this.name=`SdkHttpError`}get status(){return this.data.status}get statusText(){return this.data.statusText}};function ri(e){let t=typeof e==`string`?new URL(e):new URL(e.href);return t.hash=``,t}function ii(e){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t={...e};return delete t.issuer,t}function ai({requestedResource:e,configuredResource:t}){let n=typeof e==`string`?new URL(e):new URL(e.href),r=typeof t==`string`?new URL(t):new URL(t.href);if(n.origin!==r.origin||n.pathname.length=oi}function li(e){return e.filter(e=>!ci(e))}function ui(e){return e.filter(e=>ci(e))}function di(e){let t=e.structuredContent;return t===void 0||typeof t==`object`&&t&&!Array.isArray(t)||(e.content?.some(e=>e.type===`text`)??!1)?e:{...e,content:[...e.content??[],{type:`text`,text:JSON.stringify(t)}]}}var fi=[`task`,`inputRequests`,`requestState`];function pi(e){return typeof e!=`object`||!e||Array.isArray(e)||e.content!==void 0||fi.some(t=>t in e)?e:{...e,content:[]}}function mi(){let e=ue(()=>k([d(),C(),E(),oe(),A(d(),e),O(e)])),t=A(d(),e),n=k([d(),C().int()]),r=d(),i=m({ttl:C().optional()}),a=m({taskId:d()}),o=f({progressToken:n.optional(),"io.modelcontextprotocol/related-task":a.optional()}),s=m({_meta:o.optional()}),c=s.extend({task:i.optional()}),l=m({method:d(),params:s.loose().optional()}),u=m({_meta:o.optional()}),h=m({method:d(),params:u.loose().optional()}),g=f({_meta:o.optional()}),_=k([d(),C().int()]),y=g.strict(),ee=u.extend({requestId:_.optional(),reason:d().optional()}),x=h.extend({method:S(`notifications/cancelled`),params:ee}),w=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),T=m({icons:O(w).optional()}),ne=m({name:d(),title:d().optional()}),re=ne.extend({...ne.shape,...T.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),ie=te(m({applyDefaults:E().optional()}),t),ae=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:ie.optional(),url:t.optional()}),t.optional())),se=f({list:t.optional(),cancel:t.optional(),requests:f({sampling:f({createMessage:t.optional()}).optional(),elicitation:f({create:t.optional()}).optional()}).optional()}),le=f({list:t.optional(),cancel:t.optional(),requests:f({tools:f({call:t.optional()}).optional()}).optional()}),de=m({experimental:A(d(),t).optional(),sampling:m({context:t.optional(),tools:t.optional()}).optional(),elicitation:ae.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:se.optional(),extensions:A(d(),t).optional()}),fe=s.extend({protocolVersion:d(),capabilities:de,clientInfo:re}),pe=l.extend({method:S(`initialize`),params:fe}),me=m({experimental:A(d(),t).optional(),logging:t.optional(),completions:t.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:le.optional(),extensions:A(d(),t).optional()}),ge=g.extend({protocolVersion:d(),capabilities:me,serverInfo:re,instructions:d().optional()}),_e=h.extend({method:S(`notifications/initialized`),params:u.optional()}),j=l.extend({method:S(`ping`),params:s.optional()}),M=m({progress:C(),total:p(C()),message:p(d())}),ve=m({...u.shape,...M.shape,progressToken:n}),ye=h.extend({method:S(`notifications/progress`),params:ve}),be=s.extend({cursor:r.optional()}),N=l.extend({params:be.optional()}),xe=g.extend({nextCursor:r.optional()}),P=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),Se=P.extend({text:d()}),Ce=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),we=P.extend({blob:Ce}),Te=D([`user`,`assistant`]),Ee=m({audience:O(Te).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),De=m({...ne.shape,...T.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:Ee.optional(),_meta:p(f({}))}),Oe=m({...ne.shape,...T.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:Ee.optional(),_meta:p(f({}))}),ke=N.extend({method:S(`resources/list`)}),Ae=xe.extend({resources:O(De)}),je=N.extend({method:S(`resources/templates/list`)}),Me=xe.extend({resourceTemplates:O(Oe)}),Ne=s.extend({uri:d()}),Pe=Ne,Fe=l.extend({method:S(`resources/read`),params:Pe}),Ie=g.extend({contents:O(k([Se,we]))}),Le=h.extend({method:S(`notifications/resources/list_changed`),params:u.optional()}),Re=Ne,ze=l.extend({method:S(`resources/subscribe`),params:Re}),Be=Ne,Ve=l.extend({method:S(`resources/unsubscribe`),params:Be}),He=u.extend({uri:d()}),F=h.extend({method:S(`notifications/resources/updated`),params:He}),Ue=m({name:d(),description:p(d()),required:p(E())}),We=m({...ne.shape,...T.shape,description:p(d()),arguments:p(O(Ue)),_meta:p(f({}))}),Ge=N.extend({method:S(`prompts/list`)}),Ke=xe.extend({prompts:O(We)}),qe=s.extend({name:d(),arguments:A(d(),d()).optional()}),Je=l.extend({method:S(`prompts/get`),params:qe}),I=m({type:S(`text`),text:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),Ye=m({type:S(`image`),data:Ce,mimeType:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),L=m({type:S(`audio`),data:Ce,mimeType:d(),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),R=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),z=m({type:S(`resource`),resource:k([Se,we]),annotations:Ee.optional(),_meta:A(d(),v()).optional()}),Xe=De.extend({type:S(`resource_link`)}),B=k([I,Ye,L,Xe,z]),Ze=m({role:Te,content:B}),Qe=g.extend({description:d().optional(),messages:O(Ze)}),$e=h.extend({method:S(`notifications/prompts/list_changed`),params:u.optional()}),V=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),et=m({taskSupport:D([`required`,`optional`,`forbidden`]).optional()}),tt=m({...ne.shape,...T.shape,description:d().optional(),inputSchema:m({type:S(`object`),properties:A(d(),e).optional(),required:O(d()).optional()}).catchall(v()),outputSchema:m({type:S(`object`),properties:A(d(),e).optional(),required:O(d()).optional()}).catchall(v()).optional(),annotations:V.optional(),execution:et.optional(),_meta:A(d(),v()).optional()}),nt=N.extend({method:S(`tools/list`)}),rt=xe.extend({tools:O(tt)}),it=g.extend({content:O(B),structuredContent:A(d(),v()).optional(),isError:E().optional()}),at=c.extend({name:d(),arguments:A(d(),v()).optional()}),ot=l.extend({method:S(`tools/call`),params:at}),st=h.extend({method:S(`notifications/tools/list_changed`),params:u.optional()}),ct=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),H=s.extend({level:ct}),lt=l.extend({method:S(`logging/setLevel`),params:H}),ut=u.extend({level:ct,logger:d().optional(),data:v()}),dt=h.extend({method:S(`notifications/message`),params:ut}),ft=m({name:d().optional()}),pt=m({hints:O(ft).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),mt=m({mode:D([`auto`,`required`,`none`]).optional()}),ht=m({type:S(`tool_result`),toolUseId:d().describe(`The unique identifier for the corresponding tool call.`),content:O(B),structuredContent:m({}).loose().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),gt=ce(`type`,[I,Ye,L]),_t=ce(`type`,[I,Ye,L,R,ht]),vt=m({role:Te,content:k([_t,O(_t)]),_meta:A(d(),v()).optional()}),yt=c.extend({messages:O(vt),modelPreferences:pt.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:t.optional(),tools:O(tt).optional(),toolChoice:mt.optional()}),bt=l.extend({method:S(`sampling/createMessage`),params:yt}),xt=g.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`]).or(d())),role:Te,content:gt}),St=g.extend({model:d(),stopReason:p(D([`endTurn`,`stopSequence`,`maxTokens`,`toolUse`]).or(d())),role:Te,content:k([_t,O(_t)])}),Ct=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),wt=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Tt=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),Et=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Dt=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Ot=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),kt=k([Et,Dt]),At=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),jt=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),Mt=k([At,jt]),Nt=k([Ot,kt,Mt]),Pt=k([Nt,Ct,wt,Tt]),Ft=c.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),Pt),required:O(d()).optional()}).catchall(v())}),It=c.extend({mode:S(`url`),message:d(),elicitationId:d(),url:d().url()}),Lt=k([Ft,It]),U=l.extend({method:S(`elicitation/create`),params:Lt}),W=u.extend({elicitationId:d()}),Rt=h.extend({method:S(`notifications/elicitation/complete`),params:W}),zt=g.extend({action:D([`accept`,`decline`,`cancel`]),content:b(e=>e===null?void 0:e,A(d(),k([d(),C(),E(),O(d())])).optional())}),Bt=m({type:S(`ref/resource`),uri:d()}),Vt=m({type:S(`ref/prompt`),name:d()}),Ht=s.extend({ref:k([Vt,Bt]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()}),Ut=l.extend({method:S(`completion/complete`),params:Ht}),Wt=g.extend({completion:f({values:O(d()).max(100),total:p(C().int()),hasMore:p(E())})}),Gt=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),Kt=l.extend({method:S(`roots/list`),params:s.optional()}),qt=g.extend({roots:O(Gt)}),Jt=h.extend({method:S(`notifications/roots/list_changed`),params:u.optional()}),Yt=f({ttl:C().optional(),pollInterval:C().optional()}),Xt=D([`working`,`input_required`,`completed`,`failed`,`cancelled`]),Zt=m({taskId:d(),status:Xt,ttl:k([C(),oe()]),createdAt:d(),lastUpdatedAt:d(),pollInterval:p(C()),statusMessage:p(d())}),Qt=g.extend({task:Zt}),$t=u.merge(Zt),en=h.extend({method:S(`notifications/tasks/status`),params:$t}),tn=l.extend({method:S(`tasks/get`),params:s.extend({taskId:d()})}),G=g.merge(Zt),nn=l.extend({method:S(`tasks/result`),params:s.extend({taskId:d()})}),rn=g.loose(),an=N.extend({method:S(`tasks/list`)}),on=xe.extend({tasks:O(Zt)}),sn=l.extend({method:S(`tasks/cancel`),params:s.extend({taskId:d()})});return{JSONValueSchema:e,JSONObjectSchema:t,ProgressTokenSchema:n,CursorSchema:r,TaskMetadataSchema:i,RelatedTaskMetadataSchema:a,RequestMetaSchema:o,BaseRequestParamsSchema:s,TaskAugmentedRequestParamsSchema:c,RequestSchema:l,NotificationsParamsSchema:u,NotificationSchema:h,ResultSchema:g,RequestIdSchema:_,EmptyResultSchema:y,CancelledNotificationParamsSchema:ee,CancelledNotificationSchema:x,IconSchema:w,IconsSchema:T,BaseMetadataSchema:ne,ImplementationSchema:re,ClientTasksCapabilitySchema:se,ServerTasksCapabilitySchema:le,ClientCapabilitiesSchema:de,InitializeRequestParamsSchema:fe,InitializeRequestSchema:pe,ServerCapabilitiesSchema:me,InitializeResultSchema:ge,InitializedNotificationSchema:_e,PingRequestSchema:j,ProgressSchema:M,ProgressNotificationParamsSchema:ve,ProgressNotificationSchema:ye,PaginatedRequestParamsSchema:be,PaginatedRequestSchema:N,PaginatedResultSchema:xe,ResourceContentsSchema:P,TextResourceContentsSchema:Se,BlobResourceContentsSchema:we,RoleSchema:Te,AnnotationsSchema:Ee,ResourceSchema:De,ResourceTemplateSchema:Oe,ListResourcesRequestSchema:ke,ListResourcesResultSchema:Ae,ListResourceTemplatesRequestSchema:je,ListResourceTemplatesResultSchema:Me,ResourceRequestParamsSchema:Ne,ReadResourceRequestParamsSchema:Pe,ReadResourceRequestSchema:Fe,ReadResourceResultSchema:Ie,ResourceListChangedNotificationSchema:Le,SubscribeRequestParamsSchema:Re,SubscribeRequestSchema:ze,UnsubscribeRequestParamsSchema:Be,UnsubscribeRequestSchema:Ve,ResourceUpdatedNotificationParamsSchema:He,ResourceUpdatedNotificationSchema:F,PromptArgumentSchema:Ue,PromptSchema:We,ListPromptsRequestSchema:Ge,ListPromptsResultSchema:Ke,GetPromptRequestParamsSchema:qe,GetPromptRequestSchema:Je,TextContentSchema:I,ImageContentSchema:Ye,AudioContentSchema:L,ToolUseContentSchema:R,EmbeddedResourceSchema:z,ResourceLinkSchema:Xe,ContentBlockSchema:B,PromptMessageSchema:Ze,GetPromptResultSchema:Qe,PromptListChangedNotificationSchema:$e,ToolAnnotationsSchema:V,ToolExecutionSchema:et,ToolSchema:tt,ListToolsRequestSchema:nt,ListToolsResultSchema:rt,CallToolResultSchema:it,CallToolRequestParamsSchema:at,CallToolRequestSchema:ot,ToolListChangedNotificationSchema:st,LoggingLevelSchema:ct,SetLevelRequestParamsSchema:H,SetLevelRequestSchema:lt,LoggingMessageNotificationParamsSchema:ut,LoggingMessageNotificationSchema:dt,ModelHintSchema:ft,ModelPreferencesSchema:pt,ToolChoiceSchema:mt,ToolResultContentSchema:ht,SamplingContentSchema:gt,SamplingMessageContentBlockSchema:_t,SamplingMessageSchema:vt,CreateMessageRequestParamsSchema:yt,CreateMessageRequestSchema:bt,CreateMessageResultSchema:xt,CreateMessageResultWithToolsSchema:St,BooleanSchemaSchema:Ct,StringSchemaSchema:wt,NumberSchemaSchema:Tt,UntitledSingleSelectEnumSchemaSchema:Et,TitledSingleSelectEnumSchemaSchema:Dt,LegacyTitledEnumSchemaSchema:Ot,SingleSelectEnumSchemaSchema:kt,UntitledMultiSelectEnumSchemaSchema:At,TitledMultiSelectEnumSchemaSchema:jt,MultiSelectEnumSchemaSchema:Mt,EnumSchemaSchema:Nt,PrimitiveSchemaDefinitionSchema:Pt,ElicitRequestFormParamsSchema:Ft,ElicitRequestURLParamsSchema:It,ElicitRequestParamsSchema:Lt,ElicitRequestSchema:U,ElicitationCompleteNotificationParamsSchema:W,ElicitationCompleteNotificationSchema:Rt,ElicitResultSchema:zt,ResourceTemplateReferenceSchema:Bt,PromptReferenceSchema:Vt,CompleteRequestParamsSchema:Ht,CompleteRequestSchema:Ut,CompleteResultSchema:Wt,RootSchema:Gt,ListRootsRequestSchema:Kt,ListRootsResultSchema:qt,RootsListChangedNotificationSchema:Jt,TaskCreationParamsSchema:Yt,TaskStatusSchema:Xt,TaskSchema:Zt,CreateTaskResultSchema:Qt,TaskStatusNotificationParamsSchema:$t,TaskStatusNotificationSchema:en,GetTaskRequestSchema:tn,GetTaskResultSchema:G,GetTaskPayloadRequestSchema:nn,GetTaskPayloadResultSchema:rn,ListTasksRequestSchema:an,ListTasksResultSchema:on,CancelTaskRequestSchema:sn,CancelTaskResultSchema:g.merge(Zt),ClientRequestSchema:k([j,pe,Ut,lt,Je,Ge,ke,je,Fe,ze,Ve,ot,nt,tn,nn,an,sn]),ClientNotificationSchema:k([x,ye,_e,Jt,en]),ClientResultSchema:k([y,xt,St,zt,qt,G,on,Qt]),ServerRequestSchema:k([j,bt,U,Kt,tn,nn,an,sn]),ServerNotificationSchema:k([x,ye,dt,F,Le,st,$e,en,Rt]),ServerResultSchema:k([y,ge,Wt,Qe,Ke,Ae,Me,Ie,it,rt,G,on,Qt]),CallToolResultWireSchema:v().superRefine((e,t)=>{if(typeof e==`object`&&e&&!Array.isArray(e)&&e.content===void 0){for(let n of fi)if(n in e){t.addIssue({code:`custom`,message:`content is required when the body carries '${n}' — another result family cannot default into an empty tools/call success`});return}}}).transform(pi).pipe(it)}}var hi;function gi(){return hi??=mi()}function _i(e){return e.type!==`object`}var vi=new Set([`const`,`enum`,`default`,`examples`]),yi=new Set([`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`,`dependencies`]);function bi(e){return e!==void 0&&!(typeof e==`string`&&e.startsWith(`#`))}function xi(e){let t=typeof e.$schema==`string`?e.$schema:void 0;if(bi(e.$id))return{...t!==void 0&&{$schema:t},type:`object`,properties:{result:e},required:[`result`]};let n=je(e.$schema)&&e.$recursiveAnchor!==!0,r=(e,t)=>{if(Array.isArray(e))return e.map(e=>r(e,!1));if(typeof e!=`object`||!e||!t&&bi(e.$id))return e;let i={},a=!1;for(let[o,s]of Object.entries(e))t?i[o]=r(s,!1):(o===`$ref`||o===`$dynamicRef`)&&typeof s==`string`?i[o]=s===`#`?`#/properties/result`:s.startsWith(`#/`)?`#/properties/result${s.slice(1)}`:s:o===`$recursiveRef`&&s===`#`&&n?a=!0:i[o]=vi.has(o)?s:yi.has(o)?r(s,!0):r(s,!1);return a&&(`$ref`in i?i.allOf=[...Array.isArray(i.allOf)?i.allOf:[],{$ref:`#/properties/result`}]:i.$ref=`#/properties/result`),i};return{...t!==void 0&&{$schema:t},type:`object`,properties:{result:r(e,!1)},required:[`result`]}}var Si={ping:null,initialize:null,"completion/complete":null,"logging/setLevel":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"resources/subscribe":null,"resources/unsubscribe":null,"tools/call":null,"tools/list":null,"tasks/get":null,"tasks/result":null,"tasks/list":null,"tasks/cancel":null,"sampling/createMessage":null,"elicitation/create":null,"roots/list":null},Ci={"notifications/cancelled":null,"notifications/progress":null,"notifications/initialized":null,"notifications/roots/list_changed":null,"notifications/tasks/status":null,"notifications/message":null,"notifications/resources/updated":null,"notifications/resources/list_changed":null,"notifications/tools/list_changed":null,"notifications/prompts/list_changed":null,"notifications/elicitation/complete":null},wi={ping:null,initialize:null,"completion/complete":null,"logging/setLevel":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"resources/subscribe":null,"resources/unsubscribe":null,"tools/call":null,"tools/list":null,"sampling/createMessage":null,"elicitation/create":null,"roots/list":null},Ti;function Ei(){if(Ti)return Ti;let e=gi();return Ti={requestSchemas:{ping:e.PingRequestSchema,initialize:e.InitializeRequestSchema,"completion/complete":e.CompleteRequestSchema,"logging/setLevel":e.SetLevelRequestSchema,"prompts/get":e.GetPromptRequestSchema,"prompts/list":e.ListPromptsRequestSchema,"resources/list":e.ListResourcesRequestSchema,"resources/templates/list":e.ListResourceTemplatesRequestSchema,"resources/read":e.ReadResourceRequestSchema,"resources/subscribe":e.SubscribeRequestSchema,"resources/unsubscribe":e.UnsubscribeRequestSchema,"tools/call":e.CallToolRequestSchema,"tools/list":e.ListToolsRequestSchema,"tasks/get":e.GetTaskRequestSchema,"tasks/result":e.GetTaskPayloadRequestSchema,"tasks/list":e.ListTasksRequestSchema,"tasks/cancel":e.CancelTaskRequestSchema,"sampling/createMessage":e.CreateMessageRequestSchema,"elicitation/create":e.ElicitRequestSchema,"roots/list":e.ListRootsRequestSchema},notificationSchemas:{"notifications/cancelled":e.CancelledNotificationSchema,"notifications/progress":e.ProgressNotificationSchema,"notifications/initialized":e.InitializedNotificationSchema,"notifications/roots/list_changed":e.RootsListChangedNotificationSchema,"notifications/tasks/status":e.TaskStatusNotificationSchema,"notifications/message":e.LoggingMessageNotificationSchema,"notifications/resources/updated":e.ResourceUpdatedNotificationSchema,"notifications/resources/list_changed":e.ResourceListChangedNotificationSchema,"notifications/tools/list_changed":e.ToolListChangedNotificationSchema,"notifications/prompts/list_changed":e.PromptListChangedNotificationSchema,"notifications/elicitation/complete":e.ElicitationCompleteNotificationSchema},resultSchemas:{ping:e.EmptyResultSchema,initialize:e.InitializeResultSchema,"completion/complete":e.CompleteResultSchema,"logging/setLevel":e.EmptyResultSchema,"prompts/get":e.GetPromptResultSchema,"prompts/list":e.ListPromptsResultSchema,"resources/list":e.ListResourcesResultSchema,"resources/templates/list":e.ListResourceTemplatesResultSchema,"resources/read":e.ReadResourceResultSchema,"resources/subscribe":e.EmptyResultSchema,"resources/unsubscribe":e.EmptyResultSchema,"tools/call":e.CallToolResultWireSchema,"tools/list":e.ListToolsResultSchema,"sampling/createMessage":e.CreateMessageResultWithToolsSchema,"elicitation/create":e.ElicitResultSchema,"roots/list":e.ListRootsResultSchema}},Ti}function Di(e){return Object.prototype.hasOwnProperty.call(Si,e)}function Oi(e){return Object.prototype.hasOwnProperty.call(Ci,e)}function ki(e){return Object.prototype.hasOwnProperty.call(wi,e)}function Ai(e){return ki(e)?Ei().resultSchemas[e]:void 0}function ji(e){return Di(e)?Ei().requestSchemas[e]:void 0}function Mi(e){return Oi(e)?Ei().notificationSchemas[e]:void 0}Object.keys(Si),Object.keys(Ci);function Ni(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pi(e,t){if(e===void 0)return{ok:!1,reason:`not-in-era`};let n=e.safeParse(t);return n.success?{ok:!0,value:n.data}:{ok:!1,reason:`invalid`,message:String(n.error)}}var Fi={ok:!1,reason:`not-in-era`};function Ii(e){return Ni(e)&&Ni(e.outputSchema)&&_i(e.outputSchema)}function Li(e){return e}var Ri={era:`2025-11-25`,hasRequestMethod:Di,hasNotificationMethod:Oi,validateRequest:(e,t)=>Pi(ji(e),t),validateResult:(e,t)=>Pi(Ai(e),t),validateNotification:(e,t)=>Pi(Mi(e),t),hasInputRequestMethod:()=>!1,validateInputRequest:()=>Fi,validateInputResponse:()=>Fi,samplingResultVariant:((e,t)=>{let n=gi();return Pi(e?n.CreateMessageResultWithToolsSchema:n.CreateMessageResultSchema,t)}),outboundEnvelope:e=>void 0,validateEnvelopeMeta:e=>[],projectCallToolResult(e,t){let n=di(e),r=n.structuredContent;if(r===void 0)return n;let i=typeof r!=`object`||!r||Array.isArray(r),a=t!==void 0&&_i(t);return!i&&!a?n:{...n,structuredContent:{result:r}}},decodeResult(e,t){if(Ni(t)&&`resultType`in t){let e={...t};return delete e.resultType,{kind:`complete`,result:Li(e)}}return{kind:`complete`,result:Li(t)}},encodeResult(e,t){if(e!==`tools/list`)return t;let n=t.tools;return!Array.isArray(n)||!n.some(e=>Ii(e))?t:{...t,tools:n.map(e=>Ii(e)?{...e,outputSchema:xi(e.outputSchema)}:e)}},encodeErrorCode:e=>e===-32002?-32602:e,checkInboundEnvelope:e=>void 0};function zi(){let e=ue(()=>k([d(),C(),E(),oe(),A(d(),e),O(e)])),t=A(d(),e),n=k([d(),C().int()]),r=d(),i=k([d(),C().int()]),a=D([`user`,`assistant`]),o=D([`debug`,`info`,`notice`,`warning`,`error`,`critical`,`alert`,`emergency`]),s=d().refine(e=>{try{return atob(e),!0}catch{return!1}},{message:`Invalid Base64 string`}),c=m({ttl:C().optional()}),l=m({taskId:d()}),u=f({progressToken:n.optional(),"io.modelcontextprotocol/related-task":l.optional()}),h=m({_meta:u.optional()}),g=h.extend({task:c.optional()}),_=m({_meta:u.optional()}),y=m({method:d(),params:_.loose().optional()}),ee=m({src:d(),mimeType:d().optional(),sizes:O(d()).optional(),theme:D([`light`,`dark`]).optional()}),x=m({icons:O(ee).optional()}),w=m({name:d(),title:d().optional()}),T=w.extend({...w.shape,...x.shape,version:d(),websiteUrl:d().optional(),description:d().optional()}),ne=te(m({applyDefaults:E().optional()}),t),re=b(e=>e&&typeof e==`object`&&!Array.isArray(e)&&Object.keys(e).length===0?{form:{}}:e,te(m({form:ne.optional(),url:t.optional()}),t.optional())),ie=f({list:t.optional(),cancel:t.optional(),requests:f({sampling:f({createMessage:t.optional()}).optional(),elicitation:f({create:t.optional()}).optional()}).optional()}),ae=f({list:t.optional(),cancel:t.optional(),requests:f({tools:f({call:t.optional()}).optional()}).optional()}),se=m({experimental:A(d(),t).optional(),sampling:m({context:t.optional(),tools:t.optional()}).optional(),elicitation:re.optional(),roots:m({listChanged:E().optional()}).optional(),tasks:ie.optional(),extensions:A(d(),t).optional()}),ce=m({experimental:A(d(),t).optional(),logging:t.optional(),completions:t.optional(),prompts:m({listChanged:E().optional()}).optional(),resources:m({subscribe:E().optional(),listChanged:E().optional()}).optional(),tools:m({listChanged:E().optional()}).optional(),tasks:ae.optional(),extensions:A(d(),t).optional()}),le=m({progress:C(),total:p(C()),message:p(d())}),de=m({..._.shape,...le.shape,progressToken:n}),fe=y.extend({method:S(`notifications/progress`),params:de}),pe=_.extend({level:o,logger:d().optional(),data:v()}),me=y.extend({method:S(`notifications/message`),params:pe}),ge=m({uri:d(),mimeType:p(d()),_meta:A(d(),v()).optional()}),_e=ge.extend({text:d()}),j=ge.extend({blob:s}),M=m({audience:O(a).optional(),priority:C().min(0).max(1).optional(),lastModified:he({offset:!0}).optional()}),ve=m({...w.shape,...x.shape,uri:d(),description:p(d()),mimeType:p(d()),size:p(C()),annotations:M.optional(),_meta:p(f({}))}),ye=m({...w.shape,...x.shape,uriTemplate:d(),description:p(d()),mimeType:p(d()),annotations:M.optional(),_meta:p(f({}))}),be=y.extend({method:S(`notifications/resources/list_changed`),params:_.optional()}),N=_.extend({uri:d()}),xe=y.extend({method:S(`notifications/resources/updated`),params:N}),P=m({name:d(),description:p(d()),required:p(E())}),Se=m({...w.shape,...x.shape,description:p(d()),arguments:p(O(P)),_meta:p(f({}))}),Ce=y.extend({method:S(`notifications/prompts/list_changed`),params:_.optional()}),we=m({type:S(`text`),text:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),Te=m({type:S(`image`),data:s,mimeType:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),Ee=m({type:S(`audio`),data:s,mimeType:d(),annotations:M.optional(),_meta:A(d(),v()).optional()}),De=m({type:S(`tool_use`),name:d(),id:d(),input:A(d(),v()),_meta:A(d(),v()).optional()}),Oe=m({type:S(`resource`),resource:k([_e,j]),annotations:M.optional(),_meta:A(d(),v()).optional()}),ke=ve.extend({type:S(`resource_link`)}),Ae=k([we,Te,Ee,ke,Oe]),je=m({role:a,content:Ae}),Me=m({title:d().optional(),readOnlyHint:E().optional(),destructiveHint:E().optional(),idempotentHint:E().optional(),openWorldHint:E().optional()}),Ne=y.extend({method:S(`notifications/tools/list_changed`),params:_.optional()}),Pe=m({name:d().optional()}),Fe=m({hints:O(Pe).optional(),costPriority:C().min(0).max(1).optional(),speedPriority:C().min(0).max(1).optional(),intelligencePriority:C().min(0).max(1).optional()}),Be=m({mode:D([`auto`,`required`,`none`]).optional()}),He=m({type:S(`boolean`),title:d().optional(),description:d().optional(),default:E().optional()}),F=m({type:S(`string`),title:d().optional(),description:d().optional(),minLength:C().optional(),maxLength:C().optional(),format:D([`email`,`uri`,`date`,`date-time`]).optional(),default:d().optional()}),Ue=m({type:D([`number`,`integer`]),title:d().optional(),description:d().optional(),minimum:C().optional(),maximum:C().optional(),default:C().optional()}),We=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),default:d().optional()}),Ge=m({type:S(`string`),title:d().optional(),description:d().optional(),oneOf:O(m({const:d(),title:d()})),default:d().optional()}),Ke=m({type:S(`string`),title:d().optional(),description:d().optional(),enum:O(d()),enumNames:O(d()).optional(),default:d().optional()}),qe=k([We,Ge]),Je=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({type:S(`string`),enum:O(d())}),default:O(d()).optional()}),I=m({type:S(`array`),title:d().optional(),description:d().optional(),minItems:C().optional(),maxItems:C().optional(),items:m({anyOf:O(m({const:d(),title:d()}))}),default:O(d()).optional()}),Ye=k([Je,I]),L=k([Ke,qe,Ye]),R=k([L,He,F,Ue]),z=g.extend({mode:S(`form`).optional(),message:d(),requestedSchema:m({type:S(`object`),properties:A(d(),R),required:O(d()).optional()}).catchall(v())}),Xe=m({type:S(`ref/resource`),uri:d()}),B=m({type:S(`ref/prompt`),name:d()}),Ze=m({uri:d().startsWith(`file://`),name:d().optional(),_meta:A(d(),v()).optional()}),Qe=se.shape,$e=m({experimental:Qe.experimental,sampling:Qe.sampling,elicitation:Qe.elicitation,roots:Qe.roots,extensions:Qe.extensions}),V=ce.shape,et=m({experimental:V.experimental,logging:V.logging,completions:V.completions,prompts:V.prompts,resources:V.resources,tools:V.tools,extensions:V.extensions}),tt=f({progressToken:n.optional(),[Ie]:d(),[Le]:T.optional(),[ze]:$e,[Ve]:o.optional()}),nt=m({...w.shape,...x.shape,description:d().optional(),inputSchema:f({$schema:d().optional(),type:S(`object`)}),outputSchema:f({$schema:d().optional()}).optional(),annotations:Me.optional(),_meta:A(d(),v()).optional()}),rt=m({type:S(`tool_result`),toolUseId:d(),content:O(Ae),structuredContent:v().optional(),isError:E().optional(),_meta:A(d(),v()).optional()}),it=k([we,Te,Ee,De,rt]),at=m({role:a,content:k([it,O(it)]),_meta:A(d(),v()).optional()}),ot=d(),st=f({[Re]:T.optional().catch(void 0)}),ct=st.optional();function H(e){return f({_meta:ct,resultType:ot.default(`complete`),...e})}let lt=H({}),ut=H({nextCursor:r.optional()}),dt=H({content:O(Ae),structuredContent:v().optional(),isError:E().optional()}),ft=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),tools:O(nt),nextCursor:r.optional()}),pt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),prompts:O(Se),nextCursor:r.optional()}),mt=H({description:d().optional(),messages:O(je)}),ht=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resources:O(ve),nextCursor:r.optional()}),gt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resourceTemplates:O(ye),nextCursor:r.optional()}),_t=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),contents:O(k([_e,j]))}),vt=H({completion:m({values:O(d()).max(100),total:C().int().optional(),hasMore:E().optional()}).loose()}),yt=H({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`])}),bt=H({ttlMs:C().int().min(0).catch(0),cacheScope:D([`public`,`private`]).catch(`private`),supportedVersions:O(d()),capabilities:et,instructions:d().optional()}),xt=m({messages:O(at),modelPreferences:Fe.optional(),systemPrompt:d().optional(),includeContext:D([`none`,`thisServer`,`allServers`]).optional(),temperature:C().optional(),maxTokens:C().int(),stopSequences:O(d()).optional(),metadata:t.optional(),tools:O(nt).optional(),toolChoice:Be.optional()}),St=m({method:S(`sampling/createMessage`),params:xt}),Ct=m({method:S(`roots/list`),params:m({_meta:A(d(),v()).optional()}).optional()}),wt=m({...at.shape,model:d(),stopReason:d().optional()}),Tt=m({roots:O(Ze)}),Et=m({action:D([`accept`,`decline`,`cancel`]),content:A(d(),k([d(),C(),E(),O(d())])).optional()}),Dt=m({mode:S(`url`),message:d(),url:d().url()}),Ot=k([z,Dt]),kt=m({method:S(`elicitation/create`),params:Ot}),At=k([St,Ct,kt]),jt=k([wt,Tt,Et]),Mt=A(d(),At),Nt=A(d(),jt),Pt=H({inputRequests:Mt.optional(),requestState:d().optional()}),Ft={inputResponses:Nt.optional(),requestState:d().optional()},It=m({_meta:tt,...Ft}),Lt=f({progressToken:n.optional()});function U(e,t){return m({method:S(e),params:m({_meta:tt,...t})})}function W(e,t){return m({method:S(e),params:m({_meta:Lt.optional(),...t}).optional()})}let Rt={name:d(),arguments:A(d(),v()).optional(),...Ft},zt={cursor:r.optional()},Bt=U(`tools/call`,Rt),Vt=U(`tools/list`,zt),Ht=U(`prompts/list`,zt),Ut=U(`prompts/get`,{name:d(),arguments:A(d(),d()).optional(),...Ft}),Wt=U(`resources/list`,zt),Gt=U(`resources/templates/list`,zt),Kt=U(`resources/read`,{uri:d(),...Ft}),qt={ref:k([B,Xe]),argument:m({name:d(),value:d()}),context:m({arguments:A(d(),d()).optional()}).optional()},Jt=U(`completion/complete`,qt),Yt=U(`server/discover`,{}),Xt=m({toolsListChanged:E().optional(),promptsListChanged:E().optional(),resourcesListChanged:E().optional(),resourceSubscriptions:O(d()).optional()}),Zt={notifications:Xt},Qt=U(`subscriptions/listen`,Zt),$t=st.extend({"io.modelcontextprotocol/subscriptionId":i}),en=f({_meta:$t,resultType:ot.default(`complete`)}),tn={"tools/call":W(`tools/call`,Rt),"tools/list":W(`tools/list`,zt),"prompts/get":W(`prompts/get`,{name:d(),arguments:A(d(),d()).optional()}),"prompts/list":W(`prompts/list`,zt),"resources/list":W(`resources/list`,zt),"resources/templates/list":W(`resources/templates/list`,zt),"resources/read":W(`resources/read`,{uri:d()}),"completion/complete":W(`completion/complete`,qt),"server/discover":W(`server/discover`,{}),"subscriptions/listen":W(`subscriptions/listen`,Zt)};function G(e){return f({_meta:ct,...e})}let nn={"tools/call":G({content:O(Ae),structuredContent:v().optional(),isError:E().optional()}),"tools/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),tools:O(nt),nextCursor:r.optional()}),"prompts/get":G({description:d().optional(),messages:O(je)}),"prompts/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),prompts:O(Se),nextCursor:r.optional()}),"resources/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resources:O(ve),nextCursor:r.optional()}),"resources/templates/list":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),resourceTemplates:O(ye),nextCursor:r.optional()}),"resources/read":G({ttlMs:C().int().min(0),cacheScope:D([`public`,`private`]),contents:O(k([_e,j]))}),"completion/complete":G({completion:m({values:O(d()).max(100),total:C().int().optional(),hasMore:E().optional()}).loose()}),"server/discover":G({ttlMs:C().int().min(0).catch(0),cacheScope:D([`public`,`private`]).catch(`private`),supportedVersions:O(d()),capabilities:et,instructions:d().optional()}),"subscriptions/listen":G({})},rn=f({"io.modelcontextprotocol/subscriptionId":i.optional()}),an=m({method:S(`notifications/subscriptions/acknowledged`),params:m({_meta:rn.optional(),notifications:Xt})}),on=m({_meta:rn.optional(),requestId:i,reason:d().optional()}),sn=m({method:S(`notifications/cancelled`),params:on}),cn={"notifications/cancelled":sn,"notifications/progress":fe,"notifications/message":me,"notifications/resources/updated":xe,"notifications/resources/list_changed":be,"notifications/tools/list_changed":Ne,"notifications/prompts/list_changed":Ce,"notifications/subscriptions/acknowledged":an},K=e=>m({jsonrpc:S(`2.0`),id:k([d(),C().int()]),result:e}).strict();return{JSONValueSchema:e,JSONObjectSchema:t,ProgressTokenSchema:n,CursorSchema:r,RequestIdSchema:i,RoleSchema:a,LoggingLevelSchema:o,TaskMetadataSchema:c,RelatedTaskMetadataSchema:l,RequestMetaSchema:u,BaseRequestParamsSchema:h,TaskAugmentedRequestParamsSchema:g,NotificationsParamsSchema:_,NotificationSchema:y,IconSchema:ee,IconsSchema:x,BaseMetadataSchema:w,ImplementationSchema:T,ClientTasksCapabilitySchema:ie,ServerTasksCapabilitySchema:ae,ClientCapabilitiesSchema:se,ServerCapabilitiesSchema:ce,ProgressSchema:le,ProgressNotificationParamsSchema:de,ProgressNotificationSchema:fe,LoggingMessageNotificationParamsSchema:pe,LoggingMessageNotificationSchema:me,ResourceContentsSchema:ge,TextResourceContentsSchema:_e,BlobResourceContentsSchema:j,AnnotationsSchema:M,ResourceSchema:ve,ResourceTemplateSchema:ye,ResourceListChangedNotificationSchema:be,ResourceUpdatedNotificationParamsSchema:N,ResourceUpdatedNotificationSchema:xe,PromptArgumentSchema:P,PromptSchema:Se,PromptListChangedNotificationSchema:Ce,TextContentSchema:we,ImageContentSchema:Te,AudioContentSchema:Ee,ToolUseContentSchema:De,EmbeddedResourceSchema:Oe,ResourceLinkSchema:ke,ContentBlockSchema:Ae,PromptMessageSchema:je,ToolAnnotationsSchema:Me,ToolListChangedNotificationSchema:Ne,ModelHintSchema:Pe,ModelPreferencesSchema:Fe,ToolChoiceSchema:Be,BooleanSchemaSchema:He,StringSchemaSchema:F,NumberSchemaSchema:Ue,UntitledSingleSelectEnumSchemaSchema:We,TitledSingleSelectEnumSchemaSchema:Ge,LegacyTitledEnumSchemaSchema:Ke,SingleSelectEnumSchemaSchema:qe,UntitledMultiSelectEnumSchemaSchema:Je,TitledMultiSelectEnumSchemaSchema:I,MultiSelectEnumSchemaSchema:Ye,EnumSchemaSchema:L,PrimitiveSchemaDefinitionSchema:R,ElicitRequestFormParamsSchema:z,ResourceTemplateReferenceSchema:Xe,PromptReferenceSchema:B,RootSchema:Ze,ClientCapabilities2026Schema:$e,ServerCapabilities2026Schema:et,RequestMetaEnvelopeSchema:tt,ToolSchema:nt,ToolResultContentSchema:rt,SamplingMessageContentBlockSchema:it,SamplingMessageSchema:at,ResultTypeSchema:ot,ResultMetaSchema:st,ResultSchema:lt,PaginatedResultSchema:ut,CallToolResultSchema:dt,ListToolsResultSchema:ft,ListPromptsResultSchema:pt,GetPromptResultSchema:mt,ListResourcesResultSchema:ht,ListResourceTemplatesResultSchema:gt,ReadResourceResultSchema:_t,CompleteResultSchema:vt,CacheableResultSchema:yt,DiscoverResultSchema:bt,CreateMessageRequestParamsSchema:xt,CreateMessageRequestSchema:St,ListRootsRequestSchema:Ct,CreateMessageResultSchema:wt,ListRootsResultSchema:Tt,ElicitResultSchema:Et,ElicitRequestURLParamsSchema:Dt,ElicitRequestParamsSchema:Ot,ElicitRequestSchema:kt,InputRequestSchema:At,InputResponseSchema:jt,InputRequestsSchema:Mt,InputResponsesSchema:Nt,InputRequiredResultSchema:Pt,InputResponseRequestParamsSchema:It,CallToolRequestSchema:Bt,ListToolsRequestSchema:Vt,ListPromptsRequestSchema:Ht,GetPromptRequestSchema:Ut,ListResourcesRequestSchema:Wt,ListResourceTemplatesRequestSchema:Gt,ReadResourceRequestSchema:Kt,CompleteRequestSchema:Jt,DiscoverRequestSchema:Yt,SubscriptionFilterSchema:Xt,SubscriptionsListenRequestSchema:Qt,SubscriptionsListenResultMetaSchema:$t,SubscriptionsListenResultSchema:en,dispatchRequestSchemas:tn,dispatchResultSchemas:nn,NotificationMetaSchema:rn,SubscriptionsAcknowledgedNotificationSchema:an,CancelledNotificationParamsSchema:on,CancelledNotificationSchema:sn,notificationSchemas2026:cn,JSONRPCResultResponseSchema:K(lt),CallToolResultResponseSchema:K(k([dt,Pt])),ListToolsResultResponseSchema:K(ft),ListPromptsResultResponseSchema:K(pt),GetPromptResultResponseSchema:K(k([mt,Pt])),ListResourcesResultResponseSchema:K(ht),ListResourceTemplatesResultResponseSchema:K(gt),ReadResourceResultResponseSchema:K(k([_t,Pt])),CompleteResultResponseSchema:K(vt),DiscoverResultResponseSchema:K(bt),SubscriptionsListenResultResponseSchema:K(en)}}var Bi;function Vi(){return Bi??=zi()}var Hi=[`tools/list`,`prompts/list`,`resources/list`,`resources/templates/list`,`resources/read`,`server/discover`];function Ui(e){return Hi.includes(e)}var Wi=Symbol(`modelcontextprotocol.resultCacheHintFallback`);function Gi(e){return e[Wi]}function Ki(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function qi(e){return e===`public`||e===`private`}var X=function(e){return e[e.ParseError=-32700]=`ParseError`,e[e.InvalidRequest=-32600]=`InvalidRequest`,e[e.MethodNotFound=-32601]=`MethodNotFound`,e[e.InvalidParams=-32602]=`InvalidParams`,e[e.InternalError=-32603]=`InternalError`,e[e.ResourceNotFound=-32002]=`ResourceNotFound`,e[e.MissingRequiredClientCapability=-32021]=`MissingRequiredClientCapability`,e[e.UnsupportedProtocolVersion=-32022]=`UnsupportedProtocolVersion`,e[e.UrlElicitationRequired=-32042]=`UrlElicitationRequired`,e}({}),Z=class e extends Error{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.ProtocolError`})}static[Symbol.hasInstance](e){return $r(this,e)}static isInstance(e){if(typeof this!=`function`)throw TypeError("isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`");return $r(this,e)}constructor(e,t,n){super(t),this.code=e,this.data=n,this.name=`ProtocolError`,Qr(this,new.target)}static fromError(t,n,r){if(t===X.UrlElicitationRequired&&r){let e=r;if(e.elicitations)return new Yi(e.elicitations,n)}if(t===X.UnsupportedProtocolVersion&&r){let e=r;if(Array.isArray(e.supported)&&typeof e.requested==`string`)return new Xi({supported:e.supported,requested:e.requested},n)}if(t===X.InvalidParams||t===X.ResourceNotFound){let e=r;if(typeof e?.uri==`string`&&(t===X.ResourceNotFound||Object.keys(e).length===1))return new Ji(e.uri,n)}if(t===X.MissingRequiredClientCapability&&r){let e=r;if(e.requiredCapabilities!==null&&typeof e.requiredCapabilities==`object`&&!Array.isArray(e.requiredCapabilities))return new Zi({requiredCapabilities:e.requiredCapabilities},n)}return new e(t,n,r)}},Ji=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.ResourceNotFoundError`})}constructor(e,t=`Resource not found: ${e}`){super(X.InvalidParams,t,{uri:e})}get uri(){return this.data.uri}},Yi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.UrlElicitationRequiredError`})}constructor(e,t=`URL elicitation${e.length>1?`s`:``} required`){super(X.UrlElicitationRequired,t,{elicitations:e})}get elicitations(){return this.data?.elicitations??[]}},Xi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.UnsupportedProtocolVersionError`})}constructor(e,t=`Unsupported protocol version: ${e.requested}`){super(X.UnsupportedProtocolVersion,t,e)}get supported(){return this.data.supported}get requested(){return this.data.requested}},Zi=class extends Z{static{Object.defineProperty(this,"mcpBrand",{value:`mcp.MissingRequiredClientCapabilityError`})}constructor(e,t=`Missing required client capabilities: ${Object.keys(e.requiredCapabilities).join(`, `)}`){super(X.MissingRequiredClientCapability,t,e)}get requiredCapabilities(){return this.data.requiredCapabilities}},Qi=0,$i=`private`,ea=[`tools/call`,`prompts/get`,`resources/read`];function ta(e,t){let n=t.resultType;if(n===void 0)return{...t,resultType:`complete`};if(n===`complete`||ea.includes(e))return t;throw new Z(X.InternalError,`Handler for ${e} returned resultType '${String(n)}', but results of ${e} only support 'complete' on protocol revision 2026-07-28`)}function na(e,t){let n=Gi(t);if(t.resultType!==`complete`||!Ui(e))return n===void 0?t:sa(t);let r=t,i=Ki(r.ttlMs)?r.ttlMs:aa(n),a=qi(r.cacheScope)?r.cacheScope:oa(n),o={...r,ttlMs:i,cacheScope:a};return delete o[Wi],o}function ra(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ia(e,t){if(t===void 0)return e;let n=e._meta;return n===void 0?{...e,_meta:{[Re]:t}}:!ra(n)||n[`io.modelcontextprotocol/serverInfo`]!==void 0?e:{...e,_meta:{...n,[Re]:t}}}function aa(e){return e!==void 0&&Ki(e.ttlMs)?e.ttlMs:Qi}function oa(e){return e!==void 0&&qi(e.cacheScope)?e.cacheScope:$i}function sa(e){let t={...e};return delete t[Wi],t}var ca=[`elicitation/create`,`sampling/createMessage`,`roots/list`],la;function ua(){if(la)return la;let e=Vi();return la={request:{"elicitation/create":m({method:S(`elicitation/create`),params:e.ElicitRequestParamsSchema}),"sampling/createMessage":m({method:S(`sampling/createMessage`),params:e.CreateMessageRequestParamsSchema}),"roots/list":m({method:S(`roots/list`),params:f({}).optional()})},response:{"elicitation/create":e.ElicitResultSchema,"sampling/createMessage":e.CreateMessageResultSchema,"roots/list":e.ListRootsResultSchema}},la}function da(e){return ca.includes(e)}function fa(e){return da(e)?ua().request[e]:void 0}function pa(e){return da(e)?ua().response[e]:void 0}var ma={"tools/call":null,"tools/list":null,"prompts/get":null,"prompts/list":null,"resources/list":null,"resources/templates/list":null,"resources/read":null,"completion/complete":null,"server/discover":null,"subscriptions/listen":null},ha={"notifications/cancelled":null,"notifications/progress":null,"notifications/message":null,"notifications/resources/updated":null,"notifications/resources/list_changed":null,"notifications/tools/list_changed":null,"notifications/prompts/list_changed":null,"notifications/subscriptions/acknowledged":null};function ga(e){return Object.prototype.hasOwnProperty.call(ma,e)}function _a(e){return Object.prototype.hasOwnProperty.call(ha,e)}function va(e){return Object.prototype.hasOwnProperty.call(ma,e)}function ya(e){return ga(e)?Vi().dispatchRequestSchemas[e]:void 0}function ba(e){return va(e)?Vi().dispatchResultSchemas[e]:void 0}function xa(e){return _a(e)?Vi().notificationSchemas2026[e]:void 0}Object.keys(ma),Object.keys(ha);function Sa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ca(e,t){if(e===void 0)return{ok:!1,reason:`not-in-era`};let n=e.safeParse(t);return n.success?{ok:!0,value:n.data}:{ok:!1,reason:`invalid`,message:String(n.error)}}var wa={ok:!1,reason:`not-in-era`},Ta=[Ie,ze];function Ea(e,t){let n=t,r=!1,i=()=>(r||=(n={...n},!0),n),a=t.tools;e===`tools/list`&&Array.isArray(a)&&a.some(e=>Sa(e)&&`execution`in e)&&(i().tools=a.map(e=>{if(!Sa(e)||!(`execution`in e))return e;let t={...e};return delete t.execution,t}));let o=t.capabilities;if(Sa(o)&&`tasks`in o){let e={...o};delete e.tasks,i().capabilities=e}return n}var Da={era:`2026-07-28`,hasRequestMethod:ga,hasNotificationMethod:_a,hasInputRequestMethod:e=>fa(e)!==void 0,validateRequest:(e,t)=>Ca(ya(e),t),validateResult:(e,t)=>Ca(ba(e),t),validateNotification:(e,t)=>Ca(xa(e),t),validateInputRequest:(e,t)=>Ca(fa(e),t),validateInputResponse:(e,t)=>Ca(pa(e),t),samplingResultVariant:()=>wa,outboundEnvelope(e){return{[Ie]:e.protocolVersion,[Le]:e.clientInfo,[ze]:e.clientCapabilities,...e.logLevel!==void 0&&{"io.modelcontextprotocol/logLevel":e.logLevel}}},validateEnvelopeMeta(e){let t=[];for(let n of Ta)n in e||t.push({key:n,problem:`missing`});let n=Vi().RequestMetaEnvelopeSchema.safeParse(e);if(!n.success)for(let e of n.error.issues){let n=e.path.map(String),r=n.length>0?n.join(`.`):`_meta`;n.length===1&&t.some(e=>e.key===r&&e.problem===`missing`)||t.push({key:r,problem:e.message})}return t},projectCallToolResult:e=>di(e),inputRequestSchema:fa,decodeResult(e,t){if(!Sa(t))return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: not an object`,{method:e})};let n=t.resultType;if(n===void 0)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: missing required resultType — servers implementing protocol revision 2026-07-28 MUST include it (the absent-means-complete bridge applies only to earlier-revision servers)`,{method:e,violation:`missing-resultType`})};if(typeof n!=`string`)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: non-string resultType`,{method:e,resultType:n})};if(n===`input_required`){let n=t.inputRequests,r=Sa(n)?n:{},i=t.requestState,a=t._meta===void 0?void 0:Vi().ResultMetaSchema.safeParse(t._meta),o=a?.success?a.data:void 0;return Object.keys(r).length===0&&typeof i!=`string`?{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: input_required carries neither inputRequests nor requestState (every input_required result must include at least one of the two)`,{method:e,violation:`input-required-missing-both`})}:{kind:`input_required`,inputRequests:r,...typeof i==`string`&&{requestState:i},...o!==void 0&&{_meta:o}}}if(n!==`complete`)return{kind:`invalid`,error:new Y(J.UnsupportedResultType,`Unsupported result type '${n}' for ${e}`,{resultType:n,method:e})};let r=ka(),i=Object.hasOwn(r,e)?r[e]:void 0;if(i!==void 0){let n=i.safeParse(t);if(!n.success)return{kind:`invalid`,error:new Y(J.InvalidResult,`Invalid result for ${e}: ${n.error}`,{method:e})}}let a={...t};return delete a.resultType,{kind:`complete`,result:a}},encodeResult(e,t,n){return ia(na(e,ta(e,Ea(e,t))),n)},encodeErrorCode:e=>e===-32002?-32602:e,checkInboundEnvelope(e){if(e.envelope===void 0)return`Request is missing the required _meta envelope for protocol revision 2026-07-28 (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities)`;let t=Vi().RequestMetaEnvelopeSchema.safeParse(e.envelope);if(!t.success)return`Invalid _meta envelope for protocol revision 2026-07-28: ${t.error.issues.map(e=>e.message).join(`; `)}`}},Oa;function ka(){if(Oa)return Oa;let e=Vi();return Oa={"tools/call":e.CallToolResultSchema,"tools/list":e.ListToolsResultSchema,"prompts/get":e.GetPromptResultSchema,"prompts/list":e.ListPromptsResultSchema,"resources/list":e.ListResourcesResultSchema,"resources/templates/list":e.ListResourceTemplatesResultSchema,"resources/read":e.ReadResourceResultSchema,"completion/complete":e.CompleteResultSchema,"server/discover":e.DiscoverResultSchema},Oa}var Aa=`2026-07-28`;function ja(e){return e!==void 0&&ci(e)?Da:Ri}function Ma(e){return e.revision===void 0?e.era===`modern`?Da.era:Ri.era:ja(e.revision).era}function Na(e){return Ia.some(t=>t.hasRequestMethod(e))}function Pa(e){return Ia.some(t=>t.hasNotificationMethod(e))}function Fa(e){return e===`tasks/get`||e===`tasks/cancel`}var Ia=[Ri,Da],La=we({AnnotationsSchema:()=>Nt,AudioContentSchema:()=>ln,BaseMetadataSchema:()=>ct,BaseRequestParamsSchema:()=>I,BlobResourceContentsSchema:()=>jt,BooleanSchemaSchema:()=>Wn,CallToolRequestParamsSchema:()=>wn,CallToolRequestSchema:()=>Tn,CallToolResultSchema:()=>Sn,CancelTaskRequestSchema:()=>Ar,CancelTaskResultSchema:()=>jr,CancelledNotificationParamsSchema:()=>it,CancelledNotificationSchema:()=>at,ClientCapabilitiesSchema:()=>pt,ClientNotificationSchema:()=>Nr,ClientRequestSchema:()=>Mr,ClientResultSchema:()=>Pr,ClientTasksCapabilitySchema:()=>dt,CompatibilityCallToolResultSchema:()=>Cn,CompleteRequestParamsSchema:()=>dr,CompleteRequestSchema:()=>fr,CompleteResultSchema:()=>pr,ContentBlockSchema:()=>pn,CreateMessageRequestParamsSchema:()=>Bn,CreateMessageRequestSchema:()=>Vn,CreateMessageResultSchema:()=>Hn,CreateMessageResultWithToolsSchema:()=>Un,CreateTaskResultSchema:()=>xr,CursorSchema:()=>Ge,DiscoverRequestSchema:()=>yt,DiscoverResultSchema:()=>bt,ElicitRequestFormParamsSchema:()=>nr,ElicitRequestParamsSchema:()=>ir,ElicitRequestSchema:()=>ar,ElicitRequestURLParamsSchema:()=>rr,ElicitResultSchema:()=>cr,ElicitationCompleteNotificationParamsSchema:()=>or,ElicitationCompleteNotificationSchema:()=>sr,EmbeddedResourceSchema:()=>dn,EmptyResultSchema:()=>rt,EnumSchemaSchema:()=>er,GetPromptRequestParamsSchema:()=>on,GetPromptRequestSchema:()=>sn,GetPromptResultSchema:()=>hn,GetTaskPayloadRequestSchema:()=>Er,GetTaskPayloadResultSchema:()=>Dr,GetTaskRequestSchema:()=>wr,GetTaskResultSchema:()=>Tr,IconSchema:()=>ot,IconsSchema:()=>st,ImageContentSchema:()=>K,ImplementationSchema:()=>H,InitializeRequestParamsSchema:()=>mt,InitializeRequestSchema:()=>ht,InitializeResultSchema:()=>_t,InitializedNotificationSchema:()=>vt,JSONArraySchema:()=>Ue,JSONObjectSchema:()=>F,JSONRPCErrorResponseSchema:()=>et,JSONRPCMessageSchema:()=>tt,JSONRPCNotificationSchema:()=>$e,JSONRPCRequestSchema:()=>Qe,JSONRPCResponseSchema:()=>nt,JSONRPCResultResponseSchema:()=>V,JSONValueSchema:()=>He,LegacyTitledEnumSchemaSchema:()=>Yn,ListChangedOptionsBaseSchema:()=>Dn,ListPromptsRequestSchema:()=>rn,ListPromptsResultSchema:()=>an,ListResourceTemplatesRequestSchema:()=>U,ListResourceTemplatesResultSchema:()=>W,ListResourcesRequestSchema:()=>It,ListResourcesResultSchema:()=>Lt,ListRootsRequestSchema:()=>hr,ListRootsResultSchema:()=>gr,ListTasksRequestSchema:()=>Or,ListTasksResultSchema:()=>kr,ListToolsRequestSchema:()=>bn,ListToolsResultSchema:()=>xn,LoggingLevelSchema:()=>On,LoggingMessageNotificationParamsSchema:()=>jn,LoggingMessageNotificationSchema:()=>Mn,ModelHintSchema:()=>Nn,ModelPreferencesSchema:()=>Pn,MultiSelectEnumSchemaSchema:()=>$n,NotificationSchema:()=>z,NotificationsParamsSchema:()=>R,NumberSchemaSchema:()=>Kn,PaginatedRequestParamsSchema:()=>Tt,PaginatedRequestSchema:()=>Et,PaginatedResultSchema:()=>Dt,PingRequestSchema:()=>xt,PrimitiveSchemaDefinitionSchema:()=>tr,ProgressNotificationParamsSchema:()=>Ct,ProgressNotificationSchema:()=>wt,ProgressSchema:()=>St,ProgressTokenSchema:()=>We,PromptArgumentSchema:()=>G,PromptListChangedNotificationSchema:()=>gn,PromptMessageSchema:()=>mn,PromptReferenceSchema:()=>ur,PromptSchema:()=>nn,ReadResourceRequestParamsSchema:()=>zt,ReadResourceRequestSchema:()=>Bt,ReadResourceResultSchema:()=>Vt,RelatedTaskMetadataSchema:()=>qe,RequestIdSchema:()=>Ze,RequestMetaSchema:()=>Je,RequestSchema:()=>L,ResourceContentsSchema:()=>Ot,ResourceLinkSchema:()=>fn,ResourceListChangedNotificationSchema:()=>Ht,ResourceRequestParamsSchema:()=>Rt,ResourceSchema:()=>Pt,ResourceTemplateReferenceSchema:()=>lr,ResourceTemplateSchema:()=>Ft,ResourceUpdatedNotificationParamsSchema:()=>en,ResourceUpdatedNotificationSchema:()=>tn,ResultMetaObjectSchema:()=>Xe,ResultSchema:()=>B,RoleSchema:()=>Mt,RootSchema:()=>mr,RootsListChangedNotificationSchema:()=>_r,SamplingContentSchema:()=>Ln,SamplingMessageContentBlockSchema:()=>Rn,SamplingMessageSchema:()=>zn,ServerCapabilitiesSchema:()=>gt,ServerNotificationSchema:()=>Ir,ServerRequestSchema:()=>Fr,ServerResultSchema:()=>Lr,ServerTasksCapabilitySchema:()=>ft,SetLevelRequestParamsSchema:()=>kn,SetLevelRequestSchema:()=>An,SingleSelectEnumSchemaSchema:()=>Xn,StringSchemaSchema:()=>Gn,SubscribeRequestParamsSchema:()=>Ut,SubscribeRequestSchema:()=>Wt,SubscriptionFilterSchema:()=>qt,SubscriptionsAcknowledgedNotificationParamsSchema:()=>Xt,SubscriptionsAcknowledgedNotificationSchema:()=>Zt,SubscriptionsListenRequestParamsSchema:()=>Jt,SubscriptionsListenRequestSchema:()=>Yt,SubscriptionsListenResultMetaSchema:()=>Qt,SubscriptionsListenResultSchema:()=>$t,TaskAugmentedRequestParamsSchema:()=>Ye,TaskCreationParamsSchema:()=>vr,TaskMetadataSchema:()=>Ke,TaskSchema:()=>br,TaskStatusNotificationParamsSchema:()=>Sr,TaskStatusNotificationSchema:()=>Cr,TaskStatusSchema:()=>yr,TextContentSchema:()=>cn,TextResourceContentsSchema:()=>kt,TitledMultiSelectEnumSchemaSchema:()=>Qn,TitledSingleSelectEnumSchemaSchema:()=>Jn,ToolAnnotationsSchema:()=>_n,ToolChoiceSchema:()=>Fn,ToolExecutionSchema:()=>vn,ToolListChangedNotificationSchema:()=>En,ToolResultContentSchema:()=>In,ToolSchema:()=>yn,ToolUseContentSchema:()=>un,UnsubscribeRequestParamsSchema:()=>Gt,UnsubscribeRequestSchema:()=>Kt,UntitledMultiSelectEnumSchemaSchema:()=>Zn,UntitledSingleSelectEnumSchemaSchema:()=>qn}),Ra=e=>Qe.safeParse(e).success,za=e=>$e.safeParse(e).success,Ba=e=>V.safeParse(e).success,Va=e=>et.safeParse(e).success,Ha=e=>typeof e==`object`&&!!e&&!Array.isArray(e)&&e.resultType===`input_required`,Ua=e=>ht.safeParse(e).success,Wa=e=>vt.safeParse(e).success,Ga=`Mcp-Param-`,Ka=`x-mcp-header`,qa=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,Ja=new Set([`string`,`integer`,`boolean`,`number`]);function Ya(e){let t=[],n=new Map,r=(e,i,a)=>{if(typeof e!=`object`||!e)return;let o=e;if(Ka in o){if(!a||i.length===0)return`${Qa(i)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;let e=o[Ka];if(typeof e!=`string`||e.length===0)return`${Qa(i)}: x-mcp-header MUST be a non-empty string`;if(!qa.test(e))return`${Qa(i)}: x-mcp-header '${e}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;let r=typeof o.type==`string`?o.type:void 0;if(r===void 0||!Ja.has(r))return`${Qa(i)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${r??``}`;let s=e.toLowerCase(),c=n.get(s);if(c!==void 0)return`x-mcp-header '${e}' is not case-insensitively unique (also declared as '${c}')`;n.set(s,e),t.push({path:i,headerName:e,type:r})}let s=o.properties;if(typeof s==`object`&&s)for(let[e,t]of Object.entries(s)){let n=r(t,[...i,e],a);if(n!==void 0)return n}for(let e of Xa){let t=o[e];if(t===void 0)continue;let n=Array.isArray(t)?t:typeof t==`object`&&t&&Za.has(e)?Object.values(t):[t];for(let t of n){let n=r(t,[...i,`<${e}>`],!1);if(n!==void 0)return n}}},i=r(e,[],!0);return i===void 0?{valid:!0,declarations:t}:{valid:!1,reason:i}}var Xa=[`items`,`prefixItems`,`contains`,`additionalProperties`,`unevaluatedProperties`,`unevaluatedItems`,`propertyNames`,`patternProperties`,`dependentSchemas`,`oneOf`,`anyOf`,`allOf`,`not`,`if`,`then`,`else`,`$defs`,`definitions`],Za=new Set([`patternProperties`,`dependentSchemas`,`$defs`,`definitions`]);function Qa(e){return e.length===0?``:e.join(`.`)}var $a=`=?base64?`,eo=`?=`;function to(e){if(typeof e==`string`)return e;if(typeof e==`boolean`)return e?`true`:`false`;if(typeof e==`number`)return!Number.isFinite(e)||Number.isInteger(e)&&!Number.isSafeInteger(e)?void 0:String(e)}function no(e){if(e.length===0||e.startsWith($a)&&e.endsWith(eo)||e!==e.trim())return!0;for(let t=0;t=32&&n<=126))return!0}return!1}function ro(e){let t=new TextEncoder().encode(e),n=``;for(let e of t)n+=String.fromCodePoint(e);return btoa(n)}function io(e){return no(e)?`${$a}${ro(e)}${eo}`:e}function ao(e,t){let n=e;for(let e of t){if(typeof n!=`object`||!n)return;n=n[e]}return n}function oo(e,t){let n={};for(let r of e){let e=ao(t,r.path);if(e==null)continue;let i=to(e);i!==void 0&&(n[`${Ga}${r.headerName}`]=io(i))}return n}X.InvalidRequest,X.UnsupportedProtocolVersion,X.InvalidParams,X.MethodNotFound,X.InvalidParams,X.MissingRequiredClientCapability,X.ParseError,X.InvalidRequest,X.MethodNotFound,X.UnsupportedProtocolVersion,X.MissingRequiredClientCapability;var so={"tools/call":`name`,"prompts/get":`name`,"resources/read":`uri`,"tasks/get":`taskId`,"tasks/update":`taskId`,"tasks/cancel":`taskId`};function co(e,t){let n=Object.hasOwn(so,e)?so[e]:void 0;if(n===void 0)return;let r=lo(t)?t[n]:void 0;return{field:n,value:typeof r==`string`?r:void 0}}function lo(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function uo(e,t){return ee(e,t)}function fo(e){return new Set(e.flatMap(e=>Object.keys(e.shape)))}function po(e){if(e==null)return!1;let t=typeof e;return t!==`object`&&t!==`function`||!(`~standard`in e)?!1:typeof e[`~standard`]?.validate==`function`}var mo=!1,ho=`draft-2020-12`;function go(e,t=`input`){let n=e[`~standard`],r;if(n.jsonSchema)r=n.jsonSchema[t]({target:ho});else if(n.vendor===`zod`){if(!(`_zod`in e))throw Error(`Schema appears to be from zod 3, which the SDK cannot convert to JSON Schema. Upgrade to zod >=4.2.0, or wrap your JSON Schema with fromJsonSchema().`);mo||(mo=!0,console.warn("[mcp-sdk] Your zod version does not implement `~standard.jsonSchema` (added in zod 4.2.0). Falling back to z.toJSONSchema(). Upgrade to zod >=4.2.0 to silence this warning.")),r=h(e,{target:ho,io:t})}else throw Error(`Schema library "${n.vendor}" does not implement StandardJSONSchemaV1 (\`~standard.jsonSchema\`). Upgrade to a version that does, or wrap your JSON Schema with fromJsonSchema().`);if(t===`output`)return r.type===void 0&&_o(r)?{type:`object`,...r}:r;if(r.type!==void 0&&r.type!==`object`)throw Error(`MCP tool and prompt schemas must describe objects (got type: ${JSON.stringify(r.type)}). Wrap your schema in z.object({...}) or equivalent.`);return{type:`object`,...r}}function _o(e){if(`properties`in e||`patternProperties`in e||`additionalProperties`in e||`required`in e)return!0;for(let t of[`oneOf`,`anyOf`,`allOf`]){let n=e[t];if(Array.isArray(n)&&n.length>0)return n.every(e=>typeof e==`object`&&!!e&&(e.type===`object`||_o(e)))}return!1}function vo(e){return e.path?.length?`${e.path.map(e=>String(typeof e==`object`?e.key:e)).join(`.`)}: ${e.message}`:e.message}async function yo(e,t){let n=await e[`~standard`].validate(t);return n.issues&&n.issues.length>0?{success:!1,error:n.issues.map(e=>vo(e)).join(`, `)}:{success:!0,data:n.value}}function bo(e){let t=h(e,{target:ho,io:`input`});return typeof t.pattern==`string`?t.pattern:void 0}var xo=/\\\.\\d\{(\d+)\}/;function So(e){let t=xo.exec(e),n=[void 0,-1,0];return t&&n.push(Number(t[1])),[!1,!0].flatMap(e=>[!1,!0].flatMap(t=>n.map(n=>he({local:e,offset:t,precision:n}))))}function Co(e,t){let n;switch(e){case`email`:n=[de()];break;case`uri`:n=[y()];break;case`date`:n=[ge()];break;case`date-time`:n=So(t)}return new Set(n.map(e=>bo(e)).filter(e=>e!==void 0))}function wo(e,t,n){return n!==`zod`||Co(e,t).has(t)}function To(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Eo(e){try{return go(e,`input`)}catch(e){let t=e instanceof Error?e.message:String(e);throw new Z(X.InvalidParams,`Elicitation requestedSchema must describe an object with flat primitive properties: ${t}`)}}var Do=new Set([`$comment`,`deprecated`,`description`,`examples`,`readOnly`,`title`,`writeOnly`]);function Oo(e){return Do.has(e)||e.startsWith(`x-`)}var ko=new Set([`$schema`,...Object.keys(nr.shape.requestedSchema.shape)]),Ao={string:fo([Gn,qn,Jn,Yn]),number:fo([Kn]),integer:fo([Kn]),boolean:fo([Wn]),array:fo([Zn,Qn])},jo=new Set(Gn.shape.format.unwrap().options);function Mo(e,t,n,r){if(!To(e))return e;let i=typeof e.type==`string`&&Object.hasOwn(Ao,e.type)?Ao[e.type]:void 0;if(i===void 0)return e;let a={};for(let[o,s]of Object.entries(e))i.has(o)||Oo(o)?a[o]=s:o===`pattern`&&e.type===`string`&&typeof e.format==`string`?jo.has(e.format)?(typeof s!=`string`||!wo(e.format,s,n))&&r.push(`${t}.${o}`):a[o]=s:r.push(`${t}.${o}`);return a}function No(e,t){let n={},r=[];for(let[i,a]of Object.entries(e))i===`properties`&&To(a)?n[i]=Object.fromEntries(Object.entries(a).map(([e,n])=>[e,Mo(n,`properties.${e}`,t,r)])):ko.has(i)?n[i]=a:Oo(i)||r.push(i);if(r.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema contains unsupported JSON Schema constraint(s) after Standard Schema conversion: ${r.join(`, `)}`);return n}function Po(e,t){if(!To(e.properties))return t;let n=Object.entries(e.properties).filter(([,e])=>!uo(tr,e).success).map(([e])=>`properties.${e}`);return n.length>0?n.join(`, `):t}function Fo(e,t,n=``){return Array.isArray(e)&&Array.isArray(t)?e.flatMap((e,r)=>Fo(e,t[r],`${n}[${r}]`)):!To(e)||!To(t)?[]:Object.entries(e).flatMap(([e,r])=>{let i=n?`${n}.${e}`:e;return Object.prototype.hasOwnProperty.call(t,e)?Fo(r,t[e],i):Oo(e)?[]:[i]})}function Io(e){if(!po(e.requestedSchema))return{...e,mode:`form`,requestedSchema:e.requestedSchema};let t=e.requestedSchema[`~standard`].vendor,n=No(Eo(e.requestedSchema),t),r=uo(nr.shape.requestedSchema,n);if(!r.success)throw new Z(X.InvalidParams,`Elicitation requestedSchema only supports flat primitive properties (string, number, integer, boolean, and string enums): ${Po(n,r.error.message)}`);let i=Fo(n,r.data);if(i.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema contains unsupported JSON Schema constraint(s) after Standard Schema conversion: ${i.join(`, `)}`);let a=(r.data.required??[]).filter(e=>!Object.prototype.hasOwnProperty.call(r.data.properties,e));if(a.length>0)throw new Z(X.InvalidParams,`Elicitation requestedSchema lists required properties that are not defined in properties: ${a.join(`, `)}`);return{...e,mode:`form`,requestedSchema:r.data}}function Lo(e){let t=e.inputRequests!==void 0&&Object.keys(e.inputRequests).length>0,n=typeof e.requestState==`string`;if(!t&&!n)throw TypeError(`inputRequired() requires at least one of inputRequests (with at least one entry) or requestState (spec: every InputRequiredResult MUST include at least one of the two)`);return{resultType:`input_required`,...e.inputRequests!==void 0&&{inputRequests:e.inputRequests},...e.requestState!==void 0&&{requestState:e.requestState}}}Object.assign(Lo,{elicit(e){try{return{method:`elicitation/create`,params:Io(e)}}catch(e){throw e instanceof Z?TypeError(e.message,{cause:e}):e}},elicitUrl(e){return{method:`elicitation/create`,params:{...e,mode:`url`}}},createMessage(e){return{method:`sampling/createMessage`,params:e}},listRoots(){return{method:`roots/list`}}});var Ro=!0,zo=10,Bo=250;function Vo(e){return{autoFulfill:e?.autoFulfill??Ro,maxRounds:e?.maxRounds??zo}}function Ho(e,t,n){let r=t!==void 0&&Object.keys(t).length>0;return!r&&n===void 0?e:{...e,...r&&{inputResponses:t},...n!==void 0&&{requestState:n}}}function Uo(e,t){return`Multi-round-trip request '${e}' still required input after ${t} rounds (inputRequired.maxRounds)`}function Wo(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason instanceof Y?t.reason:new Y(J.RequestTimeout,String(t.reason)));return}let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason instanceof Y?t.reason:new Y(J.RequestTimeout,String(t?.reason)))};t?.addEventListener(`abort`,a,{once:!0})})}function Go(e){let t=new AbortController,n=()=>t.abort(e?.reason);return e?.addEventListener(`abort`,n,{once:!0}),e?.aborted&&t.abort(e.reason),{signal:t.signal,abort:e=>t.abort(e),dispose:()=>e?.removeEventListener(`abort`,n)}}async function Ko(e){let{config:t,method:n,originalParams:r,requestOptions:i,hooks:a,signal:o}=e,s=e.flowStartedAt??Date.now(),c=e.firstPayload,l=0;for(;;){if(l+=1,l>t.maxRounds)throw new Y(J.InputRequiredRoundsExceeded,Uo(n,t.maxRounds),{rounds:t.maxRounds,lastResult:{inputRequests:c.inputRequests,...c.requestState!==void 0&&{requestState:c.requestState}}});i.onprogress?.({progress:l,message:`Fulfilling input required by '${n}' (round ${l})`});let e=Object.entries(c.inputRequests??{}),u;if(e.length>0){let t=Go(o);try{let n=await Promise.all(e.map(async([e,n])=>{try{return[e,await a.dispatchInputRequest(e,n,t.signal)]}catch(e){throw t.abort(e),e}}));u=Object.fromEntries(n)}finally{t.dispose()}}else await Wo(Bo,o);let d={...i.timeout!==void 0&&{timeout:i.timeout}};if(i.maxTotalTimeout!==void 0){let e=Date.now()-s,t=i.maxTotalTimeout-e;if(t<=0)throw new Y(J.RequestTimeout,`Maximum total timeout exceeded`,{maxTotalTimeout:i.maxTotalTimeout,totalElapsed:e});d.maxTotalTimeout=t}let f=await a.retry(Ho(r,u,c.requestState),d);if(Ha(f)){c={inputRequests:f.inputRequests??{},...f.requestState!==void 0&&{requestState:f.requestState}};continue}return f}}var qo=`AnnotationsSchema.AudioContentSchema.BaseMetadataSchema.BlobResourceContentsSchema.BooleanSchemaSchema.CallToolRequestSchema.CallToolRequestParamsSchema.CallToolResultSchema.CancelledNotificationSchema.CancelledNotificationParamsSchema.CancelTaskRequestSchema.CancelTaskResultSchema.ClientCapabilitiesSchema.ClientNotificationSchema.ClientRequestSchema.ClientResultSchema.CompatibilityCallToolResultSchema.CompleteRequestSchema.CompleteRequestParamsSchema.CompleteResultSchema.ContentBlockSchema.CreateMessageRequestSchema.CreateMessageRequestParamsSchema.CreateMessageResultSchema.CreateMessageResultWithToolsSchema.CreateTaskResultSchema.CursorSchema.DiscoverRequestSchema.DiscoverResultSchema.ElicitationCompleteNotificationSchema.ElicitationCompleteNotificationParamsSchema.ElicitRequestSchema.ElicitRequestFormParamsSchema.ElicitRequestParamsSchema.ElicitRequestURLParamsSchema.ElicitResultSchema.EmbeddedResourceSchema.EmptyResultSchema.EnumSchemaSchema.GetPromptRequestSchema.GetPromptRequestParamsSchema.GetPromptResultSchema.GetTaskPayloadRequestSchema.GetTaskPayloadResultSchema.GetTaskRequestSchema.GetTaskResultSchema.IconSchema.IconsSchema.ImageContentSchema.ImplementationSchema.InitializedNotificationSchema.InitializeRequestSchema.InitializeRequestParamsSchema.InitializeResultSchema.JSONArraySchema.JSONObjectSchema.JSONRPCErrorResponseSchema.JSONRPCMessageSchema.JSONRPCNotificationSchema.JSONRPCRequestSchema.JSONRPCResponseSchema.JSONRPCResultResponseSchema.JSONValueSchema.LegacyTitledEnumSchemaSchema.ListPromptsRequestSchema.ListPromptsResultSchema.ListResourcesRequestSchema.ListResourcesResultSchema.ListResourceTemplatesRequestSchema.ListResourceTemplatesResultSchema.ListRootsRequestSchema.ListRootsResultSchema.ListTasksRequestSchema.ListTasksResultSchema.ListToolsRequestSchema.ListToolsResultSchema.LoggingLevelSchema.LoggingMessageNotificationSchema.LoggingMessageNotificationParamsSchema.ModelHintSchema.ModelPreferencesSchema.MultiSelectEnumSchemaSchema.NotificationSchema.NumberSchemaSchema.PaginatedRequestSchema.PaginatedRequestParamsSchema.PaginatedResultSchema.PingRequestSchema.PrimitiveSchemaDefinitionSchema.ProgressSchema.ProgressNotificationSchema.ProgressNotificationParamsSchema.ProgressTokenSchema.PromptSchema.PromptArgumentSchema.PromptListChangedNotificationSchema.PromptMessageSchema.PromptReferenceSchema.ReadResourceRequestSchema.ReadResourceRequestParamsSchema.ReadResourceResultSchema.RelatedTaskMetadataSchema.RequestSchema.RequestIdSchema.RequestMetaSchema.ResourceSchema.ResourceContentsSchema.ResourceLinkSchema.ResourceListChangedNotificationSchema.ResourceRequestParamsSchema.ResourceTemplateSchema.ResourceTemplateReferenceSchema.ResourceUpdatedNotificationSchema.ResourceUpdatedNotificationParamsSchema.ResultMetaObjectSchema.ResultSchema.RoleSchema.RootSchema.RootsListChangedNotificationSchema.SamplingContentSchema.SamplingMessageSchema.SamplingMessageContentBlockSchema.ServerCapabilitiesSchema.ServerNotificationSchema.ServerRequestSchema.ServerResultSchema.SetLevelRequestSchema.SetLevelRequestParamsSchema.SingleSelectEnumSchemaSchema.StringSchemaSchema.SubscribeRequestSchema.SubscribeRequestParamsSchema.SubscriptionFilterSchema.SubscriptionsAcknowledgedNotificationSchema.SubscriptionsAcknowledgedNotificationParamsSchema.SubscriptionsListenRequestSchema.SubscriptionsListenRequestParamsSchema.SubscriptionsListenResultSchema.SubscriptionsListenResultMetaSchema.TaskAugmentedRequestParamsSchema.TaskCreationParamsSchema.TaskMetadataSchema.TaskSchema.TaskStatusSchema.TaskStatusNotificationSchema.TaskStatusNotificationParamsSchema.TextContentSchema.TextResourceContentsSchema.TitledMultiSelectEnumSchemaSchema.TitledSingleSelectEnumSchemaSchema.ToolSchema.ToolAnnotationsSchema.ToolChoiceSchema.ToolExecutionSchema.ToolListChangedNotificationSchema.ToolResultContentSchema.ToolUseContentSchema.UnsubscribeRequestSchema.UnsubscribeRequestParamsSchema.UntitledMultiSelectEnumSchemaSchema.UntitledSingleSelectEnumSchemaSchema`.split(`.`),Jo={IdJagTokenExchangeResponseSchema:Ur,OAuthClientInformationFullSchema:Jr,OAuthClientInformationSchema:qr,OAuthClientMetadataSchema:Kr,OAuthClientRegistrationErrorSchema:Yr,OAuthErrorResponseSchema:Wr,OAuthMetadataSchema:zr,OAuthProtectedResourceMetadataSchema:Rr,OAuthTokenRevocationRequestSchema:Xr,OAuthTokensSchema:Hr,OpenIdProviderDiscoveryMetadataSchema:Vr,OpenIdProviderMetadataSchema:Br},Yo={},Xo={};function Zo(e,t){let n=e.slice(0,-6);Yo[n]=t,Xo[n]=e=>t.safeParse(e).success}for(let e of qo)Zo(e,La[e]);for(let[e,t]of Object.entries(Jo))Zo(e,t);Object.freeze(Yo);var Qo=Object.freeze(Xo);function $o(e){switch(e){case`initialize`:case`notifications/initialized`:return ja(void 0);case`server/discover`:return ja(Aa);default:return}}var es=[Ie,Le,ze,Ve],ts=[`inputResponses`,`requestState`];function ns(e,t){let n=e.params;if(!ss(n))return{message:e,lifted:{}};let r=n._meta,i=ss(r)?es.filter(e=>e in r):[],a=t===`request`?ts.filter(e=>e in n):[];if(i.length===0&&a.length===0)return{message:e,lifted:{}};let o={},s={...n};if(i.length>0&&ss(r)){let e={},t={...r};for(let n of i)e[n]=r[n],delete t[n];o.envelope=e,Object.keys(t).length>0?s._meta=t:delete s._meta}for(let e of a)e===`inputResponses`&&(o.inputResponses=s[e]),e===`requestState`&&(o.requestState=s[e]),delete s[e];return{message:{...e,params:s},lifted:o}}function rs(e,t){let n=e.validateResult(t,void 0);if(n.ok||n.reason!==`not-in-era`)return{"~standard":{version:1,vendor:`mcp-wire-codec`,validate(n){let r=e.validateResult(t,n);return r.ok?{value:r.value}:{issues:[{message:r.reason===`invalid`?r.message:`not-in-era: ${t}`}]}}}}}function is(e){return()=>e}var as=is(void 0),os=class{_transport;_requestMessageId=0;_requestHandlers=new Map;_customSchemaRequestMethods=new Set;_requestHandlerAbortControllers=new Map;_notificationHandlers=new Map;_responseHandlers=new Map;_progressHandlers=new Map;_timeoutInfo=new Map;_pendingDebouncedNotifications=new Set;_negotiatedProtocolVersion;_supportedProtocolVersions;onclose;onerror;fallbackRequestHandler;fallbackNotificationHandler;constructor(e){this._options=e,this._supportedProtocolVersions=e?.supportedProtocolVersions??Pe,this.setNotificationHandler(`notifications/cancelled`,e=>{this._oncancel(e)}),this.setNotificationHandler(`notifications/progress`,e=>{this._onprogress(e)}),this.setRequestHandler(`ping`,e=>({}))}_shouldDropInbound(e){}_outboundMetaEnvelope(){}_envelopeOutbound(e){let t=this._outboundMetaEnvelope();if(t===void 0)return e;let n=e.params??{};return{...e,params:{...n,_meta:{...t,...n._meta}}}}_resolveNonCompleteResult(e,t){return Promise.reject(new Y(J.UnsupportedResultType,`Unsupported result type '${e.kind}' for ${t.request.method}`,{resultType:e.kind,method:t.request.method}))}_getRequestHandler(e){return this._requestHandlers.get(e)}async _oncancel(e){e.params.requestId!==void 0&&this._requestHandlerAbortControllers.get(e.params.requestId)?.abort(e.params.reason)}_setupTimeout(e,t,n,r,i=!1){this._timeoutInfo.set(e,{timeoutId:setTimeout(r,t),startTime:Date.now(),timeout:t,maxTotalTimeout:n,resetTimeoutOnProgress:i,onTimeout:r})}_resetTimeout(e){let t=this._timeoutInfo.get(e);if(!t)return!1;let n=Date.now()-t.startTime;if(t.maxTotalTimeout&&n>=t.maxTotalTimeout)throw this._timeoutInfo.delete(e),new Y(J.RequestTimeout,`Maximum total timeout exceeded`,{maxTotalTimeout:t.maxTotalTimeout,totalElapsed:n});return clearTimeout(t.timeoutId),t.timeoutId=setTimeout(t.onTimeout,t.timeout),!0}_cleanupTimeout(e){let t=this._timeoutInfo.get(e);t&&(clearTimeout(t.timeoutId),this._timeoutInfo.delete(e))}async connect(e){this._transport=e;let t=this.transport?.onclose;this._transport.onclose=()=>{try{t?.()}finally{this._onclose()}};let n=this.transport?.onerror;this._transport.onerror=e=>{n?.(e),this._onerror(e)};let r=this._transport?.onmessage;this._transport.onmessage=(e,t)=>{r?.(e,t),Ba(e)||Va(e)?this._onresponse(e):Ra(e)?this._onrequest(e,t):za(e)?this._onnotification(e,t):this._onerror(Error(`Unknown message type: ${JSON.stringify(e)}`))},e.setSupportedProtocolVersions?.(this._supportedProtocolVersions),await this._transport.start()}_onclose(){let e=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._pendingDebouncedNotifications.clear();for(let e of this._timeoutInfo.values())clearTimeout(e.timeoutId);this._timeoutInfo.clear();let t=this._requestHandlerAbortControllers;this._requestHandlerAbortControllers=new Map;let n=new Y(J.ConnectionClosed,`Connection closed`);this._transport=void 0;try{this.onclose?.()}finally{for(let t of e.values())t(n);for(let e of t.values())e.abort(n)}}_onerror(e){this.onerror?.(e)}_onnotification(e,t){let{message:n}=ns(e,`notification`),r=this._negotiatedWireCodec();if(t?.classification===void 0&&this._shouldDropInbound(e)===`drop`)return;if(t?.classification!==void 0){let e=Ma(t.classification);if(e!==r.era){this._onerror(Error(`Era mismatch on inbound notification '${n.method}': classified as ${e} but this instance serves ${r.era}`));return}}if(Pa(n.method)&&!r.hasNotificationMethod(n.method))return;let i=this._notificationHandlers.get(n.method),a=this.fallbackNotificationHandler;(i!==void 0||a!==void 0)&&Promise.resolve().then(()=>i===void 0?a(n):i(n,r)).catch(e=>this._onerror(Error(`Uncaught error in notification handler: ${e}`)))}_onrequest(e,t){let{message:n,lifted:r}=ns(e,`request`),i=this._negotiatedWireCodec();if(t?.classification===void 0&&this._shouldDropInbound(e)===`drop`){this._onerror(Error(`Dropped inbound request '${e.method}': not servable on this connection's protocol era`));return}let a=this._transport,o=(e,t,r)=>{let i={jsonrpc:`2.0`,id:n.id,error:{code:e,message:t,...r!==void 0&&{data:r}}};a?.send(i).catch(e=>this._onerror(Error(`Failed to send an error response: ${e}`)))};if(t?.classification!==void 0){let e=Ma(t.classification);if(e!==i.era){this._onerror(Error(`Era mismatch on inbound request '${n.method}': classified as ${e} but this instance serves ${i.era}`));let r=t.classification.revision??e;o(X.UnsupportedProtocolVersion,`Unsupported protocol version: ${r}`,{supported:this._supportedProtocolVersions,requested:r});return}}if(Na(n.method)&&!i.hasRequestMethod(n.method)&&!(Fa(n.method)&&this._customSchemaRequestMethods.has(n.method))){o(X.MethodNotFound,`Method not found`);return}let s=this._requestHandlers.get(n.method)??this.fallbackRequestHandler;if(s===void 0){o(X.MethodNotFound,`Method not found`);return}let c=i.checkInboundEnvelope(r);if(c!==void 0){o(X.InvalidParams,c);return}let l=(e,t)=>this._notificationViaCodec(this._resolveOutboundCodec(e.method),e,{...t,relatedRequestId:n.id}),u=(e,t,r)=>this._requestWithSchemaViaCodec(this._resolveOutboundCodec(e.method),e,t,{...r,relatedRequestId:n.id}),d=new AbortController;this._requestHandlerAbortControllers.set(n.id,d);let f=r.inputResponses===void 0?void 0:us(r.inputResponses),p={sessionId:a?.sessionId,mcpReq:{id:n.id,method:n.method,_meta:n.params?._meta,...r.envelope!==void 0&&{envelope:r.envelope},...f!==void 0&&{inputResponses:f.accepted},...f!==void 0&&f.droppedKeys.length>0&&{droppedInputResponseKeys:f.droppedKeys},requestState:r.requestState===void 0?as:is(r.requestState),signal:d.signal,send:((e,t,n)=>{let r=this._resolveOutboundCodec(e.method);if(this._assertOutboundRequestInEra(r,e.method),po(t))return u(e,t,n);let i=rs(r,e.method);if(i===void 0)throw TypeError(`'${e.method}' is not a spec method; pass a result schema as the second argument to ctx.mcpReq.send().`);return u(e,i,t)}),notify:l},http:t?.authInfo?{authInfo:t.authInfo}:void 0},m=this.buildContext(p,t);Promise.resolve().then(()=>s(n,m)).then(async e=>{if(d.signal.aborted)return;let t;try{t=i.encodeResult(n.method,e,this._outboundServerInfo())}catch(e){this._onerror(Error(`Failed to encode result for ${n.method}: ${e}`)),o(X.InternalError,`Internal error`);return}let r={result:t,jsonrpc:`2.0`,id:n.id};await a?.send(r)},async e=>{if(d.signal.aborted)return;let t=Number.isSafeInteger(e.code)?e.code:X.InternalError,r={jsonrpc:`2.0`,id:n.id,error:{code:i.encodeErrorCode(t),message:e.message??`Internal error`,...e.data!==void 0&&{data:e.data}}};await a?.send(r)}).catch(e=>this._onerror(Error(`Failed to send response: ${e}`))).finally(()=>{this._requestHandlerAbortControllers.get(n.id)===d&&this._requestHandlerAbortControllers.delete(n.id)})}_onprogress(e){let{progressToken:t,...n}=e.params,r=Number(t),i=this._progressHandlers.get(r);if(!i){this._onerror(Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}let a=this._responseHandlers.get(r),o=this._timeoutInfo.get(r);if(o&&a&&o.resetTimeoutOnProgress)try{this._resetTimeout(r)}catch(e){this._responseHandlers.delete(r),this._progressHandlers.delete(r),this._cleanupTimeout(r),a(e);return}i(n)}_onresponse(e){let t=Number(e.id),n=this._responseHandlers.get(t);if(n===void 0){this._onerror(Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}this._responseHandlers.delete(t),this._cleanupTimeout(t),this._progressHandlers.delete(t),Ba(e)?n(e):n(Z.fromError(e.error.code,e.error.message,e.error.data))}get transport(){return this._transport}async close(){await this._transport?.close()}request(e,t,n){let r=this._resolveOutboundCodec(e.method);if(po(t))return Fa(e.method)||this._assertOutboundRequestInEra(r,e.method),this._requestWithSchemaViaCodec(r,e,t,n);this._assertOutboundRequestInEra(r,e.method);let i=rs(r,e.method);if(i===void 0)throw TypeError(`'${e.method}' is not a spec method; pass a result schema as the second argument to request().`);return this._requestWithSchemaViaCodec(r,e,i,t)}_negotiatedWireCodec(){return ja(this._negotiatedProtocolVersion)}_wireCodec(){return this._negotiatedWireCodec()}_resolveOutboundCodec(e){if(this._negotiatedProtocolVersion===void 0){let t=$o(e);if(t)return t}return this._negotiatedWireCodec()}_assertOutboundRequestInEra(e,t){if(Na(t)&&!e.hasRequestMethod(t))throw new Y(J.MethodNotSupportedByProtocolVersion,`Method '${t}' is not supported by the negotiated protocol version (wire era ${e.era})`,{method:t,era:e.era})}_requestWithSchema(e,t,n){let r=this._resolveOutboundCodec(e.method);return this._assertOutboundRequestInEra(r,e.method),this._requestWithSchemaViaCodec(r,e,t,n)}_requestWithSchemaViaCodec(e,t,n,r){let{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o,headers:s}=r??{},c=Date.now(),l,u;return new Promise((d,f)=>{let p=e=>{f(e)};if(!this._transport){p(Error(`Not connected`));return}if(this._options?.enforceStrictCapabilities===!0)try{this.assertCapabilityForMethod(t.method)}catch(e){p(e);return}if(r?.signal?.aborted){let e=r.signal.reason;throw e instanceof Y?e:new Y(J.RequestTimeout,String(e))}let m=e.era===`2026-07-28`&&this._transport.hasPerRequestStream===!0?new AbortController:void 0,h=this._requestMessageId++;u=h;let g={...t,jsonrpc:`2.0`,id:h};r?.onprogress&&(this._progressHandlers.set(h,r.onprogress),g.params={...t.params,_meta:{...t.params?._meta,progressToken:h}});let _=this._envelopeOutbound(g),v=!1,y=e=>{v||(this._progressHandlers.delete(h),m===void 0?t.method!==`initialize`&&this._transport?.send(this._envelopeOutbound({jsonrpc:`2.0`,method:`notifications/cancelled`,params:{requestId:h,reason:String(e)}}),{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o}).catch(e=>this._onerror(Error(`Failed to send cancellation: ${e}`))):m.abort(),f(e instanceof Y?e:new Y(J.RequestTimeout,String(e))))};this._responseHandlers.set(h,i=>{if(r?.signal?.aborted)return;if(v=!0,i instanceof Error)return f(i);let a;try{a=e.decodeResult(t.method,i.result)}catch(e){return f(e instanceof Error?e:Error(String(e)))}if(a.kind===`invalid`)return f(a.error);if(a.kind===`input_required`){if(r?.allowInputRequired===!0)return d(gs(a));let i={codec:e,request:t,resultSchema:n,options:r,flowStartedAt:c,retry:(r,i)=>this._requestWithSchemaViaCodec(e,r===void 0?{method:t.method}:{method:t.method,params:r},n,i)};return d(this._resolveNonCompleteResult(a,i))}let o=a.result;yo(n,o).then(e=>{e.success?d(e.data):f(new Y(J.InvalidResult,`Invalid result for ${t.method}: ${e.error}`))},f)}),l=()=>y(r?.signal?.reason),r?.signal?.addEventListener(`abort`,l,{once:!0});let b=r?.timeout??6e4;this._setupTimeout(h,b,r?.maxTotalTimeout,()=>y(new Y(J.RequestTimeout,`Request timed out`,{timeout:b})),r?.resetTimeoutOnProgress??!1),this._transport.send(_,{relatedRequestId:i,resumptionToken:a,onresumptiontoken:o,headers:s,requestSignal:m?.signal}).catch(e=>{this._progressHandlers.delete(h),f(e)})}).finally(()=>{l&&r?.signal?.removeEventListener(`abort`,l),u!==void 0&&(this._responseHandlers.delete(u),this._cleanupTimeout(u))})}async notification(e,t){return await this._notificationViaCodec(this._resolveOutboundCodec(e.method),e,t)}async _notificationViaCodec(e,t,n){if(!this._transport)throw new Y(J.NotConnected,`Not connected`);if(Pa(t.method)&&!e.hasNotificationMethod(t.method))throw new Y(J.MethodNotSupportedByProtocolVersion,`Notification '${t.method}' is not supported by the negotiated protocol version (wire era ${e.era})`,{method:t.method,era:e.era});this.assertNotificationCapability(t.method);let r=this._envelopeOutbound({jsonrpc:`2.0`,...t});if((this._options?.debouncedNotificationMethods??[]).includes(t.method)&&!t.params&&n?.relatedRequestId===void 0){if(this._pendingDebouncedNotifications.has(t.method))return;this._pendingDebouncedNotifications.add(t.method),Promise.resolve().then(()=>{this._pendingDebouncedNotifications.delete(t.method),this._transport&&this._transport?.send(r,n).catch(e=>this._onerror(e))});return}await this._transport.send(r,n)}setRequestHandler(e,t,n){this.assertRequestHandlerCapability(e);let r;if(typeof t==`function`){if(!Na(e))throw TypeError(`'${e}' is not a spec request method; pass schemas as the second argument to setRequestHandler().`);r=(n,r)=>{let i=this._negotiatedWireCodec(),a=i.validateRequest(e,n);if(!a.ok&&a.reason===`not-in-era`&&(a=i.validateInputRequest(e,n)),!a.ok)throw a.reason===`not-in-era`?new Z(X.InternalError,`No wire schema for ${e} in the resolved era`):Error(a.message);return Promise.resolve(t(a.value,r))}}else if(n)r=async(r,i)=>{let a=await yo(t.params,{...r.params});if(!a.success)throw new Z(X.InvalidParams,`Invalid params for ${e}: ${a.error}`);return n(a.data,i)};else throw TypeError(`setRequestHandler: handler is required`);typeof t==`function`?this._customSchemaRequestMethods.delete(e):this._customSchemaRequestMethods.add(e),this._requestHandlers.set(e,this._wrapHandler(e,r))}_wrapHandler(e,t){return t}_outboundServerInfo(){}removeRequestHandler(e){this._requestHandlers.delete(e),this._customSchemaRequestMethods.delete(e)}assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw Error(`A request handler for ${e} already exists, which would be overridden`)}setNotificationHandler(e,t,n){if(typeof t==`function`){if(!Pa(e))throw TypeError(`'${e}' is not a spec notification method; pass schemas as the second argument to setNotificationHandler().`);this._notificationHandlers.set(e,(n,r)=>{let i=r.validateNotification(e,n);if(!i.ok)throw i.reason===`not-in-era`?new Z(X.InternalError,`No wire schema for ${e} in the resolved era`):Error(i.message);return Promise.resolve(t(i.value))});return}if(!n)throw TypeError(`setNotificationHandler: handler is required`);this._notificationHandlers.set(e,async r=>{let i=await yo(t.params,{...r.params});if(!i.success)throw new Z(X.InvalidParams,`Invalid params for notification ${e}: ${i.error}`);await n(i.data,r)})}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};function ss(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function cs(e,t){let n={...e};for(let e in t){let r=e,i=t[r];if(i===void 0)continue;let a=n[r];n[r]=ss(a)&&ss(i)?{...a,...i}:i}return n}function ls(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function us(e){let t={},n=[];if(!ls(e))return{accepted:t,droppedKeys:n};for(let[r,i]of Object.entries(e)){if(!ls(i)||`method`in i||`result`in i){n.push(r);continue}t[r]=i}return{accepted:t,droppedKeys:n}}function ds(e){throw new Y(J.SendFailed,`ctx.mcpReq.${e} is not available while fulfilling an embedded input request: the request is fulfilled locally and has no related peer request`)}function fs(e,t,n,r,i){return{sessionId:i,mcpReq:{id:e,method:t,_meta:n?._meta,requestState:is(void 0),signal:r,send:(()=>ds(`send`)),notify:()=>ds(`notify`)}}}async function ps(e,t,n,r,i){if(!ls(r)||typeof r.method!=`string`)throw new Y(J.InvalidResult,`Invalid input request '${n}': each inputRequests entry must be an embedded request object with a method`,{key:n});let a=r.method;if(!t.hasInputRequestMethod(a))throw new Y(J.InvalidResult,`Invalid input request '${n}': '${a}' is not an embedded request the ${t.era} revision defines (expected elicitation/create, sampling/createMessage, or roots/list)`,{key:n,method:a});let o=e.getRequestHandler(a);if(o===void 0)throw new Y(J.CapabilityNotSupported,`Cannot fulfil input request '${n}': no handler is registered for '${a}' on this client. Declare the corresponding capability and register a handler, or handle input_required results manually.`,{key:n,method:a});let s=ls(r.params)?r.params:void 0;return await o({jsonrpc:`2.0`,id:n,method:a,...s!==void 0&&{params:s}},e.buildContext(fs(n,a,s,i,e.sessionId)))}function ms(e,t){return{...e?.signal!==void 0&&{signal:e.signal},...e?.onprogress!==void 0&&{onprogress:e.onprogress},...e?.resetTimeoutOnProgress!==void 0&&{resetTimeoutOnProgress:e.resetTimeoutOnProgress},...e?.headers!==void 0&&{headers:e.headers},...t.timeout!==void 0&&{timeout:t.timeout},...t.maxTotalTimeout!==void 0&&{maxTotalTimeout:t.maxTotalTimeout},allowInputRequired:!0}}function hs(e,t,n,r){let{codec:i,request:a,options:o,flowStartedAt:s}=r,c={inputRequests:n.inputRequests,...n.requestState!==void 0&&{requestState:n.requestState}},l={dispatchInputRequest:(t,n,r)=>ps(e,i,t,n,r),retry:(e,t)=>r.retry(e,ms(o,t))};return Ko({config:t,method:a.method,originalParams:a.params,firstPayload:c,flowStartedAt:s,signal:o?.signal,requestOptions:{...o?.timeout!==void 0&&{timeout:o.timeout},...o?.maxTotalTimeout!==void 0&&{maxTotalTimeout:o.maxTotalTimeout},...o?.onprogress!==void 0&&{onprogress:o.onprogress}},hooks:l})}function gs(e){return{resultType:`input_required`,inputRequests:e.inputRequests,...e.requestState!==void 0&&{requestState:e.requestState},...e._meta!==void 0&&{_meta:e._meta}}}var _s=Ee(Ce((e=>{var t=/; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g,n=/\\([\u000b\u0020-\u00ff])/g,r=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;e.parse=i;function i(e){if(!e)throw TypeError(`argument string is required`);var i=typeof e==`object`?a(e):e;if(typeof i!=`string`)throw TypeError(`argument string is required to be a string`);var s=i.indexOf(`;`),c=s===-1?i.trim():i.slice(0,s).trim();if(!r.test(c))throw TypeError(`invalid media type`);var l=new o(c.toLowerCase());if(s!==-1){var u,d,f;for(t.lastIndex=s;d=t.exec(i);){if(d.index!==s)throw TypeError(`invalid parameter format`);s+=d[0].length,u=d[1].toLowerCase(),f=d[2],f.charCodeAt(0)===34&&(f=f.slice(1,-1),f.indexOf(`\\`)!==-1&&(f=f.replace(n,`$1`))),l.parameters[u]=f}if(s!==i.length)throw TypeError(`invalid parameter format`)}return l}function a(e){var t;if(typeof e.getHeader==`function`?t=e.getHeader(`content-type`):typeof e.headers==`object`&&(t=e.headers&&e.headers[`content-type`]),typeof t!=`string`)throw TypeError(`content-type header is missing from object`);return t}function o(e){this.parameters=Object.create(null),this.type=e}}))(),1);function vs(e){if(e)try{return _s.parse(e).type}catch{let t=(e.split(`;`,1)[0]??``).trim().toLowerCase();return t===``||e.slice(t.length).includes(`,`)?void 0:t}}function ys(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e):{...e}:{}}function bs(e=fetch,t){return t?async(n,r)=>e(n,{...t,...r,headers:r?.headers?{...ys(t.headers),...ys(r.headers)}:t.headers}):e}var xs=new Set([301,302,303,307,308]),Ss=5;function Cs(e,t){return e.protocol===t.protocol&&e.host===t.host||e.protocol===`http:`&&t.protocol===`https:`&&e.hostname===t.hostname&&!e.port&&!t.port}function ws(e,t){let n=xs.has(t.status)?t.headers?.get(`location`):void 0;if(n)try{return new URL(n,e)}catch{return}}var Ts=new WeakSet;function Es(e){let t=(t,n)=>e(t,n);return Ts.add(t),t}function Ds(e){return Ts.has(e)?e:async(t,n)=>{if(n?.redirect===`error`||n?.redirect===`manual`)return e(t,n);let r=(n?.method??`GET`).toUpperCase(),i=t;for(let t=0;;t++){let a=await e(i,{...n,redirect:`manual`}),o=ws(i,a);if(!o||t===Ss)return a;let s=new URL(i),c=r===`GET`||a.status===307||a.status===308,l=!(o.username||o.password)||o.username===s.username&&o.password===s.password;if(!c||!l||!Cs(s,o))return a;await a.text?.().catch(()=>{}),i=o}}}function Os(e,t){if(t.type===`opaqueredirect`)return`Redirect not followed: this runtime does not expose where it points`;let n=ws(t.url||e,t);if(n)return n.username=n.password=n.search=n.hash=``,n.protocol===`http:`&&new URL(t.url||e).protocol===`https:`?(n.protocol=`https:`,`Redirect from https to plain http not followed; try ${n.href} as the endpoint`):`Redirect to ${n.href} not followed; use that URL as the endpoint if it is the intended server`}function ks(e,t){let n=typeof e;if(n!==typeof t)return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=e.length;if(n!==t.length)return!1;for(let r=0;r1?t[a.href]=e:(a.hash=``,r===``?n=a:Is(e,t,n))}}else if(e!==!0&&e!==!1)return t;let i=n.href+(r?`#`+r:``);if(t[i]!==void 0)throw Error(`Duplicate schema URI "${i}".`);if(t[i]=e,e===!0||e===!1)return t;if(e.__absolute_uri__===void 0&&Object.defineProperty(e,"__absolute_uri__",{enumerable:!1,value:i}),e.$ref&&e.__absolute_ref__===void 0){let t=new URL(e.$ref,n.href);t.hash=t.hash,Object.defineProperty(e,"__absolute_ref__",{enumerable:!1,value:t.href})}if(e.$recursiveRef&&e.__absolute_recursive_ref__===void 0){let t=new URL(e.$recursiveRef,n.href);t.hash=t.hash,Object.defineProperty(e,"__absolute_recursive_ref__",{enumerable:!1,value:t.href})}if(e.$anchor){let r=new URL(`#`+e.$anchor,n.href);t[r.href]=e}for(let i in e){if(Ps[i])continue;let a=`${r}/${As(i)}`,o=e[i];if(Array.isArray(o)){if(Ms[i]){let e=o.length;for(let r=0;r%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,Us=/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,Ws=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,Gs=/^(?:\/(?:[^~/]|~0|~1)*)*$/,Ks=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,qs=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,Js=e=>{if(e[0]===`"`)return!1;let[t,n,...r]=e.split(`@`);return!t||!n||r.length!==0||t.length>64||n.length>253||t[0]===`.`||t.endsWith(`.`)||t.includes(`..`)||!/^[a-z0-9.-]+$/i.test(n)||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(t)?!1:n.split(`.`).every(e=>/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(e))},Ys=/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,Xs=/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,Zs=e=>e.length>1&&e.length<80&&(/^P\d+([.,]\d+)?W$/.test(e)||/^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(e)&&/^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(e));function Qs(e){return e.test.bind(e)}var $s={date:tc,time:nc.bind(void 0,!1),"date-time":ic,duration:Zs,uri:sc,"uri-reference":Qs(Vs),"uri-template":Qs(Hs),url:Qs(Us),email:Js,hostname:Qs(Bs),ipv4:Qs(Ys),ipv6:Qs(Xs),regex:lc,uuid:Qs(Ws),"json-pointer":Qs(Gs),"json-pointer-uri-fragment":Qs(Ks),"relative-json-pointer":Qs(qs)};function ec(e){return e%4==0&&(e%100!=0||e%400==0)}function tc(e){let t=e.match(Ls);if(!t)return!1;let n=+t[1],r=+t[2],i=+t[3];return r>=1&&r<=12&&i>=1&&i<=(r==2&&ec(n)?29:Rs[r])}function nc(e,t){let n=t.match(zs);if(!n)return!1;let r=+n[1],i=+n[2],a=+n[3],o=!!n[5];return(r<=23&&i<=59&&a<=59||r==23&&i==59&&a==60)&&(!e||o)}var rc=/t|\s/i;function ic(e){let t=e.split(rc);return t.length==2&&tc(t[0])&&nc(!0,t[1])}var ac=/\/|:/,oc=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;function sc(e){return ac.test(e)&&oc.test(e)}var cc=/[^\\]\\Z/;function lc(e){if(cc.test(e))return!1;try{return new RegExp(e,`u`),!0}catch{return!1}}function uc(e){let t=0,n=e.length,r=0,i;for(;r=55296&&i<=56319&&rks(e,t))||P.push({instanceLocation:o,keyword:`enum`,keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(g)}.`}):g.some(t=>e===t)||P.push({instanceLocation:o,keyword:`enum`,keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(g)}.`})),v!==void 0){let t=`${s}/not`;Q(e,v,n,r,i,a,o,t).valid&&P.push({instanceLocation:o,keyword:`not`,keywordLocation:t,error:`Instance matched "not" schema.`})}let Se=[];if(y!==void 0){let t=`${s}/anyOf`,l=P.length,u=!1;for(let s=0;s{let u=Object.create(c),d=Q(e,s,n,r,i,p===!0?a:null,o,`${t}/${l}`,u);return P.push(...d.errors),d.valid&&Se.push(u),d.valid}).length;u===1?P.length=l:P.splice(l,0,{instanceLocation:o,keyword:`oneOf`,keywordLocation:t,error:`Instance does not match exactly one subschema (${u} matches).`})}if((u===`object`||u===`array`)&&Object.assign(c,...Se),x!==void 0){let t=`${s}/if`;if(Q(e,x,n,r,i,a,o,t,c).valid){if(S!==void 0){let l=Q(e,S,n,r,i,a,o,`${s}/then`,c);l.valid||P.push({instanceLocation:o,keyword:`if`,keywordLocation:t,error:`Instance does not match "then" schema.`},...l.errors)}}else if(C!==void 0){let l=Q(e,C,n,r,i,a,o,`${s}/else`,c);l.valid||P.push({instanceLocation:o,keyword:`if`,keywordLocation:t,error:`Instance does not match "else" schema.`},...l.errors)}}if(u===`object`){if(_!==void 0)for(let t of _)t in e||P.push({instanceLocation:o,keyword:`required`,keywordLocation:`${s}/required`,error:`Instance does not have required property "${t}".`});let t=Object.keys(e);if(D!==void 0&&t.lengthO&&P.push({instanceLocation:o,keyword:`maxProperties`,keywordLocation:`${s}/maxProperties`,error:`Instance does not have at least ${O} properties.`}),re!==void 0){let t=`${s}/propertyNames`;for(let s in e){let e=`${o}/${As(s)}`,c=Q(s,re,n,r,i,a,e,t);c.valid||P.push({instanceLocation:o,keyword:`propertyNames`,keywordLocation:t,error:`Property name "${s}" does not match schema.`},...c.errors)}}if(k!==void 0){let t=`${s}/dependantRequired`;for(let n in k)if(n in e){let r=k[n];for(let i of r)i in e||P.push({instanceLocation:o,keyword:`dependentRequired`,keywordLocation:t,error:`Instance has "${n}" but does not have "${i}".`})}}if(A!==void 0)for(let t in A){let l=`${s}/dependentSchemas`;if(t in e){let s=Q(e,A[t],n,r,i,a,o,`${l}/${As(t)}`,c);s.valid||P.push({instanceLocation:o,keyword:`dependentSchemas`,keywordLocation:l,error:`Instance has "${t}" but does not match dependant schema.`},...s.errors)}}if(ie!==void 0){let t=`${s}/dependencies`;for(let s in ie)if(s in e){let c=ie[s];if(Array.isArray(c))for(let n of c)n in e||P.push({instanceLocation:o,keyword:`dependencies`,keywordLocation:t,error:`Instance has "${s}" but does not have "${n}".`});else{let l=Q(e,c,n,r,i,a,o,`${t}/${As(s)}`);l.valid||P.push({instanceLocation:o,keyword:`dependencies`,keywordLocation:t,error:`Instance has "${s}" but does not match dependant schema.`},...l.errors)}}}let l=Object.create(null),u=!1;if(T!==void 0){let t=`${s}/properties`;for(let s in T){if(!(s in e))continue;let d=`${o}/${As(s)}`,f=Q(e[s],T[s],n,r,i,a,d,`${t}/${As(s)}`);if(f.valid)c[s]=l[s]=!0;else if(u=i,P.push({instanceLocation:o,keyword:`properties`,keywordLocation:t,error:`Property "${s}" does not match schema.`},...f.errors),u)break}}if(!u&&E!==void 0){let t=`${s}/patternProperties`;for(let s in E){let d=new RegExp(s,`u`),f=E[s];for(let p in e){if(!d.test(p))continue;let m=`${o}/${As(p)}`,h=Q(e[p],f,n,r,i,a,m,`${t}/${As(s)}`);h.valid?c[p]=l[p]=!0:(u=i,P.push({instanceLocation:o,keyword:`patternProperties`,keywordLocation:t,error:`Property "${p}" matches pattern "${s}" but does not match associated schema.`},...h.errors))}}}if(!u&&te!==void 0){let t=`${s}/additionalProperties`;for(let s in e){if(l[s])continue;let d=`${o}/${As(s)}`,f=Q(e[s],te,n,r,i,a,d,t);f.valid?c[s]=!0:(u=i,P.push({instanceLocation:o,keyword:`additionalProperties`,keywordLocation:t,error:`Property "${s}" does not match additional properties schema.`},...f.errors))}}else if(!u&&ne!==void 0){let t=`${s}/unevaluatedProperties`;for(let s in e)if(!c[s]){let l=`${o}/${As(s)}`,u=Q(e[s],ne,n,r,i,a,l,t);u.valid?c[s]=!0:P.push({instanceLocation:o,keyword:`unevaluatedProperties`,keywordLocation:t,error:`Property "${s}" does not match unevaluated properties schema.`},...u.errors)}}}else if(u===`array`){pe!==void 0&&e.length>pe&&P.push({instanceLocation:o,keyword:`maxItems`,keywordLocation:`${s}/maxItems`,error:`Array has too many items (${e.length} > ${pe}).`}),fe!==void 0&&e.length=(ue||0)&&(P.length=u),ue===void 0&&de===void 0&&d===0?P.splice(u,0,{instanceLocation:o,keyword:`contains`,keywordLocation:l,error:`Array does not contain item matching schema.`}):ue!==void 0&&dde&&P.push({instanceLocation:o,keyword:`maxContains`,keywordLocation:`${s}/maxContains`,error:`Array may contain at most ${de} items matching schema. ${d} items were found.`})}}if(!u&&ce!==void 0){let u=`${s}/unevaluatedItems`;for(;l=ge||e>ge)&&P.push({instanceLocation:o,keyword:`maximum`,keywordLocation:`${s}/maximum`,error:`${e} is greater than ${j?`or equal to `:``} ${ge}.`})):(he!==void 0&&ege&&P.push({instanceLocation:o,keyword:`maximum`,keywordLocation:`${s}/maximum`,error:`${e} is greater than ${ge}.`}),_e!==void 0&&e<=_e&&P.push({instanceLocation:o,keyword:`exclusiveMinimum`,keywordLocation:`${s}/exclusiveMinimum`,error:`${e} is less than ${_e}.`}),j!==void 0&&e>=j&&P.push({instanceLocation:o,keyword:`exclusiveMaximum`,keywordLocation:`${s}/exclusiveMaximum`,error:`${e} is greater than or equal to ${j}.`})),M!==void 0){let t=e%M;Math.abs(0-t)>=1.1920929e-7&&Math.abs(M-t)>=1.1920929e-7&&P.push({instanceLocation:o,keyword:`multipleOf`,keywordLocation:`${s}/multipleOf`,error:`${e} is not a multiple of ${M}.`})}}else if(u===`string`){let t=ve===void 0&&ye===void 0?0:uc(e);ve!==void 0&&tye&&P.push({instanceLocation:o,keyword:`maxLength`,keywordLocation:`${s}/maxLength`,error:`String is too long (${t} > ${ye}).`}),be!==void 0&&!new RegExp(be,`u`).test(e)&&P.push({instanceLocation:o,keyword:`pattern`,keywordLocation:`${s}/pattern`,error:`String does not match pattern.`}),w!==void 0&&$s[w]&&!$s[w](e)&&P.push({instanceLocation:o,keyword:`format`,keywordLocation:`${s}/format`,error:`String does not match format "${w}".`})}return{valid:P.length===0,errors:P}}var dc=class{schema;draft;shortCircuit;lookup;constructor(e,t=`2019-09`,n=!0){this.schema=e,this.draft=t,this.shortCircuit=n,this.lookup=Is(e)}validate(e){return Q(e,this.schema,this.draft,this.lookup,this.shortCircuit)}addSchema(e,t){t&&(e={...e,$id:t}),Is(e,this.lookup)}},fc=class{shortcircuit;draft;constructor(e){this.shortcircuit=e?.shortcircuit??!0,this.draft=e?.draft}_draftFor(e){let t=Me(e,`pass an explicit { draft } to CfWorkerJsonSchemaValidator to validate other dialects.`);return t===`draft-7`?`7`:t}getValidator(e){let t=new dc(e,this.draft??this._draftFor(e),this.shortcircuit);return e=>{let n=t.validate(e);return n.valid?{valid:!0,data:e,errorMessage:void 0}:{valid:!1,data:void 0,errorMessage:n.errors.map(e=>`${e.instanceLocation}: ${e.error}`).join(`; `)}}}},pc=globalThis.crypto;async function mc(e){return(await pc).getRandomValues(new Uint8Array(e))}async function hc(e){let t=``;for(;t.length128)throw`Expected a length between 43 and 128. Received ${e}.`;let t=await gc(e);return{code_verifier:t,code_challenge:await _c(t)}}var yc=class extends Error{constructor(e,t){super(e),this.name=`ParseError`,this.type=t.type,this.field=t.field,this.value=t.value,this.line=t.line}},bc=10,xc=13,Sc=32;function Cc(e){}function wc(e){if(typeof e==`function`)throw TypeError("`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?");let{onEvent:t=Cc,onError:n=Cc,onRetry:r=Cc,onComment:i,maxBufferSize:a}=e,o=[],s=0,c=!0,l,u=``,d=0,f,p=!1;function m(e){if(p)throw Error("Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.");if(c&&(c=!1,e.charCodeAt(0)===239&&e.charCodeAt(1)===187&&e.charCodeAt(2)===191&&(e=e.slice(3))),o.length===0){let t=g(e);t!==``&&(o.push(t),s=t.length),h();return}if(e.indexOf(` `)===-1&&e.indexOf(`\r`)===-1){o.push(e),s+=e.length,h();return}o.push(e);let t=o.join(``);o.length=0,s=0;let n=g(t);n!==``&&(o.push(n),s=n.length),h()}function h(){a!==void 0&&(s+u.length<=a||(p=!0,o.length=0,s=0,l=void 0,u=``,d=0,f=void 0,n(new yc(`Buffered data exceeded max buffer size of ${a} characters`,{type:`max-buffer-size-exceeded`}))))}function g(e){let n=0;if(e.indexOf(`\r`)===-1){let r=e.indexOf(` `,n);for(;r!==-1;){if(n===r){d>0&&t({id:l,event:f,data:u}),l=void 0,u=``,d=0,f=void 0,n=r+1,r=e.indexOf(` diff --git a/internal/ui/dist/assets/page-DjMwsK0m.js b/internal/ui/dist/assets/page-BJZPrXpH.js similarity index 99% rename from internal/ui/dist/assets/page-DjMwsK0m.js rename to internal/ui/dist/assets/page-BJZPrXpH.js index 4c5fbe73..d42d4899 100644 --- a/internal/ui/dist/assets/page-DjMwsK0m.js +++ b/internal/ui/dist/assets/page-BJZPrXpH.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/panel-sql-editor-Cs-4yfrn.js","assets/useRouter-ByJ6_rwb.js","assets/brand-DUaZkIz1.js","assets/index-eh4vL-r5.js","assets/useNavigate-B1zgPEUp.js","assets/preload-helper-DJZNfKNH.js","assets/Tooltip-B3r3s_B9.js","assets/index-ADB9ThEc.css"])))=>i.map(i=>d[i]); -import{a as e,i as t,o as n,r,s as i}from"./useRouter-ByJ6_rwb.js";import{A as a,C as o,D as s,E as c,K as l,M as u,O as d,P as f,Q as p,S as m,T as h,X as g,Y as _,Z as v,_ as y,_t as b,a as x,c as S,d as C,dt as w,f as T,ft as E,g as D,gt as O,h as k,j as A,k as j,lt as M,m as N,mt as P,nt as F,o as I,ot as L,p as ee,r as te,s as ne,st as re,tt as ie,u as ae,ut as R,v as oe,x as z,y as se}from"./brand-DUaZkIz1.js";import{t as ce}from"./preload-helper-DJZNfKNH.js";import{C as le,E as ue,b as de,o as fe,t as pe,w as me}from"./Tooltip-B3r3s_B9.js";import{a as he,c as ge,d as _e,i as ve,l as B,n as ye,o as be,r as xe,s as Se,t as Ce,u as we}from"./dashboard-change-chips-DcQEgN0t.js";import{n as Te,r as Ee,t as De}from"./WarningCircle.es-e9h3eY6B.js";import{$ as Oe,$t as ke,A as Ae,B as je,Bt as Me,C as Ne,D as Pe,E as Fe,F as Ie,Gt as Le,Ht as Re,I as ze,J as Be,Jt as Ve,Kt as He,M as Ue,N as We,O as Ge,P as Ke,Q as qe,Qt as Je,Ut as Ye,V as Xe,Vt as Ze,Wt as Qe,X as $e,Xt as et,Yt as tt,Z as nt,_ as rt,a as it,an as at,b as ot,c as st,ct,d as lt,en as ut,et as dt,h as ft,i as pt,in as mt,j as ht,k as gt,l as _t,m as vt,n as yt,nn as bt,o as xt,on as St,qt as Ct,r as wt,rn as Tt,s as Et,sn as Dt,t as Ot,tn as kt,u as At,v as jt,w as Mt,x as Nt}from"./index-eh4vL-r5.js";function Pt(e,t){if(Object.is(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!t.has(n)||!Object.is(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let n=Ft(e);if(n.length!==Ft(t).length)return!1;for(let r=0;r{if(typeof n!=`string`||n.trim().length===0)throw Error(t);return`${e}-${n}`}}var H=r();function Lt(e){return typeof e==`object`&&e?`base`in e?e.base:void 0:e}function Rt(e,t){if(e===t||Number.isNaN(e)&&Number.isNaN(t))return!0;if(!(e instanceof Object)||!(t instanceof Object))return!1;let n=Object.keys(e),{length:r}=n;if(r!==Object.keys(t).length)return!1;for(let i=0;i{r.current||=window.setTimeout(()=>{i(...e),r.current=null},t)},[t]),o=(0,V.useCallback)(()=>{r.current&&=(window.clearTimeout(r.current),null)},[]);return(0,V.useEffect)(()=>(n.autoInvoke&&a(),o),[o,a]),{start:a,clear:o}}function Ut(e){let t=(0,V.useRef)(void 0);return(0,V.useEffect)(()=>{t.current=e},[e]),t.current}function Wt(e,t,n){let r=(0,V.useRef)(null);(0,V.useEffect)(()=>{r.current&&=(r.current.disconnect(),null);let i=typeof n==`function`?n():n;return i&&(r.current=new MutationObserver(e),r.current.observe(i,t)),()=>{r.current&&=(r.current.disconnect(),null)}},[e,t,n])}function Gt(){let[e,t]=(0,V.useState)(!1);return(0,V.useEffect)(()=>t(!0),[]),e}function Kt(e){return typeof e==`string`||typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`}function qt(e,t=document){let n=t.querySelector(e);if(n)return n;let r=t.querySelectorAll(`*`);for(let t=0;t{if(!e||!t||!n.current)return;let r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),a=t.offsetWidth===0?1:i.width/t.offsetWidth,o=t.offsetHeight===0?1:i.height/t.offsetHeight,s=window.getComputedStyle(e),c=window.getComputedStyle(t),l=de(s.borderTopWidth)+de(c.borderTopWidth),u=de(s.borderLeftWidth)+de(c.borderLeftWidth),d={top:(r.top-i.top)/o-l,left:(r.left-i.left)/a-u,width:r.width/a,height:r.height/o};n.current.style.transform=`translateY(${d.top}px) translateX(${d.left}px)`,n.current.style.width=`${d.width}px`,n.current.style.height=`${d.height}px`},p=()=>{window.clearTimeout(o.current),n.current&&(n.current.style.transitionDuration=`0ms`),f(),o.current=window.setTimeout(()=>{n.current&&(n.current.style.transitionDuration=``)},30)},m=(0,V.useRef)(null),h=(0,V.useRef)(null);return(0,V.useEffect)(()=>{if(c&&s.current!==e&&i&&i(),s.current=e,f(),e)return m.current=new ResizeObserver(p),m.current.observe(e),t&&(h.current=new ResizeObserver(p),h.current.observe(t)),()=>{m.current?.disconnect(),h.current?.disconnect()}},[t,e]),(0,V.useEffect)(()=>{if(t){let e=e=>{Zt(e.target,t)&&(p(),d(!1))};return t.addEventListener(`transitionend`,e),()=>{t.removeEventListener(`transitionend`,e)}}},[t]),(0,V.useEffect)(()=>{if(n.current&&a){let e=e=>{e.propertyName===`transform`&&a()};return n.current.addEventListener(`transitionend`,e),()=>{n.current?.removeEventListener(`transitionend`,e)}}},[a]),Ht(()=>{_e()!==`test`&&l(!0)},20,{autoInvoke:!0}),Wt(e=>{e.forEach(e=>{e.type===`attributes`&&e.attributeName===`dir`&&p()})},{attributes:!0,attributeFilter:[`dir`]},()=>document.documentElement),{initialized:c,hidden:u}}var $t={root:`m_96b553a6`},en=g((e,{transitionDuration:t},{shouldReduceMotion:n})=>({root:{"--transition-duration":e.respectReducedMotion&&n?`0ms`:typeof t==`number`?`${t}ms`:t||`150ms`}})),tn=h(e=>{let t=u(`FloatingIndicator`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,target:d,parent:f,transitionDuration:m,mod:h,displayAfterTransitionEnd:g,onTransitionStart:_,onTransitionEnd:v,attributes:y,ref:b,...x}=t,S=p(),C=a({name:`FloatingIndicator`,classes:$t,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:y,vars:l,varsResolver:en,stylesCtx:{shouldReduceMotion:S}}),w=(0,V.useRef)(null),{initialized:T,hidden:E}=Qt({target:d,parent:f,ref:w,displayAfterTransitionEnd:g,onTransitionStart:_,onTransitionEnd:v}),D=ie(b,w);return!d||!f?null:(0,H.jsx)(o,{ref:D,mod:[{initialized:T,hidden:E},h],...C(`root`),...x})});tn.displayName=`@mantine/core/FloatingIndicator`,tn.classes=$t,tn.varsResolver=en;var[nn,rn]=ue(`Accordion component was not found in the tree`),[an,on]=ue(`Accordion.Item component was not found in the tree`),sn={root:`m_9bdbb667`,panel:`m_df78851f`,content:`m_4ba554d4`,itemTitle:`m_8fa820a0`,control:`m_4ba585b8`,"control--default":`m_6939a5e9`,"control--contained":`m_4271d21b`,label:`m_df3ffa0f`,chevron:`m_3f35ae96`,icon:`m_9bd771fe`,item:`m_9bd7b098`,"item--default":`m_fe19b709`,"item--contained":`m_1f921b3b`,"item--filled":`m_2cdf939a`,"item--separated":`m_9f59b069`},cn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,chevron:s,icon:c,onClick:l,onKeyDown:d,children:f,disabled:p,mod:h,...g}=u(`AccordionControl`,null,e),{value:_}=on(),v=rn(),y=v.isItemActive(_),b=typeof v.order==`number`,x=`h${v.order}`,S=(0,H.jsxs)(m,{...v.getStyles(`control`,{className:n,classNames:t,style:r,styles:i,variant:v.variant}),unstyled:v.unstyled,mod:[`accordion-control`,{active:y,"chevron-position":v.chevronPosition,disabled:p},h],onClick:e=>{l?.(e),v.onChange(_)},type:`button`,disabled:p,"aria-expanded":y,"aria-controls":v.getRegionId(_),id:v.getControlId(_),onKeyDown:Tt({siblingSelector:`[data-accordion-control]`,parentSelector:`[data-accordion]`,activateOnFocus:!1,loop:v.loop,orientation:`vertical`,onKeyDown:d}),...g,children:[(0,H.jsx)(o,{component:`span`,mod:{rotate:!v.disableChevronRotation&&y,position:v.chevronPosition},...v.getStyles(`chevron`,{classNames:t,styles:i}),children:s||v.chevron}),(0,H.jsx)(`span`,{...v.getStyles(`label`,{classNames:t,styles:i}),children:f}),c&&(0,H.jsx)(o,{component:`span`,mod:{"chevron-position":v.chevronPosition},...v.getStyles(`icon`,{classNames:t,styles:i}),children:c})]});return b?(0,H.jsx)(x,{...v.getStyles(`itemTitle`,{classNames:t,styles:i}),children:S}):S});cn.displayName=`@mantine/core/AccordionControl`,cn.classes=sn;var ln=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,value:s,mod:c,...l}=u(`AccordionItem`,null,e),d=rn();return(0,H.jsx)(an,{value:{value:s},children:(0,H.jsx)(o,{mod:[{active:d.isItemActive(s)},c],...d.getStyles(`item`,{className:n,classNames:t,styles:i,style:r,variant:d.variant}),...l})})});ln.displayName=`@mantine/core/AccordionItem`,ln.classes=sn;var un=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,children:o,keepMounted:s,keepMountedMode:c,...l}=u(`AccordionPanel`,null,e),{value:d}=on(),f=rn();return(0,H.jsx)(we,{...f.getStyles(`panel`,{className:n,classNames:t,style:r,styles:i}),expanded:f.isItemActive(d),transitionDuration:f.transitionDuration??200,role:`region`,id:f.getRegionId(d),"aria-labelledby":f.getControlId(d),keepMounted:s??f.keepMounted,keepMountedMode:c??f.keepMountedMode,...l,children:(0,H.jsx)(`div`,{...f.getStyles(`content`,{classNames:t,styles:i}),children:o})})});un.displayName=`@mantine/core/AccordionPanel`,un.classes=sn;var dn={multiple:!1,loop:!0,disableChevronRotation:!1,disableCollapse:!1,chevronPosition:`right`,variant:`default`,chevronSize:`auto`,chevronIconSize:16,keepMountedMode:`activity`},fn=g((e,{transitionDuration:t,chevronSize:n,radius:r})=>({root:{"--accordion-transition-duration":t===void 0?void 0:`${t}ms`,"--accordion-chevron-size":n===void 0?void 0:P(n),"--accordion-radius":r===void 0?void 0:re(r)}})),pn=c(e=>{let t=u(`Accordion`,dn,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,children:d,multiple:f,value:p,defaultValue:m,onChange:h,id:g,loop:_,transitionDuration:v,disableChevronRotation:y,disableCollapse:b,chevronPosition:x,chevronSize:S,order:C,chevron:w,variant:T,radius:E,chevronIconSize:D,attributes:O,keepMounted:k,keepMountedMode:A,...j}=t,M=F(g),[N,P]=kt({value:p,defaultValue:m,finalValue:f?[]:null,onChange:h}),I=e=>Array.isArray(N)?N.includes(e):e===N,L=e=>{if(!Array.isArray(N)&&b&&e===N)return;let t=Array.isArray(N)?N.includes(e)?N.filter(t=>t!==e):[...N,e]:e===N?null:e;P(t)},ee=a({name:`Accordion`,classes:sn,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:O,vars:l,varsResolver:fn});return(0,H.jsx)(nn,{value:{isItemActive:I,onChange:L,getControlId:It(`${M}-control`,`Accordion.Item component was rendered with invalid value or without value`),getRegionId:It(`${M}-panel`,`Accordion.Item component was rendered with invalid value or without value`),chevron:w===null?null:w||(0,H.jsx)(Ve,{size:D}),transitionDuration:v,disableChevronRotation:y,chevronPosition:x,order:C,loop:_,getStyles:ee,variant:T,unstyled:c,keepMounted:k,keepMountedMode:A},children:(0,H.jsx)(o,{...ee(`root`),id:M,...j,variant:T,"data-accordion":!0,children:d})})});pn.classes=sn,pn.varsResolver=fn,pn.displayName=`@mantine/core/Accordion`,pn.Item=ln,pn.Panel=un,pn.Control=cn,pn.Chevron=Ve;function mn(e){return typeof e==`string`?{value:e,label:e}:typeof e==`object`&&`value`in e&&!(`label`in e)?{value:e.value,label:`${e.value}`,disabled:e.disabled}:typeof e==`object`&&`group`in e?{group:e.group,items:e.items.map(e=>mn(e))}:typeof e==`number`||typeof e==`bigint`||typeof e==`boolean`?{value:e,label:`${e}`}:e}function hn(e){return e?e.map(e=>mn(e)):[]}function gn(e){return e.reduce((e,t)=>`group`in t?{...e,...gn(t.items)}:(e[`${t.value}`]=t,e),{})}var _n={dropdown:`m_88b62a41`,search:`m_985517d8`,options:`m_b2821a6e`,option:`m_92253aa5`,empty:`m_2530cd1d`,header:`m_858f94bd`,footer:`m_82b967cb`,group:`m_254f3e4f`,groupLabel:`m_2bb2e9e5`,chevron:`m_2943220b`,optionsDropdownOption:`m_390b5f4`,optionsDropdownCheckIcon:`m_8ee53fc2`,optionsDropdownCheckPlaceholder:`m_a530ee0a`},vn={error:null},yn=g((e,{size:t,color:n})=>({chevron:{"--combobox-chevron-size":M(t,`combobox-chevron-size`),"--combobox-chevron-color":n?l(n,e):void 0}})),bn=h(e=>{let t=u(`ComboboxChevron`,vn,e),{size:n,error:r,style:i,className:s,classNames:c,styles:l,unstyled:d,vars:f,attributes:p,mod:m,...h}=t,g=a({name:`ComboboxChevron`,classes:_n,props:t,style:i,className:s,classNames:c,styles:l,unstyled:d,vars:f,varsResolver:yn,attributes:p,rootSelector:`chevron`});return(0,H.jsx)(o,{component:`svg`,...h,...g(`chevron`),size:n,viewBox:`0 0 15 15`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,mod:[`combobox-chevron`,{error:r},m],children:(0,H.jsx)(`path`,{d:`M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.35753 11.9939 7.64245 11.9939 7.81819 11.8182L10.0682 9.56819Z`,fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`})})});bn.classes=_n,bn.varsResolver=yn,bn.displayName=`@mantine/core/ComboboxChevron`;var[xn,Sn]=ue(`Combobox component was not found in tree`);function Cn({onMouseDown:e,onClick:t,onClear:n,...r}){return(0,H.jsx)(k.ClearButton,{tabIndex:-1,"aria-hidden":!0,...r,onMouseDown:t=>{t.preventDefault(),e?.(t)},onClick:e=>{n(),t?.(e)}})}Cn.displayName=`@mantine/core/ComboboxClearButton`;var wn=h(e=>{let{classNames:t,styles:n,className:r,style:i,hidden:a,...o}=u(`ComboboxDropdown`,null,e),s=Sn();return(0,H.jsx)(et.Dropdown,{...o,role:`presentation`,"data-hidden":a||void 0,"data-floating-height":s.floatingHeight||void 0,...s.getStyles(`dropdown`,{className:r,style:i,classNames:t,styles:n})})});wn.classes=_n,wn.displayName=`@mantine/core/ComboboxDropdown`;var Tn={refProp:`ref`},En=h(e=>{let{children:t,refProp:n,ref:r}=u(`ComboboxDropdownTarget`,Tn,e);if(Sn(),!w(t))throw Error(`Combobox.DropdownTarget component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);return(0,H.jsx)(et.Target,{ref:r,refProp:n,children:t})});En.displayName=`@mantine/core/ComboboxDropdownTarget`;var Dn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxEmpty`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`empty`,{className:n,classNames:t,styles:i,style:r}),...s})});Dn.classes=_n,Dn.displayName=`@mantine/core/ComboboxEmpty`;function On({onKeyDown:e,onClick:t,withKeyboardNavigation:n,withAriaAttributes:r,withExpandedAttribute:i,targetType:a,autoComplete:o}){let s=Sn(),[c,l]=(0,V.useState)(null),u=t=>{if(e?.(t),!s.readOnly&&n){if(t.nativeEvent.isComposing)return;if(t.nativeEvent.code===`ArrowDown`&&(t.preventDefault(),s.store.dropdownOpened?l(s.store.selectNextOption()):(s.store.openDropdown(`keyboard`),l(s.store.selectActiveOption()),s.store.updateSelectedOptionIndex(`selected`,{scrollIntoView:!0}))),t.nativeEvent.code===`ArrowUp`&&(t.preventDefault(),s.store.dropdownOpened?l(s.store.selectPreviousOption()):(s.store.openDropdown(`keyboard`),l(s.store.selectActiveOption()),s.store.updateSelectedOptionIndex(`selected`,{scrollIntoView:!0}))),t.nativeEvent.code===`Enter`||t.nativeEvent.code===`NumpadEnter`){if(t.nativeEvent.keyCode===229)return;let e=s.store.getSelectedOptionIndex();s.store.dropdownOpened&&e!==-1?(t.preventDefault(),s.store.clickSelectedOption()):a===`button`&&(t.preventDefault(),s.store.openDropdown(`keyboard`))}t.key===`Escape`&&s.store.closeDropdown(`keyboard`),t.nativeEvent.code===`Space`&&a===`button`&&(t.preventDefault(),s.store.toggleDropdown(`keyboard`))}},d=r?{...i?{role:`combobox`}:{},"aria-haspopup":`listbox`,"aria-expanded":i?!!(s.store.listId&&s.store.dropdownOpened):void 0,"aria-controls":s.store.dropdownOpened&&s.store.listId?s.store.listId:void 0,"aria-activedescendant":s.store.dropdownOpened&&c||void 0,autoComplete:o,"data-expanded":s.store.dropdownOpened||void 0,"data-mantine-stop-propagation":s.store.dropdownOpened||void 0}:{},f=e=>{a===`button`&&e.currentTarget.focus(),t?.(e)};return{...d,onKeyDown:u,onClick:f}}var kn={refProp:`ref`,targetType:`input`,withKeyboardNavigation:!0,withAriaAttributes:!0,withExpandedAttribute:!1,autoComplete:`off`},An=h(e=>{let{children:t,refProp:n,withKeyboardNavigation:r,withAriaAttributes:i,withExpandedAttribute:a,targetType:o,autoComplete:s,ref:c,...l}=u(`ComboboxEventsTarget`,kn,e),d=v(t);if(!d)throw Error(`Combobox.EventsTarget component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);let f=Sn(),p=On({targetType:o,withAriaAttributes:i,withKeyboardNavigation:r,withExpandedAttribute:a,onKeyDown:d.props.onKeyDown,onClick:d.props.onClick,autoComplete:s});return(0,V.cloneElement)(d,{...p,...l,[n]:ie(c,f.store.targetRef,le(d))})});An.displayName=`@mantine/core/ComboboxEventsTarget`;var jn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxFooter`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`footer`,{className:n,classNames:t,style:r,styles:i}),...s,onMouseDown:e=>{e.preventDefault()}})});jn.classes=_n,jn.displayName=`@mantine/core/ComboboxFooter`;var Mn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,children:s,label:c,id:l,...d}=u(`ComboboxGroup`,null,e),f=Sn(),p=F(l),m=c!=null&&c!==!1&&c!==``;return(0,H.jsxs)(o,{role:`group`,"aria-labelledby":m?p:void 0,...f.getStyles(`group`,{className:n,classNames:t,style:r,styles:i}),...d,children:[m&&(0,H.jsx)(`div`,{id:p,...f.getStyles(`groupLabel`,{classNames:t,styles:i}),children:c}),s]})});Mn.classes=_n,Mn.displayName=`@mantine/core/ComboboxGroup`;var Nn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxHeader`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`header`,{className:n,classNames:t,style:r,styles:i}),...s,onMouseDown:e=>{e.preventDefault()}})});Nn.classes=_n,Nn.displayName=`@mantine/core/ComboboxHeader`;function Pn({value:e,valuesDivider:t=`,`,...n}){return(0,H.jsx)(`input`,{type:`hidden`,value:Array.isArray(e)?e.join(t):e?`${e}`:``,...n})}Pn.displayName=`@mantine/core/ComboboxHiddenInput`;var Fn=h(e=>{let t=u(`ComboboxOption`,null,e),{classNames:n,className:r,style:i,styles:a,vars:s,onClick:c,id:l,active:d,onMouseDown:f,onMouseOver:p,disabled:m,selected:h,mod:g,..._}=t,v=Sn(),y=(0,V.useId)(),b=l||y;return(0,H.jsx)(o,{...v.getStyles(`option`,{className:r,classNames:n,styles:a,style:i}),"aria-disabled":m||void 0,..._,id:b,mod:[`combobox-option`,{"combobox-active":d,"combobox-disabled":m,"combobox-selected":h},g],role:`option`,onClick:e=>{m?e.preventDefault():(v.onOptionSubmit?.(t.value,t),c?.(e))},onMouseDown:e=>{e.preventDefault(),f?.(e)},onMouseOver:e=>{v.resetSelectionOnOptionHover&&v.store.resetSelectedOption(),p?.(e)}})});Fn.classes=_n,Fn.displayName=`@mantine/core/ComboboxOption`;var In=h(e=>{let{classNames:t,className:n,style:r,styles:i,id:a,onMouseDown:s,labelledBy:c,...l}=u(`ComboboxOptions`,null,e),d=Sn(),f=F(a);return(0,V.useEffect)(()=>{d.store.setListId(f)},[f]),(0,H.jsx)(o,{...d.getStyles(`options`,{className:n,style:r,classNames:t,styles:i}),...l,id:f,role:`listbox`,"aria-labelledby":c,onMouseDown:e=>{e.preventDefault(),s?.(e)}})});In.classes=_n,In.displayName=`@mantine/core/ComboboxOptions`;var Ln={withAriaAttributes:!0,withKeyboardNavigation:!0},Rn=h(e=>{let{classNames:t,styles:n,unstyled:r,vars:i,withAriaAttributes:a,onKeyDown:o,onClick:s,withKeyboardNavigation:c,size:l,ref:d,...f}=u(`ComboboxSearch`,Ln,e),p=Sn(),m=p.getStyles(`search`),h=On({targetType:`input`,withAriaAttributes:a,withKeyboardNavigation:c,withExpandedAttribute:!1,onKeyDown:o,onClick:s,autoComplete:`off`});return(0,H.jsx)(k,{ref:ie(d,p.store.searchRef),classNames:[{input:m.className},t],styles:[{input:m.style},n],size:l||p.size,...h,...f,__staticSelector:`Combobox`})});Rn.classes=_n,Rn.displayName=`@mantine/core/ComboboxSearch`;var zn={refProp:`ref`,targetType:`input`,withKeyboardNavigation:!0,withAriaAttributes:!0,withExpandedAttribute:!1,autoComplete:`off`},Bn=h(e=>{let{children:t,refProp:n,withKeyboardNavigation:r,withAriaAttributes:i,withExpandedAttribute:a,targetType:o,autoComplete:s,ref:c,...l}=u(`ComboboxTarget`,zn,e),d=v(t);if(!d)throw Error(`Combobox.Target component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);let f=Sn(),p=On({targetType:o,withAriaAttributes:i,withKeyboardNavigation:r,withExpandedAttribute:a,onKeyDown:d.props.onKeyDown,onClick:d.props.onClick,autoComplete:s}),m=(0,V.cloneElement)(d,{...p,...l});return(0,H.jsx)(et.Target,{refProp:n,ref:ie(c,f.store.targetRef),children:m})});Bn.displayName=`@mantine/core/ComboboxTarget`;function Vn(e,t,n){for(let n=e-1;n>=0;--n)if(!t[n].hasAttribute(`data-combobox-disabled`))return n;if(n){for(let e=t.length-1;e>-1;--e)if(!t[e].hasAttribute(`data-combobox-disabled`))return e}return e}function Hn(e,t,n){for(let n=e+1;n{s||(c(!0),i?.(e))},[c,i,s]),_=(0,V.useCallback)((e=`unknown`)=>{s&&(c(!1),r?.(e))},[c,r,s]),v=(0,V.useCallback)((e=`unknown`)=>{s?_(e):g(e)},[_,g,s]),y=(0,V.useCallback)(()=>{let e=Yt(f.current);qt(`#${l.current} [data-combobox-selected]`,e)?.removeAttribute(`data-combobox-selected`)},[]),b=(0,V.useCallback)(e=>{let t=Yt(f.current),n=qt(`#${l.current}`,t),r=n?Jt(`[data-combobox-option]`,n):null;if(!r)return null;let i=e>=r.length?0:e<0?r.length-1:e;return u.current=i,r?.[i]&&!r[i].hasAttribute(`data-combobox-disabled`)?(y(),r[i].setAttribute(`data-combobox-selected`,`true`),r[i].scrollIntoView({block:`nearest`,behavior:o}),r[i].id):null},[o,y]),x=(0,V.useCallback)(()=>{let e=Yt(f.current),t=qt(`#${l.current} [data-combobox-active]`,e);if(t){let n=Jt(`#${l.current} [data-combobox-option]`,e).findIndex(e=>e===t);return b(n)}return b(0)},[b]),S=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Hn(u.current,t,a))},[b,a]),C=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Vn(u.current,t,a))},[b,a]),w=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Un(t))},[b]),T=(0,V.useCallback)((e=`selected`,t)=>{if(typeof e==`number`){u.current=e;let n=Yt(f.current),r=Jt(`#${l.current} [data-combobox-option]`,n);t?.scrollIntoView&&r[e]?.scrollIntoView({block:`nearest`,behavior:o});return}h.current=window.setTimeout(()=>{let n=Yt(f.current),r=Jt(`#${l.current} [data-combobox-option]`,n),i=r.findIndex(t=>t.hasAttribute(`data-combobox-${e}`));u.current=i,t?.scrollIntoView&&r[i]?.scrollIntoView({block:`nearest`,behavior:o})},0)},[]),E=(0,V.useCallback)(()=>{u.current=-1,y()},[y]),D=(0,V.useCallback)(()=>{let e=Yt(f.current);(Jt(`#${l.current} [data-combobox-option]`,e)?.[u.current])?.click()},[]),O=(0,V.useCallback)(e=>{l.current=e},[]),k=(0,V.useCallback)(()=>{p.current=window.setTimeout(()=>d.current?.focus(),0)},[]),A=(0,V.useCallback)(()=>{m.current=window.setTimeout(()=>f.current?.focus(),0)},[]),j=(0,V.useCallback)(()=>u.current,[]);return(0,V.useEffect)(()=>()=>{window.clearTimeout(p.current),window.clearTimeout(m.current),window.clearTimeout(h.current)},[]),{dropdownOpened:s,openDropdown:g,closeDropdown:_,toggleDropdown:v,selectedOptionIndex:u.current,getSelectedOptionIndex:j,selectOption:b,selectFirstOption:w,selectActiveOption:x,selectNextOption:S,selectPreviousOption:C,resetSelectedOption:E,updateSelectedOptionIndex:T,listId:l.current,setListId:O,clickSelectedOption:D,searchRef:d,focusSearchInput:k,targetRef:f,focusTarget:A}}var Gn={keepMounted:!0,keepMountedMode:`display-none`,withinPortal:!0,resetSelectionOnOptionHover:!1,width:`target`,transitionProps:{transition:`fade`,duration:0},size:`sm`},Kn=g((e,{size:t,dropdownPadding:n})=>({options:{"--combobox-option-fz":L(t),"--combobox-option-padding":M(t,`combobox-option-padding`)},dropdown:{"--combobox-padding":n===void 0?void 0:P(n),"--combobox-option-fz":L(t),"--combobox-option-padding":M(t,`combobox-option-padding`)}})),qn=e=>{let t=u(`Combobox`,Gn,e),{classNames:n,styles:r,unstyled:i,children:o,store:s,vars:c,onOptionSubmit:l,onClose:d,size:f,dropdownPadding:p,resetSelectionOnOptionHover:m,__staticSelector:h,readOnly:g,attributes:_,floatingHeight:v,middlewares:y,...b}=t,x=v===`viewport`?{...y,flip:!1,size:{...typeof y?.size==`object`?y.size:{},padding:typeof y?.size==`object`&&y.size.padding!==void 0?y.size.padding:10,apply:({availableHeight:e,availableWidth:t,elements:n,...r})=>{n.floating.style.setProperty(`--combobox-floating-max-height`,`${e}px`);let i=y?.size;typeof i==`object`&&i.apply?i.apply({availableHeight:e,availableWidth:t,elements:n,...r}):i&&Object.assign(n.floating.style,{maxWidth:`${t}px`,maxHeight:`${e}px`})}}}:y,S=Wn(),C=s||S,w=a({name:h||`Combobox`,classes:_n,props:t,classNames:n,styles:r,unstyled:i,attributes:_,vars:c,varsResolver:Kn}),T=()=>{d?.(),C.closeDropdown()};return(0,H.jsx)(xn,{value:{getStyles:w,store:C,onOptionSubmit:l,size:f,resetSelectionOnOptionHover:m,readOnly:g,floatingHeight:v},children:(0,H.jsx)(et,{opened:C.dropdownOpened,...b,middlewares:x,onChange:e=>!e&&T(),withRoles:!1,unstyled:i,children:o})})};qn.extend=e=>e,qn.classes=_n,qn.varsResolver=Kn,qn.displayName=`@mantine/core/Combobox`,qn.Target=Bn,qn.Dropdown=wn,qn.Options=In,qn.Option=Fn,qn.Search=Rn,qn.Empty=Dn,qn.Chevron=bn,qn.Footer=jn,qn.Header=Nn,qn.EventsTarget=An,qn.DropdownTarget=En,qn.Group=Mn,qn.ClearButton=Cn,qn.HiddenInput=Pn;function Jn({children:e,role:t}){let n=(0,V.use)(D);return n?(0,H.jsx)(`div`,{role:t,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,children:e}):(0,H.jsx)(H.Fragment,{children:e})}var Yn={root:`m_5f75b09e`,body:`m_5f6e695e`,labelWrapper:`m_d3ea56bb`,label:`m_8ee546b8`,description:`m_328f68c0`,error:`m_8e8a99cc`},Xn=Yn;function Zn({__staticSelector:e,__stylesApiProps:t,className:n,classNames:r,styles:i,unstyled:s,children:c,label:l,description:u,id:d,disabled:f,error:p,size:m,labelPosition:h=`left`,bodyElement:g=`div`,labelElement:_=`label`,variant:v,style:y,vars:b,mod:x,attributes:S,...C}){let w=a({name:e,props:t,className:n,style:y,classes:Yn,classNames:r,styles:i,unstyled:s,attributes:S}),T=u?`${d}-description`:void 0,E=p&&typeof p!=`boolean`?`${d}-error`:void 0;return(0,H.jsx)(o,{...w(`root`),__vars:{"--label-fz":L(m),"--label-lh":M(m,`label-lh`)},mod:[{"label-position":h},x],variant:v,size:m,...C,children:(0,H.jsxs)(o,{component:g,htmlFor:g===`label`?d:void 0,...w(`body`),children:[c,(0,H.jsxs)(`div`,{...w(`labelWrapper`),"data-disabled":f||void 0,children:[l&&(0,H.jsx)(o,{component:_,htmlFor:_===`label`?d:void 0,...w(`label`),"data-disabled":f||void 0,children:l}),u&&(0,H.jsx)(k.Description,{id:T,size:m,__inheritStyles:!1,...w(`description`),children:u}),p&&typeof p!=`boolean`&&(0,H.jsx)(k.Error,{id:E,size:m,__inheritStyles:!1,...w(`error`),children:p})]})]})})}Zn.displayName=`@mantine/core/InlineInput`;function Qn(e){return`group`in e}function $n({options:e,search:t,limit:n}){let r=t.trim().toLowerCase(),i=[];for(let a=0;a0)return!1;return!0}function tr(e,t=new Set){if(Array.isArray(e))for(let n of e)if(Qn(n))tr(n.items,t);else{if(n.value===void 0)throw Error(`[@mantine/core] Each option must have value property`);if(t.has(n.value))throw Error(`[@mantine/core] Duplicate options are not supported. Option with value "${n.value}" was provided more than once`);t.add(n.value)}}function nr(e,t){return Array.isArray(e)?e.includes(t):e===t}function rr({data:e,withCheckIcon:t,withAlignedLabels:n,value:r,checkIconPosition:i,unstyled:a,renderOption:o}){if(!Qn(e)){let s=nr(r,e.value),c=t&&(s?(0,H.jsx)(Ct,{className:_n.optionsDropdownCheckIcon}):n?(0,H.jsx)(`div`,{className:_n.optionsDropdownCheckPlaceholder}):null),l=(0,H.jsxs)(H.Fragment,{children:[i===`left`&&c,(0,H.jsx)(`span`,{children:e.label}),i===`right`&&c]});return(0,H.jsx)(qn.Option,{value:e.value,disabled:e.disabled,className:_({[_n.optionsDropdownOption]:!a}),"data-reverse":i===`right`||void 0,"data-checked":s||void 0,"aria-selected":s,active:s,children:typeof o==`function`?o({option:e,checked:s}):l})}let s=e.items.map(e=>(0,H.jsx)(rr,{data:e,value:r,unstyled:a,withCheckIcon:t,withAlignedLabels:n,checkIconPosition:i,renderOption:o},`${e.value}`));return(0,H.jsx)(qn.Group,{label:e.group,children:s})}function ir({data:e,hidden:t,hiddenWhenEmpty:n,filter:r,search:i,limit:a,maxDropdownHeight:o,floatingHeight:s,withScrollArea:c=!0,filterOptions:l=!0,withCheckIcon:u=!1,withAlignedLabels:d=!1,value:f,checkIconPosition:p,nothingFoundMessage:m,unstyled:h,labelId:g,renderOption:_,scrollAreaProps:v,"aria-label":y}){let b=Sn();tr(e);let x=typeof i==`string`?(r||$n)({options:e,search:l?i:``,limit:a??1/0}):e,S=er(x),C=x.map((e,t)=>(0,H.jsx)(rr,{data:e,withCheckIcon:u,withAlignedLabels:d,value:f,checkIconPosition:p,unstyled:h,renderOption:_},Qn(e)?`group-${typeof e.group==`string`?e.group:t}`:`${e.value}`));return(0,H.jsx)(qn.Dropdown,{hidden:t||n&&S,"data-composed":!0,children:(0,H.jsxs)(qn.Options,{labelledBy:g,"aria-label":y,children:[c?(0,H.jsx)(fe.Autosize,{mah:(s??b.floatingHeight)===`viewport`?`var(--combobox-floating-options-max-height)`:o??220,type:`scroll`,scrollbarSize:`var(--combobox-padding)`,offsetScrollbars:`y`,...v,children:C}):C,S&&m&&(0,H.jsx)(qn.Empty,{children:m})]})})}function ar(e,t,n,r){if(t===n||r===`before`&&n===t+1||r===`after`&&n===t-1)return e;let i=e.slice(),[a]=i.splice(t,1),o=t{let t=e.lastElementChild;return t?t instanceof HTMLInputElement?t:t.querySelector(`input`):null},sr=(e,t)=>{if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n{let e=i.current;e&&(i.current=null,sr(o.current,e.expectedValue)&&e.container?.querySelector(`[data-mantine-pill-index="${e.index}"]`)?.focus())});let s=(0,V.useCallback)(e=>{a.current=e},[]);return{getPillProps:e=>{if(n)return{draggable:!0,tabIndex:-1,"data-mantine-pill-index":e,"aria-keyshortcuts":`Alt+ArrowLeft Alt+ArrowRight`,onMouseDown:e=>{e.button===0&&e.stopPropagation()},onDragStart:t=>{t.stopPropagation(),t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,String(e)),r.current.draggedIndex=e;let n=t.currentTarget,i=n.getBoundingClientRect(),a=n.cloneNode(!0);a.removeAttribute(`data-dragging`),a.removeAttribute(`data-drag-over`),a.style.position=`fixed`,a.style.top=`-9999px`,a.style.left=`-9999px`,a.style.width=`${i.width}px`,a.style.height=`${i.height}px`,a.style.pointerEvents=`none`,document.body.appendChild(a),t.dataTransfer.setDragImage(a,t.clientX-i.left,t.clientY-i.top),setTimeout(()=>a.parentNode?.removeChild(a),0),requestAnimationFrame(()=>{n.setAttribute(`data-dragging`,`true`)})},onDragOver:t=>{let{draggedIndex:n}=r.current;if(n===null||n===e)return;let i=t.currentTarget,a=i.getBoundingClientRect(),o=t.clientX-a.left,s=(getComputedStyle(i).direction===`rtl`?o>a.width/2:o{let t=e.currentTarget,n=e.relatedTarget;n&&t.contains(n)||(t.removeAttribute(`data-drag-over`),r.current.currentDropTarget===t&&(r.current.currentDropTarget=null))},onDrop:n=>{n.preventDefault(),n.stopPropagation();let i=n.currentTarget,a=i.getAttribute(`data-drag-over`);i.removeAttribute(`data-drag-over`);let{draggedIndex:s}=r.current;if(s!==null&&a&&s!==e){let n=ar(o.current,s,e,a);n!==o.current&&t(n)}r.current.draggedIndex=null,r.current.currentDropTarget=null},onDragEnd:e=>{e.currentTarget.removeAttribute(`data-dragging`);let t=r.current.currentDropTarget;t&&t.removeAttribute(`data-drag-over`),r.current.draggedIndex=null,r.current.currentDropTarget=null},onKeyDown:n=>{if(n.key!==`ArrowLeft`&&n.key!==`ArrowRight`)return;let r=n.currentTarget,a=getComputedStyle(r).direction===`rtl`?n.key===`ArrowLeft`:n.key===`ArrowRight`,s=a?e+1:e-1;if(n.altKey){if(s<0||s>=o.current.length)return;n.preventDefault(),n.stopPropagation();let c=a?`after`:`before`,l=ar(o.current,e,s,c);if(l===o.current)return;i.current={container:r.parentElement,index:s,expectedValue:l},t(l);return}if(s<0)return;let c=r.parentElement;if(c){if(n.preventDefault(),n.stopPropagation(),s>=o.current.length){or(c)?.focus();return}c.querySelector(`[data-mantine-pill-index="${s}"]`)?.focus()}}}},getListProps:()=>n?{ref:s}:{},handleInputKeyDown:e=>{if(!n||e.key!==`ArrowLeft`)return;let t=e.currentTarget;if(!(t.value.length===0||t.selectionStart===0&&t.selectionEnd===0))return;let r=a.current;if(!r)return;let i=r.querySelectorAll(`[data-mantine-pill-index]`);i.length!==0&&(e.preventDefault(),i[i.length-1].focus())}}}function lr({id:e,label:t,labelProps:n,inputWrapperOrder:r}){if(t&&(!r||r.includes(`label`)))return n?.id||`${e}-label`}function ur(e){let t=e.currentTarget;return Yt(t).activeElement!==t}var dr=(0,V.createContext)(null),fr={root:`m_7cda1cd6`,"root--default":`m_44da308b`,"root--contrast":`m_e3a01f8`,label:`m_1e0e6180`,remove:`m_ae386778`,group:`m_1dcfd90b`},pr=(0,V.createContext)(null),mr=g((e,{gap:t},{size:n})=>({group:{"--pg-gap":t===void 0?M(n,`pg-gap`):M(t)}})),hr=h(e=>{let t=u(`PillGroup`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,size:d,disabled:f,attributes:p,...m}=t,h=(0,V.use)(dr)?.size||d||void 0,g=a({name:`PillGroup`,classes:fr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:p,vars:l,varsResolver:mr,stylesCtx:{size:h},rootSelector:`group`});return(0,H.jsx)(pr,{value:{size:h,disabled:f},children:(0,H.jsx)(o,{size:h,...g(`group`),...m})})});hr.classes=fr,hr.varsResolver=mr,hr.displayName=`@mantine/core/PillGroup`;var gr={variant:`default`},_r=g((e,{radius:t},{size:n})=>({root:{"--pill-fz":M(n,`pill-fz`),"--pill-height":M(n,`pill-height`),"--pill-radius":t===void 0?void 0:re(t)}})),vr=h(e=>{let t=u(`Pill`,gr,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,variant:d,children:f,withRemoveButton:p,onRemove:m,removeButtonProps:h,radius:g,size:_,disabled:v,mod:y,attributes:b,...x}=t,S=(0,V.use)(pr),C=(0,V.use)(dr),w=_||S?.size||void 0,T=C?.variant===`filled`?`contrast`:d||`default`,E=a({name:`Pill`,classes:fr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:b,vars:l,varsResolver:_r,stylesCtx:{size:w}});return(0,H.jsxs)(o,{component:`span`,variant:T,size:w,...E(`root`,{variant:T}),mod:[{"with-remove":p&&!v,disabled:v||S?.disabled},y],...x,children:[(0,H.jsx)(`span`,{...E(`label`),children:f}),p&&(0,H.jsx)(oe,{variant:`transparent`,radius:g,tabIndex:-1,"aria-hidden":!0,unstyled:c,...h,...E(`remove`,{className:h?.className,style:h?.style}),onMouseDown:e=>{e.preventDefault(),e.stopPropagation(),h?.onMouseDown?.(e)},onClick:e=>{e.stopPropagation(),m?.(),h?.onClick?.(e)}})]})});vr.classes=fr,vr.varsResolver=_r,vr.displayName=`@mantine/core/Pill`,vr.Group=hr;var yr={field:`m_45c4369d`},br={type:`visible`},xr=h(e=>{let t=u(`PillsInputField`,br,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,type:d,disabled:f,id:p,pointer:m,mod:h,attributes:g,ref:_,...v}=t,y=(0,V.use)(dr),b=(0,V.use)(D),x=a({name:`PillsInputField`,classes:yr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:g,rootSelector:`field`}),S=f||y?.disabled;return(0,H.jsx)(o,{component:`input`,ref:ie(_,y?.fieldRef),"data-type":d,disabled:S,mod:[{disabled:S,pointer:m},h],...x(`field`),...v,id:b?.inputId||p,"aria-invalid":y?.hasError,"aria-describedby":b?.describedBy,type:`text`,onMouseDown:e=>!m&&e.stopPropagation()})});xr.classes=yr,xr.displayName=`@mantine/core/PillsInputField`;var Sr={size:`sm`},Cr=h(e=>{let{children:t,onMouseDown:n,onClick:r,size:i,disabled:a,__staticSelector:o,error:s,variant:c,...l}=u([`Input`,`InputWrapper`,`PillsInput`],Sr,e),d=(0,V.useRef)(null);return(0,H.jsx)(dr,{value:{fieldRef:d,size:i,disabled:a,hasError:!!s,variant:c},children:(0,H.jsx)(N,{size:i,error:s,variant:c,component:`div`,"data-no-overflow":!0,onMouseDown:e=>{e.preventDefault(),n?.(e),d.current?.focus()},onClick:e=>{e.preventDefault(),e.currentTarget.closest(`fieldset`)?.disabled||(d.current?.focus(),r?.(e))},...l,multiline:!0,disabled:a,__staticSelector:o||`PillsInput`,withAria:!1,children:t})})});Cr.displayName=`@mantine/core/PillsInput`,Cr.classes=N.classes,Cr.Field=xr;function wr(e,t){let n=t.trim().toLowerCase();if(n===``)return;let r=Object.values(e).filter(e=>!e.disabled&&e.label.trim().toLowerCase()===n);return r.length===1?r[0]:void 0}function Tr(e){return typeof e==`string`?e.trim().toLowerCase():e}function Er({data:e,value:t}){let n=t.map(Tr);return e.reduce((e,t)=>(Qn(t)?e.push({group:t.group,items:t.items.filter(e=>n.indexOf(Tr(e.value))===-1)}):n.indexOf(Tr(t.value))===-1&&e.push(t),e),[])}var Dr={xs:41,sm:50,md:60,lg:72,xl:89},Or={maxValues:1/0,withCheckIcon:!0,checkIconPosition:`left`,hiddenInputValuesDivider:`,`,clearSearchOnChange:!0,openOnFocus:!0,size:`sm`},kr=c(e=>{let t=u([`Input`,`InputWrapper`,`MultiSelect`],Or,e),{classNames:n,className:r,style:i,styles:o,unstyled:s,vars:c,size:l,value:f,defaultValue:p,onChange:m,onKeyDown:h,variant:g,data:_,dropdownOpened:v,defaultDropdownOpened:y,onDropdownOpen:b,onDropdownClose:x,selectFirstOptionOnChange:S,selectFirstOptionOnDropdownOpen:C,onOptionSubmit:w,comboboxProps:T,filter:E,limit:D,withScrollArea:O,maxDropdownHeight:k,floatingHeight:j,searchValue:M,defaultSearchValue:N,onSearchChange:P,readOnly:I,disabled:L,onFocus:ee,onBlur:te,radius:ne,rightSection:re,rightSectionWidth:ie,rightSectionPointerEvents:ae,rightSectionProps:R,leftSection:oe,leftSectionWidth:z,leftSectionPointerEvents:se,leftSectionProps:ce,inputContainer:le,inputWrapperOrder:ue,withAsterisk:de,labelProps:fe,descriptionProps:pe,errorProps:me,successProps:he,wrapperProps:ge,description:_e,label:ve,error:B,success:ye,maxValues:be,searchable:xe,nothingFoundMessage:Se,withCheckIcon:Ce,withAlignedLabels:we,checkIconPosition:Te,hidePickedOptions:Ee,withErrorStyles:De,withSuccessStyles:Oe,name:ke,form:Ae,id:je,clearable:Me,clearSectionMode:Ne,clearButtonProps:Pe,hiddenInputProps:Fe,placeholder:Ie,hiddenInputValuesDivider:Le,required:Re,mod:ze,renderOption:Be,renderPill:Ve,onRemove:He,onClear:Ue,onMaxValues:We,scrollAreaProps:Ge,chevronColor:Ke,attributes:qe,clearSearchOnChange:Je,openOnFocus:Ye,loading:Xe,loadingPosition:Ze,withPillsReorder:Qe,...$e}=t,et=F(je),tt=lr({id:et,label:ve,labelProps:fe,inputWrapperOrder:ue}),nt=hn(_),rt=gn(nt),it=(0,V.useRef)({}),at=Wn({opened:v,defaultOpened:y,onDropdownOpen:()=>{b?.(),C&&at.selectFirstOption()},onDropdownClose:()=>{x?.(),at.resetSelectedOption()}}),{styleProps:ot,rest:{type:st,autoComplete:ct,...lt}}=d($e),[ut,dt]=kt({value:f,defaultValue:p,finalValue:[],onChange:m}),{getPillProps:ft,getListProps:pt,handleInputKeyDown:mt}=cr({value:ut,onChange:dt,enabled:Qe&&!L&&!I}),[ht,gt]=kt({value:M,defaultValue:N,finalValue:``,onChange:P}),_t=e=>{gt(e),at.resetSelectedOption()},vt=a({name:`MultiSelect`,classes:{},props:t,classNames:n,styles:o,unstyled:s,attributes:qe}),{resolvedClassNames:yt,resolvedStyles:bt}=A({props:t,styles:o,classNames:n}),xt=e=>{h?.(e),!e.defaultPrevented&&(e.key===` `&&!xe&&(e.preventDefault(),at.toggleDropdown()),e.key===`Backspace`&&ht.length===0&&ut.length>0&&!I&&(He?.(ut[ut.length-1]),dt(ut.slice(0,ut.length-1))),mt(e))},St=ut.map((e,t)=>{let n=rt[`${e}`]||it.current[`${e}`],r=ft(t);return Ve?(0,H.jsx)(V.Fragment,{children:Ve({option:n,value:e,onRemove:()=>{dt(ut.filter(t=>e!==t)),He?.(e)},disabled:L,reorderProps:r})},`${e}-${t}`):(0,H.jsx)(vr,{withRemoveButton:!I&&!rt[`${e}`]?.disabled,onRemove:()=>{dt(ut.filter(t=>e!==t)),He?.(e)},unstyled:s,disabled:L,...vt(`pill`),...r,children:n?.label||e},`${e}-${t}`)});(0,V.useEffect)(()=>{S&&at.selectFirstOption()},[S,ht]),(0,V.useEffect)(()=>{ut.forEach(e=>{`${e}`in rt&&(it.current[`${e}`]=rt[`${e}`])})},[rt,ut]);let Ct=(0,H.jsx)(qn.ClearButton,{...Pe,onClear:()=>{Ue?.(),dt([]),_t(``)}}),wt=Er({data:nt,value:ut}),Tt=Me&&ut.length>0&&!L&&!I,Et=Tt?{paddingInlineEnd:Dr[l]??Dr.sm}:void 0;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(qn,{store:at,classNames:yt,styles:bt,unstyled:s,size:l,readOnly:I,__staticSelector:`MultiSelect`,attributes:qe,floatingHeight:j,onOptionSubmit:e=>{w?.(e),Je&&_t(``),at.updateSelectedOptionIndex(`selected`),ut.includes(rt[`${e}`].value)?(dt(ut.filter(t=>t!==rt[`${e}`].value)),He?.(rt[`${e}`].value)):ut.lengthxe?at.openDropdown():at.toggleDropdown(),"data-expanded":at.dropdownOpened||void 0,id:et,required:Re,mod:ze,attributes:qe,children:(0,H.jsxs)(vr.Group,{attributes:qe,disabled:L,unstyled:s,...vt(`pillsList`,{style:Et}),...pt(),children:[St,(0,H.jsx)(qn.EventsTarget,{autoComplete:ct,withExpandedAttribute:!0,children:(0,H.jsx)(Cr.Field,{...lt,id:et,placeholder:Ie,type:!xe&&!Ie?`hidden`:`visible`,...vt(`inputField`),unstyled:s,onFocus:e=>{ee?.(e),Ye&&xe&&at.openDropdown()},onBlur:e=>{te?.(e),at.closeDropdown(),_t(``)},onKeyDown:xt,value:ht,onChange:e=>{if(ur(e)){if(!I){let t=wr(rt,e.currentTarget.value);t&&!ut.includes(t.value)&&ut.length{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ProgressLabel`,null,e),c=jr();return(0,H.jsx)(o,{...c.getStyles(`label`,{className:n,style:r,classNames:t,styles:i}),...s})});Nr.classes=Mr,Nr.displayName=`@mantine/core/ProgressLabel`;var Pr=g((e,{size:t,radius:n,transitionDuration:r})=>({root:{"--progress-size":M(t,`progress-size`),"--progress-radius":n===void 0?void 0:re(n),"--progress-transition-duration":typeof r==`number`?`${r}ms`:void 0}})),Fr=h(e=>{let t=u(`ProgressRoot`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,autoContrast:d,transitionDuration:f,orientation:p,attributes:m,mod:h,...g}=t,_=a({name:`Progress`,classes:Mr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:m,vars:l,varsResolver:Pr});return(0,H.jsx)(Ar,{value:{getStyles:_,autoContrast:d},children:(0,H.jsx)(o,{mod:[{orientation:p},h],..._(`root`),...g})})});Fr.classes=Mr,Fr.varsResolver=Pr,Fr.displayName=`@mantine/core/ProgressRoot`;var Ir={withAria:!0},Lr=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,value:s,withAria:c,color:d,striped:p,animated:m,mod:h,...g}=u(`ProgressSection`,Ir,e),_=jr(),v=f(),y=c?{role:`progressbar`,"aria-valuemax":100,"aria-valuemin":0,"aria-valuenow":s,"aria-valuetext":`${s}%`}:{};return(0,H.jsx)(o,{..._.getStyles(`section`,{className:n,classNames:t,styles:i,style:r}),...g,...y,mod:[{striped:p||m,animated:m},h],__vars:{"--progress-section-size":`${s}%`,"--progress-section-color":l(d,v),"--progress-label-color":Xt(_.autoContrast,v)?ut({color:d,theme:v,autoContrast:_.autoContrast}):void 0}})});Lr.classes=Mr,Lr.displayName=`@mantine/core/ProgressSection`;var Rr=h(e=>{let t=u(`Progress`,null,e),{value:n,classNames:r,styles:i,vars:a,color:o,striped:s,animated:c,"aria-label":l,...d}=t,{resolvedClassNames:f,resolvedStyles:p}=A({classNames:r,styles:i,props:t});return(0,H.jsx)(Fr,{classNames:f,styles:p,vars:a,...d,children:(0,H.jsx)(Lr,{value:n,color:o,striped:s,animated:c,"aria-label":l})})});Rr.classes=Mr,Rr.displayName=`@mantine/core/Progress`,Rr.Section=Lr,Rr.Root=Fr,Rr.Label=Nr;var zr={root:`m_cf365364`,indicator:`m_9e182ccd`,label:`m_1738fcb2`,input:`m_1714d588`,control:`m_69686b9b`,innerLabel:`m_78882f40`},Br={withItemsBorders:!0},Vr=g((e,{radius:t,color:n,transitionDuration:r,size:i,transitionTimingFunction:a})=>({root:{"--sc-radius":t===void 0?void 0:re(t),"--sc-color":n?l(n,e):void 0,"--sc-shadow":n?void 0:`var(--mantine-shadow-xs)`,"--sc-transition-duration":r===void 0?void 0:`${r}ms`,"--sc-transition-timing-function":a,"--sc-padding":M(i,`sc-padding`),"--sc-font-size":L(i)}})),Hr=c(e=>{let t=u(`SegmentedControl`,Br,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,data:d,value:p,defaultValue:m,onChange:h,size:g,name:_,disabled:v,readOnly:y,fullWidth:b,orientation:x,radius:S,color:C,transitionDuration:w,transitionTimingFunction:T,variant:E,autoContrast:D,withItemsBorders:O,mod:k,attributes:A,ref:j,...M}=t,N=a({name:`SegmentedControl`,props:t,classes:zr,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:A,vars:l,varsResolver:Vr}),P=f(),I=d.map(e=>Kt(e)?{label:`${e}`,value:e}:e),L=Gt(),[ee,te]=(0,V.useState)(0),[ne,re]=(0,V.useState)(null),[ae,R]=(0,V.useState)({}),oe=(e,t)=>{e!==null&&ae[t]!==e&&(ae[t]=e,R({...ae}))},[z,se]=kt({value:p,defaultValue:m,finalValue:Array.isArray(d)?I.find(e=>!e.disabled)?.value??d[0]?.value??null:null,onChange:h}),ce=F(_),le=I.map(e=>`${e.value}`),ue=I.map(e=>(0,V.createElement)(o,{...N(`control`),mod:{active:z===e.value,orientation:x},key:`${e.value}`},(0,V.createElement)(`input`,{...N(`input`),disabled:v||e.disabled,type:`radio`,name:ce,value:`${e.value}`,id:`${ce}-${e.value}`,checked:z===e.value,onChange:()=>!y&&se(e.value),"data-focus-ring":P.focusRing,key:`${e.value}-input`}),(0,V.createElement)(o,{component:`label`,...N(`label`),mod:{active:z===e.value&&!(v||e.disabled),disabled:v||e.disabled,"read-only":y},htmlFor:`${ce}-${e.value}`,ref:t=>oe(t,`${e.value}`),__vars:{"--sc-label-color":C===void 0?void 0:ut({color:C,theme:P,autoContrast:D})},key:`${e.value}-label`},(0,H.jsx)(`span`,{...N(`innerLabel`),children:e.label})))),de=ie(j,re);return Vt(()=>{te(e=>e+1)},[d.length]),Vt(()=>{R(e=>{let t={};return le.forEach(n=>{n in e&&(t[n]=e[n])}),Object.keys(t).length===Object.keys(e).length?e:t})},[le]),d.length===0?null:(0,H.jsxs)(o,{...N(`root`),variant:E,size:g,ref:de,mod:[{"full-width":b,orientation:x,initialized:L,"with-items-borders":O},k],...M,role:`radiogroup`,"data-disabled":v,children:[z!==void 0&&(0,H.jsx)(tn,{target:ae[`${z}`],parent:ne,component:`span`,transitionDuration:`var(--sc-transition-duration)`,...N(`indicator`)},ee),ue]})});Hr.classes=zr,Hr.varsResolver=Vr,Hr.displayName=`@mantine/core/SegmentedControl`;var Ur={size:`sm`,withCheckIcon:!0,allowDeselect:!0,checkIconPosition:`left`,openOnFocus:!0},Wr=c(e=>{let t=u([`Input`,`InputWrapper`,`Select`],Ur,e),{classNames:n,styles:r,unstyled:i,vars:a,dropdownOpened:o,defaultDropdownOpened:s,onDropdownClose:c,onDropdownOpen:l,onFocus:d,onBlur:f,onClick:p,onChange:m,data:h,value:g,defaultValue:_,selectFirstOptionOnChange:v,selectFirstOptionOnDropdownOpen:y,onOptionSubmit:b,comboboxProps:x,readOnly:S,disabled:C,filter:w,limit:T,withScrollArea:E,maxDropdownHeight:D,floatingHeight:O,size:k,searchable:j,rightSection:M,checkIconPosition:P,withCheckIcon:I,withAlignedLabels:L,nothingFoundMessage:ee,name:te,form:ne,searchValue:re,defaultSearchValue:ie,onSearchChange:ae,allowDeselect:R,error:oe,rightSectionPointerEvents:z,id:se,clearable:ce,clearSectionMode:le,clearButtonProps:ue,hiddenInputProps:de,renderOption:fe,onClear:pe,autoComplete:me,scrollAreaProps:he,__defaultRightSection:ge,__clearSection:_e,__clearable:ve,chevronColor:B,autoSelectOnBlur:ye,openOnFocus:be,attributes:xe,...Se}=t,Ce=(0,V.useMemo)(()=>hn(h),[h]),we=(0,V.useRef)({}),Te=(0,V.useMemo)(()=>gn(Ce),[Ce]),Ee=F(se),De=lr({id:Ee,label:Se.label,labelProps:Se.labelProps,inputWrapperOrder:Se.inputWrapperOrder}),[Oe,ke,Ae]=kt({value:g,defaultValue:_,finalValue:null,onChange:m}),je=Oe==null?void 0:`${Oe}`in Te?Te[`${Oe}`]:we.current[`${Oe}`],Me=Ut(je),[Ne,Pe,Fe]=kt({value:re,defaultValue:ie,finalValue:je?je.label:``,onChange:ae}),Ie=Wn({opened:o,defaultOpened:s,onDropdownOpen:()=>{l?.(),y?Ie.selectFirstOption():Ie.updateSelectedOptionIndex(`active`,{scrollIntoView:!0})},onDropdownClose:()=>{c?.(),setTimeout(Ie.resetSelectedOption,0)}}),Le=e=>{Pe(e),Ie.resetSelectedOption()},{resolvedClassNames:Re,resolvedStyles:ze}=A({props:t,styles:r,classNames:n});(0,V.useEffect)(()=>{v&&Ie.selectFirstOption()},[v,Ne]),(0,V.useEffect)(()=>{g===null&&Le(``),g!=null&&je&&(Me?.value!==je.value||Me?.label!==je.label)&&Le(je.label)},[g,je]),(0,V.useEffect)(()=>{!Ae&&!Fe&&Le(Oe==null?``:`${Oe}`in Te?Te[`${Oe}`]?.label:we.current[`${Oe}`]?.label||``)},[Te,Oe]),(0,V.useEffect)(()=>{Oe&&`${Oe}`in Te&&(we.current[`${Oe}`]=Te[`${Oe}`])},[Te,Oe]);let Be=(0,H.jsx)(qn.ClearButton,{...ue,onClear:()=>{ke(null,null),Le(``),pe?.()}}),Ve=ce&&Oe!=null&&!C&&!S;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(qn,{store:Ie,__staticSelector:`Select`,classNames:Re,styles:ze,unstyled:i,readOnly:S,size:k,attributes:xe,floatingHeight:O,keepMounted:ye,onOptionSubmit:e=>{b?.(e);let t=R&&`${Te[e].value}`==`${Oe}`?null:Te[e],n=t?t.value:null;n!==Oe&&ke(n,t),!Ae&&Le(n==null?``:t?.label||``),Ie.closeDropdown()},...x,children:[(0,H.jsx)(qn.Target,{targetType:j?`input`:`button`,autoComplete:me,withExpandedAttribute:!0,children:(0,H.jsx)(N,{id:Ee,__defaultRightSection:(0,H.jsx)(qn.Chevron,{size:k,error:oe,unstyled:i,color:B}),__clearSection:Be,__clearable:Ve,__clearSectionMode:le,rightSection:M,rightSectionPointerEvents:z||`none`,...Se,size:k,__staticSelector:`Select`,disabled:C,readOnly:S||!j,value:Ne,onChange:e=>{if(ur(e)){if(!S){let t=wr(Te,e.currentTarget.value);t&&`${t.value}`!=`${Oe}`&&(ke(t.value,t),!Ae&&Le(t.label))}return}Le(e.currentTarget.value),Ie.openDropdown(),v&&Ie.selectFirstOption()},onFocus:e=>{be&&j&&Ie.openDropdown(),d?.(e)},onBlur:e=>{ye&&Ie.clickSelectedOption(),Ie.closeDropdown();let t=Oe!=null&&(`${Oe}`in Te?Te[`${Oe}`]:we.current[`${Oe}`]);Le(t&&t.label||``),f?.(e)},onClick:e=>{j?Ie.openDropdown():Ie.toggleDropdown(),p?.(e)},classNames:Re,styles:ze,unstyled:i,pointer:!j,error:oe,attributes:xe})}),(0,H.jsx)(ir,{data:Ce,hidden:S||C,filter:w,search:Ne,limit:T,hiddenWhenEmpty:!ee,withScrollArea:E,maxDropdownHeight:D,filterOptions:!!j&&je?.label!==Ne,value:Oe,checkIconPosition:P,withCheckIcon:I,withAlignedLabels:L,nothingFoundMessage:ee,unstyled:i,labelId:De,"aria-label":De?void 0:Se[`aria-label`],renderOption:fe,scrollAreaProps:he})]}),(0,H.jsx)(qn.HiddenInput,{value:Oe,name:te,form:ne,disabled:C,...de})]})});Wr.classes={...N.classes,...qn.classes},Wr.displayName=`@mantine/core/Select`;function Gr(e){if(e!==void 0)return typeof e==`number`?P(e):e}function Kr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r,autoRows:i,selector:a}){let o=f(),s=t===void 0?e:t,c=r!==void 0,l=E({"--sg-spacing-x":R(Lt(e)),"--sg-spacing-y":R(Lt(s)),"--sg-auto-rows":i,...c?{"--sg-min-col-width":Gr(r)}:{"--sg-cols":Lt(n)?.toString()}}),u=O(o.breakpoints).reduce((t,r)=>(t[r]||(t[r]={}),typeof e==`object`&&e[r]!==void 0&&(t[r][`--sg-spacing-x`]=R(e[r])),typeof s==`object`&&s[r]!==void 0&&(t[r][`--sg-spacing-y`]=R(s[r])),!c&&typeof n==`object`&&n[r]!==void 0&&(t[r][`--sg-cols`]=n[r]),t),{}),d=bt(O(u),o.breakpoints).filter(e=>O(u[e.value]).length>0).map(e=>({query:`(min-width: ${o.breakpoints[e.value]})`,styles:u[e.value]}));return(0,H.jsx)(j,{styles:l,media:d,selector:a})}function qr(e){return typeof e==`object`&&e?O(e):[]}function Jr(e){return e.sort((e,t)=>mt(e)-mt(t))}function Yr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r}){return Jr(Array.from(new Set([...qr(e),...qr(t),...r===void 0?qr(n):[]])))}function Xr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r,autoRows:i,selector:a}){let o=t===void 0?e:t,s=r!==void 0,c=E({"--sg-spacing-x":R(Lt(e)),"--sg-spacing-y":R(Lt(o)),"--sg-auto-rows":i,...s?{"--sg-min-col-width":Gr(r)}:{"--sg-cols":Lt(n)?.toString()}}),l=Yr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r}),u=l.reduce((t,r)=>(t[r]||(t[r]={}),typeof e==`object`&&e[r]!==void 0&&(t[r][`--sg-spacing-x`]=R(e[r])),typeof o==`object`&&o[r]!==void 0&&(t[r][`--sg-spacing-y`]=R(o[r])),!s&&typeof n==`object`&&n[r]!==void 0&&(t[r][`--sg-cols`]=n[r]),t),{}),d=l.map(e=>({query:`simple-grid (min-width: ${e})`,styles:u[e]}));return(0,H.jsx)(j,{styles:c,container:d,selector:a})}var Zr={container:`m_925c2d2c`,root:`m_2415a157`},Qr={cols:1,spacing:`md`,type:`media`},$r=h(e=>{let t=u(`SimpleGrid`,Qr,e),{classNames:n,className:r,style:i,styles:c,unstyled:l,vars:d,cols:f,verticalSpacing:p,spacing:m,type:h,minColWidth:g,autoFlow:_,autoRows:v,attributes:y,...b}=t,x=a({name:`SimpleGrid`,classes:Zr,props:t,className:r,style:i,classNames:n,styles:c,unstyled:l,attributes:y,vars:d}),S=s(),C=g===void 0?void 0:_||`auto-fill`;return h===`container`?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Xr,{...t,selector:`.${S}`}),(0,H.jsx)(`div`,{...x(`container`),children:(0,H.jsx)(o,{...x(`root`,{className:S}),...b,"data-auto-cols":C})})]}):(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Kr,{...t,selector:`.${S}`}),(0,H.jsx)(o,{...x(`root`,{className:S}),...b,"data-auto-cols":C})]})});$r.classes=Zr,$r.displayName=`@mantine/core/SimpleGrid`;var ei=(0,V.createContext)(null),ti={hiddenInputValuesSeparator:`,`},ni=c((e=>{let{value:t,defaultValue:n,onChange:r,size:i,wrapperProps:a,children:o,readOnly:s,name:c,hiddenInputValuesSeparator:l,hiddenInputProps:d,maxSelectedValues:f,disabled:p,...m}=u(`SwitchGroup`,ti,e),[h,g]=kt({value:t,defaultValue:n,finalValue:[],onChange:r}),_=e=>{let t=e.currentTarget.value;if(s)return;let n=h.includes(t);!n&&f&&h.length>=f||g(n?h.filter(e=>e!==t):[...h,t])},v=e=>{if(p)return!0;if(!f)return!1;let t=h.includes(e),n=h.length>=f;return!t&&n},y=h.join(l);return(0,H.jsx)(ei,{value:{value:h,onChange:_,size:i,isDisabled:v},children:(0,H.jsxs)(k.Wrapper,{size:i,...a,...m,labelElement:`div`,__staticSelector:`SwitchGroup`,children:[(0,H.jsx)(Jn,{role:`group`,children:o}),(0,H.jsx)(`input`,{type:`hidden`,name:c,value:y,...d})]})})}));ni.classes=k.Wrapper.classes,ni.displayName=`@mantine/core/SwitchGroup`;var ri={root:`m_5f93f3bb`,input:`m_926b4011`,track:`m_9307d992`,thumb:`m_93039a1d`,trackLabel:`m_8277e082`},ii={labelPosition:`right`,withThumbIndicator:!0},ai=g((e,{radius:t,color:n,size:r})=>({root:{"--switch-radius":t===void 0?void 0:re(t),"--switch-height":M(r,`switch-height`),"--switch-width":M(r,`switch-width`),"--switch-thumb-size":M(r,`switch-thumb-size`),"--switch-label-font-size":M(r,`switch-label-font-size`),"--switch-track-label-padding":M(r,`switch-track-label-padding`),"--switch-color":n?l(n,e):void 0}})),oi=h(e=>{let t=u(`Switch`,ii,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,color:f,label:p,offLabel:m,onLabel:h,id:g,size:_,radius:v,wrapperProps:y,thumbIcon:b,checked:x,defaultChecked:S,onChange:C,labelPosition:w,description:T,error:E,disabled:D,variant:O,rootRef:k,mod:A,withThumbIndicator:j,attributes:M,...N}=t,P=(0,V.use)(ei),I=_||P?.size,L=a({name:`Switch`,props:t,classes:ri,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:M,vars:l,varsResolver:ai}),{styleProps:ee,rest:te}=d(N),ne=F(g),re=[T?`${ne}-description`:void 0,E&&typeof E!=`boolean`?`${ne}-error`:void 0,te[`aria-describedby`]].filter(Boolean).join(` `)||void 0,ie={checked:P?.value.includes(te.value)??x,onChange:e=>{P?.onChange(e),C?.(e)}},ae=D||P?.isDisabled?.(te.value),[R,oe]=kt({value:ie.checked??x,defaultValue:S,finalValue:!1});return(0,H.jsxs)(Zn,{...L(`root`),__staticSelector:`Switch`,__stylesApiProps:t,id:ne,size:I,labelPosition:w,label:p,description:T,error:E,disabled:ae,bodyElement:`label`,labelElement:`span`,classNames:n,styles:s,unstyled:c,"data-checked":ie.checked,variant:O,ref:k,mod:A,attributes:M,inert:te.inert,...ee,...y,children:[(0,H.jsx)(`input`,{...te,...ie,disabled:ae,checked:R,"data-checked":ie.checked,onChange:e=>{ie.onChange?.(e),oe(e.currentTarget.checked)},id:ne,type:`checkbox`,role:`switch`,inert:te.inert,"aria-describedby":re,...L(`input`)}),(0,H.jsxs)(o,{"aria-hidden":`true`,component:`span`,mod:{error:E,"label-position":w,"without-labels":!h&&!m},...L(`track`),children:[(0,H.jsx)(o,{component:`span`,mod:{"reduce-motion":!0,"with-thumb-indicator":j&&!b},...L(`thumb`),children:b}),(0,H.jsx)(`span`,{...L(`trackLabel`),children:R?h:m})]})]})});oi.classes={...ri,...Xn},oi.varsResolver=ai,oi.displayName=`@mantine/core/Switch`,oi.Group=ni;var si=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M244,56v48a12,12,0,0,1-12,12H184a12,12,0,1,1,0-24H201.1l-19-17.38c-.13-.12-.26-.24-.38-.37A76,76,0,1,0,127,204h1a75.53,75.53,0,0,0,52.15-20.72,12,12,0,0,1,16.49,17.45A99.45,99.45,0,0,1,128,228h-1.37A100,100,0,1,1,198.51,57.06L220,76.72V56a12,12,0,0,1,24,0Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1-5.66-13.66l17-17-10.55-9.65-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,1,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60l10.93,10L226.34,50.3A8,8,0,0,1,240,56Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M238,56v48a6,6,0,0,1-6,6H184a6,6,0,0,1,0-12h32.55l-30.38-27.8c-.06-.06-.12-.13-.19-.19a82,82,0,1,0-1.7,117.65,6,6,0,0,1,8.24,8.73A93.46,93.46,0,0,1,128,222h-1.28A94,94,0,1,1,194.37,61.4L226,90.35V56a6,6,0,1,1,12,0Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M236,56v48a4,4,0,0,1-4,4H184a4,4,0,0,1,0-8h37.7L187.53,68.69l-.13-.12a84,84,0,1,0-1.75,120.51,4,4,0,0,1,5.5,5.82A91.43,91.43,0,0,1,128,220h-1.26A92,92,0,1,1,193,62.84l35,32.05V56a4,4,0,1,1,8,0Z`}))]]),ci=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M228,128a100,100,0,0,1-98.66,100H128a99.39,99.39,0,0,1-68.62-27.29,12,12,0,0,1,16.48-17.45,76,76,0,1,0-1.57-109c-.13.13-.25.25-.39.37L54.89,92H72a12,12,0,0,1,0,24H24a12,12,0,0,1-12-12V56a12,12,0,0,1,24,0V76.72L57.48,57.06A100,100,0,0,1,228,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L60.63,81.29l17,17A8,8,0,0,1,72,112H24a8,8,0,0,1-8-8V56A8,8,0,0,1,29.66,50.3L49.31,70,60.25,60A96,96,0,0,1,224,128Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M222,128a94,94,0,0,1-92.74,94H128a93.43,93.43,0,0,1-64.5-25.65,6,6,0,1,1,8.24-8.72A82,82,0,1,0,70,70l-.19.19L39.44,98H72a6,6,0,0,1,0,12H24a6,6,0,0,1-6-6V56a6,6,0,0,1,12,0V90.34L61.63,61.4A94,94,0,0,1,222,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M220,128a92,92,0,0,1-90.77,92H128a91.47,91.47,0,0,1-63.13-25.1,4,4,0,1,1,5.5-5.82A84,84,0,1,0,68.6,68.57l-.13.12L34.3,100H72a4,4,0,0,1,0,8H24a4,4,0,0,1-4-4V56a4,4,0,0,1,8,0V94.89l35-32A92,92,0,0,1,220,128Z`}))]]),li=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M220,48V96a12,12,0,0,1-24,0V77l-35.51,35.52a12,12,0,0,1-17-17L179,60H160a12,12,0,0,1,0-24h48A12,12,0,0,1,220,48ZM95.51,143.51,60,179V160a12,12,0,0,0-24,0v48a12,12,0,0,0,12,12H96a12,12,0,0,0,0-24H77l35.52-35.51a12,12,0,0,0-17-17ZM208,148a12,12,0,0,0-12,12v19l-35.51-35.52a12,12,0,0,0-17,17L179,196H160a12,12,0,0,0,0,24h48a12,12,0,0,0,12-12V160A12,12,0,0,0,208,148ZM77,60H96a12,12,0,0,0,0-24H48A12,12,0,0,0,36,48V96a12,12,0,0,0,24,0V77l35.51,35.52a12,12,0,0,0,17-17Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,48V208H48V48Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M216,48V96a8,8,0,0,1-16,0V67.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L188.69,56H160a8,8,0,0,1,0-16h48A8,8,0,0,1,216,48ZM98.34,146.34,56,188.69V160a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16H67.31l42.35-42.34a8,8,0,0,0-11.32-11.32ZM208,152a8,8,0,0,0-8,8v28.69l-42.34-42.35a8,8,0,0,0-11.32,11.32L188.69,200H160a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V160A8,8,0,0,0,208,152ZM67.31,56H96a8,8,0,0,0,0-16H48a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31l42.34,42.35a8,8,0,0,0,11.32-11.32Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M109.66,146.34a8,8,0,0,1,0,11.32L83.31,184l18.35,18.34A8,8,0,0,1,96,216H48a8,8,0,0,1-8-8V160a8,8,0,0,1,13.66-5.66L72,172.69l26.34-26.35A8,8,0,0,1,109.66,146.34ZM83.31,72l18.35-18.34A8,8,0,0,0,96,40H48a8,8,0,0,0-8,8V96a8,8,0,0,0,13.66,5.66L72,83.31l26.34,26.35a8,8,0,0,0,11.32-11.32ZM208,40H160a8,8,0,0,0-5.66,13.66L172.69,72,146.34,98.34a8,8,0,0,0,11.32,11.32L184,83.31l18.34,18.35A8,8,0,0,0,216,96V48A8,8,0,0,0,208,40Zm3.06,112.61a8,8,0,0,0-8.72,1.73L184,172.69l-26.34-26.35a8,8,0,0,0-11.32,11.32L172.69,184l-18.35,18.34A8,8,0,0,0,160,216h48a8,8,0,0,0,8-8V160A8,8,0,0,0,211.06,152.61Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M214,48V96a6,6,0,0,1-12,0V62.48l-45.76,45.76a6,6,0,0,1-8.48-8.48L193.52,54H160a6,6,0,0,1,0-12h48A6,6,0,0,1,214,48ZM99.76,147.76,54,193.52V160a6,6,0,0,0-12,0v48a6,6,0,0,0,6,6H96a6,6,0,0,0,0-12H62.48l45.76-45.76a6,6,0,0,0-8.48-8.48ZM208,154a6,6,0,0,0-6,6v33.52l-45.76-45.76a6,6,0,0,0-8.48,8.48L193.52,202H160a6,6,0,0,0,0,12h48a6,6,0,0,0,6-6V160A6,6,0,0,0,208,154ZM62.48,54H96a6,6,0,0,0,0-12H48a6,6,0,0,0-6,6V96a6,6,0,0,0,12,0V62.48l45.76,45.76a6,6,0,0,0,8.48-8.48Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,48V96a8,8,0,0,1-16,0V67.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L188.69,56H160a8,8,0,0,1,0-16h48A8,8,0,0,1,216,48ZM98.34,146.34,56,188.69V160a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16H67.31l42.35-42.34a8,8,0,0,0-11.32-11.32ZM208,152a8,8,0,0,0-8,8v28.69l-42.34-42.35a8,8,0,0,0-11.32,11.32L188.69,200H160a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V160A8,8,0,0,0,208,152ZM67.31,56H96a8,8,0,0,0,0-16H48a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31l42.34,42.35a8,8,0,0,0,11.32-11.32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M212,48V96a4,4,0,0,1-8,0V57.66l-49.17,49.17a4,4,0,0,1-5.66-5.66L198.34,52H160a4,4,0,0,1,0-8h48A4,4,0,0,1,212,48ZM101.17,149.17,52,198.34V160a4,4,0,0,0-8,0v48a4,4,0,0,0,4,4H96a4,4,0,0,0,0-8H57.66l49.17-49.17a4,4,0,0,0-5.66-5.66ZM208,156a4,4,0,0,0-4,4v38.34l-49.17-49.17a4,4,0,0,0-5.66,5.66L198.34,204H160a4,4,0,0,0,0,8h48a4,4,0,0,0,4-4V160A4,4,0,0,0,208,156ZM57.66,52H96a4,4,0,0,0,0-8H48a4,4,0,0,0-4,4V96a4,4,0,0,0,8,0V57.66l49.17,49.17a4,4,0,0,0,5.66-5.66Z`}))]]),ui=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216.49,168.49a12,12,0,0,1-17,0L128,97,56.49,168.49a12,12,0,0,1-17-17l80-80a12,12,0,0,1,17,0l80,80A12,12,0,0,1,216.49,168.49Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,160H48l80-80Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M213.66,154.34l-80-80a8,8,0,0,0-11.32,0l-80,80A8,8,0,0,0,48,168H208a8,8,0,0,0,5.66-13.66ZM67.31,152,128,91.31,188.69,152Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M215.39,163.06A8,8,0,0,1,208,168H48a8,8,0,0,1-5.66-13.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,215.39,163.06Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M212.24,164.24a6,6,0,0,1-8.48,0L128,88.49,52.24,164.24a6,6,0,0,1-8.48-8.48l80-80a6,6,0,0,1,8.48,0l80,80A6,6,0,0,1,212.24,164.24Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M210.83,162.83a4,4,0,0,1-5.66,0L128,85.66,50.83,162.83a4,4,0,0,1-5.66-5.66l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,210.83,162.83Z`}))]]),di=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M172,108a12,12,0,0,1-12,12H96a12,12,0,0,1,0-24h64A12,12,0,0,1,172,108Zm-12,28H96a12,12,0,0,0,0,24h64a12,12,0,0,0,0-24Zm76-8A108,108,0,0,1,78.77,224.15L46.34,235A20,20,0,0,1,21,209.66l10.81-32.43A108,108,0,1,1,236,128Zm-24,0A84,84,0,1,0,55.27,170.06a12,12,0,0,1,1,9.81l-9.93,29.79,29.79-9.93a12.1,12.1,0,0,1,3.8-.62,12,12,0,0,1,6,1.62A84,84,0,0,0,212,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128A96,96,0,0,1,79.93,211.11h0L42.54,223.58a8,8,0,0,1-10.12-10.12l12.47-37.39h0A96,96,0,1,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24Zm0,192a87.87,87.87,0,0,1-44.06-11.81,8,8,0,0,0-4-1.08,7.85,7.85,0,0,0-2.53.42L40,216,52.47,178.6a8,8,0,0,0-.66-6.54A88,88,0,1,1,128,216Zm40-104a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,112Zm0,32a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,144Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24Zm32,128H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Zm0-32H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M166,112a6,6,0,0,1-6,6H96a6,6,0,0,1,0-12h64A6,6,0,0,1,166,112Zm-6,26H96a6,6,0,0,0,0,12h64a6,6,0,0,0,0-12Zm70-10A102,102,0,0,1,79.31,217.65L44.44,229.27a14,14,0,0,1-17.71-17.71l11.62-34.87A102,102,0,1,1,230,128Zm-12,0A90,90,0,1,0,50.08,173.06a6,6,0,0,1,.5,4.91L38.12,215.35a2,2,0,0,0,2.53,2.53L78,205.42a6.2,6.2,0,0,1,1.9-.31,6.09,6.09,0,0,1,3,.81A90,90,0,0,0,218,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M168,112a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,112Zm-8,24H96a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm72-8A104,104,0,0,1,79.12,219.82L45.07,231.17a16,16,0,0,1-20.24-20.24l11.35-34.05A104,104,0,1,1,232,128Zm-16,0A88,88,0,1,0,51.81,172.06a8,8,0,0,1,.66,6.54L40,216,77.4,203.53a7.85,7.85,0,0,1,2.53-.42,8,8,0,0,1,4,1.08A88,88,0,0,0,216,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M164,112a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h64A4,4,0,0,1,164,112Zm-4,28H96a4,4,0,0,0,0,8h64a4,4,0,0,0,0-8Zm68-12A100,100,0,0,1,79.5,215.47l-35.69,11.9a12,12,0,0,1-15.18-15.18l11.9-35.69A100,100,0,1,1,228,128Zm-8,0A92,92,0,1,0,48.35,174.07a4,4,0,0,1,.33,3.27L36.22,214.72a4,4,0,0,0,5.06,5.06l37.38-12.46a3.93,3.93,0,0,1,1.27-.21,4.05,4.05,0,0,1,2,.54A92,92,0,0,0,220,128Z`}))]]),fi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm68-84a12,12,0,0,1-12,12H128a12,12,0,0,1-12-12V72a12,12,0,0,1,24,0v44h44A12,12,0,0,1,196,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm56,112H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm62-90a6,6,0,0,1-6,6H128a6,6,0,0,1-6-6V72a6,6,0,0,1,12,0v50h50A6,6,0,0,1,190,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm60-92a4,4,0,0,1-4,4H128a4,4,0,0,1-4-4V72a4,4,0,0,1,8,0v52h52A4,4,0,0,1,188,128Z`}))]]),pi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M140,80v41.21l34.17,20.5a12,12,0,1,1-12.34,20.58l-40-24A12,12,0,0,1,116,128V80a12,12,0,0,1,24,0ZM128,28A99.38,99.38,0,0,0,57.24,57.34c-4.69,4.74-9,9.37-13.24,14V64a12,12,0,0,0-24,0v40a12,12,0,0,0,12,12H72a12,12,0,0,0,0-24H57.77C63,86,68.37,80.22,74.26,74.26a76,76,0,1,1,1.58,109,12,12,0,0,0-16.48,17.46A100,100,0,1,0,128,28Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M136,80v43.47l36.12,21.67a8,8,0,0,1-8.24,13.72l-40-24A8,8,0,0,1,120,128V80a8,8,0,0,1,16,0Zm-8-48A95.44,95.44,0,0,0,60.08,60.15C52.81,67.51,46.35,74.59,40,82V64a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H72a8,8,0,0,0,0-16H49c7.15-8.42,14.27-16.35,22.39-24.57a80,80,0,1,1,1.66,114.75,8,8,0,1,0-11,11.64A96,96,0,1,0,128,32Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128A96,96,0,0,1,62.11,197.82a8,8,0,1,1,11-11.64A80,80,0,1,0,71.43,71.43C67.9,75,64.58,78.51,61.35,82L77.66,98.34A8,8,0,0,1,72,112H32a8,8,0,0,1-8-8V64a8,8,0,0,1,13.66-5.66L50,70.7c3.22-3.49,6.54-7,10.06-10.55A96,96,0,0,1,224,128ZM128,72a8,8,0,0,0-8,8v48a8,8,0,0,0,3.88,6.86l40,24a8,8,0,1,0,8.24-13.72L136,123.47V80A8,8,0,0,0,128,72Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M134,80v44.6l37.09,22.25a6,6,0,0,1-6.18,10.3l-40-24A6,6,0,0,1,122,128V80a6,6,0,0,1,12,0Zm-6-46A93.4,93.4,0,0,0,61.51,61.56c-8.58,8.68-16,17-23.51,25.8V64a6,6,0,0,0-12,0v40a6,6,0,0,0,6,6H72a6,6,0,0,0,0-12H44.73C52.86,88.29,60.79,79.35,70,70a82,82,0,1,1,1.7,117.62,6,6,0,1,0-8.24,8.72A94,94,0,1,0,128,34Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M136,80v43.47l36.12,21.67a8,8,0,0,1-8.24,13.72l-40-24A8,8,0,0,1,120,128V80a8,8,0,0,1,16,0Zm-8-48A95.44,95.44,0,0,0,60.08,60.15C52.81,67.51,46.35,74.59,40,82V64a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H72a8,8,0,0,0,0-16H49c7.15-8.42,14.27-16.35,22.39-24.57a80,80,0,1,1,1.66,114.75,8,8,0,1,0-11,11.64A96,96,0,1,0,128,32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M132,80v45.74l38.06,22.83a4,4,0,0,1-4.12,6.86l-40-24A4,4,0,0,1,124,128V80a4,4,0,0,1,8,0Zm-4-44A91.42,91.42,0,0,0,62.93,63C53.05,73,44.66,82.47,36,92.86V64a4,4,0,0,0-8,0v40a4,4,0,0,0,4,4H72a4,4,0,0,0,0-8H40.47C49.61,89,58.3,79,68.6,68.6a84,84,0,1,1,1.75,120.49,4,4,0,1,0-5.5,5.82A92,92,0,1,0,128,36Z`}))]]),mi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M108,84a16,16,0,1,1,16,16A16,16,0,0,1,108,84Zm128,44A108,108,0,1,1,128,20,108.12,108.12,0,0,1,236,128Zm-24,0a84,84,0,1,0-84,84A84.09,84.09,0,0,0,212,128Zm-72,36.68V132a20,20,0,0,0-20-20,12,12,0,0,0-4,23.32V168a20,20,0,0,0,20,20,12,12,0,0,0,4-23.32Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M144,176a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176Zm88-48A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128ZM124,96a12,12,0,1,0-12-12A12,12,0,0,0,124,96Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-4,48a12,12,0,1,1-12,12A12,12,0,0,1,124,72Zm12,112a16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M142,176a6,6,0,0,1-6,6,14,14,0,0,1-14-14V128a2,2,0,0,0-2-2,6,6,0,0,1,0-12,14,14,0,0,1,14,14v40a2,2,0,0,0,2,2A6,6,0,0,1,142,176ZM124,94a10,10,0,1,0-10-10A10,10,0,0,0,124,94Zm106,34A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M140,176a4,4,0,0,1-4,4,12,12,0,0,1-12-12V128a4,4,0,0,0-4-4,4,4,0,0,1,0-8,12,12,0,0,1,12,12v40a4,4,0,0,0,4,4A4,4,0,0,1,140,176ZM124,92a8,8,0,1,0-8-8A8,8,0,0,0,124,92Zm104,36A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z`}))]]),hi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,44H32A20,20,0,0,0,12,64V192a20,20,0,0,0,20,20H224a20,20,0,0,0,20-20V64A20,20,0,0,0,224,44Zm-4,144H36V68H220ZM52,128a12,12,0,0,1,12-12H192a12,12,0,0,1,0,24H64A12,12,0,0,1,52,128Zm0-36A12,12,0,0,1,64,80H192a12,12,0,0,1,0,24H64A12,12,0,0,1,52,92Zm0,72a12,12,0,0,1,12-12h8a12,12,0,0,1,0,24H64A12,12,0,0,1,52,164Zm108,0a12,12,0,0,1-12,12H108a12,12,0,0,1,0-24h40A12,12,0,0,1,160,164Zm44,0a12,12,0,0,1-12,12h-8a12,12,0,0,1,0-24h8A12,12,0,0,1,204,164Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M232,64V192a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H224A8,8,0,0,1,232,64Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48Zm0,144H32V64H224V192Zm-16-64a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,128Zm0-32a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,96ZM72,160a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16h8A8,8,0,0,1,72,160Zm96,0a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,160Zm40,0a8,8,0,0,1-8,8h-8a8,8,0,0,1,0-16h8A8,8,0,0,1,208,160Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48ZM64,168H48a8,8,0,0,1,0-16H64a8,8,0,0,1,0,16Zm96,0H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Zm48,0H192a8,8,0,0,1,0-16h16a8,8,0,0,1,0,16Zm0-32H48a8,8,0,0,1,0-16H208a8,8,0,0,1,0,16Zm0-32H48a8,8,0,0,1,0-16H208a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,50H32A14,14,0,0,0,18,64V192a14,14,0,0,0,14,14H224a14,14,0,0,0,14-14V64A14,14,0,0,0,224,50Zm2,142a2,2,0,0,1-2,2H32a2,2,0,0,1-2-2V64a2,2,0,0,1,2-2H224a2,2,0,0,1,2,2Zm-20-64a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12H200A6,6,0,0,1,206,128Zm0-32a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12H200A6,6,0,0,1,206,96ZM70,160a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12h8A6,6,0,0,1,70,160Zm96,0a6,6,0,0,1-6,6H96a6,6,0,0,1,0-12h64A6,6,0,0,1,166,160Zm40,0a6,6,0,0,1-6,6h-8a6,6,0,0,1,0-12h8A6,6,0,0,1,206,160Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48Zm0,144H32V64H224V192Zm-16-64a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,128Zm0-32a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,96ZM72,160a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16h8A8,8,0,0,1,72,160Zm96,0a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,160Zm40,0a8,8,0,0,1-8,8h-8a8,8,0,0,1,0-16h8A8,8,0,0,1,208,160Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,52H32A12,12,0,0,0,20,64V192a12,12,0,0,0,12,12H224a12,12,0,0,0,12-12V64A12,12,0,0,0,224,52Zm4,140a4,4,0,0,1-4,4H32a4,4,0,0,1-4-4V64a4,4,0,0,1,4-4H224a4,4,0,0,1,4,4Zm-24-64a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8H200A4,4,0,0,1,204,128Zm0-32a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8H200A4,4,0,0,1,204,96ZM68,160a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8h8A4,4,0,0,1,68,160Zm96,0a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h64A4,4,0,0,1,164,160Zm40,0a4,4,0,0,1-4,4h-8a4,4,0,0,1,0-8h8A4,4,0,0,1,204,160Z`}))]]),gi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M76,64A12,12,0,0,1,88,52H216a12,12,0,0,1,0,24H88A12,12,0,0,1,76,64Zm140,52H88a12,12,0,0,0,0,24H216a12,12,0,0,0,0-24Zm0,64H88a12,12,0,0,0,0,24H216a12,12,0,0,0,0-24ZM44,112a16,16,0,1,0,16,16A16,16,0,0,0,44,112Zm0-64A16,16,0,1,0,60,64,16,16,0,0,0,44,48Zm0,128a16,16,0,1,0,16,16A16,16,0,0,0,44,176Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,64V192H88V64Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M80,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H88A8,8,0,0,1,80,64Zm136,56H88a8,8,0,1,0,0,16H216a8,8,0,0,0,0-16Zm0,64H88a8,8,0,1,0,0,16H216a8,8,0,0,0,0-16ZM44,52A12,12,0,1,0,56,64,12,12,0,0,0,44,52Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,116Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,180Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM68,188a12,12,0,1,1,12-12A12,12,0,0,1,68,188Zm0-48a12,12,0,1,1,12-12A12,12,0,0,1,68,140Zm0-48A12,12,0,1,1,80,80,12,12,0,0,1,68,92Zm124,92H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Zm0-48H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Zm0-48H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M82,64a6,6,0,0,1,6-6H216a6,6,0,0,1,0,12H88A6,6,0,0,1,82,64Zm134,58H88a6,6,0,0,0,0,12H216a6,6,0,0,0,0-12Zm0,64H88a6,6,0,0,0,0,12H216a6,6,0,0,0,0-12ZM44,54A10,10,0,1,0,54,64,10,10,0,0,0,44,54Zm0,128a10,10,0,1,0,10,10A10,10,0,0,0,44,182Zm0-64a10,10,0,1,0,10,10A10,10,0,0,0,44,118Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M80,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H88A8,8,0,0,1,80,64Zm136,56H88a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Zm0,64H88a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16ZM44,52A12,12,0,1,0,56,64,12,12,0,0,0,44,52Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,116Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,180Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M84,64a4,4,0,0,1,4-4H216a4,4,0,0,1,0,8H88A4,4,0,0,1,84,64Zm132,60H88a4,4,0,0,0,0,8H216a4,4,0,0,0,0-8Zm0,64H88a4,4,0,0,0,0,8H216a4,4,0,0,0,0-8ZM44,120a8,8,0,1,0,8,8A8,8,0,0,0,44,120Zm0-64a8,8,0,1,0,8,8A8,8,0,0,0,44,56Zm0,128a8,8,0,1,0,8,8A8,8,0,0,0,44,184Z`}))]]),_i=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M28,64A12,12,0,0,1,40,52H216a12,12,0,0,1,0,24H40A12,12,0,0,1,28,64Zm12,76h64a12,12,0,0,0,0-24H40a12,12,0,0,0,0,24Zm80,40H40a12,12,0,0,0,0,24h80a12,12,0,0,0,0-24Zm120.49,20.49a12,12,0,0,1-17,0l-18.08-18.08a44,44,0,1,1,17-17l18.08,18.07A12,12,0,0,1,240.49,200.49ZM184,164a20,20,0,1,0-20-20A20,20,0,0,0,184,164Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,144a32,32,0,1,1-32-32A32,32,0,0,1,216,144Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,13.66a8,8,0,0,1-11.32,0L206,177.36A40,40,0,1,1,217.36,166l20.3,20.3A8,8,0,0,1,237.66,197.66ZM184,168a24,24,0,1,0-24-24A24,24,0,0,0,184,168Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,2.34L217.36,166A40,40,0,1,0,206,177.36l20.3,20.3a8,8,0,0,0,11.32-11.32Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M34,64a6,6,0,0,1,6-6H216a6,6,0,0,1,0,12H40A6,6,0,0,1,34,64Zm6,70h72a6,6,0,0,0,0-12H40a6,6,0,0,0,0,12Zm88,52H40a6,6,0,0,0,0,12h88a6,6,0,0,0,0-12Zm108.24,10.24a6,6,0,0,1-8.48,0l-21.49-21.48a38.06,38.06,0,1,1,8.49-8.49l21.48,21.49A6,6,0,0,1,236.24,196.24ZM184,170a26,26,0,1,0-26-26A26,26,0,0,0,184,170Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,13.66a8,8,0,0,1-11.32,0L206,177.36A40,40,0,1,1,217.36,166l20.3,20.3A8,8,0,0,1,237.66,197.66ZM184,168a24,24,0,1,0-24-24A24,24,0,0,0,184,168Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M36,64a4,4,0,0,1,4-4H216a4,4,0,0,1,0,8H40A4,4,0,0,1,36,64Zm4,68h72a4,4,0,0,0,0-8H40a4,4,0,0,0,0,8Zm88,56H40a4,4,0,0,0,0,8h88a4,4,0,0,0,0-8Zm106.83,6.83a4,4,0,0,1-5.66,0l-22.72-22.72a36.06,36.06,0,1,1,5.66-5.66l22.72,22.72A4,4,0,0,1,234.83,194.83ZM184,172a28,28,0,1,0-28-28A28,28,0,0,0,184,172Z`}))]]),vi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M156,112a12,12,0,0,1-12,12H80a12,12,0,0,1,0-24h64A12,12,0,0,1,156,112Zm76.49,120.49a12,12,0,0,1-17,0L168,185a92.12,92.12,0,1,1,17-17l47.54,47.53A12,12,0,0,1,232.49,232.49ZM112,180a68,68,0,1,0-68-68A68.08,68.08,0,0,0,112,180Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Zm112,0a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h64A8,8,0,0,1,152,112Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM144,120H80a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M150,112a6,6,0,0,1-6,6H80a6,6,0,0,1,0-12h64A6,6,0,0,1,150,112Zm78.24,116.24a6,6,0,0,1-8.48,0l-51.38-51.38a86.15,86.15,0,1,1,8.48-8.48l51.38,51.38A6,6,0,0,1,228.24,228.24ZM112,186a74,74,0,1,0-74-74A74.09,74.09,0,0,0,112,186Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M152,112a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h64A8,8,0,0,1,152,112Zm77.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88.11,88.11,0,1,1,11.31-11.31l50.07,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M148,112a4,4,0,0,1-4,4H80a4,4,0,0,1,0-8h64A4,4,0,0,1,148,112Zm78.83,114.83a4,4,0,0,1-5.66,0l-52.7-52.7a84.1,84.1,0,1,1,5.66-5.66l52.7,52.7A4,4,0,0,1,226.83,226.83ZM112,188a76,76,0,1,0-76-76A76.08,76.08,0,0,0,112,188Z`}))]]),yi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M230.47,67.5a12,12,0,0,0-19.26-4.32L172.43,99l-12.68-2.72L157,83.57l35.79-38.78a12,12,0,0,0-4.32-19.26A76.07,76.07,0,0,0,88.41,121.64L30.92,174.18a4.68,4.68,0,0,0-.39.38,36,36,0,0,0,50.91,50.91l.38-.39,52.54-57.49A76.05,76.05,0,0,0,230.47,67.5ZM160,148a51.5,51.5,0,0,1-23.35-5.52,12,12,0,0,0-14.26,2.62L64.31,208.66a12,12,0,0,1-17-17l63.55-58.07a12,12,0,0,0,2.62-14.26A51.5,51.5,0,0,1,108,96a52.06,52.06,0,0,1,52-52h.89L135.17,71.87a12,12,0,0,0-2.91,10.65l5.66,26.35a12,12,0,0,0,9.21,9.21l26.35,5.66a12,12,0,0,0,10.65-2.91L212,95.12c0,.3,0,.59,0,.89A52.06,52.06,0,0,1,160,148Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,96a64,64,0,0,1-94.94,56L73,217A24,24,0,0,1,39,183L104,126.94a64,64,0,0,1,80-90.29L144,80l5.66,26.34L176,112l43.35-40A63.8,63.8,0,0,1,224,96Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M226.76,69a8,8,0,0,0-12.84-2.88l-40.3,37.19-17.23-3.7-3.7-17.23,37.19-40.3A8,8,0,0,0,187,29.24,72,72,0,0,0,88,96,72.34,72.34,0,0,0,94,124.94L33.79,177c-.15.12-.29.26-.43.39a32,32,0,0,0,45.26,45.26c.13-.13.27-.28.39-.42L131.06,162A72,72,0,0,0,232,96,71.56,71.56,0,0,0,226.76,69ZM160,152a56.14,56.14,0,0,1-27.07-7,8,8,0,0,0-9.92,1.77L67.11,211.51a16,16,0,0,1-22.62-22.62L109.18,133a8,8,0,0,0,1.77-9.93,56,56,0,0,1,58.36-82.31l-31.2,33.81a8,8,0,0,0-1.94,7.1L141.83,108a8,8,0,0,0,6.14,6.14l26.35,5.66a8,8,0,0,0,7.1-1.94l33.81-31.2A56.06,56.06,0,0,1,160,152Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M232,96a72,72,0,0,1-100.94,66L79,222.22c-.12.14-.26.29-.39.42a32,32,0,0,1-45.26-45.26c.14-.13.28-.27.43-.39L94,124.94a72.07,72.07,0,0,1,83.54-98.78,8,8,0,0,1,3.93,13.19L144,80l5.66,26.35L176,112l40.65-37.52a8,8,0,0,1,13.19,3.93A72.6,72.6,0,0,1,232,96Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224.91,69.75a6,6,0,0,0-9.63-2.16l-41.07,37.9L154.7,101.3l-4.19-19.51,37.9-41.07a6,6,0,0,0-2.16-9.63,70,70,0,0,0-89.77,94.39l-61.39,53c-.11.09-.21.19-.32.3A30,30,0,0,0,77.2,221.23c.11-.11.21-.21.3-.32l53-61.39a70,70,0,0,0,94.39-89.77ZM160,154a58,58,0,0,1-28-7.22,6,6,0,0,0-7.45,1.33L68.57,212.88a18,18,0,0,1-25.45-25.45l64.76-55.94A6,6,0,0,0,109.2,124a58,58,0,0,1,64-84.53L139.58,75.93a6,6,0,0,0-1.45,5.33l5.65,26.35a6,6,0,0,0,4.61,4.61l26.35,5.65a6,6,0,0,0,5.33-1.45L216.49,82.8A58.06,58.06,0,0,1,160,154Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M226.76,69a8,8,0,0,0-12.84-2.88l-40.3,37.19-17.23-3.7-3.7-17.23,37.19-40.3A8,8,0,0,0,187,29.24,72,72,0,0,0,88,96,72.34,72.34,0,0,0,94,124.94L33.79,177c-.15.12-.29.26-.43.39a32,32,0,0,0,45.26,45.26c.13-.13.27-.28.39-.42L131.06,162A72,72,0,0,0,232,96,71.56,71.56,0,0,0,226.76,69ZM160,152a56.14,56.14,0,0,1-27.07-7,8,8,0,0,0-9.92,1.77L67.11,211.51a16,16,0,0,1-22.62-22.62L109.18,133a8,8,0,0,0,1.77-9.93,56,56,0,0,1,58.36-82.31l-31.2,33.81a8,8,0,0,0-1.94,7.1L141.83,108a8,8,0,0,0,6.14,6.14l26.35,5.66a8,8,0,0,0,7.1-1.94l33.81-31.2A56.06,56.06,0,0,1,160,152Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M223.05,70.5a4,4,0,0,0-6.42-1.44l-41.82,38.6L153,103l-4.68-21.79,38.6-41.82a4,4,0,0,0-1.44-6.43A68,68,0,0,0,98.94,126L36.4,180l-.21.2a28,28,0,0,0,39.6,39.6l.2-.21,54-62.54A68,68,0,0,0,228,96,67.51,67.51,0,0,0,223.05,70.5ZM160,156a60,60,0,0,1-29-7.47,4,4,0,0,0-5,.89L70,214.25A20,20,0,0,1,41.75,186l64.82-56a4,4,0,0,0,.89-5,60,60,0,0,1,69.46-86.59L141.05,77.29a4,4,0,0,0-1,3.55l5.66,26.35a4,4,0,0,0,3.07,3.07l26.35,5.66a4,4,0,0,0,3.55-1l38.87-35.87A60.05,60.05,0,0,1,160,156Z`}))]]),bi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:si}));bi.displayName=`ArrowClockwiseIcon`;var xi=bi,Si=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:ci}));Si.displayName=`ArrowCounterClockwiseIcon`;var Ci=Si,wi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:li}));wi.displayName=`ArrowsOutIcon`;var Ti=wi,Ei=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:ui}));Ei.displayName=`CaretUpIcon`;var Di=Ei,Oi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:di}));Oi.displayName=`ChatCircleTextIcon`;var ki=Oi,Ai=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:fi}));Ai.displayName=`ClockIcon`;var ji=Ai,Mi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:pi}));Mi.displayName=`ClockCounterClockwiseIcon`;var Ni=Mi,Pi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:mi}));Pi.displayName=`InfoIcon`;var Fi=Pi,Ii=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:hi}));Ii.displayName=`KeyboardIcon`;var Li=Ii,Ri=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:gi}));Ri.displayName=`ListBulletsIcon`;var zi=Ri,Bi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:_i}));Bi.displayName=`ListMagnifyingGlassIcon`;var Vi=Bi,Hi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:vi}));Hi.displayName=`MagnifyingGlassMinusIcon`;var Ui=Hi,Wi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:yi}));Wi.displayName=`WrenchIcon`;var Gi=Wi,Ki=i(b(),1),qi=`$__all`;function Ji(e,t,n){if(e.kind===`constant`)return e.value??``;let r=e.kind===`custom`?e.options?.map(e=>({value:e}))??[]:n===null?[]:n,i=t[e.name],a=!e.multi&&Array.isArray(i)&&i.length===0?void 0:i;if(a===`$__all`){if(e.include_all)return qi}else if(a!==void 0){if(e.kind===`text`||r===void 0)return a;let t=new Set(r.map(e=>e.value));if(Array.isArray(a)){if(a.length===0&&e.multi)return[];let n=a.filter(e=>t.has(e));if(n.length>0)return n}else if(t.has(a))return a}return e.default?e.default:e.include_all?qi:r?.[0]?.value??``}var Yi=(e,t)=>e.replace(/\$([a-z][a-z0-9_]*)/g,(e,n)=>{let r=t[n];return r===void 0?e:r===`$__all`?`all`:Array.isArray(r)?r.join(`, `):r});function Xi(e,t,n){let r={};for(let i of e??[]){let e=Ji(i,t,n?.[i.name]);(i.kind!==`query`||e!==``)&&(r[i.name]=e)}return r}function Zi(e){return Array.from({length:e.rows},(t,n)=>Object.fromEntries(e.columns.map((t,r)=>{let i=e.values[r]?.[n]??null;return[t.name,typeof i==`number`&&!Number.isFinite(i)?null:i]})))}function Qi(e,t){return e.viz!==`logs`||!t||t.rows<2?[]:t.columns.flatMap((e,n)=>{if(e.role!==`dimension`||e.type!==`string`||[`body`,`body_template`,`severity`,`status`].includes(e.name)||/(^id$|_id$)/.test(e.name))return[];let r=t.values[n][0];return typeof r==`string`&&r!==``&&t.values[n].slice(0,t.rows).every(e=>e===r)?[{name:e.name,value:r}]:[]})}function $i(e,t){let n=t.frame??{columns:[],values:[],rows:0};return{columns:n.columns.map(e=>e.name),rows:Zi(n),selection:t=>{let n={};for(let r of e.query?.by??[]){let e=r.startsWith(`attributes[`)||r.startsWith(`resource[`)?r.slice(r.indexOf(`'`)+1,r.lastIndexOf(`'`)):r;t[e]!==void 0&&t[e]!==null&&(n[r]=String(t[e]))}return{time:typeof t.time==`number`?t.time:typeof t.start==`number`?t.start:void 0,dimensions:n,trace_id:typeof t.trace_id==`string`?t.trace_id:void 0,namespace:typeof t.namespace==`string`?t.namespace:void 0}}}}function ea(e){return e.replace(/[&<>"']/g,e=>({"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`})[e])}var ta=e=>e.map(ea).join(`
`);function na(e,t=!1){return n=>{let r=Array.isArray(n)?n:[n];return ta([...r[0]?.axisValueLabel?[r[0].axisValueLabel]:[],...r.map(n=>{let r=n.value,i=Array.isArray(r)?t?r.slice(1):r:[r];return`${n.seriesName??``}${n.name?` · ${n.name}`:``}: ${i.map(t=>typeof t==`number`?e(t,n.seriesName):String(t??`—`)).join(` · `)}`})])}}var ra=e=>/^Other(?: \(\d+\))?$/.test(e??``);function ia(e,t){let n=Math.min(6,Math.max(1,Math.floor(t.options?.top||6))),r=e.filter(e=>!ra(e.name)),i=r.slice(0,n).map(e=>({name:e.name,items:[e]})),a=[...e.filter(e=>ra(e.name)),...r.slice(n)];return a.length&&i.push({name:a.length===1&&ra(a[0].name)?a[0].name:`Other (${a.reduce((e,t)=>e+(ra(t.name)?Number(t.name.match(/\d+/)?.[0]??1):1),0)})`,items:a}),i}function aa(e){let t=e.filter(e=>e!==null);return t.length?t.reduce((e,t)=>e+t,0):null}function oa(e,t){let n=Math.min(6,Math.max(1,Math.floor(t.options?.top||6))),r=e.filter(e=>!ra(e.name));return{shown:[...r.slice(0,n),...e.filter(e=>ra(e.name))],hidden:Math.max(0,r.length-n)}}function sa(e,t){return e>0?[{type:`text`,right:8,bottom:2,silent:!0,style:{text:`${e} more series not shown`,fill:t,fontSize:11}}]:[]}function ca(e,t,n,r,i=`sans-serif`,a){let o=e=>Array.from(e).length>24?`${Array.from(e).slice(0,23).join(``)}…`:e,s=Math.max(1,t-16),c=1,l=0;for(let t of e){let e=15+(a?.(o(t),`12px ${i}`)??Array.from(o(t)).length*7.2);l&&l+10+e>s&&(c++,l=0),l+=(l?10:0)+e}let u=c>2;return{top:n?u?30:c*20+2:12,option:{type:u?`scroll`:`plain`,show:n,top:0,left:0,right:0,padding:0,itemGap:6,icon:`roundRect`,itemWidth:10,itemHeight:10,itemStyle:{borderColor:r,borderWidth:1},textStyle:{color:r,fontSize:12,lineHeight:14},data:e,formatter:o,tooltip:{show:!0,renderMode:`html`,formatter:e=>ea(e.name)}}}}function la(e,t){if(!(!Number.isFinite(e)||!Number.isFinite(t)||e>=t||Math.abs(e)>864e13||Math.abs(t)>864e13))return{from:new Date(Math.floor(e)).toISOString(),to:new Date(Math.ceil(t)).toISOString()}}function ua(e){let t=[e.time?.range?`Range ${e.time.range}`:void 0,e.time?.shift?`Shifted ${e.time.shift}`:void 0].filter(Boolean);return t.length?t.join(` · `):void 0}function da(e,t,n){if(n.interactive===!1||n.data?.value===null)return;let r=n.data?.selection;if(r)return Object.values(r.dimensions).some(ra)?void 0:r;if(ra(n.seriesName)||ra(n.name)||n.value===null||Array.isArray(n.value)&&n.value.at(-1)==null)return;let i=e.query?.by?.[0]??t.frame?.columns.find(e=>e.role===`dimension`)?.name,a=e.viz===`timeseries`?n.seriesName:n.name,o=Array.isArray(n.value)?n.value:[];return{time:e.viz===`timeseries`&&typeof o[0]==`number`?o[0]:void 0,dimensions:i&&a?{[i]:a}:{}}}var fa=new Intl.NumberFormat(`en`,{notation:`compact`,maximumFractionDigits:1}),pa=new Intl.NumberFormat(`en`,{maximumFractionDigits:2});function ma(e){return Math.abs(e)<1e-4?e.toExponential(2).replace(/\.?(0+)(?=e)/,``):String(Number(e.toPrecision(3)))}function ha(e,t=pa){return e!==0&&Math.abs(e)<1?ma(e):t.format(e)}function ga(e,t){let n=t===`s`?e*1e3:t===`ns`?e/1e6:e;return e!==0&&n===0?`${ma(e)}${t}`:n!==0&&Math.abs(n)<1?`${ma(n)}ms`:ve(n)}function _a(e){let t=[`B`,`KiB`,`MiB`,`GiB`,`TiB`],n=e,r=0;for(;Math.abs(n)>=1024&&r=1e4?fa:pa);default:return ha(t,Math.abs(t)>=1e4?fa:pa)}}function ya(e){return t=>e===`ms`||e===`s`||e===`ns`?va(e,t).replace(/(\.\d*?)0+([a-z]*)$/,`$1$2`).replace(/\.([a-z]*)$/,`$1`):va(e,t)}function ba(e,t){return ya(e)(t??NaN).replace(/(?<=\d)(ms|ns|s|m|h)\b/g,` $1`)}function xa(e){return Math.max(3,Math.min(10,Math.round(e/70)))-1}function Sa(e,t){let n=t===`ms`?1:t===`s`?1e3:t===`ns`?1e-6:void 0,r=e=>{let t=10**Math.floor(Math.log10(e));return[1,2,5,10].map(e=>e*t).find(t=>t>=e)};if(n===void 0)return r(e);let i=e*n,a=[1,10,100,1e3,1e4,6e4,6e5,36e5,36e6].flatMap(e=>[1,2,5].map(t=>e*t)).sort((e,t)=>e-t);return(i<1?r(i):a.find(e=>e>=i)??r(i/36e5)*36e5)/n}function Ca(e,t,n,r){e=Number.isFinite(e)?Math.min(0,e):0,t=Number.isFinite(t)?Math.max(0,t):1,t===e&&(t=e+1);let i=xa(r),a=Sa(Math.max(t-e,2**-52)/i,n);for(;Math.ceil(t/a)-Math.floor(e/a)>i;)a=Sa(a*1.01,n);return{min:Math.floor(e/a)*a,max:Math.ceil(t/a)*a,interval:a,splitNumber:i,fanout_unit:n}}function wa(e,t){return e.type!==`value`&&e.type!==`log`?e:{...e,...e.type===`value`&&typeof e.min==`number`&&typeof e.max==`number`?Ca(e.min,e.max,typeof e.fanout_unit==`string`?e.fanout_unit:void 0,t):{splitNumber:xa(t)}}}function Ta(e,t,n){let r=e=>va(n,e),i=``;if(n===`ms`||n===`s`||n===`ns`){let a=n===`s`?1e3:n===`ns`?1e-6:1,o=Math.abs((e??t??0)*a),s=o>=6e4?6e4:o>=1e3?1e3:1;i=s===6e4?` min`:s===1e3?` s`:` ms`;let c=s===6e4?1:s===1e3?+(o<1e4):2,l=new Intl.NumberFormat(void 0,{maximumFractionDigits:c});r=e=>l.format(e*a/s)}return t===null&&e!==null?`≥${r(e)}${i}`:(e===null||e===0)&&t!==null?`<${r(t)}${i}`:`${e===null?`−∞`:r(e)}–${t===null?`∞`:r(t)}${i}`}function Ea(e){let t=new Date(e);return t.getHours()===0&&t.getMinutes()===0&&t.getSeconds()===0?t.toLocaleDateString(void 0,{month:`short`,day:`numeric`}):t.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`})}function Da(e,t=new Date,n){let r=new Date(e);if(!Number.isFinite(r.getTime()))return`—`;let i=new Intl.DateTimeFormat(n,{month:`short`,day:`numeric`,...r.getFullYear()===t.getFullYear()?{}:{year:`numeric`},hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hourCycle:`h23`}).formatToParts(r),a=i.filter(e=>[`month`,`day`,`year`].includes(e.type)).map(e=>e.value),o=i.filter(e=>[`hour`,`minute`,`second`].includes(e.type)).map(e=>e.value);return`${a.join(` `)} ${o.join(`:`)}`}function Oa({panel:e,result:t}){let n=t?.frame;return(0,H.jsxs)(`div`,{"data-panel-data":!0,children:[t?.error&&(0,H.jsx)(T,{"data-panel-error-detail":!0,size:`sm`,role:`status`,style:{whiteSpace:`pre-wrap`,overflowWrap:`anywhere`,userSelect:`text`},children:t.error}),n?(0,H.jsxs)(B,{fz:12,striped:!0,children:[(0,H.jsx)(B.Thead,{children:(0,H.jsx)(B.Tr,{children:n.columns.map(e=>(0,H.jsx)(B.Th,{ff:xt.display,children:e.name},e.name))})}),(0,H.jsx)(B.Tbody,{children:Array.from({length:Math.min(n.rows,500)},(t,r)=>(0,H.jsx)(B.Tr,{children:n.columns.map((t,i)=>{let a=n.values[i][r];return(0,H.jsx)(B.Td,{ff:xt.display,children:a===null?`—`:t.type===`time`?new Date(Number(a)).toISOString():t.role===`measure`?va(t.unit??e.unit,Number(a)):String(a)},t.name)})},r))})]}):(0,H.jsx)(T,{c:`dimmed`,size:`sm`,children:`No data.`}),(0,H.jsxs)(T,{c:`dimmed`,fz:12,mt:8,children:[`Ran in `,t?.elapsed_ms??0,` ms`,t?.interval?`, one point per ${t.interval}`:``,n?`, ${n.rows} rows${n.truncated?` (truncated)`:``}`:``,`.`]}),(t?.sql??e.sql)&&(0,H.jsx)(Le,{block:!0,tabIndex:0,mt:8,children:t?.sql??e.sql})]})}function ka({panel:e,dark:t}){let n=JSON.stringify(e,null,2).split(/("(?:[^"\\]|\\.)*"(?=\s*:)|"(?:[^"\\]|\\.)*"|\b(?:true|false|null)\b|-?\d+(?:\.\d+)?)/g);return(0,H.jsx)(`pre`,{"data-panel-spec":!0,style:{margin:0,fontFamily:xt.display,fontSize:12,color:it[t?`dark`:`light`].text},children:n.map((e,r)=>{let i=e.startsWith(`"`)&&/^\s*:/.test(n[r+1]??``)?`key`:e.startsWith(`"`)?`string`:/^(true|false|null)$/.test(e)?`literal`:/^-?\d/.test(e)?`number`:`punctuation`,a=i===`key`?pt[t?4:7]:i===`string`?st[t?4:8]:i===`number`||i===`literal`?Et[t?4:8]:void 0;return i===`punctuation`?e:(0,H.jsx)(`span`,{"data-json-token":i,style:{color:a},children:e},r)})})}function Aa(e){let t=e.event.data?.selection,n=e.event.value;return JSON.stringify([e.event.seriesName,e.event.name,t?.from??t?.time??(Array.isArray(n)?n[0]:void 0),t?.dimensions,t?.bucket])}function ja(e){let t=new Date().toISOString().slice(0,10),n=e.from.slice(0,10),r=e.to.slice(0,10),i=e=>e.slice(11,-1).replace(/\.000$/,``);return`${(n===t?``:n+` `)+i(e.from)} – ${(r!==n&&r!==t?r+` `:``)+i(e.to)} UTC · ${ve(Date.parse(e.to)-Date.parse(e.from))}`}var Ma={background:`color-mix(in srgb, var(--mantine-color-body) 92%, transparent)`,border:`1px solid var(--mantine-color-default-border)`,borderRadius:`var(--mantine-radius-sm)`,padding:`2px 6px`};function Na(e){return e.replace(`Enter drill`,`↵ drill`).replace(`Shift+←→`,`⇧←→`)}var Pa=(0,V.createContext)(void 0);function Fa({points:e,label:t,summary:n,children:r,onClick:i,canSelect:a,onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d,rangeReset:f,height:p=`100%`,onZoom:m,bounds:h,pointWindow:g}){let[_,v]=(0,V.useState)(!1),[b,x]=(0,V.useState)(``),[S,w]=(0,V.useState)(),[E,D]=(0,V.useState)(null),O=(0,V.useRef)(null),k=(0,V.useRef)(!1);(0,V.useEffect)(()=>{let e=e=>{e.key===`Tab`&&(k.current=!1)};return document.addEventListener(`keydown`,e,!0),()=>document.removeEventListener(`keydown`,e,!0)},[]);let A=(0,V.useId)(),j=(0,V.useContext)(Pa),M=(0,V.useRef)(null),N=(0,V.useRef)({onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d});N.current={onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d};let P=(0,V.useMemo)(()=>new Map(e.map(e=>[Aa(e),e])),[e]),F=(0,V.useRef)(void 0),I=e=>g?.(e)?.from??e.event.name??(Array.isArray(e.event.value)?e.event.value[0]:void 0),L=F.current,ee=L?e.filter(e=>e.event.seriesName===L.event.seriesName):e,te=ee.length?ee:e,ne=L&&I(L),re=typeof ne==`number`?te.reduce((e,t)=>{let n=I(t),r=e&&I(e);return typeof n==`number`&&(!e||typeof r!=`number`||Math.abs(n-ne)I(e)===ne),ie=S?P.get(S)??re??te[0]??e[0]:e[0],ae=!!(m&&h&&Number.isFinite(h.from)&&Number.isFinite(h.to)&&h.from[...new Set(e.map(e=>e.event.seriesName))],[e]),oe=(0,V.useMemo)(()=>e.filter(e=>e.event.seriesName===ie?.event.seriesName),[e,ie?.event.seriesName]),z=ie?oe.indexOf(ie):-1;(0,V.useEffect)(()=>{ie&&(!S||P.has(S)||!ee.length)&&(F.current=ie,(!S||!ee.length)&&w(Aa(ie))),_&&N.current.onHighlight(ie)},[ie,S,_]),(0,V.useEffect)(()=>{if(!E)return;let e=Date.parse(E.from),t=Date.parse(E.to);h&&(Number.isFinite(e)&&eh.to)&&D(null)},[h?.from,h?.to,E]),(0,V.useEffect)(()=>{N.current.onRangePending?.(!!E)},[!!E]),(0,V.useEffect)(()=>{N.current.onRangeChange?.(E?{from:Date.parse(E.from),to:Date.parse(E.to)}:void 0)},[E]),(0,V.useEffect)(()=>{D(null)},[f]),(0,V.useEffect)(()=>()=>{N.current.onHighlight(void 0),N.current.onRangePending?.(!1),N.current.onRangeChange?.(void 0)},[]);let se=(e,t=!1)=>{if(e){if(x(n(e)),t&&ae&&ie){let t=E?.anchor??Aa(ie),n=P.get(t),r=E?.window??(n&&g?.(n)),i=g?.(e);if(r&&i){let e=Math.max(h.from,Math.min(r.from,i.from)),n=Math.min(h.to,Math.max(r.to,i.to));Number.isFinite(e)&&Number.isFinite(n)&&e{if(!ie)return;let n=R[Math.max(0,Math.min(R.length-1,R.indexOf(ie.event.seriesName)+t))],r=e.filter(e=>e.event.seriesName===n),i=I(ie),a=r.find(e=>I(e)===i),o=typeof i==`number`?r.reduce((e,t)=>{let n=I(t),r=e&&I(e);return typeof n==`number`&&(!e||typeof r!=`number`||Math.abs(n-i){e===`ArrowLeft`||e===`ArrowRight`?se(oe[Math.max(0,Math.min(oe.length-1,z+(e===`ArrowLeft`?-1:1)))],t):!t&&(e===`ArrowUp`||e===`ArrowDown`)?ce(e===`ArrowUp`?-1:1):!t&&(e===`Home`||e===`End`)&&se(e===`Home`?oe[0]:oe.at(-1))},ue=()=>{D(null),O.current?.focus()},de=ae?`←→ points · ↑↓ series · Enter drill · Shift+←→ range`:`←→ points · ↑↓ series · Enter drill`;return(0,V.useLayoutEffect)(()=>(j?.setHint(_?de:void 0),()=>j?.setHint(void 0)),[j,_,de]),(0,V.useLayoutEffect)(()=>{let e=M.current;if(!e)return;N.current.onRangeBarHeight?.(e.getBoundingClientRect().height);let t=new ResizeObserver(([t])=>{if(!t)return;let n=getComputedStyle(e),r=[n.paddingTop,n.paddingBottom,n.borderTopWidth,n.borderBottomWidth].reduce((e,t)=>e+(parseFloat(t)||0),0);N.current.onRangeBarHeight?.(t.borderBoxSize?.[0]?.blockSize??t.contentRect.height+r)});return t.observe(e),()=>{t.disconnect(),N.current.onRangeBarHeight?.(0)}},[!!(E&&ae)]),(0,H.jsxs)(o,{ref:O,"data-chart-plot":!0,tabIndex:0,role:`application`,"aria-roledescription":`chart`,"aria-label":t,"aria-describedby":A,"data-mantine-stop-propagation":E?`true`:void 0,className:`chart-keyboard-point`,style:{position:`relative`,height:p,width:`100%`,flex:`1 1 auto`,minHeight:0,minWidth:0},onPointerDownCapture:e=>{M.current?.contains(e.target)||(k.current=!0,v(!1),_&&N.current.onHighlight(void 0),N.current.onActiveChange?.(!1))},onFocus:e=>{e.target!==e.currentTarget||k.current||(N.current.onActiveChange?.(!0),v(!0))},onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||(v(!1),D(null),x(``),N.current.onHighlight(void 0),N.current.onActiveChange?.(!1))},onKeyDown:e=>{if(e.defaultPrevented||e.ctrlKey||e.metaKey||e.altKey||e.nativeEvent.isComposing)return;if(e.key===`Escape`&&!e.repeat){E?(e.preventDefault(),e.stopPropagation(),ue()):e.target===e.currentTarget&&!e.currentTarget.closest(`[data-panel-fullscreen],[data-fragment-fullscreen]`)&&(e.preventDefault(),e.stopPropagation(),e.currentTarget.blur());return}if(e.target!==e.currentTarget||e.repeat&&![`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`].includes(e.key))return;let t=[`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key);if(t&&!_&&(k.current=!1,v(!0),N.current.onActiveChange?.(!0),!ie)){e.preventDefault();return}e.key===`Enter`&&_&&!e.shiftKey&&ie&&i&&(!a||a(ie.event))?(e.preventDefault(),i(ie.event)):t&&(!e.shiftKey||e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),le(e.key,e.shiftKey))},children:[r,(0,H.jsx)(o,{"data-chart-overlay":!0,style:{position:`absolute`,inset:0,zIndex:1,pointerEvents:`none`,overflow:`hidden`},children:E&&ae&&(0,H.jsxs)(y,{ref:M,"data-chart-range-bar":!0,gap:6,style:{...Ma,position:`absolute`,bottom:4,left:4,right:4,maxHeight:`100%`,overflow:`auto`,pointerEvents:`auto`},children:[(0,H.jsx)(T,{"data-chart-range-label":!0,size:`xs`,title:E.from+` – `+E.to,truncate:!0,style:{flex:`1 1 140px`,minWidth:0},children:ja(E)}),(0,H.jsx)(C,{size:`compact-xs`,"data-mantine-stop-propagation":`true`,onClick:()=>{m(Date.parse(E.from),Date.parse(E.to)),ue()},children:`Zoom to range`}),(0,H.jsx)(C,{size:`compact-xs`,variant:`subtle`,"data-mantine-stop-propagation":`true`,onClick:ue,children:`Cancel`})]})}),(0,H.jsx)(Je,{id:A,children:de}),(0,H.jsx)(Je,{"aria-live":`polite`,"aria-atomic":`true`,children:b})]})}var Ia=new Set([`id`,`http`,`https`,`rpc`,`grpc`,`cpu`,`sql`,`url`,`uri`,`ip`,`io`,`db`,`gc`,`tls`,`api`]),La={ms:`ms`,ns:`ns`,s:`s`,us:`µs`,bytes:`bytes`,percent:`%`,ratio:`ratio`,per_second:`/s`,per_minute:`/min`},Ra={body_template:`message template`,parquet_index:`traces`};function za(e,t){let n=typeof e==`string`?e:e.name,r=t?.options?.columns?.find(e=>e.field===n)?.unit??(typeof e==`string`?void 0:e.unit)??(typeof e!=`string`&&e.role===`measure`?t?.unit:void 0),i=Ra[n]??n;/\b(?:duckdb|parquet|sqlite|variant|timestamptz_ns|timestamp_ns)\b|\btelemetry\./i.test(i)&&(i=`value`),i=i.replace(/^(\w+)\(([^()]*)\)$/,(e,t,n)=>[t,n].filter(Boolean).join(`_`));let a=i.match(/_(ms|ns|us|s|bytes|percent)$/i);a&&(i=i.slice(0,-a[0].length));let o=r??a?.[1]?.toLowerCase();return i=i.split(`_`).map((e,t)=>/^p\d+$/i.test(e)||Ia.has(e.toLowerCase())?e.toUpperCase():t===0?e.charAt(0).toUpperCase()+e.slice(1):e).join(` `),i+(o&&o!==`none`&&o!==`count`?` (${La[o]??o})`:``)}function Ba(e){return e===`healthy`?`ok`:e===`degraded`?`warn`:e===`unknown`?`gray`:`bad`}function Va(e){return it[e?`dark`:`light`]}function Ha(e){let t=e?5:7;return{ok:st[t],warn:lt[t],bad:wt[t],info:Et[t]}}function Ua(e,t){return _t[t?`dark`:`light`][e]??Va(t).muted}function Wa(e){return e===`unhealthy`?`diamond`:e===`degraded`?`roundRect`:`circle`}function Ga(e){return e===`unknown`?`dashed`:`solid`}var Ka=e=>typeof e==`number`&&Number.isFinite(e)?e:null;function qa(e){return e.columns.flatMap((e,t)=>e.role===`measure`?[t]:[])}function Ja(e){let t=e.columns.findIndex(e=>e.role===`time`);if(t<0)return[];let n=e.columns.findIndex(e=>e.role===`dimension`),r=qa(e);if(n>=0&&r.length>0){let i=r[0],a=new Map;for(let r=0;r({name:e.columns[n].name,unit:e.columns[n].unit,points:e.values[t].map((t,r)=>[Number(t),Ka(e.values[n][r])])}))}function Ya(e){let t=e.columns.flatMap((e,t)=>e.role===`dimension`?[t]:[]),n=qa(e);if(t.length===0||n.length===0)return{categories:[],series:[]};let r=t[0],i=[];for(let t=0;t1){let a=t[1],o=n[0],s=new Map;for(let t=0;tnull)),s.get(n)[i.indexOf(String(e.values[r][t]??``))]=Ka(e.values[o][t])}return{categories:i,series:[...s.entries()].map(([t,n])=>({name:t,unit:e.columns[o].unit,values:n}))}}return{categories:i,series:n.map(t=>({name:e.columns[t].name,unit:e.columns[t].unit,values:e.values[t].map(Ka)}))}}function Xa(e,t){let n=e.filter(e=>e!==null);if(n.length===0)return null;switch(t){case`last`:return n[n.length-1];case`min`:return Math.min(...n);case`max`:return Math.max(...n);case`sum`:return n.reduce((e,t)=>e+t,0);default:return n.reduce((e,t)=>e+t,0)/n.length}}function Za(e,t){let n=qa(t)[0];return n===void 0?null:(e.reduce??`window`)===`window`?t.totals?Ka(t.totals[n]):Xa(t.values[n].map(Ka),`mean`):Xa(t.values[n].map(Ka),e.reduce??`mean`)}function Qa(e){let t=qa(e)[0];return t===void 0?[]:e.values[t].map(Ka)}var $a={ok:0,warn:1,bad:2};function eo(e){if(!e?.length)return;let t=[...e].sort((e,t)=>$a[e.status]-$a[t.status]),n=t[0],r=t[t.length-1];return $a[r.status]>$a[n.status]&&r.value!==n.value?r.value>n.value?`lower`:`higher`:`lower`}function to(e,t,n){if(e===null||!t||t.length===0)return null;n??=eo(t);let r=`ok`;for(let i of t)(n===`lower`?e>=i.value:e<=i.value)&&$a[i.status]>$a[r]&&(r=i.status);return r}function no(e,t){let n=yt(e),r=yt(t);return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}function ro(e,t){return`rgba(${[1,3,5].map(t=>parseInt(e.slice(t,t+2),16)).join(`, `)}, ${t})`}function io(e,t){return{color:e,...no(e,t.surface)<3?{borderColor:t.text,borderWidth:1}:{}}}function ao(e,t){return{color:e,...no(e,t.surface)<3?{shadowColor:t.text,shadowBlur:2}:{}}}function oo(e,t){return{ok:st,warn:lt,bad:wt}[e][t?5:8]}function so(e){let t=Va(e),n=Ha(e);return{dark:e,text:t.text,muted:t.muted,grid:t.grid,surface:t.surface,border:t.border,status:{ok:n.ok,warn:n.warn,bad:n.bad},font:xt.display}}function co(e,t,n){if(!Array.isArray(e.series))return e;let r=e.series,i=Array.isArray(e.yAxis)?e.yAxis:[e.yAxis],a=[],o=r.map((e,o)=>{let s=e.endLabel;if(!s?.show||!Array.isArray(e.data))return e;let c;for(let t=e.data.length-1;t>=0;t--){let n=e.data[t];if(Array.isArray(n)&&typeof n[1]==`number`&&Number.isFinite(n[1])){c=n;break}}let l=i[Number(e.yAxisIndex??0)];if(!c||!l)return{...e,endLabel:{...s,show:!1}};let u=l.type===`log`?Math.log:e=>e,d=l.min??1/0,f=l.max??0;if(l.type===`log`&&(l.min===void 0||l.max===void 0)){for(let t of r)if(Number(t.yAxisIndex??0)===Number(e.yAxisIndex??0)&&Array.isArray(t.data))for(let e of t.data)Array.isArray(e)&&typeof e[1]==`number`&&Number.isFinite(e[1])&&e[1]>0&&(l.min===void 0&&(d=Math.min(d,e[1])),l.max===void 0&&(f=Math.max(f,e[1])))}Number.isFinite(d)||(d=1);let p=u(l.type===`log`?d:l.min??0),m=u(l.type===`log`?Math.max(f,d*1.01):l.max??1),h=n?.(o,c),g=Number.isFinite(h)?h:t.y+t.height*(1-(u(c[1])-p)/(m-p)),_=((s.lineHeight??14)+2)/2,v=[Math.max(t.y+_,Math.min(t.y+t.height-_,g)),...a.flatMap(e=>[e.y-e.half-_,e.y+e.half+_])].filter(e=>Number.isFinite(e)&&e-_>=t.y&&e+_<=t.y+t.height&&a.every(t=>Math.abs(t.y-e)>=t.half+_)).sort((e,t)=>Math.abs(e-g)-Math.abs(t-g))[0];return v===void 0?{...e,endLabel:{...s,show:!1}}:(a.push({y:v,half:_}),{...e,labelLayout:{dy:v-g,hideOverlap:!0}})});return{...e,series:o}}var lo=(e,t,n)=>ra(e)?n.muted:Ua(t,n.dark);function uo(e,t){let n=Ja(e);if(!e.columns.some(e=>e.role===`dimension`))for(let r of n)r.name=za(e.columns.find(e=>e.name===r.name)??r.name,t);return oa(n,t)}function fo(e,t){return{animationDuration:200,textStyle:{fontFamily:e.font,color:e.muted,fontSize:11},grid:{left:8,right:16,top:28,bottom:8,containLabel:!0},tooltip:{trigger:`axis`,formatter:na(e=>va(t,e)),confine:!0,backgroundColor:e.surface,borderColor:e.border,textStyle:{color:e.text,fontSize:12},valueFormatter:e=>va(t,e),axisPointer:{type:`line`,lineStyle:{color:e.border}}},aria:{enabled:!0}}}function po(e,t,n,r){return(e.thresholds??[]).map(i=>({yAxis:i.value,label:{formatter:`${i.label??i.status} ${ya(r??e.unit)(i.value).replace(/(?<=\d)(ms|s|m|h)$/,` $1`)}`,position:i.value<=(n.min+n.max)/2?`insideEndTop`:`insideEndBottom`,distance:8,color:t.muted,textBorderColor:t.surface,textBorderWidth:3,fontSize:12},lineStyle:{color:t.status[i.status],type:[4,3],width:1}}))}function mo(e,t,n,r={width:500,height:248}){let i=t.frame?uo(t.frame,e):{shown:[],hidden:0},a=i.shown,o=a[0]?.unit??e.unit,s=new Set(a.map(e=>e.name)),c=a.find(e=>ra(e.name)),l=t.previous&&t.shift_ms!==void 0?uo(t.previous,e).shown.flatMap(e=>ra(e.name)?c?[e]:[]:s.has(e.name)?[e]:[]):[],u=[...new Set([...a,...l].map(t=>t.unit??e.unit))];u.length===0&&u.push(e.unit);let d=e.options?.style??`line`,f=a.length>=2&&a.length<=6&&i.hidden===0&&d!==`bars`&&d!==`stacked`,p=f?Math.max(40,...a.map(e=>{let t=Array.from(e.name).slice(0,24).join(``);return r.measureText?.(t,`12px ${n.font}`)??Array.from(t).length*7.2}))+12:0,m=f?p+8:0,h=(e.options?.legend??`auto`)!==`hidden`&&a.length>1,g=ca(a.map(e=>e.name),r.width,h,n.text,n.font,r.measureText),_=r.height-g.top-(i.hidden?24:8)-22,v=Math.max(0,Math.floor(_/16)),y=t.shift_ms,b=u.map(t=>{let n=[...a,...l].filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.points.flatMap(([,e])=>e===null?[]:[e]));if(d===`stacked`){let r=new Map;for(let n of a.filter(n=>(n.unit??e.unit)===t))for(let[e,t]of n.points){let n=r.get(e)??{positive:0,negative:0};t!==null&&(t>0?n.positive+=t:n.negative+=t),r.set(e,n)}n.push(...[...r.values()].flatMap(e=>[e.positive,e.negative]))}return Ca(Math.min(0,...n),Math.max(0,...n),t,_)}),x=a.map((t,r)=>{let i=lo(t.name,r,n);return{name:t.name,interactive:!0,yAxisIndex:u.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:d===`bars`||d===`stacked`?`bar`:`line`,data:t.points,endLabel:f?{show:r0?{symbol:[`none`,`none`],silent:!0,data:po(e,n,b[0],o)}:void 0}}),S=y===void 0?[]:l.map(t=>({name:`${t.name} · previous`,interactive:!1,yAxisIndex:u.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:`line`,data:t.points.map(([e,t])=>[e+y,t]),showSymbol:!1,silent:!0,z:1,lineStyle:{width:1,type:`dashed`,color:n.muted},itemStyle:{color:n.muted}})),C=u.map((t,r)=>({...e.options?.scale===`log`?{splitNumber:xa(_)}:b[r],type:e.options?.scale===`log`?`log`:`value`,position:r===0?`left`:`right`,offset:Math.max(0,r-1)*56,axisLine:{show:!1},splitLine:{show:r===0,lineStyle:{color:n.grid}},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,hideOverlap:!0,formatter:ya(t)}}));return co({...fo(n,o),tooltip:{...fo(n,o).tooltip,formatter:na((t,n)=>va([...a,...l].find(e=>e.name===n||`${e.name} · previous`===n)?.unit??e.unit,t),!0)},legend:g.option,grid:{left:8,right:16+(f?m:0)+Math.max(0,u.length-2)*56,top:g.top,bottom:i.hidden?24:8,containLabel:!0},xAxis:{type:`time`,min:t.from_ms,max:t.to_ms,axisLine:{lineStyle:{color:n.grid}},axisTick:{show:!1},splitLine:{show:!1},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,hideOverlap:!0,formatter:Ea}},yAxis:C.length===1?C[0]:C,series:[...x,...S],graphic:sa(i.hidden,n.muted)},{y:g.top,height:_})}function ho(e,t,n){if(n(e)<=t)return e;let r=Array.from(e);for(let e=r.length-1;e>0;e--){let i=Math.floor(e*.45),a=e-i,o=r.slice(0,i).join(``)+`…`+r.slice(-a).join(``);if(n(o)<=t)return o}return`…`}function go(e,t,n,r={width:500,height:248}){let i=Ya(t);if(t.columns.filter(e=>e.role===`dimension`).length<2)for(let n of i.series)n.name=za(t.columns.find(e=>e.name===n.name)??n.name,e);let a=i.categories,{shown:o,hidden:s}=oa(i.series,e),c=t.columns.flatMap((e,t)=>e.role===`dimension`?[t]:[]),l=new Map;for(let n=0;nString(t.values[e][n]??``))),{dimensions:r,...i})}let u=o[0]?.unit??e.unit,d=[...new Set(o.map(t=>t.unit??e.unit))];d.length===0&&d.push(e.unit);let f=o.length>1,p=!!(t.periods?.[`Before deploy`]||t.periods?.[`Since deploy`]),m=e=>r.measureText?.(e,`11px ${n.font}`)??Array.from(e).length*6.6,h=Math.min(r.width*.4,Math.max(40,...a.map(m))),g=ca(o.map(e=>e.name),r.width,f&&e.options?.legend!==`hidden`,n.text,n.font,r.measureText),_=d.map((t,i)=>({...Ca(Math.min(0,...o.filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.values.filter(e=>e!==null))),Math.max(0,...o.filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.values.filter(e=>e!==null))),t,r.width-h-80),type:`value`,position:i===0?`bottom`:`top`,offset:Math.max(0,i-1)*36,splitLine:{show:i===0,lineStyle:{color:n.grid}},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,formatter:e=>ba(t,e),hideOverlap:!0}}));return{...fo(n,u),tooltip:{...fo(n,u).tooltip,formatter:na((t,n)=>va(o.find(e=>e.name===n)?.unit??e.unit,t)),axisPointer:{type:`shadow`}},legend:g.option,grid:{left:8,right:56,top:(f?g.top:8)+Math.max(0,d.length-1)*36,bottom:s?24:8,containLabel:!0},yAxis:{type:`category`,inverse:!0,data:a,splitLine:{show:!1},axisLine:{lineStyle:{color:n.grid}},axisTick:{show:!1},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,width:h,overflow:`truncate`,formatter:e=>ho(e,h,m)}},xAxis:_.length===1?_[0]:_,series:o.map((t,r)=>({name:t.name,interactive:!0,xAxisIndex:d.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:`bar`,data:t.values.map((e,n)=>({value:e,selection:l.get(JSON.stringify(c.length>1?[a[n],t.name]:[a[n]]))})),barMaxWidth:p&&t.name===`Before deploy`?7:14,barGap:`20%`,itemStyle:{...io(p?t.name===`Before deploy`?n.muted:Ua(0,n.dark):lo(t.name,r,n),n),borderRadius:[0,4,4,0]},label:{show:p?t.name===`Since deploy`:!f||r===0,position:`right`,color:n.text,fontFamily:n.font,fontSize:11,formatter:({value:n})=>ba(t.unit??e.unit,n)}})),graphic:sa(s,n.muted)}}function _o(e,t,n,r=e.unit,i={width:270,height:140}){let a=e.min??0,o=e.max??100,s=vo(e,a,o,n),c=va(r,t),l=to(t,e.thresholds,e.better),u=l===`bad`?`◆ Bad`:l===`warn`?`■ Warn`:l===`ok`?`● OK`:t===null?`○ Unknown`:void 0,d=e=>`${e}40`,f=i.measureText?.(c,`600 28px ${n.font}`)??c.length*28*.6,p=i.measureText?.(u??``,`11px ${n.font}`)??(u?.length??0)*11*.6,m=i.width{let r=y;return y=e,{type:`rect`,shape:{x:4+r*_,y:g,width:(e-r)*_,height:10,r:[n===0?5:0,n===s.length-1?5:0,n===s.length-1?5:0,n===0?5:0]},style:{fill:d(t)}}}),{id:`gauge-fill`,type:`rect`,shape:{x:4,y:g,width:v*_,height:10,r:5},style:{fill:l?n.status[l]:Ua(0,n.dark)}},{id:`gauge-marker`,type:`rect`,shape:{x:3+v*_,y:g-2,width:2,height:14,r:1},style:{fill:n.text}},{type:`text`,left:4,top:g+12,style:{text:va(r,a),fill:n.muted,fontSize:11,fontFamily:n.font}},{type:`text`,right:4,top:g+12,style:{text:va(r,o),fill:n.muted,fontSize:11,fontFamily:n.font}}]}}function vo(e,t,n,r){let i=n-t||1,a=[t,...(e.thresholds??[]).map(e=>Math.min(n,Math.max(t,e.value))),n].sort((e,t)=>e-t),o=[];for(let t=0;t[(e.end-t)/i,r.status[e.status]])}var yo=function(e,t){return yo=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},yo(e,t)};function U(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);yo(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var bo=`12px sans-serif`,xo=20,So=100,Co=`007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N`;function wo(e){var t={};if(typeof JSON>`u`)return t;for(var n=0;n=0)s=o*n.length;else for(var c=0;c=zo&&(Ro=0),Ro++}function Vo(){var e=[...arguments];typeof console<`u`&&console.error.apply(console,e)}function Ho(e){if(typeof e!=`object`||!e)return e;var t=e,n=ko.call(e);if(n===`[object Array]`){if(!xs(e)){t=[];for(var r=0,i=e.length;r`u`&&typeof self<`u`?Ns.worker=!0:!Ns.hasGlobalWindow||`Deno`in window||typeof navigator<`u`&&typeof navigator.userAgent==`string`&&navigator.userAgent.indexOf(`Node.js`)>-1?(Ns.node=!0,Ns.svgSupported=!0):Ps(navigator.userAgent,Ns);function Ps(e,t){var n=t.browser,r=e.match(/Firefox\/([\d.]+)/),i=e.match(/MSIE\s([\d.]+)/)||e.match(/Trident\/.+?rv:(([\d.]+))/),a=e.match(/Edge?\/([\d.]+)/),o=/micromessenger/i.test(e);if(r&&(n.firefox=!0,n.version=r[1]),i&&(n.ie=!0,n.version=i[1]),a&&(n.edge=!0,n.version=a[1],n.newEdge=+a[1].split(`.`)[0]>18),o&&(n.weChat=!0),t.svgSupported=typeof SVGRect<`u`,t.touchEventsSupported=`ontouchstart`in window&&!n.ie&&!n.edge,t.pointerEventsSupported=`onpointerdown`in window&&(n.edge||n.ie&&+n.version>=11),t.domSupported=typeof document<`u`){var s=document.documentElement.style;t.transform3dSupported=(n.ie&&`transition`in s||n.edge||`WebKitCSSMatrix`in window&&`m11`in new WebKitCSSMatrix||`MozPerspective`in s)&&!(`OTransition`in s),t.transformSupported=t.transform3dSupported||n.ie&&+n.version>=9}}var Fs=1e-4,Is=20;function Ls(e){return e.replace(/^\s+|\s+$/g,``)}var Rs=Math.min,zs=Math.max,Bs=Math.abs,Vs=Math.round,Hs=Math.floor,Us=Math.ceil,Ws=Math.pow,Gs=Math.log,Ks=Math.LN10,qs=Math.PI,Js=Math.random;function Ys(e,t,n,r){var i=t[0],a=t[1],o=n[0],s=n[1],c=a-i,l=s-o;if(c===0)return l===0?o:(o+s)/2;if(r){if(c>0){if(e<=i)return o;if(e>=a)return s}else if(e>=i)return o;else if(e<=a)return s}else{if(e===i)return o;if(e===a)return s}return(e-i)/c*l+o}var Xs=Zs;function Zs(e,t,n){switch(e){case`center`:case`middle`:e=`50%`;break;case`left`:case`top`:e=`0%`;break;case`right`:case`bottom`:e=`100%`}return Qs(e,t,n)}function Qs(e,t,n){return Y(e)?$s(e)?parseFloat(e)/100*t+(n||0):parseFloat(e):e==null?NaN:+e}function $s(e){return!!Ls(e).match(/%$/)}function ec(e,t,n){return isNaN(t)?n?``+e:+e:(t=Rs(zs(0,t),Is),e=(+e).toFixed(t),n?e:+e)}function tc(e){return e.sort(function(e,t){return e-t}),e}function nc(e){if(e=+e,isNaN(e))return 0;if(e>1e-14){for(var t=1,n=0;n<15;n++,t*=10)if(Vs(e*t)/t===e)return n}return rc(e)}function rc(e){var t=e.toString().toLowerCase(),n=t.indexOf(`e`),r=n>0?+t.slice(n+1):0,i=n>0?n:t.length,a=t.indexOf(`.`);return zs(0,(a<0?0:i-1-a)-r)}function ic(e,t,n){var r=Bs(e[1]-e[0]);if(!isFinite(r)||r===0)return NaN;var i=Gs(2*Bs(n||1)*Bs(r))/Ks,a=Gs(Bs(t))/Ks,o=zs(0,Us(-i+a));return isFinite(o)||(o=NaN),o}function ac(e,t){var n=zs(nc(e),nc(t)),r=e+t;return n>Is?r:ec(r,n)}var oc=Ws(2,53)-1;function sc(e){var t=qs*2;return(e%t+t)%t}function cc(e){return e>-Fs&&e=10&&t++,t}function pc(e,t){var n=fc(e),r=Ws(10,n),i=e/r;return e=(t===2?1:t?i<1.5?1:i<2.5?2:i<4?3:i<7?5:10:i<1?1:i<2?2:i<3?3:i<5?5:10)*r,ec(e,-n)}function mc(e){e.sort(function(e,t){return s(e,t,0)?-1:1});for(var t=-1/0,n=1,r=0;r0?e.length:0),this.item=null,this.key=NaN,this},e.prototype.next=function(){return(this._step>0?this._idx=this._end)&&(this.item=this._list[this._idx],this.key=this._idx+=this._step,!0)},e})();function ul(){return[1/0,-1/0]}function dl(e,t){hl(t)&&(te[1]&&(e[1]=t))}function fl(e,t){hl(t)&&te[1]&&(e[1]=t)}function ml(e,t){gl(t[0],t[1])&&(t[0]e[1]&&(e[1]=t[1]))}function hl(e){return e!=null&&isFinite(e)}function gl(e,t){return hl(e)&&hl(t)&&e<=t}function _l(e){var t=e[1]-e[0];return isFinite(t)&&t>=0}function vl(e){gl(e[0],e[1])&&e[0]>e[1]&&(e[0]=e[1])}function yl(){var e=`__ec_once_`+bl++;return function(t,n){Z(t,e)||(t[e]=1,n())}}var bl=_c();function xl(e,t,n){var r=Es(),i=0;G(e,function(a){var o=t(a),s=r.get(o)||0;n&&n(a,s),!s&&!n&&(e[i++]=a),r.set(o,s+1)}),n||(e.length=i)}function Sl(e){return e.value+``}function Cl(e){return e+``}function wl(e,t){return X(t,!0)?e.seriesIndex+2:0}function Tl(e,t,n){var r=e.getData().count();return{progressiveRender:n.progressiveEnabled&&t.incrementalPrepareRender&&r>=n.threshold,large:e.get(`large`)&&r>=e.get(`largeThreshold`),modDataCount:e.get(`progressiveChunkMode`)===`mod`?e.getData().count():null}}function El(e){return{overallReset:e}}var Dl=`.`,Ol=`___EC__COMPONENT__CONTAINER___`,kl=`___EC__EXTENDED_CLASS___`;function Al(e){var t={main:``,sub:``};if(e){var n=e.split(Dl);t.main=n[0]||``,t.sub=n[1]||``}return t}function jl(e){_s(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(e),`componentType "`+e+`" illegal`)}function Ml(e){return!!(e&&e[kl])}function Nl(e,t){e.$constructor=e,e.extend=function(e){var t=this,n;return Pl(t)?n=function(e){U(t,e);function t(){return e.apply(this,arguments)||this}return t}(t):(n=function(){(e.$constructor||t).apply(this,arguments)},Jo(n,this)),W(n.prototype,e),n[kl]=!0,n.extend=this.extend,n.superCall=Rl,n.superApply=zl,n.superClass=t,n}}function Pl(e){return rs(e)&&/^class\s/.test(Function.prototype.toString.call(e))}function Fl(e,t){e.extend=t.extend}var Il=Math.round(Math.random()*10);function Ll(e){var t=[`__\0is_clz`,Il++].join(`_`);e.prototype[t]=!0,e.isInstance=function(e){return!!(e&&e[t])}}function Rl(e,t){var n=[...arguments].slice(2);return this.superClass.prototype[t].apply(e,n)}function zl(e,t,n){return this.superClass.prototype[t].apply(e,n)}function Bl(e){var t={};e.registerClass=function(e){var r=e.type||e.prototype.type;if(r){jl(r),e.prototype.type=r;var i=Al(r);if(!i.sub)t[i.main]=e;else if(i.sub!==Ol){var a=n(i);a[i.sub]=e}}return e},e.getClass=function(e,n,r){var i=t[e];if(i&&i[Ol]&&(i=n?i[n]:null),r&&!i)throw Error(n?`Component `+e+`.`+(n||``)+` is used but not imported.`:e+`.type should be specified.`);return i},e.getClassesByMainType=function(e){var n=Al(e),r=[],i=t[n.main];return i&&i[Ol]?G(i,function(e,t){t!==Ol&&r.push(e)}):r.push(i),r},e.hasClass=function(e){return!!t[Al(e).main]},e.getAllClassMainTypes=function(){var e=[];return G(t,function(t,n){e.push(n)}),e},e.hasSubTypes=function(e){var n=t[Al(e).main];return n&&n[Ol]};function n(e){var n=t[e.main];return(!n||!n[Ol])&&(n=t[e.main]={},n[Ol]=!0),n}}function Vl(e,t){for(var n=0;n=0||i&&qo(i,s)<0)){var c=n.getShallow(s,t);c!=null&&(a[e[o][0]]=c)}}return a}}var Hl=Vl([[`fill`,`color`],[`shadowBlur`],[`shadowOffsetX`],[`shadowOffsetY`],[`opacity`],[`shadowColor`]]),Ul=function(){function e(){}return e.prototype.getAreaStyle=function(e,t){return Hl(this,e,t)},e}(),Wl=function(){function e(e){this.value=e}return e}(),Gl=function(){function e(){this._len=0}return e.prototype.insert=function(e){var t=new Wl(e);return this.insertEntry(t),t},e.prototype.insertEntry=function(e){this.head?(this.tail.next=e,e.prev=this.tail,e.next=null,this.tail=e):this.head=this.tail=e,this._len++},e.prototype.remove=function(e){var t=e.prev,n=e.next;t?t.next=n:this.head=n,n?n.prev=t:this.tail=t,e.next=e.prev=null,this._len--},e.prototype.len=function(){return this._len},e.prototype.clear=function(){this.head=this.tail=null,this._len=0},e}(),Kl=function(){function e(e){this._list=new Gl,this._maxSize=10,this._map={},this._maxSize=e}return e.prototype.put=function(e,t){var n=this._list,r=this._map,i=null;if(r[e]==null){var a=n.len(),o=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=n.head;n.remove(s),delete r[s.key],i=s.value,this._lastRemovedEntry=s}o?o.value=t:o=new Wl(t),o.key=e,n.insertEntry(o),r[e]=o}return i},e.prototype.get=function(e){var t=this._map[e],n=this._list;if(t!=null)return t!==n.tail&&(n.remove(t),n.insertEntry(t)),t.value},e.prototype.clear=function(){this._list.clear(),this._map={}},e.prototype.len=function(){return this._list.len()},e}(),ql=new Kl(50);function Jl(e){if(typeof e==`string`){var t=ql.get(e);return t&&t.image}return e}function Yl(e,t,n,r,i){if(!e)return t;if(typeof e==`string`){if(t&&t.__zrImageSrc===e||!n)return t;var a=ql.get(e),o={hostEl:n,cb:r,cbPayload:i};return a?(t=a.image,!Zl(t)&&a.pending.push(o)):(t=Eo.loadImage(e,Xl,Xl),t.__zrImageSrc=e,ql.put(e,t.__cachedImgObj={image:t,pending:[o]})),t}return e}function Xl(){var e=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var t=0;tu||d>f||p>m||h>g)return!1;var _=!(u=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height},e.prototype.contain=function(t,n){return e.contain(this,t,n)},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.copy=function(e){Vu(this,e)},e.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},e.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},e.prototype.isZero=function(){return this.width===0||this.height===0},e.create=function(t){return new e(t?t.x:0,t?t.y:0,t?t.width:0,t?t.height:0)},e.copy=function(e,t){return e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height,e},e.applyTransform=function(e,t,n){if(!n){e!==t&&Vu(e,t);return}if(n[1]<1e-5&&n[1]>-1e-5&&n[2]<1e-5&&n[2]>-1e-5){var r=n[0],i=n[3],a=n[4],o=n[5];e.x=t.x*r+a,e.y=t.y*i+o,e.width=t.width*r,e.height=t.height*i,e.width<0&&(e.x+=e.width,e.width=-e.width),e.height<0&&(e.y+=e.height,e.height=-e.height);return}Au.x=Mu.x=t.x,Au.y=Nu.y=t.y,ju.x=Nu.x=t.x+t.width,ju.y=Mu.y=t.y+t.height,Au.transform(n),Nu.transform(n),ju.transform(n),Mu.transform(n),e.x=Tu(Au.x,ju.x,Mu.x,Nu.x),e.y=Tu(Au.y,ju.y,Mu.y,Nu.y);var s=Eu(Au.x,ju.x,Mu.x,Nu.x),c=Eu(Au.y,ju.y,Mu.y,Nu.y);e.width=s-e.x,e.height=c-e.y},e.calculateTransform=function(e,t,n){var r=n.width/t.width,i=n.height/t.height;return e=$l(e||[]),nu(e,e,lu(qu,-t.x,-t.y)),iu(e,e,lu(qu,r,i)),nu(e,e,lu(qu,n.x,n.y)),e},e}(),zu=Ru.create,Bu=Ru.set,Vu=Ru.copy,Hu=Ru.calculateTransform,Uu=Ru.applyTransform,Wu=Ru.contain,Gu=new Ru(0,0,0,0),Ku=new Ru(0,0,0,0),qu=[];function Ju(e,t,n,r,i,a,o,s){var c=Du(t-n),l=Du(r-e),u=Tu(c,l),d=Ou[i],f=Ou[1-i],p=ku[i];t=l||!Pu.bidirectional)&&(Fu[d]=-l,Fu[f]=0,Pu.useDir&&Pu.calcDirMTV())))}function Yu(){var e=0,t=new wu,n=new wu,r={minTv:new wu,maxTv:new wu,useDir:!1,dirMinTv:new wu,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(i,a){r.touchThreshold=0,i&&i.touchThreshold!=null&&(r.touchThreshold=Eu(0,i.touchThreshold)),r.negativeSize=!1,a&&(r.minTv.set(1/0,1/0),r.maxTv.set(0,0),r.useDir=!1,i&&i.direction!=null&&(r.useDir=!0,r.dirMinTv.copy(r.minTv),n.copy(r.minTv),e=i.direction,r.bidirectional=i.bidirectional==null||!!i.bidirectional,r.bidirectional||t.set(Math.cos(e),Math.sin(e))))},calcDirMTV:function(){var a=r.minTv,o=r.dirMinTv,s=a.y*a.y+a.x*a.x,c=Math.sin(e),l=Math.cos(e),u=c*a.y+l*a.x;if(i(u)){i(a.x)&&i(a.y)&&o.set(0,0);return}if(n.x=s*l/u,n.y=s*c/u,i(n.x)&&i(n.y)){o.set(0,0);return}(r.bidirectional||t.dot(n)>0)&&n.len()=ed)){e||=`12px sans-serif`;for(var t=[],n=+new Date,r=0;r<=127;r++)t[r]=Eo.measureText(String.fromCharCode(r),e).width;var i=+new Date-n;return i>16?$u=ed:i>2&&$u++,t}}var $u=0,ed=5;function td(e,t){return e.asciiWidthMapTried||=(e.asciiWidthMap=Qu(e.font),!0),0<=t&&t<=127?e.asciiWidthMap==null?e.asciiCharWidth:e.asciiWidthMap[t]:e.stWideCharWidth}function nd(e,t){var n=e.strWidthCache,r=n.get(t);return r??(r=Eo.measureText(t,e.font).width,n.put(t,r)),r}function rd(e,t,n,r){var i=nd(Xu(t),e),a=sd(t);return new Ru(ad(0,i,n),od(0,a,r),i,a)}function id(e,t,n,r){var i=((e||``)+``).split(` +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/panel-sql-editor-Cx5hjHge.js","assets/useRouter-ByJ6_rwb.js","assets/brand-DUaZkIz1.js","assets/index-B7LmyWZW.js","assets/useNavigate-B1zgPEUp.js","assets/preload-helper-DJZNfKNH.js","assets/Tooltip-B3r3s_B9.js","assets/index-ADB9ThEc.css"])))=>i.map(i=>d[i]); +import{a as e,i as t,o as n,r,s as i}from"./useRouter-ByJ6_rwb.js";import{A as a,C as o,D as s,E as c,K as l,M as u,O as d,P as f,Q as p,S as m,T as h,X as g,Y as _,Z as v,_ as y,_t as b,a as x,c as S,d as C,dt as w,f as T,ft as E,g as D,gt as O,h as k,j as A,k as j,lt as M,m as N,mt as P,nt as F,o as I,ot as L,p as ee,r as te,s as ne,st as re,tt as ie,u as ae,ut as R,v as oe,x as z,y as se}from"./brand-DUaZkIz1.js";import{t as ce}from"./preload-helper-DJZNfKNH.js";import{C as le,E as ue,b as de,o as fe,t as pe,w as me}from"./Tooltip-B3r3s_B9.js";import{a as he,c as ge,d as _e,i as ve,l as B,n as ye,o as be,r as xe,s as Se,t as Ce,u as we}from"./dashboard-change-chips-CghpARdt.js";import{n as Te,r as Ee,t as De}from"./WarningCircle.es-eZ--e_KS.js";import{$ as Oe,$t as ke,A as Ae,B as je,Bt as Me,C as Ne,D as Pe,E as Fe,F as Ie,Gt as Le,Ht as Re,I as ze,J as Be,Jt as Ve,Kt as He,M as Ue,N as We,O as Ge,P as Ke,Q as qe,Qt as Je,Ut as Ye,V as Xe,Vt as Ze,Wt as Qe,X as $e,Xt as et,Yt as tt,Z as nt,_ as rt,a as it,an as at,b as ot,c as st,ct,d as lt,en as ut,et as dt,h as ft,i as pt,in as mt,j as ht,k as gt,l as _t,m as vt,n as yt,nn as bt,o as xt,on as St,qt as Ct,r as wt,rn as Tt,s as Et,sn as Dt,t as Ot,tn as kt,u as At,v as jt,w as Mt,x as Nt}from"./index-B7LmyWZW.js";function Pt(e,t){if(Object.is(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!t.has(n)||!Object.is(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let n=Ft(e);if(n.length!==Ft(t).length)return!1;for(let r=0;r{if(typeof n!=`string`||n.trim().length===0)throw Error(t);return`${e}-${n}`}}var H=r();function Lt(e){return typeof e==`object`&&e?`base`in e?e.base:void 0:e}function Rt(e,t){if(e===t||Number.isNaN(e)&&Number.isNaN(t))return!0;if(!(e instanceof Object)||!(t instanceof Object))return!1;let n=Object.keys(e),{length:r}=n;if(r!==Object.keys(t).length)return!1;for(let i=0;i{r.current||=window.setTimeout(()=>{i(...e),r.current=null},t)},[t]),o=(0,V.useCallback)(()=>{r.current&&=(window.clearTimeout(r.current),null)},[]);return(0,V.useEffect)(()=>(n.autoInvoke&&a(),o),[o,a]),{start:a,clear:o}}function Ut(e){let t=(0,V.useRef)(void 0);return(0,V.useEffect)(()=>{t.current=e},[e]),t.current}function Wt(e,t,n){let r=(0,V.useRef)(null);(0,V.useEffect)(()=>{r.current&&=(r.current.disconnect(),null);let i=typeof n==`function`?n():n;return i&&(r.current=new MutationObserver(e),r.current.observe(i,t)),()=>{r.current&&=(r.current.disconnect(),null)}},[e,t,n])}function Gt(){let[e,t]=(0,V.useState)(!1);return(0,V.useEffect)(()=>t(!0),[]),e}function Kt(e){return typeof e==`string`||typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`}function qt(e,t=document){let n=t.querySelector(e);if(n)return n;let r=t.querySelectorAll(`*`);for(let t=0;t{if(!e||!t||!n.current)return;let r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),a=t.offsetWidth===0?1:i.width/t.offsetWidth,o=t.offsetHeight===0?1:i.height/t.offsetHeight,s=window.getComputedStyle(e),c=window.getComputedStyle(t),l=de(s.borderTopWidth)+de(c.borderTopWidth),u=de(s.borderLeftWidth)+de(c.borderLeftWidth),d={top:(r.top-i.top)/o-l,left:(r.left-i.left)/a-u,width:r.width/a,height:r.height/o};n.current.style.transform=`translateY(${d.top}px) translateX(${d.left}px)`,n.current.style.width=`${d.width}px`,n.current.style.height=`${d.height}px`},p=()=>{window.clearTimeout(o.current),n.current&&(n.current.style.transitionDuration=`0ms`),f(),o.current=window.setTimeout(()=>{n.current&&(n.current.style.transitionDuration=``)},30)},m=(0,V.useRef)(null),h=(0,V.useRef)(null);return(0,V.useEffect)(()=>{if(c&&s.current!==e&&i&&i(),s.current=e,f(),e)return m.current=new ResizeObserver(p),m.current.observe(e),t&&(h.current=new ResizeObserver(p),h.current.observe(t)),()=>{m.current?.disconnect(),h.current?.disconnect()}},[t,e]),(0,V.useEffect)(()=>{if(t){let e=e=>{Zt(e.target,t)&&(p(),d(!1))};return t.addEventListener(`transitionend`,e),()=>{t.removeEventListener(`transitionend`,e)}}},[t]),(0,V.useEffect)(()=>{if(n.current&&a){let e=e=>{e.propertyName===`transform`&&a()};return n.current.addEventListener(`transitionend`,e),()=>{n.current?.removeEventListener(`transitionend`,e)}}},[a]),Ht(()=>{_e()!==`test`&&l(!0)},20,{autoInvoke:!0}),Wt(e=>{e.forEach(e=>{e.type===`attributes`&&e.attributeName===`dir`&&p()})},{attributes:!0,attributeFilter:[`dir`]},()=>document.documentElement),{initialized:c,hidden:u}}var $t={root:`m_96b553a6`},en=g((e,{transitionDuration:t},{shouldReduceMotion:n})=>({root:{"--transition-duration":e.respectReducedMotion&&n?`0ms`:typeof t==`number`?`${t}ms`:t||`150ms`}})),tn=h(e=>{let t=u(`FloatingIndicator`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,target:d,parent:f,transitionDuration:m,mod:h,displayAfterTransitionEnd:g,onTransitionStart:_,onTransitionEnd:v,attributes:y,ref:b,...x}=t,S=p(),C=a({name:`FloatingIndicator`,classes:$t,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:y,vars:l,varsResolver:en,stylesCtx:{shouldReduceMotion:S}}),w=(0,V.useRef)(null),{initialized:T,hidden:E}=Qt({target:d,parent:f,ref:w,displayAfterTransitionEnd:g,onTransitionStart:_,onTransitionEnd:v}),D=ie(b,w);return!d||!f?null:(0,H.jsx)(o,{ref:D,mod:[{initialized:T,hidden:E},h],...C(`root`),...x})});tn.displayName=`@mantine/core/FloatingIndicator`,tn.classes=$t,tn.varsResolver=en;var[nn,rn]=ue(`Accordion component was not found in the tree`),[an,on]=ue(`Accordion.Item component was not found in the tree`),sn={root:`m_9bdbb667`,panel:`m_df78851f`,content:`m_4ba554d4`,itemTitle:`m_8fa820a0`,control:`m_4ba585b8`,"control--default":`m_6939a5e9`,"control--contained":`m_4271d21b`,label:`m_df3ffa0f`,chevron:`m_3f35ae96`,icon:`m_9bd771fe`,item:`m_9bd7b098`,"item--default":`m_fe19b709`,"item--contained":`m_1f921b3b`,"item--filled":`m_2cdf939a`,"item--separated":`m_9f59b069`},cn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,chevron:s,icon:c,onClick:l,onKeyDown:d,children:f,disabled:p,mod:h,...g}=u(`AccordionControl`,null,e),{value:_}=on(),v=rn(),y=v.isItemActive(_),b=typeof v.order==`number`,x=`h${v.order}`,S=(0,H.jsxs)(m,{...v.getStyles(`control`,{className:n,classNames:t,style:r,styles:i,variant:v.variant}),unstyled:v.unstyled,mod:[`accordion-control`,{active:y,"chevron-position":v.chevronPosition,disabled:p},h],onClick:e=>{l?.(e),v.onChange(_)},type:`button`,disabled:p,"aria-expanded":y,"aria-controls":v.getRegionId(_),id:v.getControlId(_),onKeyDown:Tt({siblingSelector:`[data-accordion-control]`,parentSelector:`[data-accordion]`,activateOnFocus:!1,loop:v.loop,orientation:`vertical`,onKeyDown:d}),...g,children:[(0,H.jsx)(o,{component:`span`,mod:{rotate:!v.disableChevronRotation&&y,position:v.chevronPosition},...v.getStyles(`chevron`,{classNames:t,styles:i}),children:s||v.chevron}),(0,H.jsx)(`span`,{...v.getStyles(`label`,{classNames:t,styles:i}),children:f}),c&&(0,H.jsx)(o,{component:`span`,mod:{"chevron-position":v.chevronPosition},...v.getStyles(`icon`,{classNames:t,styles:i}),children:c})]});return b?(0,H.jsx)(x,{...v.getStyles(`itemTitle`,{classNames:t,styles:i}),children:S}):S});cn.displayName=`@mantine/core/AccordionControl`,cn.classes=sn;var ln=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,value:s,mod:c,...l}=u(`AccordionItem`,null,e),d=rn();return(0,H.jsx)(an,{value:{value:s},children:(0,H.jsx)(o,{mod:[{active:d.isItemActive(s)},c],...d.getStyles(`item`,{className:n,classNames:t,styles:i,style:r,variant:d.variant}),...l})})});ln.displayName=`@mantine/core/AccordionItem`,ln.classes=sn;var un=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,children:o,keepMounted:s,keepMountedMode:c,...l}=u(`AccordionPanel`,null,e),{value:d}=on(),f=rn();return(0,H.jsx)(we,{...f.getStyles(`panel`,{className:n,classNames:t,style:r,styles:i}),expanded:f.isItemActive(d),transitionDuration:f.transitionDuration??200,role:`region`,id:f.getRegionId(d),"aria-labelledby":f.getControlId(d),keepMounted:s??f.keepMounted,keepMountedMode:c??f.keepMountedMode,...l,children:(0,H.jsx)(`div`,{...f.getStyles(`content`,{classNames:t,styles:i}),children:o})})});un.displayName=`@mantine/core/AccordionPanel`,un.classes=sn;var dn={multiple:!1,loop:!0,disableChevronRotation:!1,disableCollapse:!1,chevronPosition:`right`,variant:`default`,chevronSize:`auto`,chevronIconSize:16,keepMountedMode:`activity`},fn=g((e,{transitionDuration:t,chevronSize:n,radius:r})=>({root:{"--accordion-transition-duration":t===void 0?void 0:`${t}ms`,"--accordion-chevron-size":n===void 0?void 0:P(n),"--accordion-radius":r===void 0?void 0:re(r)}})),pn=c(e=>{let t=u(`Accordion`,dn,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,children:d,multiple:f,value:p,defaultValue:m,onChange:h,id:g,loop:_,transitionDuration:v,disableChevronRotation:y,disableCollapse:b,chevronPosition:x,chevronSize:S,order:C,chevron:w,variant:T,radius:E,chevronIconSize:D,attributes:O,keepMounted:k,keepMountedMode:A,...j}=t,M=F(g),[N,P]=kt({value:p,defaultValue:m,finalValue:f?[]:null,onChange:h}),I=e=>Array.isArray(N)?N.includes(e):e===N,L=e=>{if(!Array.isArray(N)&&b&&e===N)return;let t=Array.isArray(N)?N.includes(e)?N.filter(t=>t!==e):[...N,e]:e===N?null:e;P(t)},ee=a({name:`Accordion`,classes:sn,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:O,vars:l,varsResolver:fn});return(0,H.jsx)(nn,{value:{isItemActive:I,onChange:L,getControlId:It(`${M}-control`,`Accordion.Item component was rendered with invalid value or without value`),getRegionId:It(`${M}-panel`,`Accordion.Item component was rendered with invalid value or without value`),chevron:w===null?null:w||(0,H.jsx)(Ve,{size:D}),transitionDuration:v,disableChevronRotation:y,chevronPosition:x,order:C,loop:_,getStyles:ee,variant:T,unstyled:c,keepMounted:k,keepMountedMode:A},children:(0,H.jsx)(o,{...ee(`root`),id:M,...j,variant:T,"data-accordion":!0,children:d})})});pn.classes=sn,pn.varsResolver=fn,pn.displayName=`@mantine/core/Accordion`,pn.Item=ln,pn.Panel=un,pn.Control=cn,pn.Chevron=Ve;function mn(e){return typeof e==`string`?{value:e,label:e}:typeof e==`object`&&`value`in e&&!(`label`in e)?{value:e.value,label:`${e.value}`,disabled:e.disabled}:typeof e==`object`&&`group`in e?{group:e.group,items:e.items.map(e=>mn(e))}:typeof e==`number`||typeof e==`bigint`||typeof e==`boolean`?{value:e,label:`${e}`}:e}function hn(e){return e?e.map(e=>mn(e)):[]}function gn(e){return e.reduce((e,t)=>`group`in t?{...e,...gn(t.items)}:(e[`${t.value}`]=t,e),{})}var _n={dropdown:`m_88b62a41`,search:`m_985517d8`,options:`m_b2821a6e`,option:`m_92253aa5`,empty:`m_2530cd1d`,header:`m_858f94bd`,footer:`m_82b967cb`,group:`m_254f3e4f`,groupLabel:`m_2bb2e9e5`,chevron:`m_2943220b`,optionsDropdownOption:`m_390b5f4`,optionsDropdownCheckIcon:`m_8ee53fc2`,optionsDropdownCheckPlaceholder:`m_a530ee0a`},vn={error:null},yn=g((e,{size:t,color:n})=>({chevron:{"--combobox-chevron-size":M(t,`combobox-chevron-size`),"--combobox-chevron-color":n?l(n,e):void 0}})),bn=h(e=>{let t=u(`ComboboxChevron`,vn,e),{size:n,error:r,style:i,className:s,classNames:c,styles:l,unstyled:d,vars:f,attributes:p,mod:m,...h}=t,g=a({name:`ComboboxChevron`,classes:_n,props:t,style:i,className:s,classNames:c,styles:l,unstyled:d,vars:f,varsResolver:yn,attributes:p,rootSelector:`chevron`});return(0,H.jsx)(o,{component:`svg`,...h,...g(`chevron`),size:n,viewBox:`0 0 15 15`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,mod:[`combobox-chevron`,{error:r},m],children:(0,H.jsx)(`path`,{d:`M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.35753 11.9939 7.64245 11.9939 7.81819 11.8182L10.0682 9.56819Z`,fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`})})});bn.classes=_n,bn.varsResolver=yn,bn.displayName=`@mantine/core/ComboboxChevron`;var[xn,Sn]=ue(`Combobox component was not found in tree`);function Cn({onMouseDown:e,onClick:t,onClear:n,...r}){return(0,H.jsx)(k.ClearButton,{tabIndex:-1,"aria-hidden":!0,...r,onMouseDown:t=>{t.preventDefault(),e?.(t)},onClick:e=>{n(),t?.(e)}})}Cn.displayName=`@mantine/core/ComboboxClearButton`;var wn=h(e=>{let{classNames:t,styles:n,className:r,style:i,hidden:a,...o}=u(`ComboboxDropdown`,null,e),s=Sn();return(0,H.jsx)(et.Dropdown,{...o,role:`presentation`,"data-hidden":a||void 0,"data-floating-height":s.floatingHeight||void 0,...s.getStyles(`dropdown`,{className:r,style:i,classNames:t,styles:n})})});wn.classes=_n,wn.displayName=`@mantine/core/ComboboxDropdown`;var Tn={refProp:`ref`},En=h(e=>{let{children:t,refProp:n,ref:r}=u(`ComboboxDropdownTarget`,Tn,e);if(Sn(),!w(t))throw Error(`Combobox.DropdownTarget component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);return(0,H.jsx)(et.Target,{ref:r,refProp:n,children:t})});En.displayName=`@mantine/core/ComboboxDropdownTarget`;var Dn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxEmpty`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`empty`,{className:n,classNames:t,styles:i,style:r}),...s})});Dn.classes=_n,Dn.displayName=`@mantine/core/ComboboxEmpty`;function On({onKeyDown:e,onClick:t,withKeyboardNavigation:n,withAriaAttributes:r,withExpandedAttribute:i,targetType:a,autoComplete:o}){let s=Sn(),[c,l]=(0,V.useState)(null),u=t=>{if(e?.(t),!s.readOnly&&n){if(t.nativeEvent.isComposing)return;if(t.nativeEvent.code===`ArrowDown`&&(t.preventDefault(),s.store.dropdownOpened?l(s.store.selectNextOption()):(s.store.openDropdown(`keyboard`),l(s.store.selectActiveOption()),s.store.updateSelectedOptionIndex(`selected`,{scrollIntoView:!0}))),t.nativeEvent.code===`ArrowUp`&&(t.preventDefault(),s.store.dropdownOpened?l(s.store.selectPreviousOption()):(s.store.openDropdown(`keyboard`),l(s.store.selectActiveOption()),s.store.updateSelectedOptionIndex(`selected`,{scrollIntoView:!0}))),t.nativeEvent.code===`Enter`||t.nativeEvent.code===`NumpadEnter`){if(t.nativeEvent.keyCode===229)return;let e=s.store.getSelectedOptionIndex();s.store.dropdownOpened&&e!==-1?(t.preventDefault(),s.store.clickSelectedOption()):a===`button`&&(t.preventDefault(),s.store.openDropdown(`keyboard`))}t.key===`Escape`&&s.store.closeDropdown(`keyboard`),t.nativeEvent.code===`Space`&&a===`button`&&(t.preventDefault(),s.store.toggleDropdown(`keyboard`))}},d=r?{...i?{role:`combobox`}:{},"aria-haspopup":`listbox`,"aria-expanded":i?!!(s.store.listId&&s.store.dropdownOpened):void 0,"aria-controls":s.store.dropdownOpened&&s.store.listId?s.store.listId:void 0,"aria-activedescendant":s.store.dropdownOpened&&c||void 0,autoComplete:o,"data-expanded":s.store.dropdownOpened||void 0,"data-mantine-stop-propagation":s.store.dropdownOpened||void 0}:{},f=e=>{a===`button`&&e.currentTarget.focus(),t?.(e)};return{...d,onKeyDown:u,onClick:f}}var kn={refProp:`ref`,targetType:`input`,withKeyboardNavigation:!0,withAriaAttributes:!0,withExpandedAttribute:!1,autoComplete:`off`},An=h(e=>{let{children:t,refProp:n,withKeyboardNavigation:r,withAriaAttributes:i,withExpandedAttribute:a,targetType:o,autoComplete:s,ref:c,...l}=u(`ComboboxEventsTarget`,kn,e),d=v(t);if(!d)throw Error(`Combobox.EventsTarget component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);let f=Sn(),p=On({targetType:o,withAriaAttributes:i,withKeyboardNavigation:r,withExpandedAttribute:a,onKeyDown:d.props.onKeyDown,onClick:d.props.onClick,autoComplete:s});return(0,V.cloneElement)(d,{...p,...l,[n]:ie(c,f.store.targetRef,le(d))})});An.displayName=`@mantine/core/ComboboxEventsTarget`;var jn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxFooter`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`footer`,{className:n,classNames:t,style:r,styles:i}),...s,onMouseDown:e=>{e.preventDefault()}})});jn.classes=_n,jn.displayName=`@mantine/core/ComboboxFooter`;var Mn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,children:s,label:c,id:l,...d}=u(`ComboboxGroup`,null,e),f=Sn(),p=F(l),m=c!=null&&c!==!1&&c!==``;return(0,H.jsxs)(o,{role:`group`,"aria-labelledby":m?p:void 0,...f.getStyles(`group`,{className:n,classNames:t,style:r,styles:i}),...d,children:[m&&(0,H.jsx)(`div`,{id:p,...f.getStyles(`groupLabel`,{classNames:t,styles:i}),children:c}),s]})});Mn.classes=_n,Mn.displayName=`@mantine/core/ComboboxGroup`;var Nn=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ComboboxHeader`,null,e),c=Sn();return(0,H.jsx)(o,{...c.getStyles(`header`,{className:n,classNames:t,style:r,styles:i}),...s,onMouseDown:e=>{e.preventDefault()}})});Nn.classes=_n,Nn.displayName=`@mantine/core/ComboboxHeader`;function Pn({value:e,valuesDivider:t=`,`,...n}){return(0,H.jsx)(`input`,{type:`hidden`,value:Array.isArray(e)?e.join(t):e?`${e}`:``,...n})}Pn.displayName=`@mantine/core/ComboboxHiddenInput`;var Fn=h(e=>{let t=u(`ComboboxOption`,null,e),{classNames:n,className:r,style:i,styles:a,vars:s,onClick:c,id:l,active:d,onMouseDown:f,onMouseOver:p,disabled:m,selected:h,mod:g,..._}=t,v=Sn(),y=(0,V.useId)(),b=l||y;return(0,H.jsx)(o,{...v.getStyles(`option`,{className:r,classNames:n,styles:a,style:i}),"aria-disabled":m||void 0,..._,id:b,mod:[`combobox-option`,{"combobox-active":d,"combobox-disabled":m,"combobox-selected":h},g],role:`option`,onClick:e=>{m?e.preventDefault():(v.onOptionSubmit?.(t.value,t),c?.(e))},onMouseDown:e=>{e.preventDefault(),f?.(e)},onMouseOver:e=>{v.resetSelectionOnOptionHover&&v.store.resetSelectedOption(),p?.(e)}})});Fn.classes=_n,Fn.displayName=`@mantine/core/ComboboxOption`;var In=h(e=>{let{classNames:t,className:n,style:r,styles:i,id:a,onMouseDown:s,labelledBy:c,...l}=u(`ComboboxOptions`,null,e),d=Sn(),f=F(a);return(0,V.useEffect)(()=>{d.store.setListId(f)},[f]),(0,H.jsx)(o,{...d.getStyles(`options`,{className:n,style:r,classNames:t,styles:i}),...l,id:f,role:`listbox`,"aria-labelledby":c,onMouseDown:e=>{e.preventDefault(),s?.(e)}})});In.classes=_n,In.displayName=`@mantine/core/ComboboxOptions`;var Ln={withAriaAttributes:!0,withKeyboardNavigation:!0},Rn=h(e=>{let{classNames:t,styles:n,unstyled:r,vars:i,withAriaAttributes:a,onKeyDown:o,onClick:s,withKeyboardNavigation:c,size:l,ref:d,...f}=u(`ComboboxSearch`,Ln,e),p=Sn(),m=p.getStyles(`search`),h=On({targetType:`input`,withAriaAttributes:a,withKeyboardNavigation:c,withExpandedAttribute:!1,onKeyDown:o,onClick:s,autoComplete:`off`});return(0,H.jsx)(k,{ref:ie(d,p.store.searchRef),classNames:[{input:m.className},t],styles:[{input:m.style},n],size:l||p.size,...h,...f,__staticSelector:`Combobox`})});Rn.classes=_n,Rn.displayName=`@mantine/core/ComboboxSearch`;var zn={refProp:`ref`,targetType:`input`,withKeyboardNavigation:!0,withAriaAttributes:!0,withExpandedAttribute:!1,autoComplete:`off`},Bn=h(e=>{let{children:t,refProp:n,withKeyboardNavigation:r,withAriaAttributes:i,withExpandedAttribute:a,targetType:o,autoComplete:s,ref:c,...l}=u(`ComboboxTarget`,zn,e),d=v(t);if(!d)throw Error(`Combobox.Target component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported`);let f=Sn(),p=On({targetType:o,withAriaAttributes:i,withKeyboardNavigation:r,withExpandedAttribute:a,onKeyDown:d.props.onKeyDown,onClick:d.props.onClick,autoComplete:s}),m=(0,V.cloneElement)(d,{...p,...l});return(0,H.jsx)(et.Target,{refProp:n,ref:ie(c,f.store.targetRef),children:m})});Bn.displayName=`@mantine/core/ComboboxTarget`;function Vn(e,t,n){for(let n=e-1;n>=0;--n)if(!t[n].hasAttribute(`data-combobox-disabled`))return n;if(n){for(let e=t.length-1;e>-1;--e)if(!t[e].hasAttribute(`data-combobox-disabled`))return e}return e}function Hn(e,t,n){for(let n=e+1;n{s||(c(!0),i?.(e))},[c,i,s]),_=(0,V.useCallback)((e=`unknown`)=>{s&&(c(!1),r?.(e))},[c,r,s]),v=(0,V.useCallback)((e=`unknown`)=>{s?_(e):g(e)},[_,g,s]),y=(0,V.useCallback)(()=>{let e=Yt(f.current);qt(`#${l.current} [data-combobox-selected]`,e)?.removeAttribute(`data-combobox-selected`)},[]),b=(0,V.useCallback)(e=>{let t=Yt(f.current),n=qt(`#${l.current}`,t),r=n?Jt(`[data-combobox-option]`,n):null;if(!r)return null;let i=e>=r.length?0:e<0?r.length-1:e;return u.current=i,r?.[i]&&!r[i].hasAttribute(`data-combobox-disabled`)?(y(),r[i].setAttribute(`data-combobox-selected`,`true`),r[i].scrollIntoView({block:`nearest`,behavior:o}),r[i].id):null},[o,y]),x=(0,V.useCallback)(()=>{let e=Yt(f.current),t=qt(`#${l.current} [data-combobox-active]`,e);if(t){let n=Jt(`#${l.current} [data-combobox-option]`,e).findIndex(e=>e===t);return b(n)}return b(0)},[b]),S=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Hn(u.current,t,a))},[b,a]),C=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Vn(u.current,t,a))},[b,a]),w=(0,V.useCallback)(()=>{let e=Yt(f.current),t=Jt(`#${l.current} [data-combobox-option]`,e);return b(Un(t))},[b]),T=(0,V.useCallback)((e=`selected`,t)=>{if(typeof e==`number`){u.current=e;let n=Yt(f.current),r=Jt(`#${l.current} [data-combobox-option]`,n);t?.scrollIntoView&&r[e]?.scrollIntoView({block:`nearest`,behavior:o});return}h.current=window.setTimeout(()=>{let n=Yt(f.current),r=Jt(`#${l.current} [data-combobox-option]`,n),i=r.findIndex(t=>t.hasAttribute(`data-combobox-${e}`));u.current=i,t?.scrollIntoView&&r[i]?.scrollIntoView({block:`nearest`,behavior:o})},0)},[]),E=(0,V.useCallback)(()=>{u.current=-1,y()},[y]),D=(0,V.useCallback)(()=>{let e=Yt(f.current);(Jt(`#${l.current} [data-combobox-option]`,e)?.[u.current])?.click()},[]),O=(0,V.useCallback)(e=>{l.current=e},[]),k=(0,V.useCallback)(()=>{p.current=window.setTimeout(()=>d.current?.focus(),0)},[]),A=(0,V.useCallback)(()=>{m.current=window.setTimeout(()=>f.current?.focus(),0)},[]),j=(0,V.useCallback)(()=>u.current,[]);return(0,V.useEffect)(()=>()=>{window.clearTimeout(p.current),window.clearTimeout(m.current),window.clearTimeout(h.current)},[]),{dropdownOpened:s,openDropdown:g,closeDropdown:_,toggleDropdown:v,selectedOptionIndex:u.current,getSelectedOptionIndex:j,selectOption:b,selectFirstOption:w,selectActiveOption:x,selectNextOption:S,selectPreviousOption:C,resetSelectedOption:E,updateSelectedOptionIndex:T,listId:l.current,setListId:O,clickSelectedOption:D,searchRef:d,focusSearchInput:k,targetRef:f,focusTarget:A}}var Gn={keepMounted:!0,keepMountedMode:`display-none`,withinPortal:!0,resetSelectionOnOptionHover:!1,width:`target`,transitionProps:{transition:`fade`,duration:0},size:`sm`},Kn=g((e,{size:t,dropdownPadding:n})=>({options:{"--combobox-option-fz":L(t),"--combobox-option-padding":M(t,`combobox-option-padding`)},dropdown:{"--combobox-padding":n===void 0?void 0:P(n),"--combobox-option-fz":L(t),"--combobox-option-padding":M(t,`combobox-option-padding`)}})),qn=e=>{let t=u(`Combobox`,Gn,e),{classNames:n,styles:r,unstyled:i,children:o,store:s,vars:c,onOptionSubmit:l,onClose:d,size:f,dropdownPadding:p,resetSelectionOnOptionHover:m,__staticSelector:h,readOnly:g,attributes:_,floatingHeight:v,middlewares:y,...b}=t,x=v===`viewport`?{...y,flip:!1,size:{...typeof y?.size==`object`?y.size:{},padding:typeof y?.size==`object`&&y.size.padding!==void 0?y.size.padding:10,apply:({availableHeight:e,availableWidth:t,elements:n,...r})=>{n.floating.style.setProperty(`--combobox-floating-max-height`,`${e}px`);let i=y?.size;typeof i==`object`&&i.apply?i.apply({availableHeight:e,availableWidth:t,elements:n,...r}):i&&Object.assign(n.floating.style,{maxWidth:`${t}px`,maxHeight:`${e}px`})}}}:y,S=Wn(),C=s||S,w=a({name:h||`Combobox`,classes:_n,props:t,classNames:n,styles:r,unstyled:i,attributes:_,vars:c,varsResolver:Kn}),T=()=>{d?.(),C.closeDropdown()};return(0,H.jsx)(xn,{value:{getStyles:w,store:C,onOptionSubmit:l,size:f,resetSelectionOnOptionHover:m,readOnly:g,floatingHeight:v},children:(0,H.jsx)(et,{opened:C.dropdownOpened,...b,middlewares:x,onChange:e=>!e&&T(),withRoles:!1,unstyled:i,children:o})})};qn.extend=e=>e,qn.classes=_n,qn.varsResolver=Kn,qn.displayName=`@mantine/core/Combobox`,qn.Target=Bn,qn.Dropdown=wn,qn.Options=In,qn.Option=Fn,qn.Search=Rn,qn.Empty=Dn,qn.Chevron=bn,qn.Footer=jn,qn.Header=Nn,qn.EventsTarget=An,qn.DropdownTarget=En,qn.Group=Mn,qn.ClearButton=Cn,qn.HiddenInput=Pn;function Jn({children:e,role:t}){let n=(0,V.use)(D);return n?(0,H.jsx)(`div`,{role:t,"aria-labelledby":n.labelId,"aria-describedby":n.describedBy,children:e}):(0,H.jsx)(H.Fragment,{children:e})}var Yn={root:`m_5f75b09e`,body:`m_5f6e695e`,labelWrapper:`m_d3ea56bb`,label:`m_8ee546b8`,description:`m_328f68c0`,error:`m_8e8a99cc`},Xn=Yn;function Zn({__staticSelector:e,__stylesApiProps:t,className:n,classNames:r,styles:i,unstyled:s,children:c,label:l,description:u,id:d,disabled:f,error:p,size:m,labelPosition:h=`left`,bodyElement:g=`div`,labelElement:_=`label`,variant:v,style:y,vars:b,mod:x,attributes:S,...C}){let w=a({name:e,props:t,className:n,style:y,classes:Yn,classNames:r,styles:i,unstyled:s,attributes:S}),T=u?`${d}-description`:void 0,E=p&&typeof p!=`boolean`?`${d}-error`:void 0;return(0,H.jsx)(o,{...w(`root`),__vars:{"--label-fz":L(m),"--label-lh":M(m,`label-lh`)},mod:[{"label-position":h},x],variant:v,size:m,...C,children:(0,H.jsxs)(o,{component:g,htmlFor:g===`label`?d:void 0,...w(`body`),children:[c,(0,H.jsxs)(`div`,{...w(`labelWrapper`),"data-disabled":f||void 0,children:[l&&(0,H.jsx)(o,{component:_,htmlFor:_===`label`?d:void 0,...w(`label`),"data-disabled":f||void 0,children:l}),u&&(0,H.jsx)(k.Description,{id:T,size:m,__inheritStyles:!1,...w(`description`),children:u}),p&&typeof p!=`boolean`&&(0,H.jsx)(k.Error,{id:E,size:m,__inheritStyles:!1,...w(`error`),children:p})]})]})})}Zn.displayName=`@mantine/core/InlineInput`;function Qn(e){return`group`in e}function $n({options:e,search:t,limit:n}){let r=t.trim().toLowerCase(),i=[];for(let a=0;a0)return!1;return!0}function tr(e,t=new Set){if(Array.isArray(e))for(let n of e)if(Qn(n))tr(n.items,t);else{if(n.value===void 0)throw Error(`[@mantine/core] Each option must have value property`);if(t.has(n.value))throw Error(`[@mantine/core] Duplicate options are not supported. Option with value "${n.value}" was provided more than once`);t.add(n.value)}}function nr(e,t){return Array.isArray(e)?e.includes(t):e===t}function rr({data:e,withCheckIcon:t,withAlignedLabels:n,value:r,checkIconPosition:i,unstyled:a,renderOption:o}){if(!Qn(e)){let s=nr(r,e.value),c=t&&(s?(0,H.jsx)(Ct,{className:_n.optionsDropdownCheckIcon}):n?(0,H.jsx)(`div`,{className:_n.optionsDropdownCheckPlaceholder}):null),l=(0,H.jsxs)(H.Fragment,{children:[i===`left`&&c,(0,H.jsx)(`span`,{children:e.label}),i===`right`&&c]});return(0,H.jsx)(qn.Option,{value:e.value,disabled:e.disabled,className:_({[_n.optionsDropdownOption]:!a}),"data-reverse":i===`right`||void 0,"data-checked":s||void 0,"aria-selected":s,active:s,children:typeof o==`function`?o({option:e,checked:s}):l})}let s=e.items.map(e=>(0,H.jsx)(rr,{data:e,value:r,unstyled:a,withCheckIcon:t,withAlignedLabels:n,checkIconPosition:i,renderOption:o},`${e.value}`));return(0,H.jsx)(qn.Group,{label:e.group,children:s})}function ir({data:e,hidden:t,hiddenWhenEmpty:n,filter:r,search:i,limit:a,maxDropdownHeight:o,floatingHeight:s,withScrollArea:c=!0,filterOptions:l=!0,withCheckIcon:u=!1,withAlignedLabels:d=!1,value:f,checkIconPosition:p,nothingFoundMessage:m,unstyled:h,labelId:g,renderOption:_,scrollAreaProps:v,"aria-label":y}){let b=Sn();tr(e);let x=typeof i==`string`?(r||$n)({options:e,search:l?i:``,limit:a??1/0}):e,S=er(x),C=x.map((e,t)=>(0,H.jsx)(rr,{data:e,withCheckIcon:u,withAlignedLabels:d,value:f,checkIconPosition:p,unstyled:h,renderOption:_},Qn(e)?`group-${typeof e.group==`string`?e.group:t}`:`${e.value}`));return(0,H.jsx)(qn.Dropdown,{hidden:t||n&&S,"data-composed":!0,children:(0,H.jsxs)(qn.Options,{labelledBy:g,"aria-label":y,children:[c?(0,H.jsx)(fe.Autosize,{mah:(s??b.floatingHeight)===`viewport`?`var(--combobox-floating-options-max-height)`:o??220,type:`scroll`,scrollbarSize:`var(--combobox-padding)`,offsetScrollbars:`y`,...v,children:C}):C,S&&m&&(0,H.jsx)(qn.Empty,{children:m})]})})}function ar(e,t,n,r){if(t===n||r===`before`&&n===t+1||r===`after`&&n===t-1)return e;let i=e.slice(),[a]=i.splice(t,1),o=t{let t=e.lastElementChild;return t?t instanceof HTMLInputElement?t:t.querySelector(`input`):null},sr=(e,t)=>{if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n{let e=i.current;e&&(i.current=null,sr(o.current,e.expectedValue)&&e.container?.querySelector(`[data-mantine-pill-index="${e.index}"]`)?.focus())});let s=(0,V.useCallback)(e=>{a.current=e},[]);return{getPillProps:e=>{if(n)return{draggable:!0,tabIndex:-1,"data-mantine-pill-index":e,"aria-keyshortcuts":`Alt+ArrowLeft Alt+ArrowRight`,onMouseDown:e=>{e.button===0&&e.stopPropagation()},onDragStart:t=>{t.stopPropagation(),t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,String(e)),r.current.draggedIndex=e;let n=t.currentTarget,i=n.getBoundingClientRect(),a=n.cloneNode(!0);a.removeAttribute(`data-dragging`),a.removeAttribute(`data-drag-over`),a.style.position=`fixed`,a.style.top=`-9999px`,a.style.left=`-9999px`,a.style.width=`${i.width}px`,a.style.height=`${i.height}px`,a.style.pointerEvents=`none`,document.body.appendChild(a),t.dataTransfer.setDragImage(a,t.clientX-i.left,t.clientY-i.top),setTimeout(()=>a.parentNode?.removeChild(a),0),requestAnimationFrame(()=>{n.setAttribute(`data-dragging`,`true`)})},onDragOver:t=>{let{draggedIndex:n}=r.current;if(n===null||n===e)return;let i=t.currentTarget,a=i.getBoundingClientRect(),o=t.clientX-a.left,s=(getComputedStyle(i).direction===`rtl`?o>a.width/2:o{let t=e.currentTarget,n=e.relatedTarget;n&&t.contains(n)||(t.removeAttribute(`data-drag-over`),r.current.currentDropTarget===t&&(r.current.currentDropTarget=null))},onDrop:n=>{n.preventDefault(),n.stopPropagation();let i=n.currentTarget,a=i.getAttribute(`data-drag-over`);i.removeAttribute(`data-drag-over`);let{draggedIndex:s}=r.current;if(s!==null&&a&&s!==e){let n=ar(o.current,s,e,a);n!==o.current&&t(n)}r.current.draggedIndex=null,r.current.currentDropTarget=null},onDragEnd:e=>{e.currentTarget.removeAttribute(`data-dragging`);let t=r.current.currentDropTarget;t&&t.removeAttribute(`data-drag-over`),r.current.draggedIndex=null,r.current.currentDropTarget=null},onKeyDown:n=>{if(n.key!==`ArrowLeft`&&n.key!==`ArrowRight`)return;let r=n.currentTarget,a=getComputedStyle(r).direction===`rtl`?n.key===`ArrowLeft`:n.key===`ArrowRight`,s=a?e+1:e-1;if(n.altKey){if(s<0||s>=o.current.length)return;n.preventDefault(),n.stopPropagation();let c=a?`after`:`before`,l=ar(o.current,e,s,c);if(l===o.current)return;i.current={container:r.parentElement,index:s,expectedValue:l},t(l);return}if(s<0)return;let c=r.parentElement;if(c){if(n.preventDefault(),n.stopPropagation(),s>=o.current.length){or(c)?.focus();return}c.querySelector(`[data-mantine-pill-index="${s}"]`)?.focus()}}}},getListProps:()=>n?{ref:s}:{},handleInputKeyDown:e=>{if(!n||e.key!==`ArrowLeft`)return;let t=e.currentTarget;if(!(t.value.length===0||t.selectionStart===0&&t.selectionEnd===0))return;let r=a.current;if(!r)return;let i=r.querySelectorAll(`[data-mantine-pill-index]`);i.length!==0&&(e.preventDefault(),i[i.length-1].focus())}}}function lr({id:e,label:t,labelProps:n,inputWrapperOrder:r}){if(t&&(!r||r.includes(`label`)))return n?.id||`${e}-label`}function ur(e){let t=e.currentTarget;return Yt(t).activeElement!==t}var dr=(0,V.createContext)(null),fr={root:`m_7cda1cd6`,"root--default":`m_44da308b`,"root--contrast":`m_e3a01f8`,label:`m_1e0e6180`,remove:`m_ae386778`,group:`m_1dcfd90b`},pr=(0,V.createContext)(null),mr=g((e,{gap:t},{size:n})=>({group:{"--pg-gap":t===void 0?M(n,`pg-gap`):M(t)}})),hr=h(e=>{let t=u(`PillGroup`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,size:d,disabled:f,attributes:p,...m}=t,h=(0,V.use)(dr)?.size||d||void 0,g=a({name:`PillGroup`,classes:fr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:p,vars:l,varsResolver:mr,stylesCtx:{size:h},rootSelector:`group`});return(0,H.jsx)(pr,{value:{size:h,disabled:f},children:(0,H.jsx)(o,{size:h,...g(`group`),...m})})});hr.classes=fr,hr.varsResolver=mr,hr.displayName=`@mantine/core/PillGroup`;var gr={variant:`default`},_r=g((e,{radius:t},{size:n})=>({root:{"--pill-fz":M(n,`pill-fz`),"--pill-height":M(n,`pill-height`),"--pill-radius":t===void 0?void 0:re(t)}})),vr=h(e=>{let t=u(`Pill`,gr,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,variant:d,children:f,withRemoveButton:p,onRemove:m,removeButtonProps:h,radius:g,size:_,disabled:v,mod:y,attributes:b,...x}=t,S=(0,V.use)(pr),C=(0,V.use)(dr),w=_||S?.size||void 0,T=C?.variant===`filled`?`contrast`:d||`default`,E=a({name:`Pill`,classes:fr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:b,vars:l,varsResolver:_r,stylesCtx:{size:w}});return(0,H.jsxs)(o,{component:`span`,variant:T,size:w,...E(`root`,{variant:T}),mod:[{"with-remove":p&&!v,disabled:v||S?.disabled},y],...x,children:[(0,H.jsx)(`span`,{...E(`label`),children:f}),p&&(0,H.jsx)(oe,{variant:`transparent`,radius:g,tabIndex:-1,"aria-hidden":!0,unstyled:c,...h,...E(`remove`,{className:h?.className,style:h?.style}),onMouseDown:e=>{e.preventDefault(),e.stopPropagation(),h?.onMouseDown?.(e)},onClick:e=>{e.stopPropagation(),m?.(),h?.onClick?.(e)}})]})});vr.classes=fr,vr.varsResolver=_r,vr.displayName=`@mantine/core/Pill`,vr.Group=hr;var yr={field:`m_45c4369d`},br={type:`visible`},xr=h(e=>{let t=u(`PillsInputField`,br,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,type:d,disabled:f,id:p,pointer:m,mod:h,attributes:g,ref:_,...v}=t,y=(0,V.use)(dr),b=(0,V.use)(D),x=a({name:`PillsInputField`,classes:yr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:g,rootSelector:`field`}),S=f||y?.disabled;return(0,H.jsx)(o,{component:`input`,ref:ie(_,y?.fieldRef),"data-type":d,disabled:S,mod:[{disabled:S,pointer:m},h],...x(`field`),...v,id:b?.inputId||p,"aria-invalid":y?.hasError,"aria-describedby":b?.describedBy,type:`text`,onMouseDown:e=>!m&&e.stopPropagation()})});xr.classes=yr,xr.displayName=`@mantine/core/PillsInputField`;var Sr={size:`sm`},Cr=h(e=>{let{children:t,onMouseDown:n,onClick:r,size:i,disabled:a,__staticSelector:o,error:s,variant:c,...l}=u([`Input`,`InputWrapper`,`PillsInput`],Sr,e),d=(0,V.useRef)(null);return(0,H.jsx)(dr,{value:{fieldRef:d,size:i,disabled:a,hasError:!!s,variant:c},children:(0,H.jsx)(N,{size:i,error:s,variant:c,component:`div`,"data-no-overflow":!0,onMouseDown:e=>{e.preventDefault(),n?.(e),d.current?.focus()},onClick:e=>{e.preventDefault(),e.currentTarget.closest(`fieldset`)?.disabled||(d.current?.focus(),r?.(e))},...l,multiline:!0,disabled:a,__staticSelector:o||`PillsInput`,withAria:!1,children:t})})});Cr.displayName=`@mantine/core/PillsInput`,Cr.classes=N.classes,Cr.Field=xr;function wr(e,t){let n=t.trim().toLowerCase();if(n===``)return;let r=Object.values(e).filter(e=>!e.disabled&&e.label.trim().toLowerCase()===n);return r.length===1?r[0]:void 0}function Tr(e){return typeof e==`string`?e.trim().toLowerCase():e}function Er({data:e,value:t}){let n=t.map(Tr);return e.reduce((e,t)=>(Qn(t)?e.push({group:t.group,items:t.items.filter(e=>n.indexOf(Tr(e.value))===-1)}):n.indexOf(Tr(t.value))===-1&&e.push(t),e),[])}var Dr={xs:41,sm:50,md:60,lg:72,xl:89},Or={maxValues:1/0,withCheckIcon:!0,checkIconPosition:`left`,hiddenInputValuesDivider:`,`,clearSearchOnChange:!0,openOnFocus:!0,size:`sm`},kr=c(e=>{let t=u([`Input`,`InputWrapper`,`MultiSelect`],Or,e),{classNames:n,className:r,style:i,styles:o,unstyled:s,vars:c,size:l,value:f,defaultValue:p,onChange:m,onKeyDown:h,variant:g,data:_,dropdownOpened:v,defaultDropdownOpened:y,onDropdownOpen:b,onDropdownClose:x,selectFirstOptionOnChange:S,selectFirstOptionOnDropdownOpen:C,onOptionSubmit:w,comboboxProps:T,filter:E,limit:D,withScrollArea:O,maxDropdownHeight:k,floatingHeight:j,searchValue:M,defaultSearchValue:N,onSearchChange:P,readOnly:I,disabled:L,onFocus:ee,onBlur:te,radius:ne,rightSection:re,rightSectionWidth:ie,rightSectionPointerEvents:ae,rightSectionProps:R,leftSection:oe,leftSectionWidth:z,leftSectionPointerEvents:se,leftSectionProps:ce,inputContainer:le,inputWrapperOrder:ue,withAsterisk:de,labelProps:fe,descriptionProps:pe,errorProps:me,successProps:he,wrapperProps:ge,description:_e,label:ve,error:B,success:ye,maxValues:be,searchable:xe,nothingFoundMessage:Se,withCheckIcon:Ce,withAlignedLabels:we,checkIconPosition:Te,hidePickedOptions:Ee,withErrorStyles:De,withSuccessStyles:Oe,name:ke,form:Ae,id:je,clearable:Me,clearSectionMode:Ne,clearButtonProps:Pe,hiddenInputProps:Fe,placeholder:Ie,hiddenInputValuesDivider:Le,required:Re,mod:ze,renderOption:Be,renderPill:Ve,onRemove:He,onClear:Ue,onMaxValues:We,scrollAreaProps:Ge,chevronColor:Ke,attributes:qe,clearSearchOnChange:Je,openOnFocus:Ye,loading:Xe,loadingPosition:Ze,withPillsReorder:Qe,...$e}=t,et=F(je),tt=lr({id:et,label:ve,labelProps:fe,inputWrapperOrder:ue}),nt=hn(_),rt=gn(nt),it=(0,V.useRef)({}),at=Wn({opened:v,defaultOpened:y,onDropdownOpen:()=>{b?.(),C&&at.selectFirstOption()},onDropdownClose:()=>{x?.(),at.resetSelectedOption()}}),{styleProps:ot,rest:{type:st,autoComplete:ct,...lt}}=d($e),[ut,dt]=kt({value:f,defaultValue:p,finalValue:[],onChange:m}),{getPillProps:ft,getListProps:pt,handleInputKeyDown:mt}=cr({value:ut,onChange:dt,enabled:Qe&&!L&&!I}),[ht,gt]=kt({value:M,defaultValue:N,finalValue:``,onChange:P}),_t=e=>{gt(e),at.resetSelectedOption()},vt=a({name:`MultiSelect`,classes:{},props:t,classNames:n,styles:o,unstyled:s,attributes:qe}),{resolvedClassNames:yt,resolvedStyles:bt}=A({props:t,styles:o,classNames:n}),xt=e=>{h?.(e),!e.defaultPrevented&&(e.key===` `&&!xe&&(e.preventDefault(),at.toggleDropdown()),e.key===`Backspace`&&ht.length===0&&ut.length>0&&!I&&(He?.(ut[ut.length-1]),dt(ut.slice(0,ut.length-1))),mt(e))},St=ut.map((e,t)=>{let n=rt[`${e}`]||it.current[`${e}`],r=ft(t);return Ve?(0,H.jsx)(V.Fragment,{children:Ve({option:n,value:e,onRemove:()=>{dt(ut.filter(t=>e!==t)),He?.(e)},disabled:L,reorderProps:r})},`${e}-${t}`):(0,H.jsx)(vr,{withRemoveButton:!I&&!rt[`${e}`]?.disabled,onRemove:()=>{dt(ut.filter(t=>e!==t)),He?.(e)},unstyled:s,disabled:L,...vt(`pill`),...r,children:n?.label||e},`${e}-${t}`)});(0,V.useEffect)(()=>{S&&at.selectFirstOption()},[S,ht]),(0,V.useEffect)(()=>{ut.forEach(e=>{`${e}`in rt&&(it.current[`${e}`]=rt[`${e}`])})},[rt,ut]);let Ct=(0,H.jsx)(qn.ClearButton,{...Pe,onClear:()=>{Ue?.(),dt([]),_t(``)}}),wt=Er({data:nt,value:ut}),Tt=Me&&ut.length>0&&!L&&!I,Et=Tt?{paddingInlineEnd:Dr[l]??Dr.sm}:void 0;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(qn,{store:at,classNames:yt,styles:bt,unstyled:s,size:l,readOnly:I,__staticSelector:`MultiSelect`,attributes:qe,floatingHeight:j,onOptionSubmit:e=>{w?.(e),Je&&_t(``),at.updateSelectedOptionIndex(`selected`),ut.includes(rt[`${e}`].value)?(dt(ut.filter(t=>t!==rt[`${e}`].value)),He?.(rt[`${e}`].value)):ut.lengthxe?at.openDropdown():at.toggleDropdown(),"data-expanded":at.dropdownOpened||void 0,id:et,required:Re,mod:ze,attributes:qe,children:(0,H.jsxs)(vr.Group,{attributes:qe,disabled:L,unstyled:s,...vt(`pillsList`,{style:Et}),...pt(),children:[St,(0,H.jsx)(qn.EventsTarget,{autoComplete:ct,withExpandedAttribute:!0,children:(0,H.jsx)(Cr.Field,{...lt,id:et,placeholder:Ie,type:!xe&&!Ie?`hidden`:`visible`,...vt(`inputField`),unstyled:s,onFocus:e=>{ee?.(e),Ye&&xe&&at.openDropdown()},onBlur:e=>{te?.(e),at.closeDropdown(),_t(``)},onKeyDown:xt,value:ht,onChange:e=>{if(ur(e)){if(!I){let t=wr(rt,e.currentTarget.value);t&&!ut.includes(t.value)&&ut.length{let{classNames:t,className:n,style:r,styles:i,vars:a,...s}=u(`ProgressLabel`,null,e),c=jr();return(0,H.jsx)(o,{...c.getStyles(`label`,{className:n,style:r,classNames:t,styles:i}),...s})});Nr.classes=Mr,Nr.displayName=`@mantine/core/ProgressLabel`;var Pr=g((e,{size:t,radius:n,transitionDuration:r})=>({root:{"--progress-size":M(t,`progress-size`),"--progress-radius":n===void 0?void 0:re(n),"--progress-transition-duration":typeof r==`number`?`${r}ms`:void 0}})),Fr=h(e=>{let t=u(`ProgressRoot`,null,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,autoContrast:d,transitionDuration:f,orientation:p,attributes:m,mod:h,...g}=t,_=a({name:`Progress`,classes:Mr,props:t,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:m,vars:l,varsResolver:Pr});return(0,H.jsx)(Ar,{value:{getStyles:_,autoContrast:d},children:(0,H.jsx)(o,{mod:[{orientation:p},h],..._(`root`),...g})})});Fr.classes=Mr,Fr.varsResolver=Pr,Fr.displayName=`@mantine/core/ProgressRoot`;var Ir={withAria:!0},Lr=h(e=>{let{classNames:t,className:n,style:r,styles:i,vars:a,value:s,withAria:c,color:d,striped:p,animated:m,mod:h,...g}=u(`ProgressSection`,Ir,e),_=jr(),v=f(),y=c?{role:`progressbar`,"aria-valuemax":100,"aria-valuemin":0,"aria-valuenow":s,"aria-valuetext":`${s}%`}:{};return(0,H.jsx)(o,{..._.getStyles(`section`,{className:n,classNames:t,styles:i,style:r}),...g,...y,mod:[{striped:p||m,animated:m},h],__vars:{"--progress-section-size":`${s}%`,"--progress-section-color":l(d,v),"--progress-label-color":Xt(_.autoContrast,v)?ut({color:d,theme:v,autoContrast:_.autoContrast}):void 0}})});Lr.classes=Mr,Lr.displayName=`@mantine/core/ProgressSection`;var Rr=h(e=>{let t=u(`Progress`,null,e),{value:n,classNames:r,styles:i,vars:a,color:o,striped:s,animated:c,"aria-label":l,...d}=t,{resolvedClassNames:f,resolvedStyles:p}=A({classNames:r,styles:i,props:t});return(0,H.jsx)(Fr,{classNames:f,styles:p,vars:a,...d,children:(0,H.jsx)(Lr,{value:n,color:o,striped:s,animated:c,"aria-label":l})})});Rr.classes=Mr,Rr.displayName=`@mantine/core/Progress`,Rr.Section=Lr,Rr.Root=Fr,Rr.Label=Nr;var zr={root:`m_cf365364`,indicator:`m_9e182ccd`,label:`m_1738fcb2`,input:`m_1714d588`,control:`m_69686b9b`,innerLabel:`m_78882f40`},Br={withItemsBorders:!0},Vr=g((e,{radius:t,color:n,transitionDuration:r,size:i,transitionTimingFunction:a})=>({root:{"--sc-radius":t===void 0?void 0:re(t),"--sc-color":n?l(n,e):void 0,"--sc-shadow":n?void 0:`var(--mantine-shadow-xs)`,"--sc-transition-duration":r===void 0?void 0:`${r}ms`,"--sc-transition-timing-function":a,"--sc-padding":M(i,`sc-padding`),"--sc-font-size":L(i)}})),Hr=c(e=>{let t=u(`SegmentedControl`,Br,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,data:d,value:p,defaultValue:m,onChange:h,size:g,name:_,disabled:v,readOnly:y,fullWidth:b,orientation:x,radius:S,color:C,transitionDuration:w,transitionTimingFunction:T,variant:E,autoContrast:D,withItemsBorders:O,mod:k,attributes:A,ref:j,...M}=t,N=a({name:`SegmentedControl`,props:t,classes:zr,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:A,vars:l,varsResolver:Vr}),P=f(),I=d.map(e=>Kt(e)?{label:`${e}`,value:e}:e),L=Gt(),[ee,te]=(0,V.useState)(0),[ne,re]=(0,V.useState)(null),[ae,R]=(0,V.useState)({}),oe=(e,t)=>{e!==null&&ae[t]!==e&&(ae[t]=e,R({...ae}))},[z,se]=kt({value:p,defaultValue:m,finalValue:Array.isArray(d)?I.find(e=>!e.disabled)?.value??d[0]?.value??null:null,onChange:h}),ce=F(_),le=I.map(e=>`${e.value}`),ue=I.map(e=>(0,V.createElement)(o,{...N(`control`),mod:{active:z===e.value,orientation:x},key:`${e.value}`},(0,V.createElement)(`input`,{...N(`input`),disabled:v||e.disabled,type:`radio`,name:ce,value:`${e.value}`,id:`${ce}-${e.value}`,checked:z===e.value,onChange:()=>!y&&se(e.value),"data-focus-ring":P.focusRing,key:`${e.value}-input`}),(0,V.createElement)(o,{component:`label`,...N(`label`),mod:{active:z===e.value&&!(v||e.disabled),disabled:v||e.disabled,"read-only":y},htmlFor:`${ce}-${e.value}`,ref:t=>oe(t,`${e.value}`),__vars:{"--sc-label-color":C===void 0?void 0:ut({color:C,theme:P,autoContrast:D})},key:`${e.value}-label`},(0,H.jsx)(`span`,{...N(`innerLabel`),children:e.label})))),de=ie(j,re);return Vt(()=>{te(e=>e+1)},[d.length]),Vt(()=>{R(e=>{let t={};return le.forEach(n=>{n in e&&(t[n]=e[n])}),Object.keys(t).length===Object.keys(e).length?e:t})},[le]),d.length===0?null:(0,H.jsxs)(o,{...N(`root`),variant:E,size:g,ref:de,mod:[{"full-width":b,orientation:x,initialized:L,"with-items-borders":O},k],...M,role:`radiogroup`,"data-disabled":v,children:[z!==void 0&&(0,H.jsx)(tn,{target:ae[`${z}`],parent:ne,component:`span`,transitionDuration:`var(--sc-transition-duration)`,...N(`indicator`)},ee),ue]})});Hr.classes=zr,Hr.varsResolver=Vr,Hr.displayName=`@mantine/core/SegmentedControl`;var Ur={size:`sm`,withCheckIcon:!0,allowDeselect:!0,checkIconPosition:`left`,openOnFocus:!0},Wr=c(e=>{let t=u([`Input`,`InputWrapper`,`Select`],Ur,e),{classNames:n,styles:r,unstyled:i,vars:a,dropdownOpened:o,defaultDropdownOpened:s,onDropdownClose:c,onDropdownOpen:l,onFocus:d,onBlur:f,onClick:p,onChange:m,data:h,value:g,defaultValue:_,selectFirstOptionOnChange:v,selectFirstOptionOnDropdownOpen:y,onOptionSubmit:b,comboboxProps:x,readOnly:S,disabled:C,filter:w,limit:T,withScrollArea:E,maxDropdownHeight:D,floatingHeight:O,size:k,searchable:j,rightSection:M,checkIconPosition:P,withCheckIcon:I,withAlignedLabels:L,nothingFoundMessage:ee,name:te,form:ne,searchValue:re,defaultSearchValue:ie,onSearchChange:ae,allowDeselect:R,error:oe,rightSectionPointerEvents:z,id:se,clearable:ce,clearSectionMode:le,clearButtonProps:ue,hiddenInputProps:de,renderOption:fe,onClear:pe,autoComplete:me,scrollAreaProps:he,__defaultRightSection:ge,__clearSection:_e,__clearable:ve,chevronColor:B,autoSelectOnBlur:ye,openOnFocus:be,attributes:xe,...Se}=t,Ce=(0,V.useMemo)(()=>hn(h),[h]),we=(0,V.useRef)({}),Te=(0,V.useMemo)(()=>gn(Ce),[Ce]),Ee=F(se),De=lr({id:Ee,label:Se.label,labelProps:Se.labelProps,inputWrapperOrder:Se.inputWrapperOrder}),[Oe,ke,Ae]=kt({value:g,defaultValue:_,finalValue:null,onChange:m}),je=Oe==null?void 0:`${Oe}`in Te?Te[`${Oe}`]:we.current[`${Oe}`],Me=Ut(je),[Ne,Pe,Fe]=kt({value:re,defaultValue:ie,finalValue:je?je.label:``,onChange:ae}),Ie=Wn({opened:o,defaultOpened:s,onDropdownOpen:()=>{l?.(),y?Ie.selectFirstOption():Ie.updateSelectedOptionIndex(`active`,{scrollIntoView:!0})},onDropdownClose:()=>{c?.(),setTimeout(Ie.resetSelectedOption,0)}}),Le=e=>{Pe(e),Ie.resetSelectedOption()},{resolvedClassNames:Re,resolvedStyles:ze}=A({props:t,styles:r,classNames:n});(0,V.useEffect)(()=>{v&&Ie.selectFirstOption()},[v,Ne]),(0,V.useEffect)(()=>{g===null&&Le(``),g!=null&&je&&(Me?.value!==je.value||Me?.label!==je.label)&&Le(je.label)},[g,je]),(0,V.useEffect)(()=>{!Ae&&!Fe&&Le(Oe==null?``:`${Oe}`in Te?Te[`${Oe}`]?.label:we.current[`${Oe}`]?.label||``)},[Te,Oe]),(0,V.useEffect)(()=>{Oe&&`${Oe}`in Te&&(we.current[`${Oe}`]=Te[`${Oe}`])},[Te,Oe]);let Be=(0,H.jsx)(qn.ClearButton,{...ue,onClear:()=>{ke(null,null),Le(``),pe?.()}}),Ve=ce&&Oe!=null&&!C&&!S;return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(qn,{store:Ie,__staticSelector:`Select`,classNames:Re,styles:ze,unstyled:i,readOnly:S,size:k,attributes:xe,floatingHeight:O,keepMounted:ye,onOptionSubmit:e=>{b?.(e);let t=R&&`${Te[e].value}`==`${Oe}`?null:Te[e],n=t?t.value:null;n!==Oe&&ke(n,t),!Ae&&Le(n==null?``:t?.label||``),Ie.closeDropdown()},...x,children:[(0,H.jsx)(qn.Target,{targetType:j?`input`:`button`,autoComplete:me,withExpandedAttribute:!0,children:(0,H.jsx)(N,{id:Ee,__defaultRightSection:(0,H.jsx)(qn.Chevron,{size:k,error:oe,unstyled:i,color:B}),__clearSection:Be,__clearable:Ve,__clearSectionMode:le,rightSection:M,rightSectionPointerEvents:z||`none`,...Se,size:k,__staticSelector:`Select`,disabled:C,readOnly:S||!j,value:Ne,onChange:e=>{if(ur(e)){if(!S){let t=wr(Te,e.currentTarget.value);t&&`${t.value}`!=`${Oe}`&&(ke(t.value,t),!Ae&&Le(t.label))}return}Le(e.currentTarget.value),Ie.openDropdown(),v&&Ie.selectFirstOption()},onFocus:e=>{be&&j&&Ie.openDropdown(),d?.(e)},onBlur:e=>{ye&&Ie.clickSelectedOption(),Ie.closeDropdown();let t=Oe!=null&&(`${Oe}`in Te?Te[`${Oe}`]:we.current[`${Oe}`]);Le(t&&t.label||``),f?.(e)},onClick:e=>{j?Ie.openDropdown():Ie.toggleDropdown(),p?.(e)},classNames:Re,styles:ze,unstyled:i,pointer:!j,error:oe,attributes:xe})}),(0,H.jsx)(ir,{data:Ce,hidden:S||C,filter:w,search:Ne,limit:T,hiddenWhenEmpty:!ee,withScrollArea:E,maxDropdownHeight:D,filterOptions:!!j&&je?.label!==Ne,value:Oe,checkIconPosition:P,withCheckIcon:I,withAlignedLabels:L,nothingFoundMessage:ee,unstyled:i,labelId:De,"aria-label":De?void 0:Se[`aria-label`],renderOption:fe,scrollAreaProps:he})]}),(0,H.jsx)(qn.HiddenInput,{value:Oe,name:te,form:ne,disabled:C,...de})]})});Wr.classes={...N.classes,...qn.classes},Wr.displayName=`@mantine/core/Select`;function Gr(e){if(e!==void 0)return typeof e==`number`?P(e):e}function Kr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r,autoRows:i,selector:a}){let o=f(),s=t===void 0?e:t,c=r!==void 0,l=E({"--sg-spacing-x":R(Lt(e)),"--sg-spacing-y":R(Lt(s)),"--sg-auto-rows":i,...c?{"--sg-min-col-width":Gr(r)}:{"--sg-cols":Lt(n)?.toString()}}),u=O(o.breakpoints).reduce((t,r)=>(t[r]||(t[r]={}),typeof e==`object`&&e[r]!==void 0&&(t[r][`--sg-spacing-x`]=R(e[r])),typeof s==`object`&&s[r]!==void 0&&(t[r][`--sg-spacing-y`]=R(s[r])),!c&&typeof n==`object`&&n[r]!==void 0&&(t[r][`--sg-cols`]=n[r]),t),{}),d=bt(O(u),o.breakpoints).filter(e=>O(u[e.value]).length>0).map(e=>({query:`(min-width: ${o.breakpoints[e.value]})`,styles:u[e.value]}));return(0,H.jsx)(j,{styles:l,media:d,selector:a})}function qr(e){return typeof e==`object`&&e?O(e):[]}function Jr(e){return e.sort((e,t)=>mt(e)-mt(t))}function Yr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r}){return Jr(Array.from(new Set([...qr(e),...qr(t),...r===void 0?qr(n):[]])))}function Xr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r,autoRows:i,selector:a}){let o=t===void 0?e:t,s=r!==void 0,c=E({"--sg-spacing-x":R(Lt(e)),"--sg-spacing-y":R(Lt(o)),"--sg-auto-rows":i,...s?{"--sg-min-col-width":Gr(r)}:{"--sg-cols":Lt(n)?.toString()}}),l=Yr({spacing:e,verticalSpacing:t,cols:n,minColWidth:r}),u=l.reduce((t,r)=>(t[r]||(t[r]={}),typeof e==`object`&&e[r]!==void 0&&(t[r][`--sg-spacing-x`]=R(e[r])),typeof o==`object`&&o[r]!==void 0&&(t[r][`--sg-spacing-y`]=R(o[r])),!s&&typeof n==`object`&&n[r]!==void 0&&(t[r][`--sg-cols`]=n[r]),t),{}),d=l.map(e=>({query:`simple-grid (min-width: ${e})`,styles:u[e]}));return(0,H.jsx)(j,{styles:c,container:d,selector:a})}var Zr={container:`m_925c2d2c`,root:`m_2415a157`},Qr={cols:1,spacing:`md`,type:`media`},$r=h(e=>{let t=u(`SimpleGrid`,Qr,e),{classNames:n,className:r,style:i,styles:c,unstyled:l,vars:d,cols:f,verticalSpacing:p,spacing:m,type:h,minColWidth:g,autoFlow:_,autoRows:v,attributes:y,...b}=t,x=a({name:`SimpleGrid`,classes:Zr,props:t,className:r,style:i,classNames:n,styles:c,unstyled:l,attributes:y,vars:d}),S=s(),C=g===void 0?void 0:_||`auto-fill`;return h===`container`?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Xr,{...t,selector:`.${S}`}),(0,H.jsx)(`div`,{...x(`container`),children:(0,H.jsx)(o,{...x(`root`,{className:S}),...b,"data-auto-cols":C})})]}):(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Kr,{...t,selector:`.${S}`}),(0,H.jsx)(o,{...x(`root`,{className:S}),...b,"data-auto-cols":C})]})});$r.classes=Zr,$r.displayName=`@mantine/core/SimpleGrid`;var ei=(0,V.createContext)(null),ti={hiddenInputValuesSeparator:`,`},ni=c((e=>{let{value:t,defaultValue:n,onChange:r,size:i,wrapperProps:a,children:o,readOnly:s,name:c,hiddenInputValuesSeparator:l,hiddenInputProps:d,maxSelectedValues:f,disabled:p,...m}=u(`SwitchGroup`,ti,e),[h,g]=kt({value:t,defaultValue:n,finalValue:[],onChange:r}),_=e=>{let t=e.currentTarget.value;if(s)return;let n=h.includes(t);!n&&f&&h.length>=f||g(n?h.filter(e=>e!==t):[...h,t])},v=e=>{if(p)return!0;if(!f)return!1;let t=h.includes(e),n=h.length>=f;return!t&&n},y=h.join(l);return(0,H.jsx)(ei,{value:{value:h,onChange:_,size:i,isDisabled:v},children:(0,H.jsxs)(k.Wrapper,{size:i,...a,...m,labelElement:`div`,__staticSelector:`SwitchGroup`,children:[(0,H.jsx)(Jn,{role:`group`,children:o}),(0,H.jsx)(`input`,{type:`hidden`,name:c,value:y,...d})]})})}));ni.classes=k.Wrapper.classes,ni.displayName=`@mantine/core/SwitchGroup`;var ri={root:`m_5f93f3bb`,input:`m_926b4011`,track:`m_9307d992`,thumb:`m_93039a1d`,trackLabel:`m_8277e082`},ii={labelPosition:`right`,withThumbIndicator:!0},ai=g((e,{radius:t,color:n,size:r})=>({root:{"--switch-radius":t===void 0?void 0:re(t),"--switch-height":M(r,`switch-height`),"--switch-width":M(r,`switch-width`),"--switch-thumb-size":M(r,`switch-thumb-size`),"--switch-label-font-size":M(r,`switch-label-font-size`),"--switch-track-label-padding":M(r,`switch-track-label-padding`),"--switch-color":n?l(n,e):void 0}})),oi=h(e=>{let t=u(`Switch`,ii,e),{classNames:n,className:r,style:i,styles:s,unstyled:c,vars:l,color:f,label:p,offLabel:m,onLabel:h,id:g,size:_,radius:v,wrapperProps:y,thumbIcon:b,checked:x,defaultChecked:S,onChange:C,labelPosition:w,description:T,error:E,disabled:D,variant:O,rootRef:k,mod:A,withThumbIndicator:j,attributes:M,...N}=t,P=(0,V.use)(ei),I=_||P?.size,L=a({name:`Switch`,props:t,classes:ri,className:r,style:i,classNames:n,styles:s,unstyled:c,attributes:M,vars:l,varsResolver:ai}),{styleProps:ee,rest:te}=d(N),ne=F(g),re=[T?`${ne}-description`:void 0,E&&typeof E!=`boolean`?`${ne}-error`:void 0,te[`aria-describedby`]].filter(Boolean).join(` `)||void 0,ie={checked:P?.value.includes(te.value)??x,onChange:e=>{P?.onChange(e),C?.(e)}},ae=D||P?.isDisabled?.(te.value),[R,oe]=kt({value:ie.checked??x,defaultValue:S,finalValue:!1});return(0,H.jsxs)(Zn,{...L(`root`),__staticSelector:`Switch`,__stylesApiProps:t,id:ne,size:I,labelPosition:w,label:p,description:T,error:E,disabled:ae,bodyElement:`label`,labelElement:`span`,classNames:n,styles:s,unstyled:c,"data-checked":ie.checked,variant:O,ref:k,mod:A,attributes:M,inert:te.inert,...ee,...y,children:[(0,H.jsx)(`input`,{...te,...ie,disabled:ae,checked:R,"data-checked":ie.checked,onChange:e=>{ie.onChange?.(e),oe(e.currentTarget.checked)},id:ne,type:`checkbox`,role:`switch`,inert:te.inert,"aria-describedby":re,...L(`input`)}),(0,H.jsxs)(o,{"aria-hidden":`true`,component:`span`,mod:{error:E,"label-position":w,"without-labels":!h&&!m},...L(`track`),children:[(0,H.jsx)(o,{component:`span`,mod:{"reduce-motion":!0,"with-thumb-indicator":j&&!b},...L(`thumb`),children:b}),(0,H.jsx)(`span`,{...L(`trackLabel`),children:R?h:m})]})]})});oi.classes={...ri,...Xn},oi.varsResolver=ai,oi.displayName=`@mantine/core/Switch`,oi.Group=ni;var si=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M244,56v48a12,12,0,0,1-12,12H184a12,12,0,1,1,0-24H201.1l-19-17.38c-.13-.12-.26-.24-.38-.37A76,76,0,1,0,127,204h1a75.53,75.53,0,0,0,52.15-20.72,12,12,0,0,1,16.49,17.45A99.45,99.45,0,0,1,128,228h-1.37A100,100,0,1,1,198.51,57.06L220,76.72V56a12,12,0,0,1,24,0Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1-5.66-13.66l17-17-10.55-9.65-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,1,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60l10.93,10L226.34,50.3A8,8,0,0,1,240,56Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M238,56v48a6,6,0,0,1-6,6H184a6,6,0,0,1,0-12h32.55l-30.38-27.8c-.06-.06-.12-.13-.19-.19a82,82,0,1,0-1.7,117.65,6,6,0,0,1,8.24,8.73A93.46,93.46,0,0,1,128,222h-1.28A94,94,0,1,1,194.37,61.4L226,90.35V56a6,6,0,1,1,12,0Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M236,56v48a4,4,0,0,1-4,4H184a4,4,0,0,1,0-8h37.7L187.53,68.69l-.13-.12a84,84,0,1,0-1.75,120.51,4,4,0,0,1,5.5,5.82A91.43,91.43,0,0,1,128,220h-1.26A92,92,0,1,1,193,62.84l35,32.05V56a4,4,0,1,1,8,0Z`}))]]),ci=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M228,128a100,100,0,0,1-98.66,100H128a99.39,99.39,0,0,1-68.62-27.29,12,12,0,0,1,16.48-17.45,76,76,0,1,0-1.57-109c-.13.13-.25.25-.39.37L54.89,92H72a12,12,0,0,1,0,24H24a12,12,0,0,1-12-12V56a12,12,0,0,1,24,0V76.72L57.48,57.06A100,100,0,0,1,228,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L60.63,81.29l17,17A8,8,0,0,1,72,112H24a8,8,0,0,1-8-8V56A8,8,0,0,1,29.66,50.3L49.31,70,60.25,60A96,96,0,0,1,224,128Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M222,128a94,94,0,0,1-92.74,94H128a93.43,93.43,0,0,1-64.5-25.65,6,6,0,1,1,8.24-8.72A82,82,0,1,0,70,70l-.19.19L39.44,98H72a6,6,0,0,1,0,12H24a6,6,0,0,1-6-6V56a6,6,0,0,1,12,0V90.34L61.63,61.4A94,94,0,0,1,222,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M220,128a92,92,0,0,1-90.77,92H128a91.47,91.47,0,0,1-63.13-25.1,4,4,0,1,1,5.5-5.82A84,84,0,1,0,68.6,68.57l-.13.12L34.3,100H72a4,4,0,0,1,0,8H24a4,4,0,0,1-4-4V56a4,4,0,0,1,8,0V94.89l35-32A92,92,0,0,1,220,128Z`}))]]),li=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M220,48V96a12,12,0,0,1-24,0V77l-35.51,35.52a12,12,0,0,1-17-17L179,60H160a12,12,0,0,1,0-24h48A12,12,0,0,1,220,48ZM95.51,143.51,60,179V160a12,12,0,0,0-24,0v48a12,12,0,0,0,12,12H96a12,12,0,0,0,0-24H77l35.52-35.51a12,12,0,0,0-17-17ZM208,148a12,12,0,0,0-12,12v19l-35.51-35.52a12,12,0,0,0-17,17L179,196H160a12,12,0,0,0,0,24h48a12,12,0,0,0,12-12V160A12,12,0,0,0,208,148ZM77,60H96a12,12,0,0,0,0-24H48A12,12,0,0,0,36,48V96a12,12,0,0,0,24,0V77l35.51,35.52a12,12,0,0,0,17-17Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,48V208H48V48Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M216,48V96a8,8,0,0,1-16,0V67.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L188.69,56H160a8,8,0,0,1,0-16h48A8,8,0,0,1,216,48ZM98.34,146.34,56,188.69V160a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16H67.31l42.35-42.34a8,8,0,0,0-11.32-11.32ZM208,152a8,8,0,0,0-8,8v28.69l-42.34-42.35a8,8,0,0,0-11.32,11.32L188.69,200H160a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V160A8,8,0,0,0,208,152ZM67.31,56H96a8,8,0,0,0,0-16H48a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31l42.34,42.35a8,8,0,0,0,11.32-11.32Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M109.66,146.34a8,8,0,0,1,0,11.32L83.31,184l18.35,18.34A8,8,0,0,1,96,216H48a8,8,0,0,1-8-8V160a8,8,0,0,1,13.66-5.66L72,172.69l26.34-26.35A8,8,0,0,1,109.66,146.34ZM83.31,72l18.35-18.34A8,8,0,0,0,96,40H48a8,8,0,0,0-8,8V96a8,8,0,0,0,13.66,5.66L72,83.31l26.34,26.35a8,8,0,0,0,11.32-11.32ZM208,40H160a8,8,0,0,0-5.66,13.66L172.69,72,146.34,98.34a8,8,0,0,0,11.32,11.32L184,83.31l18.34,18.35A8,8,0,0,0,216,96V48A8,8,0,0,0,208,40Zm3.06,112.61a8,8,0,0,0-8.72,1.73L184,172.69l-26.34-26.35a8,8,0,0,0-11.32,11.32L172.69,184l-18.35,18.34A8,8,0,0,0,160,216h48a8,8,0,0,0,8-8V160A8,8,0,0,0,211.06,152.61Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M214,48V96a6,6,0,0,1-12,0V62.48l-45.76,45.76a6,6,0,0,1-8.48-8.48L193.52,54H160a6,6,0,0,1,0-12h48A6,6,0,0,1,214,48ZM99.76,147.76,54,193.52V160a6,6,0,0,0-12,0v48a6,6,0,0,0,6,6H96a6,6,0,0,0,0-12H62.48l45.76-45.76a6,6,0,0,0-8.48-8.48ZM208,154a6,6,0,0,0-6,6v33.52l-45.76-45.76a6,6,0,0,0-8.48,8.48L193.52,202H160a6,6,0,0,0,0,12h48a6,6,0,0,0,6-6V160A6,6,0,0,0,208,154ZM62.48,54H96a6,6,0,0,0,0-12H48a6,6,0,0,0-6,6V96a6,6,0,0,0,12,0V62.48l45.76,45.76a6,6,0,0,0,8.48-8.48Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,48V96a8,8,0,0,1-16,0V67.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L188.69,56H160a8,8,0,0,1,0-16h48A8,8,0,0,1,216,48ZM98.34,146.34,56,188.69V160a8,8,0,0,0-16,0v48a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16H67.31l42.35-42.34a8,8,0,0,0-11.32-11.32ZM208,152a8,8,0,0,0-8,8v28.69l-42.34-42.35a8,8,0,0,0-11.32,11.32L188.69,200H160a8,8,0,0,0,0,16h48a8,8,0,0,0,8-8V160A8,8,0,0,0,208,152ZM67.31,56H96a8,8,0,0,0,0-16H48a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31l42.34,42.35a8,8,0,0,0,11.32-11.32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M212,48V96a4,4,0,0,1-8,0V57.66l-49.17,49.17a4,4,0,0,1-5.66-5.66L198.34,52H160a4,4,0,0,1,0-8h48A4,4,0,0,1,212,48ZM101.17,149.17,52,198.34V160a4,4,0,0,0-8,0v48a4,4,0,0,0,4,4H96a4,4,0,0,0,0-8H57.66l49.17-49.17a4,4,0,0,0-5.66-5.66ZM208,156a4,4,0,0,0-4,4v38.34l-49.17-49.17a4,4,0,0,0-5.66,5.66L198.34,204H160a4,4,0,0,0,0,8h48a4,4,0,0,0,4-4V160A4,4,0,0,0,208,156ZM57.66,52H96a4,4,0,0,0,0-8H48a4,4,0,0,0-4,4V96a4,4,0,0,0,8,0V57.66l49.17,49.17a4,4,0,0,0,5.66-5.66Z`}))]]),ui=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216.49,168.49a12,12,0,0,1-17,0L128,97,56.49,168.49a12,12,0,0,1-17-17l80-80a12,12,0,0,1,17,0l80,80A12,12,0,0,1,216.49,168.49Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,160H48l80-80Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M213.66,154.34l-80-80a8,8,0,0,0-11.32,0l-80,80A8,8,0,0,0,48,168H208a8,8,0,0,0,5.66-13.66ZM67.31,152,128,91.31,188.69,152Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M215.39,163.06A8,8,0,0,1,208,168H48a8,8,0,0,1-5.66-13.66l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,215.39,163.06Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M212.24,164.24a6,6,0,0,1-8.48,0L128,88.49,52.24,164.24a6,6,0,0,1-8.48-8.48l80-80a6,6,0,0,1,8.48,0l80,80A6,6,0,0,1,212.24,164.24Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M210.83,162.83a4,4,0,0,1-5.66,0L128,85.66,50.83,162.83a4,4,0,0,1-5.66-5.66l80-80a4,4,0,0,1,5.66,0l80,80A4,4,0,0,1,210.83,162.83Z`}))]]),di=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M172,108a12,12,0,0,1-12,12H96a12,12,0,0,1,0-24h64A12,12,0,0,1,172,108Zm-12,28H96a12,12,0,0,0,0,24h64a12,12,0,0,0,0-24Zm76-8A108,108,0,0,1,78.77,224.15L46.34,235A20,20,0,0,1,21,209.66l10.81-32.43A108,108,0,1,1,236,128Zm-24,0A84,84,0,1,0,55.27,170.06a12,12,0,0,1,1,9.81l-9.93,29.79,29.79-9.93a12.1,12.1,0,0,1,3.8-.62,12,12,0,0,1,6,1.62A84,84,0,0,0,212,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128A96,96,0,0,1,79.93,211.11h0L42.54,223.58a8,8,0,0,1-10.12-10.12l12.47-37.39h0A96,96,0,1,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24Zm0,192a87.87,87.87,0,0,1-44.06-11.81,8,8,0,0,0-4-1.08,7.85,7.85,0,0,0-2.53.42L40,216,52.47,178.6a8,8,0,0,0-.66-6.54A88,88,0,1,1,128,216Zm40-104a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,112Zm0,32a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,144Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,0,0,36.18,176.88L24.83,210.93a16,16,0,0,0,20.24,20.24l34.05-11.35A104,104,0,1,0,128,24Zm32,128H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Zm0-32H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M166,112a6,6,0,0,1-6,6H96a6,6,0,0,1,0-12h64A6,6,0,0,1,166,112Zm-6,26H96a6,6,0,0,0,0,12h64a6,6,0,0,0,0-12Zm70-10A102,102,0,0,1,79.31,217.65L44.44,229.27a14,14,0,0,1-17.71-17.71l11.62-34.87A102,102,0,1,1,230,128Zm-12,0A90,90,0,1,0,50.08,173.06a6,6,0,0,1,.5,4.91L38.12,215.35a2,2,0,0,0,2.53,2.53L78,205.42a6.2,6.2,0,0,1,1.9-.31,6.09,6.09,0,0,1,3,.81A90,90,0,0,0,218,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M168,112a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,112Zm-8,24H96a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm72-8A104,104,0,0,1,79.12,219.82L45.07,231.17a16,16,0,0,1-20.24-20.24l11.35-34.05A104,104,0,1,1,232,128Zm-16,0A88,88,0,1,0,51.81,172.06a8,8,0,0,1,.66,6.54L40,216,77.4,203.53a7.85,7.85,0,0,1,2.53-.42,8,8,0,0,1,4,1.08A88,88,0,0,0,216,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M164,112a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h64A4,4,0,0,1,164,112Zm-4,28H96a4,4,0,0,0,0,8h64a4,4,0,0,0,0-8Zm68-12A100,100,0,0,1,79.5,215.47l-35.69,11.9a12,12,0,0,1-15.18-15.18l11.9-35.69A100,100,0,1,1,228,128Zm-8,0A92,92,0,1,0,48.35,174.07a4,4,0,0,1,.33,3.27L36.22,214.72a4,4,0,0,0,5.06,5.06l37.38-12.46a3.93,3.93,0,0,1,1.27-.21,4.05,4.05,0,0,1,2,.54A92,92,0,0,0,220,128Z`}))]]),fi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm68-84a12,12,0,0,1-12,12H128a12,12,0,0,1-12-12V72a12,12,0,0,1,24,0v44h44A12,12,0,0,1,196,128Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm56,112H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,26A102,102,0,1,0,230,128,102.12,102.12,0,0,0,128,26Zm0,192a90,90,0,1,1,90-90A90.1,90.1,0,0,1,128,218Zm62-90a6,6,0,0,1-6,6H128a6,6,0,0,1-6-6V72a6,6,0,0,1,12,0v50h50A6,6,0,0,1,190,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm0,192a92,92,0,1,1,92-92A92.1,92.1,0,0,1,128,220Zm60-92a4,4,0,0,1-4,4H128a4,4,0,0,1-4-4V72a4,4,0,0,1,8,0v52h52A4,4,0,0,1,188,128Z`}))]]),pi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M140,80v41.21l34.17,20.5a12,12,0,1,1-12.34,20.58l-40-24A12,12,0,0,1,116,128V80a12,12,0,0,1,24,0ZM128,28A99.38,99.38,0,0,0,57.24,57.34c-4.69,4.74-9,9.37-13.24,14V64a12,12,0,0,0-24,0v40a12,12,0,0,0,12,12H72a12,12,0,0,0,0-24H57.77C63,86,68.37,80.22,74.26,74.26a76,76,0,1,1,1.58,109,12,12,0,0,0-16.48,17.46A100,100,0,1,0,128,28Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M136,80v43.47l36.12,21.67a8,8,0,0,1-8.24,13.72l-40-24A8,8,0,0,1,120,128V80a8,8,0,0,1,16,0Zm-8-48A95.44,95.44,0,0,0,60.08,60.15C52.81,67.51,46.35,74.59,40,82V64a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H72a8,8,0,0,0,0-16H49c7.15-8.42,14.27-16.35,22.39-24.57a80,80,0,1,1,1.66,114.75,8,8,0,1,0-11,11.64A96,96,0,1,0,128,32Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128A96,96,0,0,1,62.11,197.82a8,8,0,1,1,11-11.64A80,80,0,1,0,71.43,71.43C67.9,75,64.58,78.51,61.35,82L77.66,98.34A8,8,0,0,1,72,112H32a8,8,0,0,1-8-8V64a8,8,0,0,1,13.66-5.66L50,70.7c3.22-3.49,6.54-7,10.06-10.55A96,96,0,0,1,224,128ZM128,72a8,8,0,0,0-8,8v48a8,8,0,0,0,3.88,6.86l40,24a8,8,0,1,0,8.24-13.72L136,123.47V80A8,8,0,0,0,128,72Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M134,80v44.6l37.09,22.25a6,6,0,0,1-6.18,10.3l-40-24A6,6,0,0,1,122,128V80a6,6,0,0,1,12,0Zm-6-46A93.4,93.4,0,0,0,61.51,61.56c-8.58,8.68-16,17-23.51,25.8V64a6,6,0,0,0-12,0v40a6,6,0,0,0,6,6H72a6,6,0,0,0,0-12H44.73C52.86,88.29,60.79,79.35,70,70a82,82,0,1,1,1.7,117.62,6,6,0,1,0-8.24,8.72A94,94,0,1,0,128,34Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M136,80v43.47l36.12,21.67a8,8,0,0,1-8.24,13.72l-40-24A8,8,0,0,1,120,128V80a8,8,0,0,1,16,0Zm-8-48A95.44,95.44,0,0,0,60.08,60.15C52.81,67.51,46.35,74.59,40,82V64a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H72a8,8,0,0,0,0-16H49c7.15-8.42,14.27-16.35,22.39-24.57a80,80,0,1,1,1.66,114.75,8,8,0,1,0-11,11.64A96,96,0,1,0,128,32Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M132,80v45.74l38.06,22.83a4,4,0,0,1-4.12,6.86l-40-24A4,4,0,0,1,124,128V80a4,4,0,0,1,8,0Zm-4-44A91.42,91.42,0,0,0,62.93,63C53.05,73,44.66,82.47,36,92.86V64a4,4,0,0,0-8,0v40a4,4,0,0,0,4,4H72a4,4,0,0,0,0-8H40.47C49.61,89,58.3,79,68.6,68.6a84,84,0,1,1,1.75,120.49,4,4,0,1,0-5.5,5.82A92,92,0,1,0,128,36Z`}))]]),mi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M108,84a16,16,0,1,1,16,16A16,16,0,0,1,108,84Zm128,44A108,108,0,1,1,128,20,108.12,108.12,0,0,1,236,128Zm-24,0a84,84,0,1,0-84,84A84.09,84.09,0,0,0,212,128Zm-72,36.68V132a20,20,0,0,0-20-20,12,12,0,0,0-4,23.32V168a20,20,0,0,0,20,20,12,12,0,0,0,4-23.32Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M144,176a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176Zm88-48A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128ZM124,96a12,12,0,1,0-12-12A12,12,0,0,0,124,96Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-4,48a12,12,0,1,1-12,12A12,12,0,0,1,124,72Zm12,112a16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M142,176a6,6,0,0,1-6,6,14,14,0,0,1-14-14V128a2,2,0,0,0-2-2,6,6,0,0,1,0-12,14,14,0,0,1,14,14v40a2,2,0,0,0,2,2A6,6,0,0,1,142,176ZM124,94a10,10,0,1,0-10-10A10,10,0,0,0,124,94Zm106,34A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M140,176a4,4,0,0,1-4,4,12,12,0,0,1-12-12V128a4,4,0,0,0-4-4,4,4,0,0,1,0-8,12,12,0,0,1,12,12v40a4,4,0,0,0,4,4A4,4,0,0,1,140,176ZM124,92a8,8,0,1,0-8-8A8,8,0,0,0,124,92Zm104,36A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z`}))]]),hi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,44H32A20,20,0,0,0,12,64V192a20,20,0,0,0,20,20H224a20,20,0,0,0,20-20V64A20,20,0,0,0,224,44Zm-4,144H36V68H220ZM52,128a12,12,0,0,1,12-12H192a12,12,0,0,1,0,24H64A12,12,0,0,1,52,128Zm0-36A12,12,0,0,1,64,80H192a12,12,0,0,1,0,24H64A12,12,0,0,1,52,92Zm0,72a12,12,0,0,1,12-12h8a12,12,0,0,1,0,24H64A12,12,0,0,1,52,164Zm108,0a12,12,0,0,1-12,12H108a12,12,0,0,1,0-24h40A12,12,0,0,1,160,164Zm44,0a12,12,0,0,1-12,12h-8a12,12,0,0,1,0-24h8A12,12,0,0,1,204,164Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M232,64V192a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H224A8,8,0,0,1,232,64Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48Zm0,144H32V64H224V192Zm-16-64a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,128Zm0-32a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,96ZM72,160a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16h8A8,8,0,0,1,72,160Zm96,0a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,160Zm40,0a8,8,0,0,1-8,8h-8a8,8,0,0,1,0-16h8A8,8,0,0,1,208,160Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48ZM64,168H48a8,8,0,0,1,0-16H64a8,8,0,0,1,0,16Zm96,0H96a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Zm48,0H192a8,8,0,0,1,0-16h16a8,8,0,0,1,0,16Zm0-32H48a8,8,0,0,1,0-16H208a8,8,0,0,1,0,16Zm0-32H48a8,8,0,0,1,0-16H208a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,50H32A14,14,0,0,0,18,64V192a14,14,0,0,0,14,14H224a14,14,0,0,0,14-14V64A14,14,0,0,0,224,50Zm2,142a2,2,0,0,1-2,2H32a2,2,0,0,1-2-2V64a2,2,0,0,1,2-2H224a2,2,0,0,1,2,2Zm-20-64a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12H200A6,6,0,0,1,206,128Zm0-32a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12H200A6,6,0,0,1,206,96ZM70,160a6,6,0,0,1-6,6H56a6,6,0,0,1,0-12h8A6,6,0,0,1,70,160Zm96,0a6,6,0,0,1-6,6H96a6,6,0,0,1,0-12h64A6,6,0,0,1,166,160Zm40,0a6,6,0,0,1-6,6h-8a6,6,0,0,1,0-12h8A6,6,0,0,1,206,160Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,48H32A16,16,0,0,0,16,64V192a16,16,0,0,0,16,16H224a16,16,0,0,0,16-16V64A16,16,0,0,0,224,48Zm0,144H32V64H224V192Zm-16-64a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,128Zm0-32a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16H200A8,8,0,0,1,208,96ZM72,160a8,8,0,0,1-8,8H56a8,8,0,0,1,0-16h8A8,8,0,0,1,72,160Zm96,0a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h64A8,8,0,0,1,168,160Zm40,0a8,8,0,0,1-8,8h-8a8,8,0,0,1,0-16h8A8,8,0,0,1,208,160Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,52H32A12,12,0,0,0,20,64V192a12,12,0,0,0,12,12H224a12,12,0,0,0,12-12V64A12,12,0,0,0,224,52Zm4,140a4,4,0,0,1-4,4H32a4,4,0,0,1-4-4V64a4,4,0,0,1,4-4H224a4,4,0,0,1,4,4Zm-24-64a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8H200A4,4,0,0,1,204,128Zm0-32a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8H200A4,4,0,0,1,204,96ZM68,160a4,4,0,0,1-4,4H56a4,4,0,0,1,0-8h8A4,4,0,0,1,68,160Zm96,0a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h64A4,4,0,0,1,164,160Zm40,0a4,4,0,0,1-4,4h-8a4,4,0,0,1,0-8h8A4,4,0,0,1,204,160Z`}))]]),gi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M76,64A12,12,0,0,1,88,52H216a12,12,0,0,1,0,24H88A12,12,0,0,1,76,64Zm140,52H88a12,12,0,0,0,0,24H216a12,12,0,0,0,0-24Zm0,64H88a12,12,0,0,0,0,24H216a12,12,0,0,0,0-24ZM44,112a16,16,0,1,0,16,16A16,16,0,0,0,44,112Zm0-64A16,16,0,1,0,60,64,16,16,0,0,0,44,48Zm0,128a16,16,0,1,0,16,16A16,16,0,0,0,44,176Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,64V192H88V64Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M80,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H88A8,8,0,0,1,80,64Zm136,56H88a8,8,0,1,0,0,16H216a8,8,0,0,0,0-16Zm0,64H88a8,8,0,1,0,0,16H216a8,8,0,0,0,0-16ZM44,52A12,12,0,1,0,56,64,12,12,0,0,0,44,52Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,116Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,180Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM68,188a12,12,0,1,1,12-12A12,12,0,0,1,68,188Zm0-48a12,12,0,1,1,12-12A12,12,0,0,1,68,140Zm0-48A12,12,0,1,1,80,80,12,12,0,0,1,68,92Zm124,92H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Zm0-48H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Zm0-48H104a8,8,0,0,1,0-16h88a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M82,64a6,6,0,0,1,6-6H216a6,6,0,0,1,0,12H88A6,6,0,0,1,82,64Zm134,58H88a6,6,0,0,0,0,12H216a6,6,0,0,0,0-12Zm0,64H88a6,6,0,0,0,0,12H216a6,6,0,0,0,0-12ZM44,54A10,10,0,1,0,54,64,10,10,0,0,0,44,54Zm0,128a10,10,0,1,0,10,10A10,10,0,0,0,44,182Zm0-64a10,10,0,1,0,10,10A10,10,0,0,0,44,118Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M80,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H88A8,8,0,0,1,80,64Zm136,56H88a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Zm0,64H88a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16ZM44,52A12,12,0,1,0,56,64,12,12,0,0,0,44,52Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,116Zm0,64a12,12,0,1,0,12,12A12,12,0,0,0,44,180Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M84,64a4,4,0,0,1,4-4H216a4,4,0,0,1,0,8H88A4,4,0,0,1,84,64Zm132,60H88a4,4,0,0,0,0,8H216a4,4,0,0,0,0-8Zm0,64H88a4,4,0,0,0,0,8H216a4,4,0,0,0,0-8ZM44,120a8,8,0,1,0,8,8A8,8,0,0,0,44,120Zm0-64a8,8,0,1,0,8,8A8,8,0,0,0,44,56Zm0,128a8,8,0,1,0,8,8A8,8,0,0,0,44,184Z`}))]]),_i=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M28,64A12,12,0,0,1,40,52H216a12,12,0,0,1,0,24H40A12,12,0,0,1,28,64Zm12,76h64a12,12,0,0,0,0-24H40a12,12,0,0,0,0,24Zm80,40H40a12,12,0,0,0,0,24h80a12,12,0,0,0,0-24Zm120.49,20.49a12,12,0,0,1-17,0l-18.08-18.08a44,44,0,1,1,17-17l18.08,18.07A12,12,0,0,1,240.49,200.49ZM184,164a20,20,0,1,0-20-20A20,20,0,0,0,184,164Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M216,144a32,32,0,1,1-32-32A32,32,0,0,1,216,144Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,13.66a8,8,0,0,1-11.32,0L206,177.36A40,40,0,1,1,217.36,166l20.3,20.3A8,8,0,0,1,237.66,197.66ZM184,168a24,24,0,1,0-24-24A24,24,0,0,0,184,168Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,2.34L217.36,166A40,40,0,1,0,206,177.36l20.3,20.3a8,8,0,0,0,11.32-11.32Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M34,64a6,6,0,0,1,6-6H216a6,6,0,0,1,0,12H40A6,6,0,0,1,34,64Zm6,70h72a6,6,0,0,0,0-12H40a6,6,0,0,0,0,12Zm88,52H40a6,6,0,0,0,0,12h88a6,6,0,0,0,0-12Zm108.24,10.24a6,6,0,0,1-8.48,0l-21.49-21.48a38.06,38.06,0,1,1,8.49-8.49l21.48,21.49A6,6,0,0,1,236.24,196.24ZM184,170a26,26,0,1,0-26-26A26,26,0,0,0,184,170Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72h72a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm88,48H40a8,8,0,0,0,0,16h88a8,8,0,0,0,0-16Zm109.66,13.66a8,8,0,0,1-11.32,0L206,177.36A40,40,0,1,1,217.36,166l20.3,20.3A8,8,0,0,1,237.66,197.66ZM184,168a24,24,0,1,0-24-24A24,24,0,0,0,184,168Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M36,64a4,4,0,0,1,4-4H216a4,4,0,0,1,0,8H40A4,4,0,0,1,36,64Zm4,68h72a4,4,0,0,0,0-8H40a4,4,0,0,0,0,8Zm88,56H40a4,4,0,0,0,0,8h88a4,4,0,0,0,0-8Zm106.83,6.83a4,4,0,0,1-5.66,0l-22.72-22.72a36.06,36.06,0,1,1,5.66-5.66l22.72,22.72A4,4,0,0,1,234.83,194.83ZM184,172a28,28,0,1,0-28-28A28,28,0,0,0,184,172Z`}))]]),vi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M156,112a12,12,0,0,1-12,12H80a12,12,0,0,1,0-24h64A12,12,0,0,1,156,112Zm76.49,120.49a12,12,0,0,1-17,0L168,185a92.12,92.12,0,1,1,17-17l47.54,47.53A12,12,0,0,1,232.49,232.49ZM112,180a68,68,0,1,0-68-68A68.08,68.08,0,0,0,112,180Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M192,112a80,80,0,1,1-80-80A80,80,0,0,1,192,112Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Zm112,0a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h64A8,8,0,0,1,152,112Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M229.66,218.34,179.6,168.28a88.21,88.21,0,1,0-11.32,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM144,120H80a8,8,0,0,1,0-16h64a8,8,0,0,1,0,16Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M150,112a6,6,0,0,1-6,6H80a6,6,0,0,1,0-12h64A6,6,0,0,1,150,112Zm78.24,116.24a6,6,0,0,1-8.48,0l-51.38-51.38a86.15,86.15,0,1,1,8.48-8.48l51.38,51.38A6,6,0,0,1,228.24,228.24ZM112,186a74,74,0,1,0-74-74A74.09,74.09,0,0,0,112,186Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M152,112a8,8,0,0,1-8,8H80a8,8,0,0,1,0-16h64A8,8,0,0,1,152,112Zm77.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88.11,88.11,0,1,1,11.31-11.31l50.07,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M148,112a4,4,0,0,1-4,4H80a4,4,0,0,1,0-8h64A4,4,0,0,1,148,112Zm78.83,114.83a4,4,0,0,1-5.66,0l-52.7-52.7a84.1,84.1,0,1,1,5.66-5.66l52.7,52.7A4,4,0,0,1,226.83,226.83ZM112,188a76,76,0,1,0-76-76A76.08,76.08,0,0,0,112,188Z`}))]]),yi=new Map([[`bold`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M230.47,67.5a12,12,0,0,0-19.26-4.32L172.43,99l-12.68-2.72L157,83.57l35.79-38.78a12,12,0,0,0-4.32-19.26A76.07,76.07,0,0,0,88.41,121.64L30.92,174.18a4.68,4.68,0,0,0-.39.38,36,36,0,0,0,50.91,50.91l.38-.39,52.54-57.49A76.05,76.05,0,0,0,230.47,67.5ZM160,148a51.5,51.5,0,0,1-23.35-5.52,12,12,0,0,0-14.26,2.62L64.31,208.66a12,12,0,0,1-17-17l63.55-58.07a12,12,0,0,0,2.62-14.26A51.5,51.5,0,0,1,108,96a52.06,52.06,0,0,1,52-52h.89L135.17,71.87a12,12,0,0,0-2.91,10.65l5.66,26.35a12,12,0,0,0,9.21,9.21l26.35,5.66a12,12,0,0,0,10.65-2.91L212,95.12c0,.3,0,.59,0,.89A52.06,52.06,0,0,1,160,148Z`}))],[`duotone`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224,96a64,64,0,0,1-94.94,56L73,217A24,24,0,0,1,39,183L104,126.94a64,64,0,0,1,80-90.29L144,80l5.66,26.34L176,112l43.35-40A63.8,63.8,0,0,1,224,96Z`,opacity:`0.2`}),V.createElement(`path`,{d:`M226.76,69a8,8,0,0,0-12.84-2.88l-40.3,37.19-17.23-3.7-3.7-17.23,37.19-40.3A8,8,0,0,0,187,29.24,72,72,0,0,0,88,96,72.34,72.34,0,0,0,94,124.94L33.79,177c-.15.12-.29.26-.43.39a32,32,0,0,0,45.26,45.26c.13-.13.27-.28.39-.42L131.06,162A72,72,0,0,0,232,96,71.56,71.56,0,0,0,226.76,69ZM160,152a56.14,56.14,0,0,1-27.07-7,8,8,0,0,0-9.92,1.77L67.11,211.51a16,16,0,0,1-22.62-22.62L109.18,133a8,8,0,0,0,1.77-9.93,56,56,0,0,1,58.36-82.31l-31.2,33.81a8,8,0,0,0-1.94,7.1L141.83,108a8,8,0,0,0,6.14,6.14l26.35,5.66a8,8,0,0,0,7.1-1.94l33.81-31.2A56.06,56.06,0,0,1,160,152Z`}))],[`fill`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M232,96a72,72,0,0,1-100.94,66L79,222.22c-.12.14-.26.29-.39.42a32,32,0,0,1-45.26-45.26c.14-.13.28-.27.43-.39L94,124.94a72.07,72.07,0,0,1,83.54-98.78,8,8,0,0,1,3.93,13.19L144,80l5.66,26.35L176,112l40.65-37.52a8,8,0,0,1,13.19,3.93A72.6,72.6,0,0,1,232,96Z`}))],[`light`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M224.91,69.75a6,6,0,0,0-9.63-2.16l-41.07,37.9L154.7,101.3l-4.19-19.51,37.9-41.07a6,6,0,0,0-2.16-9.63,70,70,0,0,0-89.77,94.39l-61.39,53c-.11.09-.21.19-.32.3A30,30,0,0,0,77.2,221.23c.11-.11.21-.21.3-.32l53-61.39a70,70,0,0,0,94.39-89.77ZM160,154a58,58,0,0,1-28-7.22,6,6,0,0,0-7.45,1.33L68.57,212.88a18,18,0,0,1-25.45-25.45l64.76-55.94A6,6,0,0,0,109.2,124a58,58,0,0,1,64-84.53L139.58,75.93a6,6,0,0,0-1.45,5.33l5.65,26.35a6,6,0,0,0,4.61,4.61l26.35,5.65a6,6,0,0,0,5.33-1.45L216.49,82.8A58.06,58.06,0,0,1,160,154Z`}))],[`regular`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M226.76,69a8,8,0,0,0-12.84-2.88l-40.3,37.19-17.23-3.7-3.7-17.23,37.19-40.3A8,8,0,0,0,187,29.24,72,72,0,0,0,88,96,72.34,72.34,0,0,0,94,124.94L33.79,177c-.15.12-.29.26-.43.39a32,32,0,0,0,45.26,45.26c.13-.13.27-.28.39-.42L131.06,162A72,72,0,0,0,232,96,71.56,71.56,0,0,0,226.76,69ZM160,152a56.14,56.14,0,0,1-27.07-7,8,8,0,0,0-9.92,1.77L67.11,211.51a16,16,0,0,1-22.62-22.62L109.18,133a8,8,0,0,0,1.77-9.93,56,56,0,0,1,58.36-82.31l-31.2,33.81a8,8,0,0,0-1.94,7.1L141.83,108a8,8,0,0,0,6.14,6.14l26.35,5.66a8,8,0,0,0,7.1-1.94l33.81-31.2A56.06,56.06,0,0,1,160,152Z`}))],[`thin`,V.createElement(V.Fragment,null,V.createElement(`path`,{d:`M223.05,70.5a4,4,0,0,0-6.42-1.44l-41.82,38.6L153,103l-4.68-21.79,38.6-41.82a4,4,0,0,0-1.44-6.43A68,68,0,0,0,98.94,126L36.4,180l-.21.2a28,28,0,0,0,39.6,39.6l.2-.21,54-62.54A68,68,0,0,0,228,96,67.51,67.51,0,0,0,223.05,70.5ZM160,156a60,60,0,0,1-29-7.47,4,4,0,0,0-5,.89L70,214.25A20,20,0,0,1,41.75,186l64.82-56a4,4,0,0,0,.89-5,60,60,0,0,1,69.46-86.59L141.05,77.29a4,4,0,0,0-1,3.55l5.66,26.35a4,4,0,0,0,3.07,3.07l26.35,5.66a4,4,0,0,0,3.55-1l38.87-35.87A60.05,60.05,0,0,1,160,156Z`}))]]),bi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:si}));bi.displayName=`ArrowClockwiseIcon`;var xi=bi,Si=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:ci}));Si.displayName=`ArrowCounterClockwiseIcon`;var Ci=Si,wi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:li}));wi.displayName=`ArrowsOutIcon`;var Ti=wi,Ei=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:ui}));Ei.displayName=`CaretUpIcon`;var Di=Ei,Oi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:di}));Oi.displayName=`ChatCircleTextIcon`;var ki=Oi,Ai=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:fi}));Ai.displayName=`ClockIcon`;var ji=Ai,Mi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:pi}));Mi.displayName=`ClockCounterClockwiseIcon`;var Ni=Mi,Pi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:mi}));Pi.displayName=`InfoIcon`;var Fi=Pi,Ii=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:hi}));Ii.displayName=`KeyboardIcon`;var Li=Ii,Ri=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:gi}));Ri.displayName=`ListBulletsIcon`;var zi=Ri,Bi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:_i}));Bi.displayName=`ListMagnifyingGlassIcon`;var Vi=Bi,Hi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:vi}));Hi.displayName=`MagnifyingGlassMinusIcon`;var Ui=Hi,Wi=V.forwardRef((e,t)=>V.createElement(x,{ref:t,...e,weights:yi}));Wi.displayName=`WrenchIcon`;var Gi=Wi,Ki=i(b(),1),qi=`$__all`;function Ji(e,t,n){if(e.kind===`constant`)return e.value??``;let r=e.kind===`custom`?e.options?.map(e=>({value:e}))??[]:n===null?[]:n,i=t[e.name],a=!e.multi&&Array.isArray(i)&&i.length===0?void 0:i;if(a===`$__all`){if(e.include_all)return qi}else if(a!==void 0){if(e.kind===`text`||r===void 0)return a;let t=new Set(r.map(e=>e.value));if(Array.isArray(a)){if(a.length===0&&e.multi)return[];let n=a.filter(e=>t.has(e));if(n.length>0)return n}else if(t.has(a))return a}return e.default?e.default:e.include_all?qi:r?.[0]?.value??``}var Yi=(e,t)=>e.replace(/\$([a-z][a-z0-9_]*)/g,(e,n)=>{let r=t[n];return r===void 0?e:r===`$__all`?`all`:Array.isArray(r)?r.join(`, `):r});function Xi(e,t,n){let r={};for(let i of e??[]){let e=Ji(i,t,n?.[i.name]);(i.kind!==`query`||e!==``)&&(r[i.name]=e)}return r}function Zi(e){return Array.from({length:e.rows},(t,n)=>Object.fromEntries(e.columns.map((t,r)=>{let i=e.values[r]?.[n]??null;return[t.name,typeof i==`number`&&!Number.isFinite(i)?null:i]})))}function Qi(e,t){return e.viz!==`logs`||!t||t.rows<2?[]:t.columns.flatMap((e,n)=>{if(e.role!==`dimension`||e.type!==`string`||[`body`,`body_template`,`severity`,`status`].includes(e.name)||/(^id$|_id$)/.test(e.name))return[];let r=t.values[n][0];return typeof r==`string`&&r!==``&&t.values[n].slice(0,t.rows).every(e=>e===r)?[{name:e.name,value:r}]:[]})}function $i(e,t){let n=t.frame??{columns:[],values:[],rows:0};return{columns:n.columns.map(e=>e.name),rows:Zi(n),selection:t=>{let n={};for(let r of e.query?.by??[]){let e=r.startsWith(`attributes[`)||r.startsWith(`resource[`)?r.slice(r.indexOf(`'`)+1,r.lastIndexOf(`'`)):r;t[e]!==void 0&&t[e]!==null&&(n[r]=String(t[e]))}return{time:typeof t.time==`number`?t.time:typeof t.start==`number`?t.start:void 0,dimensions:n,trace_id:typeof t.trace_id==`string`?t.trace_id:void 0,namespace:typeof t.namespace==`string`?t.namespace:void 0}}}}function ea(e){return e.replace(/[&<>"']/g,e=>({"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`})[e])}var ta=e=>e.map(ea).join(`
`);function na(e,t=!1){return n=>{let r=Array.isArray(n)?n:[n];return ta([...r[0]?.axisValueLabel?[r[0].axisValueLabel]:[],...r.map(n=>{let r=n.value,i=Array.isArray(r)?t?r.slice(1):r:[r];return`${n.seriesName??``}${n.name?` · ${n.name}`:``}: ${i.map(t=>typeof t==`number`?e(t,n.seriesName):String(t??`—`)).join(` · `)}`})])}}var ra=e=>/^Other(?: \(\d+\))?$/.test(e??``);function ia(e,t){let n=Math.min(6,Math.max(1,Math.floor(t.options?.top||6))),r=e.filter(e=>!ra(e.name)),i=r.slice(0,n).map(e=>({name:e.name,items:[e]})),a=[...e.filter(e=>ra(e.name)),...r.slice(n)];return a.length&&i.push({name:a.length===1&&ra(a[0].name)?a[0].name:`Other (${a.reduce((e,t)=>e+(ra(t.name)?Number(t.name.match(/\d+/)?.[0]??1):1),0)})`,items:a}),i}function aa(e){let t=e.filter(e=>e!==null);return t.length?t.reduce((e,t)=>e+t,0):null}function oa(e,t){let n=Math.min(6,Math.max(1,Math.floor(t.options?.top||6))),r=e.filter(e=>!ra(e.name));return{shown:[...r.slice(0,n),...e.filter(e=>ra(e.name))],hidden:Math.max(0,r.length-n)}}function sa(e,t){return e>0?[{type:`text`,right:8,bottom:2,silent:!0,style:{text:`${e} more series not shown`,fill:t,fontSize:11}}]:[]}function ca(e,t,n,r,i=`sans-serif`,a){let o=e=>Array.from(e).length>24?`${Array.from(e).slice(0,23).join(``)}…`:e,s=Math.max(1,t-16),c=1,l=0;for(let t of e){let e=15+(a?.(o(t),`12px ${i}`)??Array.from(o(t)).length*7.2);l&&l+10+e>s&&(c++,l=0),l+=(l?10:0)+e}let u=c>2;return{top:n?u?30:c*20+2:12,option:{type:u?`scroll`:`plain`,show:n,top:0,left:0,right:0,padding:0,itemGap:6,icon:`roundRect`,itemWidth:10,itemHeight:10,itemStyle:{borderColor:r,borderWidth:1},textStyle:{color:r,fontSize:12,lineHeight:14},data:e,formatter:o,tooltip:{show:!0,renderMode:`html`,formatter:e=>ea(e.name)}}}}function la(e,t){if(!(!Number.isFinite(e)||!Number.isFinite(t)||e>=t||Math.abs(e)>864e13||Math.abs(t)>864e13))return{from:new Date(Math.floor(e)).toISOString(),to:new Date(Math.ceil(t)).toISOString()}}function ua(e){let t=[e.time?.range?`Range ${e.time.range}`:void 0,e.time?.shift?`Shifted ${e.time.shift}`:void 0].filter(Boolean);return t.length?t.join(` · `):void 0}function da(e,t,n){if(n.interactive===!1||n.data?.value===null)return;let r=n.data?.selection;if(r)return Object.values(r.dimensions).some(ra)?void 0:r;if(ra(n.seriesName)||ra(n.name)||n.value===null||Array.isArray(n.value)&&n.value.at(-1)==null)return;let i=e.query?.by?.[0]??t.frame?.columns.find(e=>e.role===`dimension`)?.name,a=e.viz===`timeseries`?n.seriesName:n.name,o=Array.isArray(n.value)?n.value:[];return{time:e.viz===`timeseries`&&typeof o[0]==`number`?o[0]:void 0,dimensions:i&&a?{[i]:a}:{}}}var fa=new Intl.NumberFormat(`en`,{notation:`compact`,maximumFractionDigits:1}),pa=new Intl.NumberFormat(`en`,{maximumFractionDigits:2});function ma(e){return Math.abs(e)<1e-4?e.toExponential(2).replace(/\.?(0+)(?=e)/,``):String(Number(e.toPrecision(3)))}function ha(e,t=pa){return e!==0&&Math.abs(e)<1?ma(e):t.format(e)}function ga(e,t){let n=t===`s`?e*1e3:t===`ns`?e/1e6:e;return e!==0&&n===0?`${ma(e)}${t}`:n!==0&&Math.abs(n)<1?`${ma(n)}ms`:ve(n)}function _a(e){let t=[`B`,`KiB`,`MiB`,`GiB`,`TiB`],n=e,r=0;for(;Math.abs(n)>=1024&&r=1e4?fa:pa);default:return ha(t,Math.abs(t)>=1e4?fa:pa)}}function ya(e){return t=>e===`ms`||e===`s`||e===`ns`?va(e,t).replace(/(\.\d*?)0+([a-z]*)$/,`$1$2`).replace(/\.([a-z]*)$/,`$1`):va(e,t)}function ba(e,t){return ya(e)(t??NaN).replace(/(?<=\d)(ms|ns|s|m|h)\b/g,` $1`)}function xa(e){return Math.max(3,Math.min(10,Math.round(e/70)))-1}function Sa(e,t){let n=t===`ms`?1:t===`s`?1e3:t===`ns`?1e-6:void 0,r=e=>{let t=10**Math.floor(Math.log10(e));return[1,2,5,10].map(e=>e*t).find(t=>t>=e)};if(n===void 0)return r(e);let i=e*n,a=[1,10,100,1e3,1e4,6e4,6e5,36e5,36e6].flatMap(e=>[1,2,5].map(t=>e*t)).sort((e,t)=>e-t);return(i<1?r(i):a.find(e=>e>=i)??r(i/36e5)*36e5)/n}function Ca(e,t,n,r){e=Number.isFinite(e)?Math.min(0,e):0,t=Number.isFinite(t)?Math.max(0,t):1,t===e&&(t=e+1);let i=xa(r),a=Sa(Math.max(t-e,2**-52)/i,n);for(;Math.ceil(t/a)-Math.floor(e/a)>i;)a=Sa(a*1.01,n);return{min:Math.floor(e/a)*a,max:Math.ceil(t/a)*a,interval:a,splitNumber:i,fanout_unit:n}}function wa(e,t){return e.type!==`value`&&e.type!==`log`?e:{...e,...e.type===`value`&&typeof e.min==`number`&&typeof e.max==`number`?Ca(e.min,e.max,typeof e.fanout_unit==`string`?e.fanout_unit:void 0,t):{splitNumber:xa(t)}}}function Ta(e,t,n){let r=e=>va(n,e),i=``;if(n===`ms`||n===`s`||n===`ns`){let a=n===`s`?1e3:n===`ns`?1e-6:1,o=Math.abs((e??t??0)*a),s=o>=6e4?6e4:o>=1e3?1e3:1;i=s===6e4?` min`:s===1e3?` s`:` ms`;let c=s===6e4?1:s===1e3?+(o<1e4):2,l=new Intl.NumberFormat(void 0,{maximumFractionDigits:c});r=e=>l.format(e*a/s)}return t===null&&e!==null?`≥${r(e)}${i}`:(e===null||e===0)&&t!==null?`<${r(t)}${i}`:`${e===null?`−∞`:r(e)}–${t===null?`∞`:r(t)}${i}`}function Ea(e){let t=new Date(e);return t.getHours()===0&&t.getMinutes()===0&&t.getSeconds()===0?t.toLocaleDateString(void 0,{month:`short`,day:`numeric`}):t.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`})}function Da(e,t=new Date,n){let r=new Date(e);if(!Number.isFinite(r.getTime()))return`—`;let i=new Intl.DateTimeFormat(n,{month:`short`,day:`numeric`,...r.getFullYear()===t.getFullYear()?{}:{year:`numeric`},hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hourCycle:`h23`}).formatToParts(r),a=i.filter(e=>[`month`,`day`,`year`].includes(e.type)).map(e=>e.value),o=i.filter(e=>[`hour`,`minute`,`second`].includes(e.type)).map(e=>e.value);return`${a.join(` `)} ${o.join(`:`)}`}function Oa({panel:e,result:t}){let n=t?.frame;return(0,H.jsxs)(`div`,{"data-panel-data":!0,children:[t?.error&&(0,H.jsx)(T,{"data-panel-error-detail":!0,size:`sm`,role:`status`,style:{whiteSpace:`pre-wrap`,overflowWrap:`anywhere`,userSelect:`text`},children:t.error}),n?(0,H.jsxs)(B,{fz:12,striped:!0,children:[(0,H.jsx)(B.Thead,{children:(0,H.jsx)(B.Tr,{children:n.columns.map(e=>(0,H.jsx)(B.Th,{ff:xt.display,children:e.name},e.name))})}),(0,H.jsx)(B.Tbody,{children:Array.from({length:Math.min(n.rows,500)},(t,r)=>(0,H.jsx)(B.Tr,{children:n.columns.map((t,i)=>{let a=n.values[i][r];return(0,H.jsx)(B.Td,{ff:xt.display,children:a===null?`—`:t.type===`time`?new Date(Number(a)).toISOString():t.role===`measure`?va(t.unit??e.unit,Number(a)):String(a)},t.name)})},r))})]}):(0,H.jsx)(T,{c:`dimmed`,size:`sm`,children:`No data.`}),(0,H.jsxs)(T,{c:`dimmed`,fz:12,mt:8,children:[`Ran in `,t?.elapsed_ms??0,` ms`,t?.interval?`, one point per ${t.interval}`:``,n?`, ${n.rows} rows${n.truncated?` (truncated)`:``}`:``,`.`]}),(t?.sql??e.sql)&&(0,H.jsx)(Le,{block:!0,tabIndex:0,mt:8,children:t?.sql??e.sql})]})}function ka({panel:e,dark:t}){let n=JSON.stringify(e,null,2).split(/("(?:[^"\\]|\\.)*"(?=\s*:)|"(?:[^"\\]|\\.)*"|\b(?:true|false|null)\b|-?\d+(?:\.\d+)?)/g);return(0,H.jsx)(`pre`,{"data-panel-spec":!0,style:{margin:0,fontFamily:xt.display,fontSize:12,color:it[t?`dark`:`light`].text},children:n.map((e,r)=>{let i=e.startsWith(`"`)&&/^\s*:/.test(n[r+1]??``)?`key`:e.startsWith(`"`)?`string`:/^(true|false|null)$/.test(e)?`literal`:/^-?\d/.test(e)?`number`:`punctuation`,a=i===`key`?pt[t?4:7]:i===`string`?st[t?4:8]:i===`number`||i===`literal`?Et[t?4:8]:void 0;return i===`punctuation`?e:(0,H.jsx)(`span`,{"data-json-token":i,style:{color:a},children:e},r)})})}function Aa(e){let t=e.event.data?.selection,n=e.event.value;return JSON.stringify([e.event.seriesName,e.event.name,t?.from??t?.time??(Array.isArray(n)?n[0]:void 0),t?.dimensions,t?.bucket])}function ja(e){let t=new Date().toISOString().slice(0,10),n=e.from.slice(0,10),r=e.to.slice(0,10),i=e=>e.slice(11,-1).replace(/\.000$/,``);return`${(n===t?``:n+` `)+i(e.from)} – ${(r!==n&&r!==t?r+` `:``)+i(e.to)} UTC · ${ve(Date.parse(e.to)-Date.parse(e.from))}`}var Ma={background:`color-mix(in srgb, var(--mantine-color-body) 92%, transparent)`,border:`1px solid var(--mantine-color-default-border)`,borderRadius:`var(--mantine-radius-sm)`,padding:`2px 6px`};function Na(e){return e.replace(`Enter drill`,`↵ drill`).replace(`Shift+←→`,`⇧←→`)}var Pa=(0,V.createContext)(void 0);function Fa({points:e,label:t,summary:n,children:r,onClick:i,canSelect:a,onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d,rangeReset:f,height:p=`100%`,onZoom:m,bounds:h,pointWindow:g}){let[_,v]=(0,V.useState)(!1),[b,x]=(0,V.useState)(``),[S,w]=(0,V.useState)(),[E,D]=(0,V.useState)(null),O=(0,V.useRef)(null),k=(0,V.useRef)(!1);(0,V.useEffect)(()=>{let e=e=>{e.key===`Tab`&&(k.current=!1)};return document.addEventListener(`keydown`,e,!0),()=>document.removeEventListener(`keydown`,e,!0)},[]);let A=(0,V.useId)(),j=(0,V.useContext)(Pa),M=(0,V.useRef)(null),N=(0,V.useRef)({onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d});N.current={onHighlight:s,onActiveChange:c,onRangePending:l,onRangeChange:u,onRangeBarHeight:d};let P=(0,V.useMemo)(()=>new Map(e.map(e=>[Aa(e),e])),[e]),F=(0,V.useRef)(void 0),I=e=>g?.(e)?.from??e.event.name??(Array.isArray(e.event.value)?e.event.value[0]:void 0),L=F.current,ee=L?e.filter(e=>e.event.seriesName===L.event.seriesName):e,te=ee.length?ee:e,ne=L&&I(L),re=typeof ne==`number`?te.reduce((e,t)=>{let n=I(t),r=e&&I(e);return typeof n==`number`&&(!e||typeof r!=`number`||Math.abs(n-ne)I(e)===ne),ie=S?P.get(S)??re??te[0]??e[0]:e[0],ae=!!(m&&h&&Number.isFinite(h.from)&&Number.isFinite(h.to)&&h.from[...new Set(e.map(e=>e.event.seriesName))],[e]),oe=(0,V.useMemo)(()=>e.filter(e=>e.event.seriesName===ie?.event.seriesName),[e,ie?.event.seriesName]),z=ie?oe.indexOf(ie):-1;(0,V.useEffect)(()=>{ie&&(!S||P.has(S)||!ee.length)&&(F.current=ie,(!S||!ee.length)&&w(Aa(ie))),_&&N.current.onHighlight(ie)},[ie,S,_]),(0,V.useEffect)(()=>{if(!E)return;let e=Date.parse(E.from),t=Date.parse(E.to);h&&(Number.isFinite(e)&&eh.to)&&D(null)},[h?.from,h?.to,E]),(0,V.useEffect)(()=>{N.current.onRangePending?.(!!E)},[!!E]),(0,V.useEffect)(()=>{N.current.onRangeChange?.(E?{from:Date.parse(E.from),to:Date.parse(E.to)}:void 0)},[E]),(0,V.useEffect)(()=>{D(null)},[f]),(0,V.useEffect)(()=>()=>{N.current.onHighlight(void 0),N.current.onRangePending?.(!1),N.current.onRangeChange?.(void 0)},[]);let se=(e,t=!1)=>{if(e){if(x(n(e)),t&&ae&&ie){let t=E?.anchor??Aa(ie),n=P.get(t),r=E?.window??(n&&g?.(n)),i=g?.(e);if(r&&i){let e=Math.max(h.from,Math.min(r.from,i.from)),n=Math.min(h.to,Math.max(r.to,i.to));Number.isFinite(e)&&Number.isFinite(n)&&e{if(!ie)return;let n=R[Math.max(0,Math.min(R.length-1,R.indexOf(ie.event.seriesName)+t))],r=e.filter(e=>e.event.seriesName===n),i=I(ie),a=r.find(e=>I(e)===i),o=typeof i==`number`?r.reduce((e,t)=>{let n=I(t),r=e&&I(e);return typeof n==`number`&&(!e||typeof r!=`number`||Math.abs(n-i){e===`ArrowLeft`||e===`ArrowRight`?se(oe[Math.max(0,Math.min(oe.length-1,z+(e===`ArrowLeft`?-1:1)))],t):!t&&(e===`ArrowUp`||e===`ArrowDown`)?ce(e===`ArrowUp`?-1:1):!t&&(e===`Home`||e===`End`)&&se(e===`Home`?oe[0]:oe.at(-1))},ue=()=>{D(null),O.current?.focus()},de=ae?`←→ points · ↑↓ series · Enter drill · Shift+←→ range`:`←→ points · ↑↓ series · Enter drill`;return(0,V.useLayoutEffect)(()=>(j?.setHint(_?de:void 0),()=>j?.setHint(void 0)),[j,_,de]),(0,V.useLayoutEffect)(()=>{let e=M.current;if(!e)return;N.current.onRangeBarHeight?.(e.getBoundingClientRect().height);let t=new ResizeObserver(([t])=>{if(!t)return;let n=getComputedStyle(e),r=[n.paddingTop,n.paddingBottom,n.borderTopWidth,n.borderBottomWidth].reduce((e,t)=>e+(parseFloat(t)||0),0);N.current.onRangeBarHeight?.(t.borderBoxSize?.[0]?.blockSize??t.contentRect.height+r)});return t.observe(e),()=>{t.disconnect(),N.current.onRangeBarHeight?.(0)}},[!!(E&&ae)]),(0,H.jsxs)(o,{ref:O,"data-chart-plot":!0,tabIndex:0,role:`application`,"aria-roledescription":`chart`,"aria-label":t,"aria-describedby":A,"data-mantine-stop-propagation":E?`true`:void 0,className:`chart-keyboard-point`,style:{position:`relative`,height:p,width:`100%`,flex:`1 1 auto`,minHeight:0,minWidth:0},onPointerDownCapture:e=>{M.current?.contains(e.target)||(k.current=!0,v(!1),_&&N.current.onHighlight(void 0),N.current.onActiveChange?.(!1))},onFocus:e=>{e.target!==e.currentTarget||k.current||(N.current.onActiveChange?.(!0),v(!0))},onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||(v(!1),D(null),x(``),N.current.onHighlight(void 0),N.current.onActiveChange?.(!1))},onKeyDown:e=>{if(e.defaultPrevented||e.ctrlKey||e.metaKey||e.altKey||e.nativeEvent.isComposing)return;if(e.key===`Escape`&&!e.repeat){E?(e.preventDefault(),e.stopPropagation(),ue()):e.target===e.currentTarget&&!e.currentTarget.closest(`[data-panel-fullscreen],[data-fragment-fullscreen]`)&&(e.preventDefault(),e.stopPropagation(),e.currentTarget.blur());return}if(e.target!==e.currentTarget||e.repeat&&![`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`].includes(e.key))return;let t=[`ArrowLeft`,`ArrowRight`,`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key);if(t&&!_&&(k.current=!1,v(!0),N.current.onActiveChange?.(!0),!ie)){e.preventDefault();return}e.key===`Enter`&&_&&!e.shiftKey&&ie&&i&&(!a||a(ie.event))?(e.preventDefault(),i(ie.event)):t&&(!e.shiftKey||e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),le(e.key,e.shiftKey))},children:[r,(0,H.jsx)(o,{"data-chart-overlay":!0,style:{position:`absolute`,inset:0,zIndex:1,pointerEvents:`none`,overflow:`hidden`},children:E&&ae&&(0,H.jsxs)(y,{ref:M,"data-chart-range-bar":!0,gap:6,style:{...Ma,position:`absolute`,bottom:4,left:4,right:4,maxHeight:`100%`,overflow:`auto`,pointerEvents:`auto`},children:[(0,H.jsx)(T,{"data-chart-range-label":!0,size:`xs`,title:E.from+` – `+E.to,truncate:!0,style:{flex:`1 1 140px`,minWidth:0},children:ja(E)}),(0,H.jsx)(C,{size:`compact-xs`,"data-mantine-stop-propagation":`true`,onClick:()=>{m(Date.parse(E.from),Date.parse(E.to)),ue()},children:`Zoom to range`}),(0,H.jsx)(C,{size:`compact-xs`,variant:`subtle`,"data-mantine-stop-propagation":`true`,onClick:ue,children:`Cancel`})]})}),(0,H.jsx)(Je,{id:A,children:de}),(0,H.jsx)(Je,{"aria-live":`polite`,"aria-atomic":`true`,children:b})]})}var Ia=new Set([`id`,`http`,`https`,`rpc`,`grpc`,`cpu`,`sql`,`url`,`uri`,`ip`,`io`,`db`,`gc`,`tls`,`api`]),La={ms:`ms`,ns:`ns`,s:`s`,us:`µs`,bytes:`bytes`,percent:`%`,ratio:`ratio`,per_second:`/s`,per_minute:`/min`},Ra={body_template:`message template`,parquet_index:`traces`};function za(e,t){let n=typeof e==`string`?e:e.name,r=t?.options?.columns?.find(e=>e.field===n)?.unit??(typeof e==`string`?void 0:e.unit)??(typeof e!=`string`&&e.role===`measure`?t?.unit:void 0),i=Ra[n]??n;/\b(?:duckdb|parquet|sqlite|variant|timestamptz_ns|timestamp_ns)\b|\btelemetry\./i.test(i)&&(i=`value`),i=i.replace(/^(\w+)\(([^()]*)\)$/,(e,t,n)=>[t,n].filter(Boolean).join(`_`));let a=i.match(/_(ms|ns|us|s|bytes|percent)$/i);a&&(i=i.slice(0,-a[0].length));let o=r??a?.[1]?.toLowerCase();return i=i.split(`_`).map((e,t)=>/^p\d+$/i.test(e)||Ia.has(e.toLowerCase())?e.toUpperCase():t===0?e.charAt(0).toUpperCase()+e.slice(1):e).join(` `),i+(o&&o!==`none`&&o!==`count`?` (${La[o]??o})`:``)}function Ba(e){return e===`healthy`?`ok`:e===`degraded`?`warn`:e===`unknown`?`gray`:`bad`}function Va(e){return it[e?`dark`:`light`]}function Ha(e){let t=e?5:7;return{ok:st[t],warn:lt[t],bad:wt[t],info:Et[t]}}function Ua(e,t){return _t[t?`dark`:`light`][e]??Va(t).muted}function Wa(e){return e===`unhealthy`?`diamond`:e===`degraded`?`roundRect`:`circle`}function Ga(e){return e===`unknown`?`dashed`:`solid`}var Ka=e=>typeof e==`number`&&Number.isFinite(e)?e:null;function qa(e){return e.columns.flatMap((e,t)=>e.role===`measure`?[t]:[])}function Ja(e){let t=e.columns.findIndex(e=>e.role===`time`);if(t<0)return[];let n=e.columns.findIndex(e=>e.role===`dimension`),r=qa(e);if(n>=0&&r.length>0){let i=r[0],a=new Map;for(let r=0;r({name:e.columns[n].name,unit:e.columns[n].unit,points:e.values[t].map((t,r)=>[Number(t),Ka(e.values[n][r])])}))}function Ya(e){let t=e.columns.flatMap((e,t)=>e.role===`dimension`?[t]:[]),n=qa(e);if(t.length===0||n.length===0)return{categories:[],series:[]};let r=t[0],i=[];for(let t=0;t1){let a=t[1],o=n[0],s=new Map;for(let t=0;tnull)),s.get(n)[i.indexOf(String(e.values[r][t]??``))]=Ka(e.values[o][t])}return{categories:i,series:[...s.entries()].map(([t,n])=>({name:t,unit:e.columns[o].unit,values:n}))}}return{categories:i,series:n.map(t=>({name:e.columns[t].name,unit:e.columns[t].unit,values:e.values[t].map(Ka)}))}}function Xa(e,t){let n=e.filter(e=>e!==null);if(n.length===0)return null;switch(t){case`last`:return n[n.length-1];case`min`:return Math.min(...n);case`max`:return Math.max(...n);case`sum`:return n.reduce((e,t)=>e+t,0);default:return n.reduce((e,t)=>e+t,0)/n.length}}function Za(e,t){let n=qa(t)[0];return n===void 0?null:(e.reduce??`window`)===`window`?t.totals?Ka(t.totals[n]):Xa(t.values[n].map(Ka),`mean`):Xa(t.values[n].map(Ka),e.reduce??`mean`)}function Qa(e){let t=qa(e)[0];return t===void 0?[]:e.values[t].map(Ka)}var $a={ok:0,warn:1,bad:2};function eo(e){if(!e?.length)return;let t=[...e].sort((e,t)=>$a[e.status]-$a[t.status]),n=t[0],r=t[t.length-1];return $a[r.status]>$a[n.status]&&r.value!==n.value?r.value>n.value?`lower`:`higher`:`lower`}function to(e,t,n){if(e===null||!t||t.length===0)return null;n??=eo(t);let r=`ok`;for(let i of t)(n===`lower`?e>=i.value:e<=i.value)&&$a[i.status]>$a[r]&&(r=i.status);return r}function no(e,t){let n=yt(e),r=yt(t);return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}function ro(e,t){return`rgba(${[1,3,5].map(t=>parseInt(e.slice(t,t+2),16)).join(`, `)}, ${t})`}function io(e,t){return{color:e,...no(e,t.surface)<3?{borderColor:t.text,borderWidth:1}:{}}}function ao(e,t){return{color:e,...no(e,t.surface)<3?{shadowColor:t.text,shadowBlur:2}:{}}}function oo(e,t){return{ok:st,warn:lt,bad:wt}[e][t?5:8]}function so(e){let t=Va(e),n=Ha(e);return{dark:e,text:t.text,muted:t.muted,grid:t.grid,surface:t.surface,border:t.border,status:{ok:n.ok,warn:n.warn,bad:n.bad},font:xt.display}}function co(e,t,n){if(!Array.isArray(e.series))return e;let r=e.series,i=Array.isArray(e.yAxis)?e.yAxis:[e.yAxis],a=[],o=r.map((e,o)=>{let s=e.endLabel;if(!s?.show||!Array.isArray(e.data))return e;let c;for(let t=e.data.length-1;t>=0;t--){let n=e.data[t];if(Array.isArray(n)&&typeof n[1]==`number`&&Number.isFinite(n[1])){c=n;break}}let l=i[Number(e.yAxisIndex??0)];if(!c||!l)return{...e,endLabel:{...s,show:!1}};let u=l.type===`log`?Math.log:e=>e,d=l.min??1/0,f=l.max??0;if(l.type===`log`&&(l.min===void 0||l.max===void 0)){for(let t of r)if(Number(t.yAxisIndex??0)===Number(e.yAxisIndex??0)&&Array.isArray(t.data))for(let e of t.data)Array.isArray(e)&&typeof e[1]==`number`&&Number.isFinite(e[1])&&e[1]>0&&(l.min===void 0&&(d=Math.min(d,e[1])),l.max===void 0&&(f=Math.max(f,e[1])))}Number.isFinite(d)||(d=1);let p=u(l.type===`log`?d:l.min??0),m=u(l.type===`log`?Math.max(f,d*1.01):l.max??1),h=n?.(o,c),g=Number.isFinite(h)?h:t.y+t.height*(1-(u(c[1])-p)/(m-p)),_=((s.lineHeight??14)+2)/2,v=[Math.max(t.y+_,Math.min(t.y+t.height-_,g)),...a.flatMap(e=>[e.y-e.half-_,e.y+e.half+_])].filter(e=>Number.isFinite(e)&&e-_>=t.y&&e+_<=t.y+t.height&&a.every(t=>Math.abs(t.y-e)>=t.half+_)).sort((e,t)=>Math.abs(e-g)-Math.abs(t-g))[0];return v===void 0?{...e,endLabel:{...s,show:!1}}:(a.push({y:v,half:_}),{...e,labelLayout:{dy:v-g,hideOverlap:!0}})});return{...e,series:o}}var lo=(e,t,n)=>ra(e)?n.muted:Ua(t,n.dark);function uo(e,t){let n=Ja(e);if(!e.columns.some(e=>e.role===`dimension`))for(let r of n)r.name=za(e.columns.find(e=>e.name===r.name)??r.name,t);return oa(n,t)}function fo(e,t){return{animationDuration:200,textStyle:{fontFamily:e.font,color:e.muted,fontSize:11},grid:{left:8,right:16,top:28,bottom:8,containLabel:!0},tooltip:{trigger:`axis`,formatter:na(e=>va(t,e)),confine:!0,backgroundColor:e.surface,borderColor:e.border,textStyle:{color:e.text,fontSize:12},valueFormatter:e=>va(t,e),axisPointer:{type:`line`,lineStyle:{color:e.border}}},aria:{enabled:!0}}}function po(e,t,n,r){return(e.thresholds??[]).map(i=>({yAxis:i.value,label:{formatter:`${i.label??i.status} ${ya(r??e.unit)(i.value).replace(/(?<=\d)(ms|s|m|h)$/,` $1`)}`,position:i.value<=(n.min+n.max)/2?`insideEndTop`:`insideEndBottom`,distance:8,color:t.muted,textBorderColor:t.surface,textBorderWidth:3,fontSize:12},lineStyle:{color:t.status[i.status],type:[4,3],width:1}}))}function mo(e,t,n,r={width:500,height:248}){let i=t.frame?uo(t.frame,e):{shown:[],hidden:0},a=i.shown,o=a[0]?.unit??e.unit,s=new Set(a.map(e=>e.name)),c=a.find(e=>ra(e.name)),l=t.previous&&t.shift_ms!==void 0?uo(t.previous,e).shown.flatMap(e=>ra(e.name)?c?[e]:[]:s.has(e.name)?[e]:[]):[],u=[...new Set([...a,...l].map(t=>t.unit??e.unit))];u.length===0&&u.push(e.unit);let d=e.options?.style??`line`,f=a.length>=2&&a.length<=6&&i.hidden===0&&d!==`bars`&&d!==`stacked`,p=f?Math.max(40,...a.map(e=>{let t=Array.from(e.name).slice(0,24).join(``);return r.measureText?.(t,`12px ${n.font}`)??Array.from(t).length*7.2}))+12:0,m=f?p+8:0,h=(e.options?.legend??`auto`)!==`hidden`&&a.length>1,g=ca(a.map(e=>e.name),r.width,h,n.text,n.font,r.measureText),_=r.height-g.top-(i.hidden?24:8)-22,v=Math.max(0,Math.floor(_/16)),y=t.shift_ms,b=u.map(t=>{let n=[...a,...l].filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.points.flatMap(([,e])=>e===null?[]:[e]));if(d===`stacked`){let r=new Map;for(let n of a.filter(n=>(n.unit??e.unit)===t))for(let[e,t]of n.points){let n=r.get(e)??{positive:0,negative:0};t!==null&&(t>0?n.positive+=t:n.negative+=t),r.set(e,n)}n.push(...[...r.values()].flatMap(e=>[e.positive,e.negative]))}return Ca(Math.min(0,...n),Math.max(0,...n),t,_)}),x=a.map((t,r)=>{let i=lo(t.name,r,n);return{name:t.name,interactive:!0,yAxisIndex:u.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:d===`bars`||d===`stacked`?`bar`:`line`,data:t.points,endLabel:f?{show:r0?{symbol:[`none`,`none`],silent:!0,data:po(e,n,b[0],o)}:void 0}}),S=y===void 0?[]:l.map(t=>({name:`${t.name} · previous`,interactive:!1,yAxisIndex:u.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:`line`,data:t.points.map(([e,t])=>[e+y,t]),showSymbol:!1,silent:!0,z:1,lineStyle:{width:1,type:`dashed`,color:n.muted},itemStyle:{color:n.muted}})),C=u.map((t,r)=>({...e.options?.scale===`log`?{splitNumber:xa(_)}:b[r],type:e.options?.scale===`log`?`log`:`value`,position:r===0?`left`:`right`,offset:Math.max(0,r-1)*56,axisLine:{show:!1},splitLine:{show:r===0,lineStyle:{color:n.grid}},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,hideOverlap:!0,formatter:ya(t)}}));return co({...fo(n,o),tooltip:{...fo(n,o).tooltip,formatter:na((t,n)=>va([...a,...l].find(e=>e.name===n||`${e.name} · previous`===n)?.unit??e.unit,t),!0)},legend:g.option,grid:{left:8,right:16+(f?m:0)+Math.max(0,u.length-2)*56,top:g.top,bottom:i.hidden?24:8,containLabel:!0},xAxis:{type:`time`,min:t.from_ms,max:t.to_ms,axisLine:{lineStyle:{color:n.grid}},axisTick:{show:!1},splitLine:{show:!1},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,hideOverlap:!0,formatter:Ea}},yAxis:C.length===1?C[0]:C,series:[...x,...S],graphic:sa(i.hidden,n.muted)},{y:g.top,height:_})}function ho(e,t,n){if(n(e)<=t)return e;let r=Array.from(e);for(let e=r.length-1;e>0;e--){let i=Math.floor(e*.45),a=e-i,o=r.slice(0,i).join(``)+`…`+r.slice(-a).join(``);if(n(o)<=t)return o}return`…`}function go(e,t,n,r={width:500,height:248}){let i=Ya(t);if(t.columns.filter(e=>e.role===`dimension`).length<2)for(let n of i.series)n.name=za(t.columns.find(e=>e.name===n.name)??n.name,e);let a=i.categories,{shown:o,hidden:s}=oa(i.series,e),c=t.columns.flatMap((e,t)=>e.role===`dimension`?[t]:[]),l=new Map;for(let n=0;nString(t.values[e][n]??``))),{dimensions:r,...i})}let u=o[0]?.unit??e.unit,d=[...new Set(o.map(t=>t.unit??e.unit))];d.length===0&&d.push(e.unit);let f=o.length>1,p=!!(t.periods?.[`Before deploy`]||t.periods?.[`Since deploy`]),m=e=>r.measureText?.(e,`11px ${n.font}`)??Array.from(e).length*6.6,h=Math.min(r.width*.4,Math.max(40,...a.map(m))),g=ca(o.map(e=>e.name),r.width,f&&e.options?.legend!==`hidden`,n.text,n.font,r.measureText),_=d.map((t,i)=>({...Ca(Math.min(0,...o.filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.values.filter(e=>e!==null))),Math.max(0,...o.filter(n=>(n.unit??e.unit)===t).flatMap(e=>e.values.filter(e=>e!==null))),t,r.width-h-80),type:`value`,position:i===0?`bottom`:`top`,offset:Math.max(0,i-1)*36,splitLine:{show:i===0,lineStyle:{color:n.grid}},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,formatter:e=>ba(t,e),hideOverlap:!0}}));return{...fo(n,u),tooltip:{...fo(n,u).tooltip,formatter:na((t,n)=>va(o.find(e=>e.name===n)?.unit??e.unit,t)),axisPointer:{type:`shadow`}},legend:g.option,grid:{left:8,right:56,top:(f?g.top:8)+Math.max(0,d.length-1)*36,bottom:s?24:8,containLabel:!0},yAxis:{type:`category`,inverse:!0,data:a,splitLine:{show:!1},axisLine:{lineStyle:{color:n.grid}},axisTick:{show:!1},axisLabel:{color:n.muted,fontFamily:n.font,fontSize:11,width:h,overflow:`truncate`,formatter:e=>ho(e,h,m)}},xAxis:_.length===1?_[0]:_,series:o.map((t,r)=>({name:t.name,interactive:!0,xAxisIndex:d.indexOf(t.unit??e.unit),tooltip:{valueFormatter:n=>va(t.unit??e.unit,n)},type:`bar`,data:t.values.map((e,n)=>({value:e,selection:l.get(JSON.stringify(c.length>1?[a[n],t.name]:[a[n]]))})),barMaxWidth:p&&t.name===`Before deploy`?7:14,barGap:`20%`,itemStyle:{...io(p?t.name===`Before deploy`?n.muted:Ua(0,n.dark):lo(t.name,r,n),n),borderRadius:[0,4,4,0]},label:{show:p?t.name===`Since deploy`:!f||r===0,position:`right`,color:n.text,fontFamily:n.font,fontSize:11,formatter:({value:n})=>ba(t.unit??e.unit,n)}})),graphic:sa(s,n.muted)}}function _o(e,t,n,r=e.unit,i={width:270,height:140}){let a=e.min??0,o=e.max??100,s=vo(e,a,o,n),c=va(r,t),l=to(t,e.thresholds,e.better),u=l===`bad`?`◆ Bad`:l===`warn`?`■ Warn`:l===`ok`?`● OK`:t===null?`○ Unknown`:void 0,d=e=>`${e}40`,f=i.measureText?.(c,`600 28px ${n.font}`)??c.length*28*.6,p=i.measureText?.(u??``,`11px ${n.font}`)??(u?.length??0)*11*.6,m=i.width{let r=y;return y=e,{type:`rect`,shape:{x:4+r*_,y:g,width:(e-r)*_,height:10,r:[n===0?5:0,n===s.length-1?5:0,n===s.length-1?5:0,n===0?5:0]},style:{fill:d(t)}}}),{id:`gauge-fill`,type:`rect`,shape:{x:4,y:g,width:v*_,height:10,r:5},style:{fill:l?n.status[l]:Ua(0,n.dark)}},{id:`gauge-marker`,type:`rect`,shape:{x:3+v*_,y:g-2,width:2,height:14,r:1},style:{fill:n.text}},{type:`text`,left:4,top:g+12,style:{text:va(r,a),fill:n.muted,fontSize:11,fontFamily:n.font}},{type:`text`,right:4,top:g+12,style:{text:va(r,o),fill:n.muted,fontSize:11,fontFamily:n.font}}]}}function vo(e,t,n,r){let i=n-t||1,a=[t,...(e.thresholds??[]).map(e=>Math.min(n,Math.max(t,e.value))),n].sort((e,t)=>e-t),o=[];for(let t=0;t[(e.end-t)/i,r.status[e.status]])}var yo=function(e,t){return yo=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},yo(e,t)};function U(e,t){if(typeof t!=`function`&&t!==null)throw TypeError(`Class extends value `+String(t)+` is not a constructor or null`);yo(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var bo=`12px sans-serif`,xo=20,So=100,Co=`007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N`;function wo(e){var t={};if(typeof JSON>`u`)return t;for(var n=0;n=0)s=o*n.length;else for(var c=0;c=zo&&(Ro=0),Ro++}function Vo(){var e=[...arguments];typeof console<`u`&&console.error.apply(console,e)}function Ho(e){if(typeof e!=`object`||!e)return e;var t=e,n=ko.call(e);if(n===`[object Array]`){if(!xs(e)){t=[];for(var r=0,i=e.length;r`u`&&typeof self<`u`?Ns.worker=!0:!Ns.hasGlobalWindow||`Deno`in window||typeof navigator<`u`&&typeof navigator.userAgent==`string`&&navigator.userAgent.indexOf(`Node.js`)>-1?(Ns.node=!0,Ns.svgSupported=!0):Ps(navigator.userAgent,Ns);function Ps(e,t){var n=t.browser,r=e.match(/Firefox\/([\d.]+)/),i=e.match(/MSIE\s([\d.]+)/)||e.match(/Trident\/.+?rv:(([\d.]+))/),a=e.match(/Edge?\/([\d.]+)/),o=/micromessenger/i.test(e);if(r&&(n.firefox=!0,n.version=r[1]),i&&(n.ie=!0,n.version=i[1]),a&&(n.edge=!0,n.version=a[1],n.newEdge=+a[1].split(`.`)[0]>18),o&&(n.weChat=!0),t.svgSupported=typeof SVGRect<`u`,t.touchEventsSupported=`ontouchstart`in window&&!n.ie&&!n.edge,t.pointerEventsSupported=`onpointerdown`in window&&(n.edge||n.ie&&+n.version>=11),t.domSupported=typeof document<`u`){var s=document.documentElement.style;t.transform3dSupported=(n.ie&&`transition`in s||n.edge||`WebKitCSSMatrix`in window&&`m11`in new WebKitCSSMatrix||`MozPerspective`in s)&&!(`OTransition`in s),t.transformSupported=t.transform3dSupported||n.ie&&+n.version>=9}}var Fs=1e-4,Is=20;function Ls(e){return e.replace(/^\s+|\s+$/g,``)}var Rs=Math.min,zs=Math.max,Bs=Math.abs,Vs=Math.round,Hs=Math.floor,Us=Math.ceil,Ws=Math.pow,Gs=Math.log,Ks=Math.LN10,qs=Math.PI,Js=Math.random;function Ys(e,t,n,r){var i=t[0],a=t[1],o=n[0],s=n[1],c=a-i,l=s-o;if(c===0)return l===0?o:(o+s)/2;if(r){if(c>0){if(e<=i)return o;if(e>=a)return s}else if(e>=i)return o;else if(e<=a)return s}else{if(e===i)return o;if(e===a)return s}return(e-i)/c*l+o}var Xs=Zs;function Zs(e,t,n){switch(e){case`center`:case`middle`:e=`50%`;break;case`left`:case`top`:e=`0%`;break;case`right`:case`bottom`:e=`100%`}return Qs(e,t,n)}function Qs(e,t,n){return Y(e)?$s(e)?parseFloat(e)/100*t+(n||0):parseFloat(e):e==null?NaN:+e}function $s(e){return!!Ls(e).match(/%$/)}function ec(e,t,n){return isNaN(t)?n?``+e:+e:(t=Rs(zs(0,t),Is),e=(+e).toFixed(t),n?e:+e)}function tc(e){return e.sort(function(e,t){return e-t}),e}function nc(e){if(e=+e,isNaN(e))return 0;if(e>1e-14){for(var t=1,n=0;n<15;n++,t*=10)if(Vs(e*t)/t===e)return n}return rc(e)}function rc(e){var t=e.toString().toLowerCase(),n=t.indexOf(`e`),r=n>0?+t.slice(n+1):0,i=n>0?n:t.length,a=t.indexOf(`.`);return zs(0,(a<0?0:i-1-a)-r)}function ic(e,t,n){var r=Bs(e[1]-e[0]);if(!isFinite(r)||r===0)return NaN;var i=Gs(2*Bs(n||1)*Bs(r))/Ks,a=Gs(Bs(t))/Ks,o=zs(0,Us(-i+a));return isFinite(o)||(o=NaN),o}function ac(e,t){var n=zs(nc(e),nc(t)),r=e+t;return n>Is?r:ec(r,n)}var oc=Ws(2,53)-1;function sc(e){var t=qs*2;return(e%t+t)%t}function cc(e){return e>-Fs&&e=10&&t++,t}function pc(e,t){var n=fc(e),r=Ws(10,n),i=e/r;return e=(t===2?1:t?i<1.5?1:i<2.5?2:i<4?3:i<7?5:10:i<1?1:i<2?2:i<3?3:i<5?5:10)*r,ec(e,-n)}function mc(e){e.sort(function(e,t){return s(e,t,0)?-1:1});for(var t=-1/0,n=1,r=0;r0?e.length:0),this.item=null,this.key=NaN,this},e.prototype.next=function(){return(this._step>0?this._idx=this._end)&&(this.item=this._list[this._idx],this.key=this._idx+=this._step,!0)},e})();function ul(){return[1/0,-1/0]}function dl(e,t){hl(t)&&(te[1]&&(e[1]=t))}function fl(e,t){hl(t)&&te[1]&&(e[1]=t)}function ml(e,t){gl(t[0],t[1])&&(t[0]e[1]&&(e[1]=t[1]))}function hl(e){return e!=null&&isFinite(e)}function gl(e,t){return hl(e)&&hl(t)&&e<=t}function _l(e){var t=e[1]-e[0];return isFinite(t)&&t>=0}function vl(e){gl(e[0],e[1])&&e[0]>e[1]&&(e[0]=e[1])}function yl(){var e=`__ec_once_`+bl++;return function(t,n){Z(t,e)||(t[e]=1,n())}}var bl=_c();function xl(e,t,n){var r=Es(),i=0;G(e,function(a){var o=t(a),s=r.get(o)||0;n&&n(a,s),!s&&!n&&(e[i++]=a),r.set(o,s+1)}),n||(e.length=i)}function Sl(e){return e.value+``}function Cl(e){return e+``}function wl(e,t){return X(t,!0)?e.seriesIndex+2:0}function Tl(e,t,n){var r=e.getData().count();return{progressiveRender:n.progressiveEnabled&&t.incrementalPrepareRender&&r>=n.threshold,large:e.get(`large`)&&r>=e.get(`largeThreshold`),modDataCount:e.get(`progressiveChunkMode`)===`mod`?e.getData().count():null}}function El(e){return{overallReset:e}}var Dl=`.`,Ol=`___EC__COMPONENT__CONTAINER___`,kl=`___EC__EXTENDED_CLASS___`;function Al(e){var t={main:``,sub:``};if(e){var n=e.split(Dl);t.main=n[0]||``,t.sub=n[1]||``}return t}function jl(e){_s(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(e),`componentType "`+e+`" illegal`)}function Ml(e){return!!(e&&e[kl])}function Nl(e,t){e.$constructor=e,e.extend=function(e){var t=this,n;return Pl(t)?n=function(e){U(t,e);function t(){return e.apply(this,arguments)||this}return t}(t):(n=function(){(e.$constructor||t).apply(this,arguments)},Jo(n,this)),W(n.prototype,e),n[kl]=!0,n.extend=this.extend,n.superCall=Rl,n.superApply=zl,n.superClass=t,n}}function Pl(e){return rs(e)&&/^class\s/.test(Function.prototype.toString.call(e))}function Fl(e,t){e.extend=t.extend}var Il=Math.round(Math.random()*10);function Ll(e){var t=[`__\0is_clz`,Il++].join(`_`);e.prototype[t]=!0,e.isInstance=function(e){return!!(e&&e[t])}}function Rl(e,t){var n=[...arguments].slice(2);return this.superClass.prototype[t].apply(e,n)}function zl(e,t,n){return this.superClass.prototype[t].apply(e,n)}function Bl(e){var t={};e.registerClass=function(e){var r=e.type||e.prototype.type;if(r){jl(r),e.prototype.type=r;var i=Al(r);if(!i.sub)t[i.main]=e;else if(i.sub!==Ol){var a=n(i);a[i.sub]=e}}return e},e.getClass=function(e,n,r){var i=t[e];if(i&&i[Ol]&&(i=n?i[n]:null),r&&!i)throw Error(n?`Component `+e+`.`+(n||``)+` is used but not imported.`:e+`.type should be specified.`);return i},e.getClassesByMainType=function(e){var n=Al(e),r=[],i=t[n.main];return i&&i[Ol]?G(i,function(e,t){t!==Ol&&r.push(e)}):r.push(i),r},e.hasClass=function(e){return!!t[Al(e).main]},e.getAllClassMainTypes=function(){var e=[];return G(t,function(t,n){e.push(n)}),e},e.hasSubTypes=function(e){var n=t[Al(e).main];return n&&n[Ol]};function n(e){var n=t[e.main];return(!n||!n[Ol])&&(n=t[e.main]={},n[Ol]=!0),n}}function Vl(e,t){for(var n=0;n=0||i&&qo(i,s)<0)){var c=n.getShallow(s,t);c!=null&&(a[e[o][0]]=c)}}return a}}var Hl=Vl([[`fill`,`color`],[`shadowBlur`],[`shadowOffsetX`],[`shadowOffsetY`],[`opacity`],[`shadowColor`]]),Ul=function(){function e(){}return e.prototype.getAreaStyle=function(e,t){return Hl(this,e,t)},e}(),Wl=function(){function e(e){this.value=e}return e}(),Gl=function(){function e(){this._len=0}return e.prototype.insert=function(e){var t=new Wl(e);return this.insertEntry(t),t},e.prototype.insertEntry=function(e){this.head?(this.tail.next=e,e.prev=this.tail,e.next=null,this.tail=e):this.head=this.tail=e,this._len++},e.prototype.remove=function(e){var t=e.prev,n=e.next;t?t.next=n:this.head=n,n?n.prev=t:this.tail=t,e.next=e.prev=null,this._len--},e.prototype.len=function(){return this._len},e.prototype.clear=function(){this.head=this.tail=null,this._len=0},e}(),Kl=function(){function e(e){this._list=new Gl,this._maxSize=10,this._map={},this._maxSize=e}return e.prototype.put=function(e,t){var n=this._list,r=this._map,i=null;if(r[e]==null){var a=n.len(),o=this._lastRemovedEntry;if(a>=this._maxSize&&a>0){var s=n.head;n.remove(s),delete r[s.key],i=s.value,this._lastRemovedEntry=s}o?o.value=t:o=new Wl(t),o.key=e,n.insertEntry(o),r[e]=o}return i},e.prototype.get=function(e){var t=this._map[e],n=this._list;if(t!=null)return t!==n.tail&&(n.remove(t),n.insertEntry(t)),t.value},e.prototype.clear=function(){this._list.clear(),this._map={}},e.prototype.len=function(){return this._list.len()},e}(),ql=new Kl(50);function Jl(e){if(typeof e==`string`){var t=ql.get(e);return t&&t.image}return e}function Yl(e,t,n,r,i){if(!e)return t;if(typeof e==`string`){if(t&&t.__zrImageSrc===e||!n)return t;var a=ql.get(e),o={hostEl:n,cb:r,cbPayload:i};return a?(t=a.image,!Zl(t)&&a.pending.push(o)):(t=Eo.loadImage(e,Xl,Xl),t.__zrImageSrc=e,ql.put(e,t.__cachedImgObj={image:t,pending:[o]})),t}return e}function Xl(){var e=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var t=0;tu||d>f||p>m||h>g)return!1;var _=!(u=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height},e.prototype.contain=function(t,n){return e.contain(this,t,n)},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.copy=function(e){Vu(this,e)},e.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},e.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},e.prototype.isZero=function(){return this.width===0||this.height===0},e.create=function(t){return new e(t?t.x:0,t?t.y:0,t?t.width:0,t?t.height:0)},e.copy=function(e,t){return e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height,e},e.applyTransform=function(e,t,n){if(!n){e!==t&&Vu(e,t);return}if(n[1]<1e-5&&n[1]>-1e-5&&n[2]<1e-5&&n[2]>-1e-5){var r=n[0],i=n[3],a=n[4],o=n[5];e.x=t.x*r+a,e.y=t.y*i+o,e.width=t.width*r,e.height=t.height*i,e.width<0&&(e.x+=e.width,e.width=-e.width),e.height<0&&(e.y+=e.height,e.height=-e.height);return}Au.x=Mu.x=t.x,Au.y=Nu.y=t.y,ju.x=Nu.x=t.x+t.width,ju.y=Mu.y=t.y+t.height,Au.transform(n),Nu.transform(n),ju.transform(n),Mu.transform(n),e.x=Tu(Au.x,ju.x,Mu.x,Nu.x),e.y=Tu(Au.y,ju.y,Mu.y,Nu.y);var s=Eu(Au.x,ju.x,Mu.x,Nu.x),c=Eu(Au.y,ju.y,Mu.y,Nu.y);e.width=s-e.x,e.height=c-e.y},e.calculateTransform=function(e,t,n){var r=n.width/t.width,i=n.height/t.height;return e=$l(e||[]),nu(e,e,lu(qu,-t.x,-t.y)),iu(e,e,lu(qu,r,i)),nu(e,e,lu(qu,n.x,n.y)),e},e}(),zu=Ru.create,Bu=Ru.set,Vu=Ru.copy,Hu=Ru.calculateTransform,Uu=Ru.applyTransform,Wu=Ru.contain,Gu=new Ru(0,0,0,0),Ku=new Ru(0,0,0,0),qu=[];function Ju(e,t,n,r,i,a,o,s){var c=Du(t-n),l=Du(r-e),u=Tu(c,l),d=Ou[i],f=Ou[1-i],p=ku[i];t=l||!Pu.bidirectional)&&(Fu[d]=-l,Fu[f]=0,Pu.useDir&&Pu.calcDirMTV())))}function Yu(){var e=0,t=new wu,n=new wu,r={minTv:new wu,maxTv:new wu,useDir:!1,dirMinTv:new wu,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(i,a){r.touchThreshold=0,i&&i.touchThreshold!=null&&(r.touchThreshold=Eu(0,i.touchThreshold)),r.negativeSize=!1,a&&(r.minTv.set(1/0,1/0),r.maxTv.set(0,0),r.useDir=!1,i&&i.direction!=null&&(r.useDir=!0,r.dirMinTv.copy(r.minTv),n.copy(r.minTv),e=i.direction,r.bidirectional=i.bidirectional==null||!!i.bidirectional,r.bidirectional||t.set(Math.cos(e),Math.sin(e))))},calcDirMTV:function(){var a=r.minTv,o=r.dirMinTv,s=a.y*a.y+a.x*a.x,c=Math.sin(e),l=Math.cos(e),u=c*a.y+l*a.x;if(i(u)){i(a.x)&&i(a.y)&&o.set(0,0);return}if(n.x=s*l/u,n.y=s*c/u,i(n.x)&&i(n.y)){o.set(0,0);return}(r.bidirectional||t.dot(n)>0)&&n.len()=ed)){e||=`12px sans-serif`;for(var t=[],n=+new Date,r=0;r<=127;r++)t[r]=Eo.measureText(String.fromCharCode(r),e).width;var i=+new Date-n;return i>16?$u=ed:i>2&&$u++,t}}var $u=0,ed=5;function td(e,t){return e.asciiWidthMapTried||=(e.asciiWidthMap=Qu(e.font),!0),0<=t&&t<=127?e.asciiWidthMap==null?e.asciiCharWidth:e.asciiWidthMap[t]:e.stWideCharWidth}function nd(e,t){var n=e.strWidthCache,r=n.get(t);return r??(r=Eo.measureText(t,e.font).width,n.put(t,r)),r}function rd(e,t,n,r){var i=nd(Xu(t),e),a=sd(t);return new Ru(ad(0,i,n),od(0,a,r),i,a)}function id(e,t,n,r){var i=((e||``)+``).split(` `);if(i.length===1)return rd(i[0],t,n,r);for(var a=new Ru(0,0,0,0),o=0;o=0?parseFloat(e)/100*t:parseFloat(e):e}function ld(e,t,n){var r=t.position||`inside`,i=t.distance==null?5:t.distance,a=n.height,o=n.width,s=a/2,c=n.x,l=n.y,u=`left`,d=`top`;if(r instanceof Array)c+=cd(r[0],n.width),l+=cd(r[1],n.height),u=null,d=null;else switch(r){case`left`:c-=i,l+=s,u=`right`,d=`middle`;break;case`right`:c+=i+o,l+=s,d=`middle`;break;case`top`:c+=o/2,l-=i,u=`center`,d=`bottom`;break;case`bottom`:c+=o/2,l+=a+i,u=`center`;break;case`inside`:c+=o/2,l+=s,u=`center`,d=`middle`;break;case`insideLeft`:c+=i,l+=s,d=`middle`;break;case`insideRight`:c+=o-i,l+=s,u=`right`,d=`middle`;break;case`insideTop`:c+=o/2,l+=i,u=`center`;break;case`insideBottom`:c+=o/2,l+=a-i,u=`center`,d=`bottom`;break;case`insideTopLeft`:c+=i,l+=i;break;case`insideTopRight`:c+=o-i,l+=i,u=`right`;break;case`insideBottomLeft`:c+=i,l+=a-i,d=`bottom`;break;case`insideBottomRight`:c+=o-i,l+=a-i,u=`right`,d=`bottom`}return e||={},e.x=c,e.y=l,e.align=u,e.verticalAlign=d,e}var ud=/\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;function dd(e,t,n,r,i,a){if(!n){e.text=``,e.isTruncated=!1;return}var o=(t+``).split(` `);a=fd(n,r,i,a);for(var s=!1,c={},l=0,u=o.length;l=s;l++)c-=s;var u=nd(o,n);return u>c&&(n=``,u=0),c=e-u,i.ellipsis=n,i.ellipsisWidth=u,i.contentWidth=c,i.containerWidth=e,i}function pd(e,t,n){var r=n.containerWidth,i=n.contentWidth,a=n.fontMeasureInfo;if(!r){e.textLine=``,e.isTruncated=!1;return}var o=nd(a,t);if(o<=r){e.textLine=t,e.isTruncated=!1;return}for(var s=0;;s++){if(o<=i||s>=n.maxIterations){t+=n.ellipsis;break}var c=s===0?md(t,i,a):o>0?Math.floor(t.length*i/o):0;t=t.substr(0,c),o=nd(a,t)}t===``&&(t=n.placeholder),e.textLine=t,e.isTruncated=!0}function md(e,t,n){for(var r=0,i=0,a=e.length;i{A6(e)}):A6(e)}function A6(e){if(e)try{e.body&&M6(e.body,`react-draggable-transparent-selection`);let t=e.selection;if(t)t.empty();else{let t=(e.defaultView||window).getSelection();t&&t.type!==`Caret`&&t.removeAllRanges()}}catch{}}function j6(e,t){e.classList?e.classList.add(t):e.className.match(RegExp(`(?:^|\\s)${t}(?!\\S)`))||(e.className+=` ${t}`)}function M6(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(RegExp(`(?:^|\\s)${t}(?!\\S)`,`g`),``)}function N6(e,t,n){if(!e.props.bounds)return[t,n];let{bounds:r}=e.props;r=typeof r==`string`?r:B6(r);let i=V6(e);if(typeof r==`string`){let{ownerDocument:e}=i,t=e.defaultView;if(!t)throw Error(`Cannot resolve the owner window of the draggable node.`);let n;if(n=r===`parent`?i.parentNode:i.getRootNode().querySelector(r),!(n instanceof t.HTMLElement))throw Error(`Bounds selector "`+r+`" could not find an element.`);let a=n,o=t.getComputedStyle(i),s=t.getComputedStyle(a);r={left:-i.offsetLeft+a6(s.paddingLeft)+a6(o.marginLeft),top:-i.offsetTop+a6(s.paddingTop)+a6(o.marginTop),right:b6(a)-v6(i)-i.offsetLeft+a6(s.paddingRight)-a6(o.marginRight),bottom:y6(a)-_6(i)-i.offsetTop+a6(s.paddingBottom)-a6(o.marginBottom)}}return i6(r.right)&&(t=Math.min(t,r.right)),i6(r.bottom)&&(n=Math.min(n,r.bottom)),i6(r.left)&&(t=Math.max(t,r.left)),i6(r.top)&&(n=Math.max(n,r.top)),[t,n]}function P6(e,t,n){return[Math.round(t/e[0])*e[0],Math.round(n/e[1])*e[1]]}function F6(e){return e.props.axis===`both`||e.props.axis===`x`}function I6(e){return e.props.axis===`both`||e.props.axis===`y`}function L6(e,t,n){let r=typeof t==`number`?T6(e,t):null;if(typeof t==`number`&&!r)return null;let i=V6(n),a=n.props.offsetParent||i.offsetParent||i.ownerDocument.body;return x6(r||e,a,n.props.scale)}function R6(e,t,n){let r=!i6(e.lastX),i=V6(e);return r?{node:i,deltaX:0,deltaY:0,lastX:t,lastY:n,x:t,y:n}:{node:i,deltaX:t-e.lastX,deltaY:n-e.lastY,lastX:e.lastX,lastY:e.lastY,x:t,y:n}}function z6(e,t){let n=e.props.scale;return{node:t.node,x:e.state.x+t.deltaX/n,y:e.state.y+t.deltaY/n,deltaX:t.deltaX/n,deltaY:t.deltaY/n,lastX:e.state.x,lastY:e.state.y}}function B6(e){return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}function V6(e){let t=e.findDOMNode();if(!t)throw Error(`: Unmounted during event!`);return t}var H6=typeof process<`u`&&{}.DRAGGABLE_DEBUG?console.log.bind(console):function(){},U6={touch:{start:`touchstart`,move:`touchmove`,stop:`touchend`},mouse:{start:`mousedown`,move:`mousemove`,stop:`mouseup`}},W6=U6.mouse,G6=class extends V.Component{constructor(){super(...arguments),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,this.touchIdentifier=null,this.mounted=!1,this.handleDragStart=e=>{if(this.props.onMouseDown(e),!this.props.allowAnyClick&&(typeof e.button==`number`&&e.button!==0||e.ctrlKey))return!1;let t=this.findDOMNode();if(!t||!t.ownerDocument||!t.ownerDocument.body)throw Error(` not mounted on DragStart!`);let{ownerDocument:n}=t;if(this.props.disabled||!(e.target instanceof n.defaultView.Node)||this.props.handle&&!m6(e.target,this.props.handle,t)||this.props.cancel&&m6(e.target,this.props.cancel,t))return;e.type===`touchstart`&&!this.props.allowMobileScroll&&e.preventDefault();let r=E6(e);this.touchIdentifier=r;let i=L6(e,r,this);if(i==null)return;let{x:a,y:o}=i,s=R6(this,a,o);H6(`DraggableCore: handleDragStart: %j`,s),H6(`calling`,this.props.onStart),this.props.onStart(e,s)!==!1&&this.mounted!==!1&&(this.props.enableUserSelectHack&&O6(n,this.props.nonce),this.dragging=!0,this.lastX=a,this.lastY=o,h6(n,W6.move,this.handleDrag),h6(n,W6.stop,this.handleDragStop))},this.handleDrag=e=>{let t=L6(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX,t=r-this.lastY;if([e,t]=P6(this.props.grid,e,t),!e&&!t)return;n=this.lastX+e,r=this.lastY+t}let i=R6(this,n,r);if(H6(`DraggableCore: handleDrag: %j`,i),this.props.onDrag(e,i)===!1||this.mounted===!1){try{this.handleDragStop(new MouseEvent(`mouseup`))}catch{let e=document.createEvent(`MouseEvents`);e.initMouseEvent(`mouseup`,!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),this.handleDragStop(e)}return}this.lastX=n,this.lastY=r},this.handleDragStop=e=>{if(!this.dragging)return;let t=L6(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX||0,t=r-this.lastY||0;[e,t]=P6(this.props.grid,e,t),n=this.lastX+e,r=this.lastY+t}let i=R6(this,n,r);if(this.props.onStop(e,i)===!1||this.mounted===!1)return!1;let a=this.findDOMNode();a&&this.props.enableUserSelectHack&&k6(a.ownerDocument),H6(`DraggableCore: handleDragStop: %j`,i),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,a&&(H6(`DraggableCore: Removing handlers`),g6(a.ownerDocument,W6.move,this.handleDrag),g6(a.ownerDocument,W6.stop,this.handleDragStop))},this.onMouseDown=e=>(W6=U6.mouse,this.handleDragStart(e)),this.onMouseUp=e=>(W6=U6.mouse,this.handleDragStop(e)),this.onTouchStart=e=>(W6=U6.touch,this.handleDragStart(e)),this.onTouchEnd=e=>(W6=U6.touch,this.handleDragStop(e))}componentDidMount(){this.mounted=!0;let e=this.findDOMNode();e&&h6(e,U6.touch.start,this.onTouchStart,{passive:!1})}componentWillUnmount(){this.mounted=!1;let e=this.findDOMNode();if(e){let{ownerDocument:t}=e;g6(t,U6.mouse.move,this.handleDrag),g6(t,U6.touch.move,this.handleDrag),g6(t,U6.mouse.stop,this.handleDragStop),g6(t,U6.touch.stop,this.handleDragStop),g6(e,U6.touch.start,this.onTouchStart,{passive:!1}),this.props.enableUserSelectHack&&k6(t)}}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=Ki.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):(H6(`react-draggable: ReactDOM.findDOMNode is not available in React 19+. You must provide a nodeRef prop. See: https://github.com/react-grid-layout/react-draggable#noderef`),null)}render(){return V.cloneElement(V.Children.only(this.props.children),{onMouseDown:this.onMouseDown,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}};G6.displayName=`DraggableCore`,G6.propTypes={allowAnyClick:t6.default.bool,allowMobileScroll:t6.default.bool,children:t6.default.node.isRequired,disabled:t6.default.bool,enableUserSelectHack:t6.default.bool,offsetParent:function(e,t){if(e[t]&&e[t].nodeType!==1)throw Error(`Draggable's offsetParent must be a DOM Node.`)},grid:t6.default.arrayOf(t6.default.number),handle:t6.default.string,cancel:t6.default.string,nodeRef:t6.default.object,nonce:t6.default.string,onStart:t6.default.func,onDrag:t6.default.func,onStop:t6.default.func,onMouseDown:t6.default.func,scale:t6.default.number,className:o6,style:o6,transform:o6},G6.defaultProps={allowAnyClick:!1,allowMobileScroll:!1,disabled:!1,enableUserSelectHack:!0,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){},scale:1};var K6=class extends V.Component{constructor(e){super(e),this.onDragStart=(e,t)=>{if(H6(`Draggable: onDragStart: %j`,t),this.props.onStart(e,z6(this,t))===!1)return!1;this.setState({dragging:!0,dragged:!0})},this.onDrag=(e,t)=>{if(!this.state.dragging)return!1;H6(`Draggable: onDrag: %j`,t);let n=z6(this,t),r={x:n.x,y:n.y,slackX:0,slackY:0};if(this.props.bounds){let{x:e,y:t}=r;r.x+=this.state.slackX,r.y+=this.state.slackY;let[i,a]=N6(this,r.x,r.y);r.x=i,r.y=a,r.slackX=this.state.slackX+(e-r.x),r.slackY=this.state.slackY+(t-r.y),n.x=r.x,n.y=r.y,n.deltaX=r.x-this.state.x,n.deltaY=r.y-this.state.y}if(this.props.onDrag(e,n)===!1)return!1;this.setState(r)},this.onDragStop=(e,t)=>{if(!this.state.dragging||this.props.onStop(e,z6(this,t))===!1)return!1;H6(`Draggable: onDragStop: %j`,t);let n={dragging:!1,slackX:0,slackY:0};if(this.props.position){let{x:e,y:t}=this.props.position;n.x=e,n.y=t}this.setState(n)},this.state={dragging:!1,dragged:!1,x:e.position?e.position.x:e.defaultPosition.x,y:e.position?e.position.y:e.defaultPosition.y,prevPropsPosition:{...e.position},slackX:0,slackY:0,isElementSVG:!1},e.position&&!(e.onDrag||e.onStop)&&console.warn("A `position` was applied to this , without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}static getDerivedStateFromProps({position:e},{prevPropsPosition:t}){return e&&(!t||e.x!==t.x||e.y!==t.y)?(H6(`Draggable: getDerivedStateFromProps %j`,{position:e,prevPropsPosition:t}),{x:e.x,y:e.y,prevPropsPosition:{...e}}):null}componentDidMount(){window.SVGElement!==void 0&&this.findDOMNode()instanceof window.SVGElement&&this.setState({isElementSVG:!0})}componentWillUnmount(){this.state.dragging&&this.setState({dragging:!1})}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=Ki.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):null}render(){let{axis:e,bounds:t,children:n,defaultPosition:r,defaultClassName:i,defaultClassNameDragging:a,defaultClassNameDragged:o,position:s,positionOffset:c,scale:l,...u}=this.props,d={},f=null,p=!s||this.state.dragging,m=s||r,h={x:F6(this)&&p?this.state.x:m.x,y:I6(this)&&p?this.state.y:m.y};this.state.isElementSVG?f=C6(h,c):d=S6(h,c);let g=V.Children.only(n),v=_(g.props.className||``,i,{[a]:this.state.dragging,[o]:this.state.dragged});return V.createElement(G6,{...u,onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop},V.cloneElement(g,{className:v,style:{...g.props.style,...d},transform:f}))}};K6.displayName=`Draggable`,K6.propTypes={...G6.propTypes,axis:t6.default.oneOf([`both`,`x`,`y`,`none`]),bounds:t6.default.oneOfType([t6.default.shape({left:t6.default.number,right:t6.default.number,top:t6.default.number,bottom:t6.default.number}),t6.default.string,t6.default.oneOf([!1])]),defaultClassName:t6.default.string,defaultClassNameDragging:t6.default.string,defaultClassNameDragged:t6.default.string,defaultPosition:t6.default.shape({x:t6.default.number,y:t6.default.number}),positionOffset:t6.default.shape({x:t6.default.oneOfType([t6.default.number,t6.default.string]),y:t6.default.oneOfType([t6.default.number,t6.default.string])}),position:t6.default.shape({x:t6.default.number,y:t6.default.number}),className:o6,style:o6,transform:o6},K6.defaultProps={...G6.defaultProps,axis:`both`,bounds:!1,defaultClassName:`react-draggable`,defaultClassNameDragging:`react-draggable-dragging`,defaultClassNameDragged:`react-draggable-dragged`,defaultPosition:{x:0,y:0},scale:1};var q6=e(((e,t)=>{function n(e){var t,r,i=``;if(typeof e==`string`||typeof e==`number`)i+=e;else if(typeof e==`object`){if(Array.isArray(e)){var a=e.length;for(t=0;t{var r=Object.create,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,l=(e,t)=>{for(var n in t)i(e,n,{get:t[n],enumerable:!0})},u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(let s of o(t))!c.call(e,s)&&s!==n&&i(e,s,{get:()=>t[s],enumerable:!(r=a(t,s))||r.enumerable});return e},d=(e,t,n)=>(n=e==null?{}:r(s(e)),u(t||!e||!e.__esModule?i(n,`default`,{value:e,enumerable:!0}):n,e)),f=e=>u(i({},`__esModule`,{value:!0}),e),p={};l(p,{DraggableCore:()=>we,default:()=>Te}),n.exports=f(p);var m=d(t()),h=d(e6()),g=d(b()),_=q6();function v(e,t){for(let n=0,r=e.length;n`u`)return``;let t=window.document?.documentElement?.style;if(!t||e in t)return``;for(let n=0;nt===e.identifier)||e.changedTouches&&v(e.changedTouches,e=>t===e.identifier)}function ae(e){if(e.targetTouches&&e.targetTouches[0])return e.targetTouches[0].identifier;if(e.changedTouches&&e.changedTouches[0])return e.changedTouches[0].identifier}function R(){return typeof __webpack_nonce__<`u`?__webpack_nonce__:void 0}function oe(e,t){if(!e)return;let n=e.getElementById(`react-draggable-style-el`);if(!n){n=e.createElement(`style`),n.type=`text/css`,n.id=`react-draggable-style-el`;let r=t??R();r&&n.setAttribute(`nonce`,r),n.innerHTML=`.react-draggable-transparent-selection *::-moz-selection {all: inherit;} `,n.innerHTML+=`.react-draggable-transparent-selection *::selection {all: inherit;} -`,e.getElementsByTagName(`head`)[0].appendChild(n)}e.body&&ce(e.body,`react-draggable-transparent-selection`)}function z(e){window.requestAnimationFrame?window.requestAnimationFrame(()=>{se(e)}):se(e)}function se(e){if(e)try{e.body&&le(e.body,`react-draggable-transparent-selection`);let t=e.selection;if(t)t.empty();else{let t=(e.defaultView||window).getSelection();t&&t.type!==`Caret`&&t.removeAllRanges()}}catch{}}function ce(e,t){e.classList?e.classList.add(t):e.className.match(RegExp(`(?:^|\\s)${t}(?!\\S)`))||(e.className+=` ${t}`)}function le(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(RegExp(`(?:^|\\s)${t}(?!\\S)`,`g`),``)}function ue(e,t,n){if(!e.props.bounds)return[t,n];let{bounds:r}=e.props;r=typeof r==`string`?r:_e(r);let i=ve(e);if(typeof r==`string`){let{ownerDocument:e}=i,t=e.defaultView;if(!t)throw Error(`Cannot resolve the owner window of the draggable node.`);let n;if(n=r===`parent`?i.parentNode:i.getRootNode().querySelector(r),!(n instanceof t.HTMLElement))throw Error(`Bounds selector "`+r+`" could not find an element.`);let a=n,o=t.getComputedStyle(i),s=t.getComputedStyle(a);r={left:-i.offsetLeft+S(s.paddingLeft)+S(o.marginLeft),top:-i.offsetTop+S(s.paddingTop)+S(o.marginTop),right:L(a)-F(i)-i.offsetLeft+S(s.paddingRight)-S(o.marginRight),bottom:I(a)-P(i)-i.offsetTop+S(s.paddingBottom)-S(o.marginBottom)}}return x(r.right)&&(t=Math.min(t,r.right)),x(r.bottom)&&(n=Math.min(n,r.bottom)),x(r.left)&&(t=Math.max(t,r.left)),x(r.top)&&(n=Math.max(n,r.top)),[t,n]}function de(e,t,n){return[Math.round(t/e[0])*e[0],Math.round(n/e[1])*e[1]]}function fe(e){return e.props.axis===`both`||e.props.axis===`x`}function pe(e){return e.props.axis===`both`||e.props.axis===`y`}function me(e,t,n){let r=typeof t==`number`?ie(e,t):null;if(typeof t==`number`&&!r)return null;let i=ve(n),a=n.props.offsetParent||i.offsetParent||i.ownerDocument.body;return ee(r||e,a,n.props.scale)}function he(e,t,n){let r=!x(e.lastX),i=ve(e);return r?{node:i,deltaX:0,deltaY:0,lastX:t,lastY:n,x:t,y:n}:{node:i,deltaX:t-e.lastX,deltaY:n-e.lastY,lastX:e.lastX,lastY:e.lastY,x:t,y:n}}function ge(e,t){let n=e.props.scale;return{node:t.node,x:e.state.x+t.deltaX/n,y:e.state.y+t.deltaY/n,deltaX:t.deltaX/n,deltaY:t.deltaY/n,lastX:e.state.x,lastY:e.state.y}}function _e(e){return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}function ve(e){let t=e.findDOMNode();if(!t)throw Error(`: Unmounted during event!`);return t}var B=d(t()),ye=d(e6()),be=d(b()),xe=typeof process<`u`&&{}.DRAGGABLE_DEBUG?console.log.bind(console):function(){},Se={touch:{start:`touchstart`,move:`touchmove`,stop:`touchend`},mouse:{start:`mousedown`,move:`mousemove`,stop:`mouseup`}},Ce=Se.mouse,we=class extends B.Component{constructor(){super(...arguments),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,this.touchIdentifier=null,this.mounted=!1,this.handleDragStart=e=>{if(this.props.onMouseDown(e),!this.props.allowAnyClick&&(typeof e.button==`number`&&e.button!==0||e.ctrlKey))return!1;let t=this.findDOMNode();if(!t||!t.ownerDocument||!t.ownerDocument.body)throw Error(` not mounted on DragStart!`);let{ownerDocument:n}=t;if(this.props.disabled||!(e.target instanceof n.defaultView.Node)||this.props.handle&&!j(e.target,this.props.handle,t)||this.props.cancel&&j(e.target,this.props.cancel,t))return;e.type===`touchstart`&&!this.props.allowMobileScroll&&e.preventDefault();let r=ae(e);this.touchIdentifier=r;let i=me(e,r,this);if(i==null)return;let{x:a,y:o}=i,s=he(this,a,o);xe(`DraggableCore: handleDragStart: %j`,s),xe(`calling`,this.props.onStart),this.props.onStart(e,s)!==!1&&this.mounted!==!1&&(this.props.enableUserSelectHack&&oe(n,this.props.nonce),this.dragging=!0,this.lastX=a,this.lastY=o,M(n,Ce.move,this.handleDrag),M(n,Ce.stop,this.handleDragStop))},this.handleDrag=e=>{let t=me(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX,t=r-this.lastY;if([e,t]=de(this.props.grid,e,t),!e&&!t)return;n=this.lastX+e,r=this.lastY+t}let i=he(this,n,r);if(xe(`DraggableCore: handleDrag: %j`,i),this.props.onDrag(e,i)===!1||this.mounted===!1){try{this.handleDragStop(new MouseEvent(`mouseup`))}catch{let e=document.createEvent(`MouseEvents`);e.initMouseEvent(`mouseup`,!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),this.handleDragStop(e)}return}this.lastX=n,this.lastY=r},this.handleDragStop=e=>{if(!this.dragging)return;let t=me(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX||0,t=r-this.lastY||0;[e,t]=de(this.props.grid,e,t),n=this.lastX+e,r=this.lastY+t}let i=he(this,n,r);if(this.props.onStop(e,i)===!1||this.mounted===!1)return!1;let a=this.findDOMNode();a&&this.props.enableUserSelectHack&&z(a.ownerDocument),xe(`DraggableCore: handleDragStop: %j`,i),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,a&&(xe(`DraggableCore: Removing handlers`),N(a.ownerDocument,Ce.move,this.handleDrag),N(a.ownerDocument,Ce.stop,this.handleDragStop))},this.onMouseDown=e=>(Ce=Se.mouse,this.handleDragStart(e)),this.onMouseUp=e=>(Ce=Se.mouse,this.handleDragStop(e)),this.onTouchStart=e=>(Ce=Se.touch,this.handleDragStart(e)),this.onTouchEnd=e=>(Ce=Se.touch,this.handleDragStop(e))}componentDidMount(){this.mounted=!0;let e=this.findDOMNode();e&&M(e,Se.touch.start,this.onTouchStart,{passive:!1})}componentWillUnmount(){this.mounted=!1;let e=this.findDOMNode();if(e){let{ownerDocument:t}=e;N(t,Se.mouse.move,this.handleDrag),N(t,Se.touch.move,this.handleDrag),N(t,Se.mouse.stop,this.handleDragStop),N(t,Se.touch.stop,this.handleDragStop),N(e,Se.touch.start,this.onTouchStart,{passive:!1}),this.props.enableUserSelectHack&&z(t)}}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=be.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):(xe(`react-draggable: ReactDOM.findDOMNode is not available in React 19+. You must provide a nodeRef prop. See: https://github.com/react-grid-layout/react-draggable#noderef`),null)}render(){return B.cloneElement(B.Children.only(this.props.children),{onMouseDown:this.onMouseDown,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}};we.displayName=`DraggableCore`,we.propTypes={allowAnyClick:ye.default.bool,allowMobileScroll:ye.default.bool,children:ye.default.node.isRequired,disabled:ye.default.bool,enableUserSelectHack:ye.default.bool,offsetParent:function(e,t){if(e[t]&&e[t].nodeType!==1)throw Error(`Draggable's offsetParent must be a DOM Node.`)},grid:ye.default.arrayOf(ye.default.number),handle:ye.default.string,cancel:ye.default.string,nodeRef:ye.default.object,nonce:ye.default.string,onStart:ye.default.func,onDrag:ye.default.func,onStop:ye.default.func,onMouseDown:ye.default.func,scale:ye.default.number,className:C,style:C,transform:C},we.defaultProps={allowAnyClick:!1,allowMobileScroll:!1,disabled:!1,enableUserSelectHack:!0,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){},scale:1};var Te=class extends m.Component{constructor(e){super(e),this.onDragStart=(e,t)=>{if(xe(`Draggable: onDragStart: %j`,t),this.props.onStart(e,ge(this,t))===!1)return!1;this.setState({dragging:!0,dragged:!0})},this.onDrag=(e,t)=>{if(!this.state.dragging)return!1;xe(`Draggable: onDrag: %j`,t);let n=ge(this,t),r={x:n.x,y:n.y,slackX:0,slackY:0};if(this.props.bounds){let{x:e,y:t}=r;r.x+=this.state.slackX,r.y+=this.state.slackY;let[i,a]=ue(this,r.x,r.y);r.x=i,r.y=a,r.slackX=this.state.slackX+(e-r.x),r.slackY=this.state.slackY+(t-r.y),n.x=r.x,n.y=r.y,n.deltaX=r.x-this.state.x,n.deltaY=r.y-this.state.y}if(this.props.onDrag(e,n)===!1)return!1;this.setState(r)},this.onDragStop=(e,t)=>{if(!this.state.dragging||this.props.onStop(e,ge(this,t))===!1)return!1;xe(`Draggable: onDragStop: %j`,t);let n={dragging:!1,slackX:0,slackY:0};if(this.props.position){let{x:e,y:t}=this.props.position;n.x=e,n.y=t}this.setState(n)},this.state={dragging:!1,dragged:!1,x:e.position?e.position.x:e.defaultPosition.x,y:e.position?e.position.y:e.defaultPosition.y,prevPropsPosition:{...e.position},slackX:0,slackY:0,isElementSVG:!1},e.position&&!(e.onDrag||e.onStop)&&console.warn("A `position` was applied to this , without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}static getDerivedStateFromProps({position:e},{prevPropsPosition:t}){return e&&(!t||e.x!==t.x||e.y!==t.y)?(xe(`Draggable: getDerivedStateFromProps %j`,{position:e,prevPropsPosition:t}),{x:e.x,y:e.y,prevPropsPosition:{...e}}):null}componentDidMount(){window.SVGElement!==void 0&&this.findDOMNode()instanceof window.SVGElement&&this.setState({isElementSVG:!0})}componentWillUnmount(){this.state.dragging&&this.setState({dragging:!1})}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=g.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):null}render(){let{axis:e,bounds:t,children:n,defaultPosition:r,defaultClassName:i,defaultClassNameDragging:a,defaultClassNameDragged:o,position:s,positionOffset:c,scale:l,...u}=this.props,d={},f=null,p=!s||this.state.dragging,h=s||r,g={x:fe(this)&&p?this.state.x:h.x,y:pe(this)&&p?this.state.y:h.y};this.state.isElementSVG?f=ne(g,c):d=te(g,c);let v=m.Children.only(n),y=(0,_.clsx)(v.props.className||``,i,{[a]:this.state.dragging,[o]:this.state.dragged});return m.createElement(we,{...u,onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop},m.cloneElement(v,{className:y,style:{...v.props.style,...d},transform:f}))}};Te.displayName=`Draggable`,Te.propTypes={...we.propTypes,axis:h.default.oneOf([`both`,`x`,`y`,`none`]),bounds:h.default.oneOfType([h.default.shape({left:h.default.number,right:h.default.number,top:h.default.number,bottom:h.default.number}),h.default.string,h.default.oneOf([!1])]),defaultClassName:h.default.string,defaultClassNameDragging:h.default.string,defaultClassNameDragged:h.default.string,defaultPosition:h.default.shape({x:h.default.number,y:h.default.number}),positionOffset:h.default.shape({x:h.default.oneOfType([h.default.number,h.default.string]),y:h.default.oneOfType([h.default.number,h.default.string])}),position:h.default.shape({x:h.default.number,y:h.default.number}),className:C,style:C,transform:C},Te.defaultProps={...we.defaultProps,axis:`both`,bounds:!1,defaultClassName:`react-draggable`,defaultClassNameDragging:`react-draggable-dragging`,defaultClassNameDragged:`react-draggable-dragged`,defaultPosition:{x:0,y:0},scale:1},0&&(n.exports={DraggableCore:we})})),Y6=e(((e,t)=>{var n=J6(),r=n.DraggableCore,i=n.default||n;t.exports=i,t.exports.default=i,t.exports.DraggableCore=r})),X6=e((e=>{e.__esModule=!0,e.cloneElement=l;var n=r(t());function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function a(e){for(var t=1;t{e.__esModule=!0,e.resizableProps=void 0;var t=n(e6());Y6();function n(e){return e&&e.__esModule?e:{default:e}}e.resizableProps={axis:t.default.oneOf([`both`,`x`,`y`,`none`]),className:t.default.string,children:t.default.element.isRequired,draggableOpts:t.default.shape({allowAnyClick:t.default.bool,cancel:t.default.string,children:t.default.node,disabled:t.default.bool,enableUserSelectHack:t.default.bool,offsetParent:typeof Element<`u`?t.default.instanceOf(Element):t.default.any,grid:t.default.arrayOf(t.default.number),handle:t.default.string,nodeRef:t.default.object,onStart:t.default.func,onDrag:t.default.func,onStop:t.default.func,onMouseDown:t.default.func,scale:t.default.number}),height:function(){var e=[...arguments];let n=e[0];return n.axis===`both`||n.axis===`y`?t.default.number.isRequired(...e):t.default.number(...e)},handle:t.default.oneOfType([t.default.node,t.default.func]),handleSize:t.default.arrayOf(t.default.number),lockAspectRatio:t.default.bool,maxConstraints:t.default.arrayOf(t.default.number),minConstraints:t.default.arrayOf(t.default.number),onResizeStop:t.default.func,onResizeStart:t.default.func,onResize:t.default.func,resizeHandles:t.default.arrayOf(t.default.oneOf([`s`,`w`,`e`,`n`,`sw`,`nw`,`se`,`ne`])),transformScale:t.default.number,width:function(){var e=[...arguments];let n=e[0];return n.axis===`both`||n.axis===`x`?t.default.number.isRequired(...e):t.default.number(...e)}}})),Q6=e((e=>{e.__esModule=!0,e.default=void 0;var n=s(t()),r=Y6(),i=X6(),a=Z6(),o=[`children`,`className`,`draggableOpts`,`width`,`height`,`handle`,`handleSize`,`lockAspectRatio`,`axis`,`minConstraints`,`maxConstraints`,`onResize`,`onResizeStop`,`onResizeStart`,`resizeHandles`,`transformScale`];function s(e,t){if(typeof WeakMap==`function`)var n=new WeakMap,r=new WeakMap;return(s=function(e,t){if(!t&&e&&e.__esModule)return e;var i,a,o={__proto__:null,default:e};if(e===null||typeof e!=`object`&&typeof e!=`function`)return o;if(i=t?r:n){if(i.has(e))return i.get(e);i.set(e,o)}for(let t in e)t!=="default"&&{}.hasOwnProperty.call(e,t)&&((a=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?i(o,t,a):o[t]=e[t]);return o})(e,t)}function c(){return c=Object.assign?Object.assign.bind():function(e){for(var t=1;tMath.abs(i*n)?t=e/n:e=t*n}let o=e,s=t,c=this.slack||[0,0],l=c[0],u=c[1];return e+=l,t+=u,r&&(e=Math.max(r[0],e),t=Math.max(r[1],t)),i&&(e=Math.min(i[0],e),t=Math.min(i[1],t)),this.slack=[l+(o-e),u+(s-t)],[e,t]}resizeHandler(e,t){return(n,r)=>{let i=r.node,a=r.deltaX,o=r.deltaY;e===`onResizeStart`&&this.resetData();let s=(this.props.axis===`both`||this.props.axis===`x`)&&t!==`n`&&t!==`s`,c=(this.props.axis===`both`||this.props.axis===`y`)&&t!==`e`&&t!==`w`;if(!s&&!c)return;let l=t[0],u=t[t.length-1],d=i.getBoundingClientRect();if(this.lastHandleRect!=null){if(u===`w`){let e=d.left-this.lastHandleRect.left;a+=e}if(l===`n`){let e=d.top-this.lastHandleRect.top;o+=e}}this.lastHandleRect=d,u===`w`&&(a=-a),l===`n`&&(o=-o);let f=this.lastSize?.width??this.props.width,p=this.lastSize?.height??this.props.height,m=f+(s?a/this.props.transformScale:0),h=p+(c?o/this.props.transformScale:0);var g=this.runConstraints(m,h);if(m=g[0],h=g[1],e===`onResizeStop`&&this.lastSize){var _=this.lastSize;m=_.width,h=_.height}let v=m!==f||h!==p;e!==`onResizeStop`&&(this.lastSize={width:m,height:h});let y=typeof this.props[e]==`function`?this.props[e]:null;y&&(e!==`onResize`||v)&&(n.persist==null||n.persist(),y(n,{node:i,size:{width:m,height:h},handle:t})),e===`onResizeStop`&&this.resetData()}}renderResizeHandle(e,t){let r=this.props.handle;if(!r)return n.createElement(`span`,{className:`react-resizable-handle react-resizable-handle-`+e,ref:t});if(typeof r==`function`)return r(e,t);let i=typeof r.type==`string`,a=d({ref:t},i?{}:{handleAxis:e});return n.cloneElement(r,a)}render(){let e=this.props,t=e.children,a=e.className,s=e.draggableOpts;e.width,e.height,e.handle,e.handleSize,e.lockAspectRatio,e.axis,e.minConstraints,e.maxConstraints,e.onResize,e.onResizeStop,e.onResizeStart;let u=e.resizeHandles;e.transformScale;let f=l(e,o);return(0,i.cloneElement)(t,d(d({},f),{},{className:(a?a+` `:``)+`react-resizable`,children:[...n.Children.toArray(t.props.children),...u.map(e=>{let t=this.handleRefs[e]??(this.handleRefs[e]=n.createRef());return n.createElement(r.DraggableCore,c({},s,{nodeRef:t,key:`resizableHandle-`+e,onStop:this.resizeHandler(`onResizeStop`,e),onStart:this.resizeHandler(`onResizeStart`,e),onDrag:this.resizeHandler(`onResize`,e)}),this.renderResizeHandle(e,t))})]}))}};e.default=h,h.propTypes=a.resizableProps,h.defaultProps={axis:`both`,handleSize:[20,20],lockAspectRatio:!1,minConstraints:[20,20],maxConstraints:[1/0,1/0],resizeHandles:[`se`],transformScale:1}})),$6=e((e=>{e.__esModule=!0,e.default=void 0;var n=c(t()),r=s(e6()),i=s(Q6()),a=Z6(),o=[`handle`,`handleSize`,`onResize`,`onResizeStart`,`onResizeStop`,`draggableOpts`,`minConstraints`,`maxConstraints`,`lockAspectRatio`,`axis`,`width`,`height`,`resizeHandles`,`style`,`transformScale`];function s(e){return e&&e.__esModule?e:{default:e}}function c(e,t){if(typeof WeakMap==`function`)var n=new WeakMap,r=new WeakMap;return(c=function(e,t){if(!t&&e&&e.__esModule)return e;var i,a,o={__proto__:null,default:e};if(e===null||typeof e!=`object`&&typeof e!=`function`)return o;if(i=t?r:n){if(i.has(e))return i.get(e);i.set(e,o)}for(let t in e)t!=="default"&&{}.hasOwnProperty.call(e,t)&&((a=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?i(o,t,a):o[t]=e[t]);return o})(e,t)}function l(){return l=Object.assign?Object.assign.bind():function(e){for(var t=1;t{let n=t.size;this.props.onResize?(e.persist==null||e.persist(),this.setState(n,()=>this.props.onResize&&this.props.onResize(e,t))):this.setState(n)}}static getDerivedStateFromProps(e,t){return t.propsWidth!==e.width||t.propsHeight!==e.height?{width:e.width,height:e.height,propsWidth:e.width,propsHeight:e.height}:null}render(){let e=this.props,t=e.handle,r=e.handleSize;e.onResize;let a=e.onResizeStart,s=e.onResizeStop,c=e.draggableOpts,u=e.minConstraints,f=e.maxConstraints,p=e.lockAspectRatio,m=e.axis;e.width,e.height;let g=e.resizeHandles,_=e.style,v=e.transformScale,y=h(e,o);return n.createElement(i.default,{axis:m,draggableOpts:c,handle:t,handleSize:r,height:this.state.height,lockAspectRatio:p,maxConstraints:f,minConstraints:u,onResizeStart:a,onResize:this.onResize,onResizeStop:s,resizeHandles:g,transformScale:v,width:this.state.width},n.createElement(`div`,l({},y,{style:d(d({},_),{},{width:this.state.width+`px`,height:this.state.height+`px`})})))}};e.default=g,g.propTypes=d(d({},a.resizableProps),{},{children:r.default.element})})),e8=e(((e,t)=>{t.exports=function(){throw Error(`Don't instantiate Resizable directly! Use require('react-resizable').Resizable`)},t.exports.Resizable=Q6().default,t.exports.ResizableBox=$6().default}))(),t8=Z3(),n8=50,r8=12;function i8(e){let t=e;for(;t;){let e=window.getComputedStyle(t).overflowY;if((e===`auto`||e===`scroll`)&&t.scrollHeight>t.clientHeight)return t;t=t.parentElement}return null}function a8(e){let t=i8(e),n=null,r=0,i=0,a=!1;function o(){let e=t;if(!e)return;let s=e.getBoundingClientRect(),{clientHeight:c,scrollTop:l,scrollHeight:u}=e,{scrollLeft:d,scrollWidth:f,clientWidth:p}=e,m=0,h=0;i0?m=-r8:i>s.bottom-n8&&l+c0?h=-r8:r>s.right-n8&&d+p({cols:n,containerPadding:a,containerWidth:r,margin:i,maxRows:s,rowHeight:o}),[n,a,r,i,s,o]),ye=(0,V.useMemo)(()=>({cols:n,maxRows:s,containerWidth:r,containerHeight:0,rowHeight:o,margin:i,layout:[]}),[n,s,r,o,i]),be=(0,V.useCallback)(e=>({...ye,containerHeight:e??ye.containerHeight,layout:fe.current}),[ye]),xe=(0,V.useMemo)(()=>I??{i:M,x:w,y:T,w:E,h:D,minW:O,maxW:k,minH:A,maxH:j},[I,M,w,T,E,D,O,k,A,j]),Se=(0,V.useCallback)(e=>{if(g?.calcStyle)return g.calcStyle(e);if(p)return v3(e);let t=y3(e);return m?{...t,left:b3(e.left/r),width:b3(e.width/r)}:t},[g,p,m,r]),Ce=(0,V.useCallback)((e,{node:t})=>{if(!ee)return;let{offsetParent:n}=t;if(!n)return;let r=n.getBoundingClientRect(),i=t.getBoundingClientRect(),a=i.left/h,o=r.left/h,s=i.top/h,c=r.top/h,l;if(g?.calcDragPosition){let t=e;l=g.calcDragPosition(t.clientX,t.clientY,t.clientX-i.left,t.clientY-i.top)}else l={left:a-o+n.scrollLeft,top:s-c+n.scrollTop};if(le.current=l,ve.current||=a8(t instanceof HTMLElement?t:null),v>0){let t=e;ge.current={x:t.clientX,y:t.clientY},he.current=!0,_e.current=!1,oe(!0);return}oe(!0);let u=Y4(B,l.top,l.left),{x:d,y:f}=g3(F,xe,u.x,u.y,be());ee(M,d,f,{e,node:t,newPosition:l})},[ee,h,B,g,v,F,xe,be,M]),we=(0,V.useCallback)((e,{node:t,deltaX:n,deltaY:a})=>{if(!te||!R)return;let s=e;if(he.current&&!_e.current){let n=s.clientX-ge.current.x,r=s.clientY-ge.current.y;if(Math.hypot(n,r){if(!ne||!R)return;ve.current?.stop(),ve.current=null;let n=he.current;if(he.current=!1,_e.current=!1,ge.current={x:0,y:0},n){oe(!1),le.current={left:0,top:0};return}let{left:r,top:i}=le.current,a={top:i,left:r};oe(!1),le.current={left:0,top:0};let o=Y4(B,i,r),{x:s,y:c}=g3(F,xe,o.x,o.y,be());ne(M,s,c,{e,node:t,newPosition:a})},[ne,R,B,F,xe,be,M]);pe.current=Ce,me.current=we;let Ee=(0,V.useCallback)((e,{node:t,size:n,handle:i},a,o)=>{let s=o===`onResizeStart`?re:o===`onResize`?ie:ae;if(!s)return;let c;c=t?A3(i,a,n,r):{...n,top:a.top,left:a.left},ue.current=c;let l=t?.offsetParent?.clientHeight??0,u=X4(B,c.width,c.height),{w:d,h:f}=_3(F,xe,u.w,u.h,i,be(l));s(M,d,f,{e:e.nativeEvent??e,node:t,size:c,handle:i})},[re,ie,ae,r,B,M,F,xe,be]),De=(0,V.useCallback)((e,t)=>{se(!0);let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResizeStart`)},[Ee,B,w,T,E,D]),Oe=(0,V.useCallback)((e,t)=>{let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResize`)},[Ee,B,w,T,E,D]),ke=(0,V.useCallback)((e,t)=>{se(!1),ue.current={top:0,left:0,width:0,height:0};let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResizeStop`)},[Ee,B,w,T,E,D]);(0,V.useEffect)(()=>{if(!y)return;let e=ce.current;if(!e)return;let t=de.current||{left:0,top:0},n=R&&(y.left!==t.left||y.top!==t.top);if(!R){let t={node:e,deltaX:y.left,deltaY:y.top,lastX:0,lastY:0,x:y.left,y:y.top};pe.current?.(y.e,t)}else if(n){let t={node:e,deltaX:y.left-le.current.left,deltaY:y.top-le.current.top,lastX:le.current.left,lastY:le.current.top,x:y.left,y:y.top};me.current?.(y.e,t)}de.current=y},[y,R,M]);let Ae=q4(B,w,T,E,D,R?le.current:null,z?ue.current:null),je=V.Children.only(t),Me=G4(B),Ne=[K4(O,Me,i[0]),K4(A,o,i[1])],Pe=[K4(k,Me,i[0]),K4(j,o,i[1])],Fe=je.props,Ie=Fe.className,Le=Fe.style,Re=V.cloneElement(je,{ref:ce,className:_(`react-grid-item`,Ie,b,{static:f,resizing:z,"react-draggable":c,"react-draggable-dragging":R,dropping:!!y,cssTransforms:p}),style:{...x,...Le,...Se(Ae)}}),ze=P;return Re=(0,H.jsx)(e8.Resizable,{draggableOpts:{disabled:!l},className:l?void 0:`react-resizable-hide`,width:Ae.width,height:Ae.height,minConstraints:Ne,maxConstraints:Pe,onResizeStart:De,onResize:Oe,onResizeStop:ke,transformScale:h,resizeHandles:N,handle:ze,children:Re}),Re=(0,H.jsx)(G6,{disabled:!c,onStart:Ce,onDrag:we,onStop:Te,handle:S,cancel:`.react-resizable-handle`+(C?`,`+C:``),scale:h,allowMobileScroll:d,nodeRef:ce,children:Re}),Re}var s8=V.memo(o8,(e,t)=>e.x===t.x&&e.y===t.y&&e.w===t.w&&e.h===t.h&&e.minW===t.minW&&e.maxW===t.maxW&&e.minH===t.minH&&e.maxH===t.maxH&&e.cols===t.cols&&e.containerWidth===t.containerWidth&&e.rowHeight===t.rowHeight&&e.maxRows===t.maxRows&&e.margin===t.margin&&e.containerPadding===t.containerPadding&&e.transformScale===t.transformScale&&e.isDraggable===t.isDraggable&&e.isResizable===t.isResizable&&e.isBounded===t.isBounded&&e.allowMobileScroll===t.allowMobileScroll&&e.useCSSTransforms===t.useCSSTransforms&&e.usePercentages===t.usePercentages&&e.children===t.children&&e.onDrag===t.onDrag&&e.onDragStop===t.onDragStop&&e.onResize===t.onResize&&e.onResizeStop===t.onResizeStop&&e.droppingPosition===t.droppingPosition);s8.displayName=`GridItem`;function c8(e){let{clientX:t,clientY:n,gridElement:r,droppingItem:i,event:a,dragOffsetX:o=0,dragOffsetY:s=0,transformScale:c,cols:l,margin:u,maxRows:d,rowHeight:f,width:p,containerPadding:m}=e,h=r.getBoundingClientRect(),g={cols:l,margin:u,maxRows:d,rowHeight:f,containerWidth:p,containerPadding:m},_=G4(g),v=K4(i.w,_,u[0]),y=K4(i.h,f,u[1]),b=v/2,x=y/2,S=r.scrollLeft??0,C=r.scrollTop??0,w=t-h.left+S+o-b,T=n-h.top+C+s-x,E=Math.max(0,w),D=Math.max(0,T);return{newDroppingPosition:{left:E/c,top:D/c,e:a},calculatedXY:J4(g,D,E,i.w,i.h)}}var l8=()=>{},u8=`react-grid-layout`,d8=!1;try{d8=/firefox/i.test(navigator.userAgent)}catch{}function f8(e,t){let n=V.Children.toArray(e),r=V.Children.toArray(t);if(n.length!==r.length)return!1;for(let e=0;e{if(!V.isValidElement(t)||t.key===null)return;let n=String(t.key);a.add(n);let r=e.find(e=>e.i===n);if(r)i.push(s3(r));else{let e=t.props[`data-grid`];e?i.push({i:n,x:e.x??0,y:e.y??0,w:e.w??1,h:e.h??1,minW:e.minW,maxW:e.maxW,minH:e.minH,maxH:e.maxH,static:e.static,isDraggable:e.isDraggable,isResizable:e.isResizable,resizeHandles:e.resizeHandles,isBounded:e.isBounded}):i.push({i:n,x:0,y:i3(i),w:1,h:1})}});let o=d3(i,{cols:n});return r.compact(o,n)}function m8(e){let{children:t,width:n,gridConfig:r,dragConfig:i,resizeConfig:a,dropConfig:o,positionStrategy:s=j3,compactor:c,constraints:l=h3,layout:u=[],droppingItem:d,autoSize:f=!0,className:p=``,style:m={},innerRef:h,onLayoutChange:g=l8,onDragStart:v=l8,onDrag:y=l8,onDragStop:b=l8,onResizeStart:x=l8,onResize:S=l8,onResizeStop:C=l8,onDrop:w=l8,onDropDragOver:T=l8}=e,E=(0,V.useMemo)(()=>({...M3,...r}),[r]),D=(0,V.useMemo)(()=>({...N3,...i}),[i]),O=(0,V.useMemo)(()=>({...P3,...a}),[a]),k=(0,V.useMemo)(()=>({...F3,...o}),[o]),{cols:A,rowHeight:j,maxRows:M,margin:N,containerPadding:P}=E,{enabled:F,bounded:I,handle:L,cancel:ee,threshold:te,allowMobileScroll:ne}=D,{enabled:re,handles:ie,handleComponent:ae}=O,{enabled:R,defaultItem:oe,onDragOver:z,touchEnabled:se=!0,touchDragSource:ce=`[data-rgl-draggable]`}=k,le=c??G3(`vertical`),ue=le.type,de=le.allowOverlap,fe=le.preventCollision??!1,pe=(0,V.useMemo)(()=>d??{i:`__dropping-elem__`,...oe},[d,oe]),me=s.type===`transform`,he=s.scale,ge=P??N,[_e,ve]=(0,V.useState)(!1),[B,ye]=(0,V.useState)(()=>p8(u,t,A,le)),[be,xe]=(0,V.useState)(null),[Se,Ce]=(0,V.useState)(!1),[we,Te]=(0,V.useState)(null),[Ee,De]=(0,V.useState)(),Oe=(0,V.useRef)(void 0);Oe.current=Ee;let ke=(0,V.useRef)(null),Ae=(0,V.useRef)(null),je=(0,V.useRef)(null),Me=(0,V.useRef)(0),Ne=(0,V.useRef)(B),Pe=(0,V.useRef)(u),Fe=(0,V.useRef)(t),Ie=(0,V.useRef)(ue),Le=(0,V.useRef)(null),Re=(0,V.useRef)(!1),ze=(0,V.useRef)(null),Be=(0,V.useRef)(null);Be.current=we;let Ve=(0,V.useRef)(w);(0,V.useLayoutEffect)(()=>{Ve.current=w});let He=(0,V.useRef)(B);He.current=B,(0,V.useEffect)(()=>{ve(!0),(0,t8.deepEqual)(B,u)||g(B)},[]),(0,V.useEffect)(()=>{if(be||we)return;let e=!(0,t8.deepEqual)(u,Pe.current),n=!f8(t,Fe.current),r=ue!==Ie.current;if(e||n||r){let n=p8(e?u:B,t,A,le);(0,t8.deepEqual)(n,B)||ye(n)}Pe.current=u,Fe.current=t,Ie.current=ue},[u,t,A,ue,le,be,we,B]),(0,V.useEffect)(()=>{if(!be&&!we&&!(0,t8.deepEqual)(B,Ne.current)){Ne.current=B;let e=B.filter(e=>e.i!==pe.i);g(e)}},[B,be,we,g,pe.i]);let Ue=(0,V.useMemo)(()=>{if(!f)return;let e=i3(B),t=ge[1];return e*j+(e-1)*N[1]+t*2+`px`},[f,B,j,N,ge]),We=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=a3(i,e);if(!a)return;let o={w:a.w,h:a.h,x:a.x,y:a.y,i:e};ke.current=s3(a),je.current=i,xe(o),v(i,a,a,null,r.e,r.node)},[v]),Ge=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=ke.current,o=a3(i,e);if(!o)return;let s={w:o.w,h:o.h,x:o.x,y:o.y,i:e},c=f3(i,o,t,n,!0,fe,ue,A,de);y(c,a,o,s,r.e,r.node),ye(le.compact(c,A)),xe(s)},[fe,ue,A,de,le,y]),Ke=(0,V.useCallback)((e,t,n,r)=>{if(!ke.current)return;let i=He.current,a=ke.current,o=a3(i,e);if(!o)return;let s=f3(i,o,t,n,!0,fe,ue,A,de),c=le.compact(s,A);b(c,a,o,null,r.e,r.node);let l=je.current;ke.current=null,je.current=null,xe(null),ye(c),l&&!(0,t8.deepEqual)(l,c)&&g(c)},[fe,ue,A,de,le,b,g]),qe=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=a3(i,e);a&&(Ae.current=s3(a),je.current=i,Ce(!0),x(i,a,a,null,r.e,r.node))},[x]),Je=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=Ae.current,{handle:o}=r,s=!1,c,l,[u,d]=u3(i,e,e=>(c=e.x,l=e.y,[`sw`,`w`,`nw`,`n`,`ne`].includes(o)&&([`sw`,`nw`,`w`].includes(o)&&(c=e.x+(e.w-t),t=e.x!==c&&c<0?e.w:t,c=c<0?0:c),[`ne`,`n`,`nw`].includes(o)&&(l=e.y+(e.h-n),n=e.y!==l&&l<0?e.h:n,l=l<0?0:l),s=!0),fe&&!de&&e3(i,{...e,w:t,h:n,x:c??e.x,y:l??e.y}).filter(t=>t.i!==e.i).length>0&&(l=e.y,n=e.h,c=e.x,t=e.w,s=!1),e.w=t,e.h=n,(o===`n`||o===`nw`||o===`ne`)&&(e.y=l??e.y),e));if(!d)return;let f=u;s&&c!==void 0&&l!==void 0&&(f=f3(u,d,c,l,!0,fe,ue,A,de));let p={w:d.w,h:d.h,x:d.x,y:d.y,i:e,static:!0};S(f,a,d,p,r.e,r.node);let m=le.compact(f,A);if(o===`n`||o===`nw`||o===`ne`){let t=m.find(t=>t.i===e);t&&(t.y=d.y)}ye(m),xe(p)},[fe,ue,A,de,le,S]),Ye=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=Ae.current,o=a3(i,e),s=le.compact(i,A);C(s,a,o??null,null,r.e,r.node);let c=je.current;Ae.current=null,je.current=null,xe(null),Ce(!1),ye(s),c&&!(0,t8.deepEqual)(c,s)&&g(s)},[A,le,C,g]),Xe=(0,V.useCallback)((e,t,n,r)=>{if(r)Oe.current&&(Oe.current.left!==t.left||Oe.current.top!==t.top)&&(De(t),ye(t=>t.map(t=>t.i===e.i&&(t.x!==n.x||t.y!==n.y)?{...t,x:n.x,y:n.y}:t)));else{Te((0,H.jsx)(`div`,{},e.i)),De(t);let r=He.current.filter(t=>t.i!==e.i);ye([...r,{...e,x:n.x,y:n.y,static:!1,isDraggable:!0}])}},[]),Ze=(0,V.useCallback)((e,t,r)=>{let i=Le.current;if(!i)return;let{newDroppingPosition:a,calculatedXY:o}=c8({clientX:e,clientY:t,gridElement:i,droppingItem:pe,event:r,transformScale:he,cols:A,margin:N,maxRows:M,rowHeight:j,width:n,containerPadding:ge});Xe(pe,a,o,!!Be.current)},[pe,he,A,N,M,j,n,ge,Xe]),Qe=(0,V.useCallback)(()=>{let e=He.current;if(!e.some(e=>e.i===pe.i)){Te(null),xe(null),De(void 0);return}let t=le.compact(e.filter(e=>e.i!==pe.i),A);ye(t),Te(null),xe(null),De(void 0)},[pe.i,A,le]),$e=(0,V.useCallback)(e=>{if(e.preventDefault(),e.stopPropagation(),d8&&!e.nativeEvent.target?.classList.contains(u8))return!1;let t=z?z(e.nativeEvent):T(e);if(t===!1)return we&&Qe(),!1;let{dragOffsetX:r=0,dragOffsetY:i=0,...a}=t??{},o={...pe,...a},{newDroppingPosition:s,calculatedXY:c}=c8({clientX:e.clientX,clientY:e.clientY,gridElement:e.currentTarget,droppingItem:o,event:e.nativeEvent,dragOffsetX:r,dragOffsetY:i,transformScale:he,cols:A,margin:N,maxRows:M,rowHeight:j,width:n,containerPadding:ge});Xe(o,s,c,!!we)},[we,pe,z,T,Qe,Xe,he,A,N,M,j,n,ge]),et=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current--,Me.current<0&&(Me.current=0),Me.current===0&&Qe()},[Qe]),tt=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current++},[]),nt=(0,V.useCallback)(e=>{let t=He.current,n=t.find(e=>e.i===pe.i);Qe(),Ve.current(t,n,e)},[pe.i,Qe]),rt=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current=0,nt(e.nativeEvent)},[nt]);(0,V.useEffect)(()=>{if(!R||!se)return;let e=Le.current;if(!e)return;let t=(t,n)=>{let r=document.elementFromPoint(t,n);return r?e.contains(r):!1},n=e=>e instanceof HTMLElement&&e.closest(ce)!==null,r=e=>{let t=e.changedTouches;if(!t||t.length===0)return;let n=ze.current;if(n===null)return t[0];for(let e=0;e{if(!n(e.target)||ze.current!==null)return;e.preventDefault();let t=e.changedTouches?.[0];t&&(ze.current=t.identifier,Re.current=!0)},a=e=>{if(!Re.current)return;e.preventDefault();let n=r(e);if(n){if(!t(n.clientX,n.clientY)){Be.current&&Qe();return}Ze(n.clientX,n.clientY,e)}},o=e=>{if(!Re.current)return;e.preventDefault();let n=r(e);if(Re.current=!1,ze.current=null,n){if(!t(n.clientX,n.clientY)){Qe();return}nt(e)}},s=()=>{Re.current&&(Re.current=!1,ze.current=null,Qe())},c={passive:!1};return document.addEventListener(`touchstart`,i,c),document.addEventListener(`touchmove`,a,c),document.addEventListener(`touchend`,o,c),document.addEventListener(`touchcancel`,s,c),()=>{document.removeEventListener(`touchstart`,i,c),document.removeEventListener(`touchmove`,a,c),document.removeEventListener(`touchend`,o,c),document.removeEventListener(`touchcancel`,s,c)}},[R,se,ce,Ze,Qe,nt,pe.i]);let it=(0,V.useCallback)((e,t)=>{if(!e||!e.key)return null;let r=a3(B,String(e.key));if(!r)return null;let i=typeof r.isDraggable==`boolean`?r.isDraggable:!r.static&&F,a=typeof r.isResizable==`boolean`?r.isResizable:!r.static&&re,o=r.resizeHandles||[...ie],c=i&&I&&r.isBounded!==!1,u=ae;return(0,H.jsx)(s8,{containerWidth:n,cols:A,margin:N,containerPadding:ge,maxRows:M,rowHeight:j,cancel:ee,handle:L,onDragStart:We,onDrag:Ge,onDragStop:Ke,onResizeStart:qe,onResize:Je,onResizeStop:Ye,isDraggable:i,isResizable:a,isBounded:c,allowMobileScroll:ne,useCSSTransforms:me&&_e,usePercentages:!_e,transformScale:he,positionStrategy:s,dragThreshold:te,w:r.w,h:r.h,x:r.x,y:r.y,i:r.i,minH:r.minH,minW:r.minW,maxH:r.maxH,maxW:r.maxW,static:r.static,droppingPosition:t?Ee:void 0,resizeHandles:o,resizeHandle:u,constraints:l,layoutItem:r,layout:B,children:e},r.i)},[B,n,A,N,ge,M,j,ee,L,We,Ge,Ke,qe,Je,Ye,F,re,I,me,_e,he,s,te,Ee,ie,ae,l]),at=()=>be?(0,H.jsx)(s8,{w:be.w,h:be.h,x:be.x,y:be.y,i:be.i,className:`react-grid-placeholder ${Se?`placeholder-resizing`:``}`,containerWidth:n,cols:A,margin:N,containerPadding:ge,maxRows:M,rowHeight:j,isDraggable:!1,isResizable:!1,isBounded:!1,useCSSTransforms:me,transformScale:he,constraints:l,layout:B,children:(0,H.jsx)(`div`,{})}):null,ot=(0,V.useCallback)(e=>{Le.current=e,typeof h==`function`?h(e):h&&`current`in h&&(h.current=e)},[h]),st=_(u8,p),ct={height:Ue,...m};return(0,H.jsxs)(`div`,{ref:ot,className:st,style:ct,onDrop:R?rt:void 0,onDragLeave:R?et:void 0,onDragEnter:R?tt:void 0,onDragOver:R?$e:void 0,children:[V.Children.map(t,e=>V.isValidElement(e)?it(e):null),R&&we&&it(we,!0),at()]})}var h8={lg:1200,md:996,sm:768,xs:480,xxs:0},g8={lg:12,md:10,sm:6,xs:4,xxs:2},_8=()=>{};function v8(e,t,n,r,i=!1){let a=[];V.Children.forEach(t,t=>{if(!V.isValidElement(t)||t.key===null)return;let n=String(t.key),r=t.props[`data-grid`],o=e.find(e=>e.i===n);o?i&&r?a.push({...o,i:n,w:r.w??o.w,h:r.h??o.h,minW:r.minW??o.minW,maxW:r.maxW??o.maxW,minH:r.minH??o.minH,maxH:r.maxH??o.maxH}):a.push({...o,i:n}):r?a.push({i:n,x:r.x??0,y:r.y??0,w:r.w??1,h:r.h??1,minW:r.minW,maxW:r.maxW,minH:r.minH,maxH:r.maxH,static:r.static,isDraggable:r.isDraggable,isResizable:r.isResizable,resizeHandles:r.resizeHandles,isBounded:r.isBounded}):a.push({i:n,x:0,y:i3(a),w:1,h:1})});let o=d3(a,{cols:n});return r.compact(o,n)}function y8(e){let{children:t,width:n,breakpoint:r,breakpoints:i=h8,cols:a=g8,layouts:o={},rowHeight:s=150,maxRows:c=1/0,margin:l=[10,10],containerPadding:u=null,compactor:d,onBreakpointChange:f=_8,onLayoutChange:p=_8,onWidthChange:m=_8,...h}=e,g=d??G3(`vertical`),_=g.type,v=g.allowOverlap,y=(0,V.useMemo)(()=>r??q3(i,n),[]),b=(0,V.useMemo)(()=>J3(y,a),[y,a]),x=(0,V.useMemo)(()=>Y3(o,i,y,y,b,_),[]),[S,C]=(0,V.useState)(y),[w,T]=(0,V.useState)(b),[E,D]=(0,V.useState)(x),[O,k]=(0,V.useState)(o),A=(0,V.useRef)(n),j=(0,V.useRef)(r),M=(0,V.useRef)(i),N=(0,V.useRef)(a),P=(0,V.useRef)(o),F=(0,V.useRef)(_),I=(0,V.useRef)(O);(0,V.useEffect)(()=>{I.current=O},[O]);let L=(0,V.useMemo)(()=>(0,t8.deepEqual)(o,P.current)?null:Y3(o,i,S,S,w,g),[o,i,S,w,g]),ee=L??E;(0,V.useEffect)(()=>{L!==null&&(D(L),k(o),I.current=o,P.current=o)},[L,o]),(0,V.useEffect)(()=>{if(_!==F.current){let e=g.compact(c3(ee),w),t={...I.current,[S]:e};D(e),k(t),I.current=t,p(e,t),F.current=_}},[_,g,ee,w,v,S,p]),(0,V.useEffect)(()=>{let e=n!==A.current,o=r!==j.current,s=!(0,t8.deepEqual)(i,M.current),c=!(0,t8.deepEqual)(a,N.current);if(e||o||s||c){let e=r??q3(i,n),o=J3(e,a),d=S;if(d!==e||s||c){let n={...I.current};n[d]||(n[d]=c3(E));let r=Y3(n,i,e,d,o,g),a=!n[e];r=v8(r,t,o,g,a),n[e]=r,C(e),T(o),D(r),k(n),I.current=n,f(e,o),p(r,n)}let h=X3(l,e),_=u?X3(u,e):null;m(n,h,o,_),A.current=n,j.current=r,M.current=i,N.current=a}},[n,r,i,a,S,w,E,t,g,_,v,l,u,f,p,m]);let te=(0,V.useCallback)(e=>{let t={...I.current,[S]:e};D(e),k(t),I.current=t,p(e,t)},[S,p]),ne=(0,V.useMemo)(()=>X3(l,S),[l,S]),re=(0,V.useMemo)(()=>u===null?null:X3(u,S),[u,S]),ie=(0,V.useMemo)(()=>({cols:w,rowHeight:s,maxRows:c,margin:ne,containerPadding:re}),[w,s,c,ne,re]);return(0,H.jsx)(m8,{...h,width:n,gridConfig:ie,compactor:g,onLayoutChange:te,layout:ee,children:t})}var b8=V.forwardRef(function(e,t){let{innerRef:n,...r}=e,i=n??t;return(0,H.jsx)(y8,{...r,innerRef:i})});b8.displayName=`ResponsiveGridLayout`;function x8(e,t,n,r){let i=e=>t?.frame?.columns.some((n,r)=>n.name===e&&t.frame.values[r]?.some(e=>typeof e==`string`&&e!==``));return{onSelect:e.click&&(e.viz===`service_map`||!(e.drill&&r))?t=>n(e.click.set_variable,t):void 0,onPoint:r&&(e.viz===`service_map`||e.click||e.drill||i(`trace_id`)||e.options?.columns?.some(e=>e.format===`trace_link`&&i(e.field)))?r:void 0}}function S8(e,t,n,r){if(!t)return;let i=ot(e,t,n);if(!i)return;let a=Object.values(n.dimensions)[0],o=e.click?.set_variable;return{target:i,vars:o&&a!==void 0?{...r,[o]:a}:r}}function C8(e){return`Explain the panel “${e.title}”`}function w8(e){return`Fix the panel “${e.title}”`}function T8(e){return[{description:`Observed panel diagnostics`,value:JSON.stringify(e)}]}var E8=e=>e*40+(e-1)*12,D8={s:3,m:6,l:10},O8={stat:4},k8=e=>Math.max(O8[e.viz]??0,D8[e.height??(e.viz===`service_map`?`l`:e.viz===`stat`?`s`:`m`)]),A8=(0,V.lazy)(()=>ce(()=>import(`./panel-sql-editor-Cs-4yfrn.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]))),j8=0;function M8(e){let t;do t=`p_${Date.now().toString(36)}_${(++j8).toString(36)}_${Math.random().toString(36).slice(2,10)}`;while(e.some(e=>e.id===t));return t}function N8({dashboardId:e,version:t,spec:n,vars:r,results:i,fetching:a,annotations:o,fetchingIds:s=[],staleAt:c=new Map,time:l=n.time,onEditExit:u,editing:d,view:f,agentAvailable:p,canManage:m=!1,onOpenChat:h,onVariable:g,onRetry:_,onPoint:v,onZoom:b,onZoomReset:x,zoomed:S,onView:w,onVisible:E,onRangePending:D,shortcutScope:O,onShortcuts:k,overlayOpen:A,returnViewFocus:j}){let M=ct(),[N,P]=(0,V.useState)(),[F,I]=(0,V.useState)(()=>n.panels.map(e=>({i:e.id,x:e.grid?.x??0,y:e.grid?.y??0,w:e.grid?.w??6,h:e.grid?.h??k8(e)})));(0,V.useEffect)(()=>{I(n.panels.map(e=>({i:e.id,x:e.grid?.x??0,y:e.grid?.y??0,w:e.grid?.w??6,h:e.grid?.h??k8(e)})))},[n]);let[L,te]=(0,V.useState)(()=>window.innerHeight),[ne,re]=(0,V.useState)();(0,V.useEffect)(()=>{let e=()=>te(window.innerHeight);return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]);let ie=(0,V.useRef)(null),ae=(0,V.useRef)(new Map),R=(0,V.useRef)(null),oe=(0,V.useRef)(null),z=()=>{let e=N?.panel.id;P(void 0),requestAnimationFrame(()=>(oe.current?.isConnected?oe.current:ae.current.get(e??``))?.focus())},ce=(0,V.useRef)(f);f&&(ce.current=f);let[le,ue]=(0,V.useState)(0),de=le>0,fe=d&&(le>=1100?`lg`:le>=800?`md`:`sm`)==`lg`;(0,V.useLayoutEffect)(()=>{if(!ie.current)return;ue(Math.max(0,Math.round(ie.current.getBoundingClientRect().width)));let e=new ResizeObserver(([e])=>{e&&ue(Math.max(0,Math.round(e.contentRect.width)))});return e.observe(ie.current),()=>e.disconnect()},[]);let pe=(0,V.useRef)(E);pe.current=E,(0,V.useEffect)(()=>{if(!de||!ie.current||typeof IntersectionObserver>`u`)return;let e=new Set(n.panels.map(e=>e.id)),t=new IntersectionObserver(t=>{for(let n of t){let t=n.target.dataset.panel;t&&(n.isIntersecting?e.add(t):e.delete(t))}f&&n.panels.some(e=>e.id===f)&&e.add(f),pe.current([...e])},{rootMargin:`200px`});return ie.current.querySelectorAll(`.react-grid-item[data-panel]`).forEach(e=>t.observe(e)),()=>t.disconnect()},[n,f,de]);let me=(0,V.useMemo)(()=>n.panels.some(e=>{let t=F.find(t=>t.i===e.id);return t&&(t.x!==e.grid?.x||t.y!==e.grid?.y||t.w!==e.grid?.w||t.h!==e.grid?.h)}),[F,n]),he=e=>({...n,panels:e.map(e=>{let t=F.find(t=>t.i===e.id);return t?{...e,grid:{x:t.x,y:t.y,w:t.w,h:t.h}}:e})}),ge=Te({mutationFn:()=>Ke(e,he(n.panels),t,`Edited layout`),onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}}),_e=Te({mutationFn:r=>me?Ke(e,he(n.panels.filter(e=>e.id!==r)),t,`Removed a panel and saved layout`):Ae(e,[{op:`remove_panel`,id:r}],t,`Removed a panel`),onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}}),ve=Te({mutationFn:r=>{let i={...r,id:M8(n.panels),title:`${Array.from(r.title).slice(0,73).join(``)} (copy)`,grid:void 0};if(me){let a=[...n.panels];return a.splice(a.findIndex(e=>e.id===r.id)+1,0,i),Ke(e,he(a),t,`Duplicated a panel and saved layout`)}return Ae(e,[{op:`add_panel`,after:r.id,panel:i}],t,`Duplicated a panel`)},onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}});(0,V.useEffect)(()=>{d||(ge.reset(),_e.reset(),ve.reset())},[d]);let B=()=>{ge.reset(),_e.reset(),ve.reset(),u?.(),M.invalidateQueries({queryKey:[`dashboard`,e]})},ye=async e=>{let t=new URL(window.location.href);t.searchParams.set(`view`,e),t.searchParams.delete(`edit`);try{await navigator.clipboard.writeText(t.toString()),re(`Link copied`)}catch{re(`Copy this URL: ${t.toString()}`)}},be=`dashboard-${e}`,xe=n=>({dashboard_id:e,version:t,panel_id:n.id,title:Yi(n.title,r),from_ms:i.get(n.id)?.from_ms,to_ms:i.get(n.id)?.to_ms,vars:r,error:i.get(n.id)?.error,status:i.get(n.id)?.status,diagnosis:i.get(n.id)?.diagnosis,stale_since:c.get(n.id),truncated:i.has(n.id)?!!(i.get(n.id)?.frame?.truncated||i.get(n.id)?.previous?.truncated):void 0,note:i.get(n.id)?.frame?.note,spec:{...n,dashboard_time:l}}),Se=(u,d,y=!1)=>(0,H.jsx)(V4,{panel:u,title:Yi(u.title,r),result:i.get(u.id),loading:a&&s.includes(u.id),height:d,group:be,editing:fe&&!y,agentAvailable:p,suspended:!y&&u.id===f,menuRef:y?R:e=>{e?ae.current.set(u.id,e):ae.current.delete(u.id)},compare:l.compare===`previous_period`,range:u.time?.range??l.range,annotations:o,vars:r,onVariable:g,...x8(u,i.get(u.id),g,v?e=>v(u,e):void 0),onRangePending:e=>D?.(u.id,e),onZoom:b,zoomed:S,onZoomReset:x,onRetry:_?()=>_(u.id):void 0,onView:()=>w(u.id),onCopyLink:()=>{ye(u.id)},onEditSQL:m&&typeof u.sql==`string`?()=>{oe.current=y?R.current:ae.current.get(u.id)??null,P({panel:u,spec:n,version:t})}:void 0,onExplain:p&&e?()=>h(C8(xe(u)),{answer_only:!0,context:T8(xe(u))}):void 0,onFix:p&&e&&m?()=>h(w8(xe(u)),{context:T8(xe(u))}):void 0,staleAt:c.get(u.id),onDuplicate:fe&&!y?()=>ve.mutate(u):void 0,onRemove:fe&&!y?()=>_e.mutate(u.id):void 0}),Ce=n.panels.find(e=>e.id===f),we=d?ge.error??_e.error??ve.error:null,Ee=we instanceof $e&&we.code===`dashboard_version_conflict`,De=e=>{fe&&I(e.map(({i:e,x:t,y:n,w:r,h:i})=>({i:e,x:t,y:n,w:r,h:i})))};return(0,H.jsxs)(`div`,{ref:ie,style:{minWidth:0},children:[d&&(0,H.jsxs)(y,{justify:`space-between`,mb:`sm`,p:`xs`,style:{border:`1px dashed var(--mantine-color-default-border)`,borderRadius:8},children:[(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:fe?`Drag a panel by its title and resize it from the corner. Changes are saved as a new version.`:`The layout can be edited only on a wider screen.`}),(0,H.jsx)(C,{size:`compact-sm`,disabled:!me||!fe,loading:ge.isPending,onClick:()=>ge.mutate(),children:`Save layout`})]}),Ee&&(0,H.jsxs)(ee,{color:`warn`,mb:`sm`,children:[`Someone saved this dashboard since you opened it. Load the latest version, then redo your change. `,(0,H.jsx)(C,{size:`compact-sm`,onClick:B,children:`Load latest`})]}),we&&!Ee&&(0,H.jsx)(ee,{color:`bad`,mb:`sm`,children:we.message}),ne&&(0,H.jsx)(ee,{role:`status`,mb:`sm`,children:ne}),!de&&(0,H.jsx)(`div`,{"data-grid-placeholder":!0,style:{height:E8(Math.max(1,...F.map(e=>e.y+e.h)))}}),de&&(0,H.jsx)(b8,{width:le,className:`dashboard-grid${fe?` dashboard-grid-editing`:``}`,layouts:{lg:F,md:F,sm:F.map(e=>({...e,x:0,w:12}))},breakpoints:{lg:1100,md:800,sm:0},cols:{lg:12,md:12,sm:12},rowHeight:40,margin:[12,12],containerPadding:[0,0],compactor:z3,dragConfig:{enabled:fe,handle:`.panel-drag`,cancel:`button`},resizeConfig:{enabled:fe},onDragStop:De,onResizeStop:De,children:n.panels.map(e=>{let t=F.find(t=>t.i===e.id);return(0,H.jsx)(`div`,{"data-panel":e.id,children:Se(e,E8(t?.h??6))},e.id)})}),(0,H.jsx)(B4,{shortcutScope:O,onShortcuts:k,escapeEnabled:!A&&!N,opened:!!f,onClose:()=>w(void 0),title:Ce?Yi(Ce.title,r):`Missing panel`,returnFocusTo:()=>j?.(ce.current)??ae.current.get(ce.current??``)??ae.current.values().next().value,children:Ce?(0,H.jsx)(`div`,{style:{height:`calc(100vh - 120px)`},children:Se(Ce,Math.max(40,L-140),!0)}):(0,H.jsx)(ee,{color:`warn`,children:`This panel is missing from the dashboard. The shared link may be out of date.`})}),N&&(0,H.jsx)(V.Suspense,{fallback:(0,H.jsx)(Ze,{opened:!0,onClose:z,title:`Loading SQL editor`,children:(0,H.jsx)(se,{size:`sm`,"aria-label":`Loading SQL editor`})}),children:(0,H.jsx)(A8,{dashboardId:e,version:N.version,spec:N.spec,panel:N.panel,time:l,vars:r,onClose:z})})]})}function P8(e,t=1,n=8){let r=(t-1)*n;return e.slice(r,r+n)}function F8({icon:e,title:t,children:n,tall:r=!1}){return(0,H.jsx)(ae,{mih:r?220:130,p:`xl`,children:(0,H.jsxs)(y,{wrap:`nowrap`,children:[(0,H.jsx)(ne,{variant:`light`,size:`xl`,radius:`md`,children:e}),(0,H.jsxs)(o,{children:[(0,H.jsx)(T,{fw:700,size:`sm`,children:t}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,mt:3,children:n})]})]})})}function I8(e,t=8){let[n,r]=(0,V.useState)(1),i=Math.max(1,Math.ceil(e.length/t));(0,V.useEffect)(()=>{n>i&&r(i)},[n,i]);let a=(n-1)*t;return{page:n,setPage:r,totalPages:i,pageItems:P8(e,n,t),from:e.length?a+1:0,to:Math.min(a+t,e.length),total:e.length}}function L8({page:e,totalPages:t,from:n,to:r,total:i,onChange:a}){return t<=1?null:(0,H.jsxs)(y,{justify:`space-between`,mt:`xs`,children:[(0,H.jsxs)(T,{c:`dimmed`,size:`xs`,children:[n,`–`,r,` of `,i]}),(0,H.jsx)(y,{gap:4,children:[{label:`First page`,page:1,disabled:e===1},{label:`Previous page`,page:e-1,disabled:e===1},{label:`Next page`,page:e+1,disabled:e===t},{label:`Last page`,page:t,disabled:e===t}].map(e=>(0,H.jsx)(C,{size:`compact-xs`,variant:`subtle`,"aria-label":e.label,disabled:e.disabled,onClick:()=>a(e.page),children:e.label},e.label))})]})}function R8({spans:e,dark:t,onSpan:n}){let r=Math.min(...e.map(e=>new Date(e.start).valueOf())),i=Math.max(...e.map(e=>new Date(e.start).valueOf()+e.duration_ms)),a=Math.max(i-r,1),s=[...new Set(e.map(e=>e.service))],c=I8(e);return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(B.ScrollContainer,{minWidth:680,children:(0,H.jsxs)(B,{highlightOnHover:!!n,verticalSpacing:`sm`,children:[(0,H.jsx)(B.Thead,{children:(0,H.jsxs)(B.Tr,{children:[(0,H.jsx)(B.Th,{w:230,children:`Operation`}),(0,H.jsx)(B.Th,{children:`Timeline`}),(0,H.jsx)(B.Th,{w:90,ta:`right`,children:`Duration`})]})}),(0,H.jsx)(B.Tbody,{children:c.pageItems.map(e=>{let i=(new Date(e.start).valueOf()-r)/a*100,c=Math.max(e.duration_ms/a*100,.6),l=e.status===`STATUS_CODE_ERROR`;return(0,H.jsxs)(B.Tr,{tabIndex:n?0:void 0,onClick:n?()=>n(e):void 0,onKeyDown:n?t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),n(e))}:void 0,style:{cursor:n?`pointer`:void 0},children:[(0,H.jsx)(B.Td,{children:(0,H.jsxs)(y,{gap:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(o,{w:8,h:8,bg:Ua(s.indexOf(e.service),t),style:{borderRadius:`50%`,flex:`0 0 auto`}}),(0,H.jsxs)(o,{miw:0,children:[(0,H.jsx)(T,{fw:600,size:`sm`,truncate:!0,children:e.operation}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,truncate:!0,children:e.service})]})]})}),(0,H.jsx)(B.Td,{children:(0,H.jsx)(pe,{label:`${e.service} · ${e.operation} · ${ve(e.duration_ms)}`,withArrow:!0,children:(0,H.jsx)(o,{pos:`relative`,h:14,bg:`var(--mantine-color-default-hover)`,role:`img`,"aria-label":`${e.operation} on ${e.service} took ${ve(e.duration_ms)}`,style:{borderRadius:`var(--mantine-radius-sm)`},children:(0,H.jsx)(o,{pos:`absolute`,left:`${i}%`,w:`${Math.min(c,100-i)}%`,h:`100%`,bg:l?`bad`:Ua(s.indexOf(e.service),t),style:{borderRadius:`var(--mantine-radius-sm)`,minWidth:3}})})})}),(0,H.jsx)(B.Td,{ta:`right`,children:(0,H.jsx)(T,{size:`sm`,ff:`monospace`,children:ve(e.duration_ms)})})]},e.span_id)})})]})}),(0,H.jsx)(L8,{...c,onChange:c.setPage})]})}function z8({result:e,dark:t,onSpan:n}){let[r,i]=(0,V.useState)(`waterfall`),a=e.data,s=(0,V.useMemo)(()=>({id:`correlated_logs`,status:a.logs.length?`ok`:`empty`,elapsed_ms:0,frame:{columns:[{name:`time`,type:`time`,role:`time`},...[`severity`,`service`,`body`].map(e=>({name:e,type:`string`,role:`dimension`}))],rows:a.logs.length,values:[a.logs.map(e=>Date.parse(e.time)),a.logs.map(e=>e.severity),a.logs.map(e=>e.service),a.logs.map(e=>e.body)]}}),[a.logs]);return(0,H.jsxs)(S,{gap:`sm`,children:[(0,H.jsxs)(y,{children:[(0,H.jsx)(T,{fw:600,children:a.trace_id}),(0,H.jsx)(T,{c:a.has_error?`bad`:`dimmed`,children:a.has_error?`■ Error`:`● OK`})]}),a.spans.length>0?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(y,{role:`group`,"aria-label":`Trace view`,children:[(0,H.jsx)(C,{"aria-pressed":r===`waterfall`,variant:r===`waterfall`?`light`:`subtle`,onClick:()=>i(`waterfall`),children:`Waterfall`}),(0,H.jsx)(C,{"aria-pressed":r===`flame`,variant:r===`flame`?`light`:`subtle`,onClick:()=>i(`flame`),children:`Flame graph`})]}),r===`waterfall`?(0,H.jsx)(R8,{spans:a.spans,dark:t,onSpan:n}):(0,H.jsx)(B8,{spans:a.spans,dark:t,onSpan:n})]}):(0,H.jsx)(T,{c:`dimmed`,children:`No spans were found for this trace.`}),(0,H.jsx)(T,{fw:600,children:`Correlated logs`}),a.logs.length?(0,H.jsx)(o,{style:{overflow:`auto`,minWidth:0},children:(0,H.jsx)(P4,{foldConstants:!1,panel:{id:`correlated_logs`,title:`Correlated logs`,viz:`logs`},result:s,dark:t,height:320})}):(0,H.jsx)(F8,{tall:!0,icon:(0,H.jsx)(zi,{size:20,weight:`duotone`}),title:`No correlated logs`,children:`No logs in this window carry the selected trace ID.`}),a.truncated&&(0,H.jsxs)(ee,{color:`warn`,children:[`This trace is truncated: `,a.spans.length,` of `,a.span_count,` spans, `,a.services.length,` of `,a.service_count,` services.`]})]})}function B8({spans:e,dark:t,onSpan:n}){let r=(0,V.useMemo)(()=>V8(e),[e]),i=[...new Set(e.map(e=>e.service))];return(0,H.jsxs)(S,{px:{base:`md`,sm:`lg`},pb:`md`,gap:`xs`,children:[(0,H.jsxs)(y,{justify:`space-between`,children:[(0,H.jsx)(y,{gap:`md`,children:i.map(e=>(0,H.jsxs)(y,{gap:5,children:[(0,H.jsx)(o,{w:8,h:8,bg:Ua(i.indexOf(e),t),style:{borderRadius:`50%`}}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,children:e})]},e))}),(0,H.jsx)(He,{variant:`light`,children:ve(r.total)})]}),(0,H.jsx)(z,{withBorder:!0,radius:`md`,p:`sm`,children:(0,H.jsx)(fe,{type:`auto`,offsetScrollbars:!0,children:(0,H.jsxs)(o,{miw:760,children:[(0,H.jsx)(o,{pos:`relative`,h:22,mb:4,children:[0,25,50,75,100].map(e=>(0,H.jsx)(T,{pos:`absolute`,left:`${e}%`,c:`dimmed`,size:`xs`,style:{transform:e===100?`translateX(-100%)`:e?`translateX(-50%)`:void 0},children:ve(r.total*e/100)},e))}),(0,H.jsxs)(o,{pos:`relative`,h:Math.max(150,r.laneCount*36+12),bg:`var(--mantine-color-default-hover)`,style:{overflow:`hidden`,borderRadius:`var(--mantine-radius-md)`},children:[[0,25,50,75,100].map(e=>(0,H.jsx)(o,{pos:`absolute`,left:`${e}%`,top:0,bottom:0,style:{borderLeft:`1px solid var(--mantine-color-default-border)`}},e)),r.frames.map(({span:e,lane:r,left:a,width:s})=>{let c=e.status===`STATUS_CODE_ERROR`,l=s<7,u=c?Ha(t).bad:Ua(i.indexOf(e.service),t),d=`${e.operation} · ${ve(e.duration_ms)} · ${e.service}`,f=(0,H.jsxs)(T,{component:`span`,size:`xs`,fw:700,truncate:!0,children:[l?``:e.operation,s>=12?` · ${ve(e.duration_ms)}`:``]}),p={position:`absolute`,left:`${a}%`,top:r*36+6,width:`${Math.max(s,.35)}%`,height:30,overflow:`hidden`,minWidth:3};return(0,H.jsx)(pe,{label:`${e.service} · ${e.operation} · ${ve(e.duration_ms)}`,withArrow:!0,events:{hover:!0,focus:!0,touch:!1},children:n?(0,H.jsx)(C,{variant:`filled`,color:u,"aria-label":d,px:l?2:`xs`,size:`compact-xs`,onClick:()=>n(e),style:p,children:f}):(0,H.jsx)(o,{role:`img`,tabIndex:0,"aria-label":d,style:{...p,display:`flex`,alignItems:`center`,paddingInline:l?2:8,borderRadius:`var(--mantine-radius-sm)`,background:u,color:Ot(u)},children:f})},e.span_id)})]})]})})}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,children:`Width represents wall-clock duration; lanes preserve span hierarchy without overlap.`})]})}function V8(e){let t=Math.min(...e.map(e=>new Date(e.start).valueOf())),n=Math.max(...e.map(e=>new Date(e.start).valueOf()+e.duration_ms)),r=Math.max(n-t,1),i=new Map(e.map(e=>[e.span_id,e])),a=(e,t=new Set)=>{if(!e.parent_span_id||t.has(e.span_id))return 0;let n=i.get(e.parent_span_id);return n?(t.add(e.span_id),1+a(n,t)):0},o=e.map(e=>{let n=new Date(e.start).valueOf();return{span:e,depth:a(e),start:n,end:n+e.duration_ms,left:(n-t)/r*100,width:e.duration_ms/r*100}}).sort((e,t)=>e.depth-t.depth||e.start-t.start||t.span.duration_ms-e.span.duration_ms),s=[],c=0;for(let e of[...new Set(o.map(e=>e.depth))].sort((e,t)=>e-t)){let t=[];for(let n of o.filter(t=>t.depth===e)){let e=t.findIndex(e=>e<=n.start);e===-1&&(e=t.length),t[e]=n.end,s.push({...n,lane:c+e})}c+=Math.max(t.length,1)}return{frames:s,laneCount:c,total:r}}function H8({client:e,spec:t,time:n,vars:r,target:i,onChange:a}){let o=ke(`light`)===`dark`,s=t.panels.find(e=>e.id===i?.panel_id),c=i?.kind===`logs`&&s?.query?.from===`logs`,l=dt({queryKey:[`exemplars`,t,i,r],queryFn:({signal:n})=>e.exemplars({dashboard:t,panel_id:i.panel_id,kind:c?`logs`:`traces`,time:{from:i.window_from,to:i.window_to,refresh:`off`},from:i.from,to:i.to,dimensions:i.dimensions,bucket:i.bucket,vars:r},n),enabled:!!(i&&s&&!i.trace_id),retry:!1}),u=dt({queryKey:[`drill-trace`,i],queryFn:({signal:t})=>e.trace(i,t),enabled:!!i?.trace_id,retry:!1});return(0,H.jsxs)(Qe,{opened:!!i,onClose:()=>a(void 0),title:s?`${s.title} · ${i?.kind}`:`Panel selection unavailable`,position:`right`,size:`xl`,children:[i?.trace_id&&(0,H.jsx)(C,{variant:`subtle`,mb:`sm`,onClick:()=>{let{trace_id:e,namespace:t,...n}=i;a(n)},children:`Back to traces`}),!s&&(0,H.jsx)(ee,{color:`bad`,children:`This panel is no longer in the dashboard.`}),(l.isFetching||u.isFetching)&&(0,H.jsx)(se,{role:`status`,"aria-label":`Loading drill data`,size:`sm`}),(l.error||u.error)&&(0,H.jsx)(ee,{color:`bad`,children:(l.error??u.error)?.message}),c&&l.data?.logs&&s&&(0,H.jsx)(P4,{panel:{...s,viz:`logs`},result:{id:s.id,status:l.data.logs.rows?`ok`:`empty`,frame:l.data.logs,elapsed_ms:0,from_ms:Date.parse(i.from),to_ms:Date.parse(i.to)},dark:o,height:500}),c&&l.data?.logs?.rows===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No logs match this selection.`}),!c&&!i?.trace_id&&l.data&&(0,H.jsxs)(S,{gap:`xs`,children:[l.data.traces.length===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No exemplar traces match this selection.`}),l.data.traces.map(e=>(0,H.jsxs)(C,{variant:`default`,justify:`space-between`,onClick:()=>a({...i,trace_id:e.trace_id,namespace:e.namespace}),children:[e.service,` · `,e.operation,` · `,e.duration_ms.toFixed(1),` ms`]},`${e.namespace}/${e.trace_id}`)),l.data.truncated&&(0,H.jsx)(T,{size:`xs`,c:`dimmed`,children:`Showing at most 20 exemplar traces.`})]}),u.data&&(0,H.jsx)(z8,{result:u.data,dark:o})]})}var U8={"5m":`Last 5 minutes`,"15m":`Last 15 minutes`,"1h":`Last hour`,"3h":`Last 3 hours`,"6h":`Last 6 hours`,"12h":`Last 12 hours`,"24h":`Last 24 hours`,"2d":`Last 2 days`,"7d":`Last 7 days`,"30d":`Last 30 days`};function W8(e){return e.from&&e.to?`${he(e.from)} – ${he(e.to)}`:U8[e.range??`1h`]??e.range??`Last hour`}function G8({time:e,refresh:t,compare:n,editing:r,fetching:i,updatedAt:a,onRange:o,onAbsolute:s,onZoomOut:c,onRefresh:l,onRefreshNow:u,onCompare:d,onEdit:f,onHistory:p,onShortcuts:m,selecting:h=!1}){let[g,_]=(0,V.useState)(``),[v,b]=(0,V.useState)(``),[x,S]=(0,V.useState)(!1);return(0,H.jsxs)(y,{gap:`xs`,wrap:`wrap`,role:`group`,"aria-label":`Dashboard controls`,children:[(0,H.jsxs)(Re,{position:`bottom-end`,withinPortal:!0,opened:x,onChange:S,children:[(0,H.jsx)(Re.Target,{children:(0,H.jsx)(C,{variant:`default`,size:`sm`,leftSection:(0,H.jsx)(ji,{size:15}),rightSection:(0,H.jsx)(ge,{size:12,weight:`bold`}),children:W8(e)})}),(0,H.jsxs)(Re.Dropdown,{miw:260,children:[(0,H.jsx)(Re.Label,{children:`Relative`}),rt.map(t=>(0,H.jsx)(Re.Item,{onClick:()=>o(t),fw:e.range===t?600:void 0,children:U8[t]},t)),(0,H.jsx)(Re.Divider,{}),(0,H.jsx)(Re.Label,{children:`Absolute (your time zone)`}),(0,H.jsxs)(y,{gap:6,px:`xs`,pb:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(Me,{type:`datetime-local`,size:`xs`,"aria-label":`From`,value:g,onChange:e=>_(e.currentTarget.value)}),(0,H.jsx)(Me,{type:`datetime-local`,size:`xs`,"aria-label":`To`,value:v,onChange:e=>b(e.currentTarget.value)})]}),(0,H.jsx)(y,{px:`xs`,pb:`xs`,justify:`flex-end`,children:(0,H.jsx)(C,{size:`compact-sm`,disabled:!g||!v||g>=v,onClick:()=>{s(new Date(g).toISOString(),new Date(v).toISOString()),S(!1)},children:`Apply range`})})]})]}),(0,H.jsx)(pe,{label:`Zoom out`,children:(0,H.jsx)(C,{variant:`default`,size:`sm`,px:10,"aria-label":`Zoom out`,onClick:c,children:(0,H.jsx)(Ui,{size:15})})}),(0,H.jsxs)(y,{"data-refresh-controls":!0,gap:4,wrap:`nowrap`,children:[(0,H.jsx)(pe,{label:a?`Updated ${he(a)}`:`Refresh now`,children:(0,H.jsx)(C,{variant:`default`,size:`sm`,px:10,"aria-label":`Refresh now`,loading:i,onClick:u,children:(0,H.jsx)(xi,{size:15})})}),(0,H.jsx)(Hr,{size:`xs`,"aria-label":`Auto refresh`,value:t,onChange:l,data:jt.map(e=>({value:e,label:e===`off`?`Off`:e}))})]}),(0,H.jsx)(oi,{size:`sm`,label:`Compare with previous period`,checked:n,onChange:e=>d(e.currentTarget.checked)}),(0,H.jsx)(C,{variant:r?`filled`:`default`,size:`sm`,leftSection:(0,H.jsx)(qe,{size:15}),onClick:f,children:r?`Done`:`Edit layout`}),(0,H.jsx)(C,{variant:`default`,size:`sm`,leftSection:(0,H.jsx)(Ni,{size:15}),onClick:p,children:`History`}),m&&(0,H.jsx)(R4,{onClick:m}),a&&(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,visibleFrom:`md`,children:[`Updated `,new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`,second:`2-digit`}).format(a)]}),h&&(0,H.jsx)(T,{"data-range-paused":!0,size:`xs`,c:`dimmed`,role:`status`,children:`Paused while selecting`})]})}var K8=(e,t)=>!(t instanceof $e&&t.status<500)&&e<2,q8=(e,t)=>!(t instanceof $e&&t.code===`timeout`)&&K8(e,t),J8=e=>({panels:e.panels.map(({grid:e,...t})=>t),variables:e.variables,time:e.time,annotations:e.annotations});function Y8(e,t,n,r,i){return[`panels`,JSON.stringify([e,J8(t),n,r,i])]}function X8(e,t,n,r){return[`variables`,e,J8(t),n,r]}async function Z8(e,t){let n=await We(e,t),r=new Set(e.dashboard.panels.filter(e=>[`timeseries`,`heatmap`,`state_timeline`].includes(e.viz)).map(e=>e.id)),i=n.filter(e=>r.has(e.id)&&e.from_ms!==void 0&&e.to_ms!==void 0&&e.from_mse.from_ms)),o=Math.max(...i.map(e=>e.to_ms));try{return{results:n,annotations:await ht({from:new Date(a).toISOString(),to:new Date(o).toISOString()},t)}}catch(e){if(t?.aborted)throw e;return{results:n,annotation_error:e instanceof Error?e.message:`Annotations unavailable`}}}var Q8={off:!1,"10s":1e4,"30s":3e4,"1m":6e4,"5m":3e5},$8=0;function e5(e,t){let[n,r]=e.queryKey;if(n!==`panels`||typeof r!=`string`)return!1;try{return JSON.parse(r)[0]===t}catch{return!1}}function t5({dashboardId:e,spec:t,time:n,vars:r,compare:i,widths:a,visible:o,refresh:s,enabled:c=!0}){let l=(0,V.useMemo)(()=>Object.fromEntries(Object.entries(a).map(([e,t])=>[e,Math.max(100,Math.round(t/100)*100)])),[a]),u=Y8(e,t,n,r,i),d=u[1],f=o.filter(e=>t.panels.some(t=>t.id===e)),p=(0,V.useRef)([]),m=(0,V.useRef)(void 0),h=(0,V.useRef)(null),g=(0,V.useRef)(!1),_=(0,V.useRef)(null),v=(0,V.useRef)({key:d,ids:new Set}),[y,b]=(0,V.useState)({key:d}),[x,S]=(0,V.useState)({key:d,results:new Map,updated:new Map,stale:new Set,receivedAt:0}),C=f.length===0&&x.key===d&&x.receivedAt>0,w=c&&t.panels.some(e=>e.viz!==`text`),T=dt({queryKey:u,queryFn:({signal:e})=>{if(C&&h.current?.key!==d)return p.current=[],Promise.resolve({results:[],hasTimePanels:!1,batch:++$8});let a=h.current?.key===d?h.current.ids:f;p.current=(a.length?[...a]:t.panels.map(e=>e.id)).sort(),v.current.key!==d&&(v.current={key:d,ids:new Set});for(let e of p.current)v.current.ids.add(e);let o=[...p.current];return Z8({dashboard:t,panels:o,time:n,vars:r,widths:l,compare:i},e).then(e=>{let n=new Set(e.results.map(e=>e.id)),r=o.filter(e=>!n.has(e)&&t.panels.find(t=>t.id===e)?.viz!==`text`).map(e=>({id:e,status:`error`,elapsed_ms:0,error:`No result was returned for this panel; refresh to retry.`,request_error:o}));return{...e,batch:++$8,results:[...e.results.map(e=>W4(e,o)),...r],hasTimePanels:t.panels.some(e=>o.includes(e.id)&&[`timeseries`,`heatmap`,`state_timeline`].includes(e.viz))}}).catch(n=>{throw e.aborted||(m.current={key:d,ids:o.filter(e=>t.panels.find(t=>t.id===e)?.viz!==`text`),error:n instanceof Error?n.message:String(n),retryable:!(n instanceof $e)||n.status===408||n.status===429||n.status>=500}),n})},retry:q8,enabled:w,refetchInterval:C?!1:Q8[s]??3e4,staleTime:5e3,placeholderData:e=>e}),E=T.error&&m.current?.key===d?m.current:void 0,D=(0,V.useMemo)(()=>n5(x,d,T.isPlaceholderData?void 0:T.data?.results,T.dataUpdatedAt,T.data?.batch,E),[x,d,T.data,T.dataUpdatedAt,T.isPlaceholderData,T.error,T.errorUpdatedAt]),O=D.results,k=T.isPlaceholderData?void 0:T.data?.hasTimePanels?T.data:y.key===d?y:void 0;(0,V.useEffect)(()=>{!T.isPlaceholderData&&T.data?.hasTimePanels&&b({key:d,annotations:T.data.annotations,annotation_error:T.data.annotation_error})},[d,T.data,T.isPlaceholderData]),(0,V.useEffect)(()=>{T.isPlaceholderData||S(e=>n5(e,d,T.data?.results,T.dataUpdatedAt,T.data?.batch,E))},[d,T.data,T.dataUpdatedAt,T.isPlaceholderData,T.error,T.errorUpdatedAt]);let A=new Map([...D.stale].flatMap(e=>{let t=D.updated.get(e);return t?[[e,t]]:[]})),j=(T.data?.results??[]).find(e=>e.status===`error`&&D.stale.has(e.id));(0,V.useEffect)(()=>{if(!w||T.isFetching||g.current||_.current?.key===d||h.current?.key===d)return;let e=v.current.key===d?v.current.ids:new Set,n=[...new Set(f.filter(n=>!O.has(n)&&!e.has(n)&&t.panels.find(e=>e.id===n)?.viz!==`text`))].sort();if(!n.length)return;let r={key:d,ids:n};h.current=r,T.refetch({cancelRefetch:!1}).finally(()=>{h.current===r&&(h.current=null)})},[o,w,d,T.isFetching,T.error,T.refetch,O,t.panels]),(0,V.useEffect)(()=>{!T.isFetching&&_.current?.key!==d&&g.current&&(g.current=!1,h.current=null,w&&!C&&T.refetch({cancelRefetch:!1}))},[T.isFetching,d,w,C,T.refetch]);let M=e=>{let t={key:d,ids:e};h.current=t,T.refetch({cancelRefetch:!1}).finally(()=>{h.current===t&&(h.current=null)})};return(0,V.useEffect)(()=>{if(T.isFetching||!_.current)return;let e=_.current;if(_.current=null,e.key!==d||!w)return;let n=[...e.ids].filter(e=>t.panels.some(t=>t.id===e&&t.viz!==`text`)&&O.get(e)?.request_error).sort();n.length&&M(n)},[T.isFetching,d,w,O,t.panels]),{retry:e=>{if(!w)return;let n=e?O.get(e)?.request_error??[]:[...O.values()].flatMap(e=>e.request_error??[]),r=[...new Set(n)].filter(e=>t.panels.some(t=>t.id===e&&t.viz!==`text`)&&O.get(e)?.request_error).sort();if(r.length){if(T.isFetching){_.current?.key!==d&&(_.current={key:d,ids:new Set});for(let e of r)_.current.ids.add(e);return}M(r)}},results:O,staleAt:A,annotations:k?.annotations,annotationError:k?.annotation_error,fetchingIds:T.isFetching?p.current:[],fetching:T.isFetching,error:T.error??(j?Error(j.error??`Panel refresh failed`):null),updatedAt:T.isPlaceholderData?null:T.dataUpdatedAt||null,refetch:()=>{if(w&&!C){if(T.isFetching){h.current?.key===d&&(g.current=!0);return}T.refetch({cancelRefetch:!1})}}}}function n5(e,t,n,r,i,a){let o=e.key===t?{key:t,results:new Map(e.results),updated:new Map(e.updated),stale:new Set(e.stale),receivedAt:e.receivedAt,receivedBatch:e.receivedBatch}:{key:t,results:new Map,updated:new Map,stale:new Set,receivedAt:0};for(let e of n&&i!==o.receivedBatch?n:[])e.status===`error`&&o.results.get(e.id)?.frame?(o.stale.add(e.id),o.results.set(e.id,{...o.results.get(e.id),error:e.error,request_error:e.request_error})):(o.results.set(e.id,e),o.updated.set(e.id,r),o.stale.delete(e.id));n&&(o.receivedAt=r,o.receivedBatch=i);for(let e of a?.ids??[]){let t=o.results.get(e);t?.frame?(o.stale.add(e),o.results.set(e,{...t,error:a.error,request_error:a.retryable?a.ids:void 0})):o.results.set(e,{id:e,status:`error`,elapsed_ms:0,error:a.error,request_error:a.retryable?a.ids:void 0})}return o}function r5(e,t){return e.queryKey[0]===`variables`&&e.queryKey[1]===t}function i5(e,t,n,r,i,a=!1){let o=!!t.variables?.some(e=>e.kind===`query`),s=dt({queryKey:X8(e,t,n,r),queryFn:async({signal:e})=>{let a=await i({dashboard:t,time:n,vars:r},e);return Object.fromEntries((t.variables??[]).map(e=>[e.name,a[e.name]??(e.kind===`custom`?e.options?.map(e=>({value:e})):void 0)??[]]))},enabled:o,retry:a,staleTime:6e4,placeholderData:e=>e}),c=s.isPlaceholderData?void 0:s.data,l=s.isError||(t.variables??[]).every(e=>e.kind!==`query`||r[e.name]!==void 0&&r[e.name]!==`$__all`&&(e.multi||!Array.isArray(r[e.name])||r[e.name].length>0)||!!e.default||e.include_all||c?.[e.name]!==void 0);return{...s,currentData:c,ready:l}}function a5(e){return t=>e5(t,e)||r5(t,`dashboard-${e}`)}function o5({id:e,currentVersion:t,opened:n,onClose:r,onRestored:i}){let a=ct(),[o,s]=(0,V.useState)(),[c,l]=(0,V.useState)(``),[u,d]=(0,V.useState)(!1),[f,p]=(0,V.useState)(n),m=(0,V.useRef)(0),h=(0,V.useRef)(n);h.current=n;let g=(0,V.useRef)(!1),_=(0,V.useRef)(!1),v=(0,V.useRef)(i);v.current=i,(0,V.useEffect)(()=>(_.current=!0,()=>{_.current=!1}),[]);let y=Te({mutationFn:({version:t})=>ze(e,t),retry:!1,onSuccess:(t,{version:n,generation:r})=>{a.cancelQueries({queryKey:[`dashboard`,e],exact:!0}),a.cancelQueries({predicate:a5(e)}),a.cancelQueries({queryKey:[`exemplars`]}),a.cancelQueries({queryKey:[`drill-trace`]}),a.setQueryData([`dashboard`,e],t),a.invalidateQueries({predicate:a5(e),refetchType:`none`}),_.current&&(h.current&&r===m.current&&l(`Restored v${n} as v${t.version}`),v.current(t)),a.invalidateQueries({queryKey:Ne}),a.invalidateQueries({queryKey:[`dashboard-versions`,e]},{cancelRefetch:!1}),a.invalidateQueries({queryKey:[`exemplars`],refetchType:`none`}),a.invalidateQueries({queryKey:[`drill-trace`],refetchType:`none`})},onError:t=>{t instanceof $e&&t.code===`dashboard_version_not_found`&&a.invalidateQueries({queryKey:[`dashboard-versions`,e]})},onSettled:()=>{g.current=!1,_.current&&d(!1)}}),b=()=>{m.current++,y.reset(),l(``)};(0,V.useEffect)(()=>{if(n){p(!0);return}m.current++,y.reset(),l(``),a.cancelQueries({queryKey:[`dashboard-versions`,e]}),a.cancelQueries({queryKey:[`dashboard-version`,e]})},[n,e,a,y.reset]);let x=(0,V.useRef)(t);return(0,V.useEffect)(()=>{x.current!==t&&(x.current=t,a.invalidateQueries({queryKey:[`dashboard-versions`,e]},{cancelRefetch:!1}))},[t,e,a]),(0,H.jsx)(Qe,{opened:n,onClose:()=>{b(),r()},onExitTransitionEnd:()=>p(!1),title:`Version history`,position:`right`,size:`xl`,children:(n||f)&&(0,H.jsx)(s5,{id:e,opened:n,currentVersion:t,selected:o,onSelect:e=>{b(),s(e)},pending:u,error:y.error,failedVersion:y.variables?.version,success:c,onRestore:e=>{g.current||(g.current=!0,d(!0),l(``),y.mutate({version:e,generation:m.current}))}})})}function s5({id:e,opened:t,currentVersion:n,selected:r,onSelect:i,pending:a,error:s,failedVersion:c,success:l,onRestore:u}){let d=dt({queryKey:[`dashboard-versions`,e],queryFn:({signal:t})=>gt(e,t),enabled:t,retry:!1}),f=r??d.data?.[0]?.version,p=dt({queryKey:[`dashboard-version`,e,f],queryFn:({signal:t})=>Pe(e,f,t),enabled:t&&f!==void 0,retry:!1});return(0,H.jsxs)(S,{gap:`md`,"data-version-history":!0,children:[(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:`Inspect saved specs and changes. Restoring adds a new version.`}),l&&(0,H.jsx)(ee,{color:`ok`,role:`status`,children:l}),s&&c===f&&(0,H.jsx)(d5,{error:s,version:f}),(0,H.jsxs)(o,{mih:160,children:[d.isPending&&(0,H.jsxs)(y,{gap:`xs`,role:`status`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{size:`sm`,children:`Loading history…`})]}),d.error&&(0,H.jsxs)(ee,{color:`bad`,title:`History unavailable`,children:[d.error.message,(0,H.jsx)(C,{mt:`xs`,variant:`default`,size:`xs`,onClick:()=>void d.refetch(),children:`Retry history`})]}),d.data?.length===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No versions available.`}),!!d.data?.length&&(0,H.jsx)(fe,{h:200,type:`auto`,children:(0,H.jsx)(S,{gap:`xs`,pr:`sm`,role:`list`,"aria-label":`Saved versions`,children:d.data.map(e=>(0,H.jsxs)(z,{role:`listitem`,withBorder:!0,p:`xs`,radius:`sm`,style:{borderColor:f===e.version?`var(--mantine-color-brand-filled)`:void 0},children:[(0,H.jsxs)(y,{justify:`space-between`,gap:`xs`,children:[(0,H.jsxs)(C,{variant:f===e.version?`light`:`subtle`,size:`compact-sm`,"aria-pressed":f===e.version,onClick:()=>i(e.version),children:[`Version `,e.version]}),e.version===n&&(0,H.jsx)(He,{color:`gray`,variant:`light`,tt:`none`,children:`Current`}),(0,H.jsx)(l5,{at:e.created_at})]}),(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,mt:4,children:[c5(e),` · `,e.message||`No edit message`]})]},e.version))})})]}),(0,H.jsx)(Je,{role:`status`,"aria-live":`polite`,children:f===void 0?`Select a version.`:p.isFetching?`Loading version ${f}…`:p.error?`Version ${f} unavailable.`:`Version ${f} ready.`}),(0,H.jsxs)(o,{mih:280,"aria-busy":p.isFetching,children:[f!==void 0&&p.isPending&&(0,H.jsxs)(y,{gap:`xs`,role:`status`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{size:`sm`,children:`Loading version…`})]}),p.error&&(0,H.jsxs)(ee,{color:`bad`,title:p.error instanceof $e&&p.error.code===`dashboard_version_not_found`?`This version is no longer available`:`Version unavailable`,children:[p.error.message,(0,H.jsx)(C,{mt:`xs`,variant:`default`,size:`xs`,onClick:()=>void p.refetch(),children:`Retry version`})]}),p.data&&!p.error&&(0,H.jsx)(u5,{record:p.data,currentVersion:n,pending:a,onRestore:()=>u(p.data.dashboard.version)})]})]})}function c5(e){return e.author_kind===`agent`?`Agent`:e.author_kind===`user`?`You`:`System`}function l5({at:e}){let t=(Date.parse(e)-Date.now())/1e3,[n,r]=Math.abs(t)<60?[1,`second`]:Math.abs(t)<3600?[60,`minute`]:Math.abs(t)<86400?[3600,`hour`]:[86400,`day`];return(0,H.jsx)(T,{component:`time`,dateTime:e,title:he(e),size:`xs`,c:`dimmed`,children:new Intl.RelativeTimeFormat(void 0,{numeric:`auto`}).format(Math.round(t/n),r)})}function u5({record:e,currentVersion:t,pending:n,onRestore:r}){let{dashboard:i}=e,a=Xe(e);return(0,H.jsxs)(S,{gap:`sm`,"data-history-version":i.version,children:[(0,H.jsxs)(y,{justify:`space-between`,align:`flex-start`,children:[(0,H.jsxs)(o,{miw:0,children:[(0,H.jsxs)(I,{order:2,fz:`lg`,children:[i.name,` · v`,i.version]}),(0,H.jsxs)(T,{size:`sm`,c:`dimmed`,children:[c5(e),` · `,e.message||`No edit message`]}),(0,H.jsx)(l5,{at:e.created_at})]}),i.version===t?(0,H.jsx)(C,{size:`sm`,variant:`default`,disabled:!0,children:`Current version`}):(0,H.jsxs)(C,{size:`sm`,disabled:n,loading:n,onClick:r,children:[`Restore version `,i.version]})]}),i.description&&(0,H.jsx)(T,{size:`sm`,children:i.description}),e.changes_available?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Ce,{labels:a}),!a.length&&!e.layout_changed&&(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:`No authored changes.`})]}):(0,H.jsx)(ee,{color:`warn`,title:`Changes unavailable`,children:`The preceding version is no longer retained. This saved spec is still available.`}),(0,H.jsxs)(T,{size:`sm`,c:`dimmed`,children:[`Read-only · `,i.spec.panels.length,` panels. Historical data is not queried.`]}),(0,H.jsxs)(pn,{variant:`contained`,children:[(0,H.jsxs)(pn.Item,{value:`spec`,children:[(0,H.jsx)(pn.Control,{children:`Spec`}),(0,H.jsx)(pn.Panel,{children:(0,H.jsx)(Le,{block:!0,tabIndex:0,style:{maxHeight:320,overflow:`auto`},children:JSON.stringify(i.spec,null,2)})})]}),(0,H.jsxs)(pn.Item,{value:`data`,children:[(0,H.jsx)(pn.Control,{children:`Data`}),(0,H.jsx)(pn.Panel,{children:(0,H.jsx)(S,{gap:`xs`,children:i.spec.panels.map(e=>(0,H.jsxs)(o,{children:[(0,H.jsxs)(T,{size:`sm`,fw:500,children:[e.title,` · `,e.viz]}),(0,H.jsx)(Le,{block:!0,tabIndex:0,children:e.content??e.sql??JSON.stringify(e.query??{},null,2)})]},e.id))})})]})]})]})}function d5({error:e,version:t}){let n=e instanceof $e?e.code:void 0,r=!(e instanceof $e)||e.status>=500?`Try again with the restore button.`:n===`invalid_spec`?`This saved spec is invalid. Review the fields below and choose another version.`:n===`dashboard_version_not_found`?`Reload history and choose a retained version.`:[`already_current`,`dashboard_version_conflict`,`conflict`].includes(n??``)?`This dashboard changed or its name conflicts. Reload history and choose another version.`:`Check your access and reload history.`;return(0,H.jsxs)(ee,{color:`bad`,title:`Restore of version ${t} failed`,children:[(0,H.jsx)(T,{size:`sm`,children:e.message}),e instanceof $e&&e.problems.length>0&&(0,H.jsx)(`ul`,{children:e.problems.map((e,t)=>(0,H.jsxs)(`li`,{children:[e.path,`: `,e.message,e.hint?` (${e.hint})`:``]},t))}),(0,H.jsx)(T,{size:`sm`,mt:`xs`,children:r})]})}function f5(e,t){let n=JSON.stringify([e.range,e.from,e.to]),r=(0,V.useRef)({search:e,onSearch:t,scope:n}),i=(0,V.useRef)(``),a=(0,V.useRef)(void 0),[o,s]=(0,V.useState)(!1);r.current.scope!==n&&(i.current!==`${e.from}/${e.to}`&&(a.current=void 0,o&&s(!1)),i.current=``),r.current={search:e,onSearch:t,scope:n};let c=(0,V.useCallback)(()=>{i.current=``,a.current=void 0,s(!1)},[]),l=(0,V.useCallback)(()=>{if(!a.current)return;let e=a.current;c(),r.current.onSearch({...r.current.search,...e},!1)},[c]);return{zoom:(0,V.useCallback)((e,t)=>{let n=la(e,t);if(!n)return;let o=r.current,c=`${n.from}/${n.to}`;o.search.from===n.from&&o.search.to===n.to||i.current===c||(a.current??={range:o.search.range,from:o.search.from,to:o.search.to},s(!0),i.current=c,o.onSearch({...o.search,range:void 0,...n},!1))},[]),reset:c,resetZoom:l,zoomed:o}}function p5({variables:e,vars:t,options:n,onChange:r}){return e.length===0?null:(0,H.jsx)(y,{gap:`sm`,wrap:`wrap`,role:`group`,"aria-label":`Dashboard variables`,children:e.map(e=>{let i=Ji(e,t,n[e.name]),a=[...e.include_all?[{value:qi,label:`All`}]:[],...(n[e.name]??e.options?.map(e=>({value:e}))??[]).map(e=>({value:e.value,label:e.value}))],o=(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,ff:`monospace`,children:[`$`,e.name]});return e.kind===`constant`?(0,H.jsx)(Me,{label:o,size:`xs`,value:e.value,readOnly:!0,w:160},e.name):e.kind===`text`?(0,H.jsx)(Me,{label:o,size:`xs`,w:200,defaultValue:typeof i==`string`?i:``,onBlur:t=>r(e.name,t.currentTarget.value),onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()}},`${e.name}:${JSON.stringify(i)}`):e.multi?(0,H.jsx)(kr,{label:o,size:`xs`,w:260,searchable:!0,clearable:!0,data:a.filter(e=>e.value!==qi),value:Array.isArray(i)?i:i&&i!==`$__all`?[i]:[],placeholder:e.include_all?`All`:`None`,onChange:t=>r(e.name,t.length?t:e.include_all?qi:[])},e.name):(0,H.jsx)(Wr,{label:o,size:`xs`,w:220,searchable:!0,allowDeselect:!1,data:a,value:Array.isArray(i)?i[0]??null:i||null,onChange:t=>t!==null&&r(e.name,t)},e.name)})})}function m5(e,t,n=!1){let r=e.target;return t||e.defaultPrevented||e.repeat||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey&&e.key!==`?`||r instanceof Element&&r.closest(`input,textarea,select,[contenteditable]:not([contenteditable="false"]),[role="textbox"],[role="menu"]`)||r instanceof Element&&r.closest(`[role="dialog"]`)&&!(n&&r.closest(`[data-panel-fullscreen]`))?null:[`r`,`e`,`h`,`f`,`?`].includes(e.key)?e.key:null}function h5(e,t,n={}){let r=(0,V.useRef)({actions:t,options:n});r.current={actions:t,options:n},(0,V.useEffect)(()=>{let t=t=>{let n=e.current,i=t.target,{actions:a,options:o}=r.current;if(!n||!(i instanceof Element)||o.enabled===!1)return;let s=o.fullscreenScope?[...document.querySelectorAll(`[data-shortcut-scope]`)].find(e=>e.dataset.shortcutScope===o.fullscreenScope&&e.hasAttribute(`data-panel-fullscreen`)):void 0,c=n.contains(i)&&n.contains(document.activeElement),l=i===document.body&&document.activeElement===document.body,u=s?.contains(i)&&s.contains(document.activeElement);if(!c&&!l&&!u)return;let d=m5(t,!!(o.modalOpen||[...document.querySelectorAll(`[role="dialog"]`)].some(e=>e!==s)),!!s);if(!d||s&&![`r`,`f`,`?`].includes(d))return;let f=a[d];f&&(t.preventDefault(),f(i))};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[e])}function g5({opened:e,onClose:t,fullscreen:n=!1,enabled:r,onEnabled:i}){let a=[[`r`,`Refresh now`],...n?[]:[[`e`,`Toggle layout mode`],[`h`,`Open history`]],[`f`,n?`Exit full-screen`:`Open the focused panel in full-screen`],[`?`,`Open keyboard shortcuts`],[`Escape`,`Cancel a range, then leave the chart or close full-screen`]];return(0,H.jsx)(Ze,{opened:e,onClose:t,title:`Keyboard shortcuts`,trapFocus:!0,returnFocus:!0,closeOnEscape:!0,children:(0,H.jsxs)(S,{gap:`xs`,children:[(0,H.jsx)(oi,{label:`Single-key shortcuts`,checked:r,onChange:e=>i(e.currentTarget.checked)}),a.map(([e,t])=>(0,H.jsxs)(y,{gap:`sm`,children:[(0,H.jsx)(Ye,{children:e}),(0,H.jsx)(T,{size:`sm`,children:t})]},e)),!n&&(0,H.jsx)(T,{size:`sm`,children:`Focus a chart or a panel control before pressing f. Without a focused panel, f does nothing.`}),(0,H.jsx)(T,{size:`sm`,children:`Tab directly to a chart. Left/Right moves between points; Up/Down changes series at the same time or category. Home/End jumps to the first/last point. Enter drills or applies the panel filter. Comparison and Other values can be read even when selection is unavailable.`}),(0,H.jsx)(T,{size:`sm`,children:`On time charts, Shift+Left/Right extends a range and pauses auto-refresh. Review the shaded range and compact UTC label, then choose Zoom to range. Use the time picker after zooming for precise edits. Escape or Cancel cancels it and resumes refresh. The next Escape leaves the chart or closes full-screen. Reset zoom, Zoom out and browser Back preserve comparison and filters.`}),(0,H.jsxs)(T,{size:`sm`,children:[n?`In full-screen, r refreshes, f exits and ? opens help; e and h are inactive.`:`Shortcuts work in the dashboard.`,` Typing, menus and other dialogs or drawers pause shortcuts. Modifier shortcuts keep their browser behavior. Turning off single-key shortcuts keeps chart navigation and visible controls available.`]}),(0,H.jsx)(T,{size:`sm`,children:`The global / shortcut focuses the chat composer.`})]})})}function _5(e){let t=`fanout:single-key-shortcuts:`+e,n=()=>{try{return localStorage.getItem(t)!==`off`}catch{return!0}},[r,i]=(0,V.useState)(n);return(0,V.useEffect)(()=>{i(n())},[t]),(0,V.useEffect)(()=>{let e=e=>{e.key===t&&i(n())};return window.addEventListener(`storage`,e),()=>window.removeEventListener(`storage`,e)},[t]),{enabled:r,change:e=>{i(e);try{localStorage.setItem(t,e?`on`:`off`)}catch{}}}}function v5(e){let t=(0,V.useRef)(void 0),n=t=>[...e.current?.querySelectorAll(`[data-panel]`)??[]].find(e=>e.dataset.panel===t&&!e.closest(`[data-panel-fullscreen],[data-fragment-fullscreen]`));return(0,V.useEffect)(()=>{t.current&&!n(t.current.panel)&&(t.current=void 0)}),{remember(n){t.current=void 0;let r=document.activeElement;if(!(r instanceof HTMLElement)||!e.current?.contains(r)||r.closest(`[data-panel]`)?.dataset.panel!==n)return;let i=r.getAttribute(`data-panel-view`),a=r.getAttribute(`aria-label`),o=r.hasAttribute(`data-chart-plot`)?`[data-chart-plot]`:i?`[data-panel-view=${JSON.stringify(i)}]`:a?`[aria-label=${JSON.stringify(a)}]`:void 0;t.current={element:r,panel:n,selector:o}},restore(e){let r=t.current;if(t.current=void 0,r&&(e===void 0||r.panel===e)&&n(r.panel))return r.element.isConnected&&!r.element.closest(`[hidden]`)?r.element:r.selector?n(r.panel)?.querySelector(r.selector)??void 0:void 0}}}var y5={exemplars:Ue,trace:Fe},b5={"5m":`15m`,"15m":`1h`,"1h":`3h`,"3h":`6h`,"6h":`12h`,"12h":`24h`,"24h":`2d`,"2d":`7d`,"7d":`30d`,"30d":`30d`};function x5({dashboardId:e,search:t,onSearch:n,onOpen:r}){let{agentAvailable:i,openChat:a}=je(),o=dt({queryKey:Ne,queryFn:Ge,staleTime:15e3});(0,V.useEffect)(()=>{!e&&o.data?.length&&r((o.data.find(e=>e.is_default)??o.data[0]).id,!0)},[e,o.data]);let s=dt({queryKey:[`dashboard`,e],queryFn:({signal:t})=>Mt(e,t),enabled:!!e,retry:(e,t)=>!(t instanceof $e&&t.code===`not_found`)&&e<2});return!e&&o.error?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsx)(ee,{color:`bad`,title:`Dashboards could not be loaded`,children:o.error.message})}):!e&&o.data?.length===0?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsxs)(S,{align:`center`,gap:`xs`,children:[(0,H.jsx)(I,{order:1,fz:24,children:`No dashboards yet`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ta:`center`,children:`Create a dashboard to explore your services.`}),i&&(0,H.jsx)(C,{mt:`sm`,size:`sm`,onClick:()=>a(`Build me a dashboard for my services, showing request volume, latency, and errors. Ask me which services to monitor first.`),children:`Create with AI`})]})}):!e||s.isLoading?(0,H.jsxs)(ae,{mih:`50vh`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ml:`sm`,children:`Loading your dashboard…`})]}):s.error instanceof $e&&s.error.code===`not_found`?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsxs)(S,{align:`center`,gap:`xs`,children:[(0,H.jsx)(I,{order:1,fz:24,children:`This dashboard isn't here`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ta:`center`,children:`The link may be out of date, or the dashboard may have been deleted.`}),o.data?.length?(0,H.jsx)(C,{mt:`sm`,variant:`default`,size:`sm`,onClick:()=>r((o.data.find(e=>e.is_default)??o.data[0]).id,!0),children:`Open your default dashboard`}):null]})}):s.error||!s.data?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsx)(T,{c:`dimmed`,size:`sm`,children:`Your dashboard is unavailable. Try refreshing.`})}):(0,H.jsx)(S5,{id:s.data.id,version:s.data.version,spec:s.data.spec,search:t,onSearch:n,agentAvailable:i,openChat:a},s.data.id)}function S5({id:e,version:t,spec:n,search:r,onSearch:i,agentAvailable:a,openChat:s}){let[c,l]=(0,V.useState)(!1),[u,d]=(0,V.useState)(!1),f=(0,V.useRef)(null),p=(0,V.useId)(),m=_5(Be().id),h=v5(f),[g,_]=(0,V.useState)(()=>new Set),v=(0,V.useCallback)((e,t)=>_(n=>{if(n.has(e)===t)return n;let r=new Set(n);return t?r.add(e):r.delete(e),r}),[]),b=ct(),[x,w]=(0,V.useState)(),{zoom:E,reset:D,resetZoom:O,zoomed:k}=f5(r,i),A=ft(n,r),[j,M]=(0,V.useState)(A.refresh??`30s`),N=r.compare?r.compare===`1`:n.time.compare===`previous_period`,P=r.vars??{},F=i5(`dashboard-${e}`,n,A,P,Ie,K8),L=(0,V.useMemo)(()=>Xi(n.variables,P,F.currentData),[n.variables,P,F.currentData]),[te,ne]=(0,V.useState)(()=>window.innerWidth);(0,V.useEffect)(()=>{let e=0,t=()=>{window.clearTimeout(e),e=window.setTimeout(()=>ne(window.innerWidth),300)};return window.addEventListener(`resize`,t),()=>{window.removeEventListener(`resize`,t),window.clearTimeout(e)}},[]);let re=(0,V.useMemo)(()=>{let e=Math.max(320,Math.min(te-64,1600));return Object.fromEntries(n.panels.map(t=>[t.id,e/12*(t.grid?.w??t.width??6)]))},[te,n]),[ie,ae]=(0,V.useState)(()=>n.panels.map(e=>e.id)),R=t5({dashboardId:e,version:t,spec:n,time:A,vars:L,compare:N,widths:re,visible:(0,V.useMemo)(()=>ie.filter(e=>n.panels.some(t=>t.id===e)),[ie,n.panels]),refresh:g.size?`off`:j,enabled:F.ready});(0,V.useEffect)(()=>{x===t&&b.refetchQueries({predicate:a5(e),type:`active`,stale:!0},{cancelRefetch:!1})},[x,t,e,b]);let oe=(0,V.useMemo)(()=>R.annotations?{...R.annotations,deploys:n.annotations?.deploys===!1?[]:R.annotations.deploys,anomalies:n.annotations?.anomalies===!1?[]:R.annotations.anomalies}:void 0,[R.annotations,n.annotations?.deploys,n.annotations?.anomalies]),z=F.error??R.error,se=(e,t)=>{let n={...P};t===void 0?delete n[e]:n[e]=t,i({...r,vars:n},!0)},ce=()=>i({...r,edit:r.edit===`1`?void 0:`1`}),le=e=>{e&&h.remember(e),i({...r,view:e},e===void 0)};return h5(f,{r:()=>R.refetch(),e:ce,h:()=>l(!0),"?":()=>d(!0),f:e=>{if(r.view){le();return}let t=e.closest(`[data-panel]`)?.dataset.panel;t&&n.panels.some(e=>e.id===t)&&le(t)}},{modalOpen:c||u||!!r.drill,fullscreenScope:r.view?p:void 0,enabled:m.enabled}),(0,H.jsxs)(o,{component:`main`,ref:f,"aria-label":`Dashboard`,maw:1600,mx:`auto`,px:{base:`md`,sm:`xl`},pt:`lg`,pb:`xl`,children:[(0,H.jsxs)(S,{gap:`sm`,mb:`md`,children:[(0,H.jsxs)(y,{justify:`space-between`,align:`flex-start`,wrap:`wrap`,gap:`sm`,children:[(0,H.jsxs)(o,{miw:0,children:[(0,H.jsx)(I,{order:1,fz:28,lts:`-0.02em`,children:n.name}),n.description&&(0,H.jsx)(T,{c:`dimmed`,size:`sm`,mt:2,children:n.description})]}),(0,H.jsx)(G8,{selecting:g.size>0,time:A,refresh:j,compare:N,editing:r.edit===`1`,fetching:R.fetching,updatedAt:R.updatedAt,onRange:e=>{D(),i({...r,range:e,from:void 0,to:void 0})},onAbsolute:(e,t)=>{D(),i({...r,range:void 0,from:e,to:t})},onZoomOut:()=>{if(A.from&&A.to){let e=Date.parse(A.from),t=Date.parse(A.to),n=(t-e)/2;i({...r,range:void 0,from:new Date(e-n).toISOString(),to:new Date(t+n).toISOString()})}else i({...r,range:b5[A.range??`1h`]??`1h`,from:void 0,to:void 0})},onRefresh:M,onRefreshNow:R.refetch,onCompare:e=>i({...r,compare:e?`1`:`0`},!0),onEdit:ce,onHistory:()=>l(!0),onShortcuts:()=>d(!0)})]}),(0,H.jsx)(p5,{variables:n.variables??[],vars:P,options:F.data??{},onChange:se}),Object.entries(P).filter(([,e])=>e!==`$__all`).length>0&&(0,H.jsx)(y,{gap:6,children:Object.entries(P).filter(([,e])=>e!==`$__all`).map(([e,t])=>(0,H.jsxs)(C,{size:`compact-xs`,variant:`light`,"aria-label":`$${e} = ${Array.isArray(t)?t.join(`, `):t} ×: remove filter`,onClick:()=>se(e,void 0),children:[`$`,e,` = `,Array.isArray(t)?t.join(`, `):t,` ×`]},e))}),R.annotationError&&(0,H.jsx)(ee,{color:`warn`,title:`Annotations unavailable`,children:R.annotationError}),R.annotations?.truncated&&(0,H.jsx)(T,{size:`xs`,c:`warn`,role:`status`,children:`Annotation history is limited.`})]}),z&&(0,H.jsxs)(ee,{color:`bad`,icon:(0,H.jsx)(De,{size:18,weight:`fill`}),mb:`md`,title:F.error?`Variables could not be loaded`:`Panels could not be loaded`,children:[z.message,z instanceof $e&&(0,H.jsx)(`ul`,{children:z.problems.map((e,t)=>(0,H.jsxs)(`li`,{children:[e.path,`: `,e.message,e.hint?` (${e.hint})`:``]},t))})]}),(0,H.jsx)(N8,{dashboardId:e,version:t,spec:n,vars:L,results:R.results,annotations:oe,fetching:R.fetching,fetchingIds:R.fetchingIds,staleAt:R.staleAt,time:{...A,compare:N?`previous_period`:void 0},onEditExit:()=>i({...r,edit:void 0}),editing:r.edit===`1`,view:r.view,canManage:!0,agentAvailable:a,onOpenChat:s,onRetry:R.retry,onVariable:se,onZoom:E,zoomed:k,onZoomReset:O,onView:le,onRangePending:v,shortcutScope:p,onShortcuts:()=>d(!0),overlayOpen:c||u||!!r.drill,returnViewFocus:h.restore,onVisible:ae,onPoint:(e,t)=>{let n=S8(e,R.results.get(e.id),t,P);n&&i({...r,vars:n.vars,drill:JSON.stringify(n.target)},!1)}}),(0,H.jsx)(H8,{client:y5,spec:n,time:A,vars:L,target:Nt(r.drill),onChange:e=>i({...r,drill:e?JSON.stringify(e):void 0},!1)}),(0,H.jsx)(o5,{id:e,currentVersion:t,opened:c,onClose:()=>l(!1),onRestored:e=>{w(e.version);let t=new Set(e.spec.panels.map(e=>e.id)),n=Nt(r.drill),a=r.view&&!t.has(r.view)?void 0:r.view,o=n&&!t.has(n.panel_id)?void 0:r.drill;(a!==r.view||o!==r.drill)&&i({...r,view:a,drill:o},!0)}}),(0,H.jsx)(g5,{opened:u,onClose:()=>d(!1),fullscreen:!!r.view,enabled:m.enabled,onEnabled:m.change})]})}export{Yi as i,W4 as n,V4 as r,x5 as t}; \ No newline at end of file +`,e.getElementsByTagName(`head`)[0].appendChild(n)}e.body&&ce(e.body,`react-draggable-transparent-selection`)}function z(e){window.requestAnimationFrame?window.requestAnimationFrame(()=>{se(e)}):se(e)}function se(e){if(e)try{e.body&&le(e.body,`react-draggable-transparent-selection`);let t=e.selection;if(t)t.empty();else{let t=(e.defaultView||window).getSelection();t&&t.type!==`Caret`&&t.removeAllRanges()}}catch{}}function ce(e,t){e.classList?e.classList.add(t):e.className.match(RegExp(`(?:^|\\s)${t}(?!\\S)`))||(e.className+=` ${t}`)}function le(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(RegExp(`(?:^|\\s)${t}(?!\\S)`,`g`),``)}function ue(e,t,n){if(!e.props.bounds)return[t,n];let{bounds:r}=e.props;r=typeof r==`string`?r:_e(r);let i=ve(e);if(typeof r==`string`){let{ownerDocument:e}=i,t=e.defaultView;if(!t)throw Error(`Cannot resolve the owner window of the draggable node.`);let n;if(n=r===`parent`?i.parentNode:i.getRootNode().querySelector(r),!(n instanceof t.HTMLElement))throw Error(`Bounds selector "`+r+`" could not find an element.`);let a=n,o=t.getComputedStyle(i),s=t.getComputedStyle(a);r={left:-i.offsetLeft+S(s.paddingLeft)+S(o.marginLeft),top:-i.offsetTop+S(s.paddingTop)+S(o.marginTop),right:L(a)-F(i)-i.offsetLeft+S(s.paddingRight)-S(o.marginRight),bottom:I(a)-P(i)-i.offsetTop+S(s.paddingBottom)-S(o.marginBottom)}}return x(r.right)&&(t=Math.min(t,r.right)),x(r.bottom)&&(n=Math.min(n,r.bottom)),x(r.left)&&(t=Math.max(t,r.left)),x(r.top)&&(n=Math.max(n,r.top)),[t,n]}function de(e,t,n){return[Math.round(t/e[0])*e[0],Math.round(n/e[1])*e[1]]}function fe(e){return e.props.axis===`both`||e.props.axis===`x`}function pe(e){return e.props.axis===`both`||e.props.axis===`y`}function me(e,t,n){let r=typeof t==`number`?ie(e,t):null;if(typeof t==`number`&&!r)return null;let i=ve(n),a=n.props.offsetParent||i.offsetParent||i.ownerDocument.body;return ee(r||e,a,n.props.scale)}function he(e,t,n){let r=!x(e.lastX),i=ve(e);return r?{node:i,deltaX:0,deltaY:0,lastX:t,lastY:n,x:t,y:n}:{node:i,deltaX:t-e.lastX,deltaY:n-e.lastY,lastX:e.lastX,lastY:e.lastY,x:t,y:n}}function ge(e,t){let n=e.props.scale;return{node:t.node,x:e.state.x+t.deltaX/n,y:e.state.y+t.deltaY/n,deltaX:t.deltaX/n,deltaY:t.deltaY/n,lastX:e.state.x,lastY:e.state.y}}function _e(e){return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}function ve(e){let t=e.findDOMNode();if(!t)throw Error(`: Unmounted during event!`);return t}var B=d(t()),ye=d(e6()),be=d(b()),xe=typeof process<`u`&&{}.DRAGGABLE_DEBUG?console.log.bind(console):function(){},Se={touch:{start:`touchstart`,move:`touchmove`,stop:`touchend`},mouse:{start:`mousedown`,move:`mousemove`,stop:`mouseup`}},Ce=Se.mouse,we=class extends B.Component{constructor(){super(...arguments),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,this.touchIdentifier=null,this.mounted=!1,this.handleDragStart=e=>{if(this.props.onMouseDown(e),!this.props.allowAnyClick&&(typeof e.button==`number`&&e.button!==0||e.ctrlKey))return!1;let t=this.findDOMNode();if(!t||!t.ownerDocument||!t.ownerDocument.body)throw Error(` not mounted on DragStart!`);let{ownerDocument:n}=t;if(this.props.disabled||!(e.target instanceof n.defaultView.Node)||this.props.handle&&!j(e.target,this.props.handle,t)||this.props.cancel&&j(e.target,this.props.cancel,t))return;e.type===`touchstart`&&!this.props.allowMobileScroll&&e.preventDefault();let r=ae(e);this.touchIdentifier=r;let i=me(e,r,this);if(i==null)return;let{x:a,y:o}=i,s=he(this,a,o);xe(`DraggableCore: handleDragStart: %j`,s),xe(`calling`,this.props.onStart),this.props.onStart(e,s)!==!1&&this.mounted!==!1&&(this.props.enableUserSelectHack&&oe(n,this.props.nonce),this.dragging=!0,this.lastX=a,this.lastY=o,M(n,Ce.move,this.handleDrag),M(n,Ce.stop,this.handleDragStop))},this.handleDrag=e=>{let t=me(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX,t=r-this.lastY;if([e,t]=de(this.props.grid,e,t),!e&&!t)return;n=this.lastX+e,r=this.lastY+t}let i=he(this,n,r);if(xe(`DraggableCore: handleDrag: %j`,i),this.props.onDrag(e,i)===!1||this.mounted===!1){try{this.handleDragStop(new MouseEvent(`mouseup`))}catch{let e=document.createEvent(`MouseEvents`);e.initMouseEvent(`mouseup`,!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),this.handleDragStop(e)}return}this.lastX=n,this.lastY=r},this.handleDragStop=e=>{if(!this.dragging)return;let t=me(e,this.touchIdentifier,this);if(t==null)return;let{x:n,y:r}=t;if(Array.isArray(this.props.grid)){let e=n-this.lastX||0,t=r-this.lastY||0;[e,t]=de(this.props.grid,e,t),n=this.lastX+e,r=this.lastY+t}let i=he(this,n,r);if(this.props.onStop(e,i)===!1||this.mounted===!1)return!1;let a=this.findDOMNode();a&&this.props.enableUserSelectHack&&z(a.ownerDocument),xe(`DraggableCore: handleDragStop: %j`,i),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,a&&(xe(`DraggableCore: Removing handlers`),N(a.ownerDocument,Ce.move,this.handleDrag),N(a.ownerDocument,Ce.stop,this.handleDragStop))},this.onMouseDown=e=>(Ce=Se.mouse,this.handleDragStart(e)),this.onMouseUp=e=>(Ce=Se.mouse,this.handleDragStop(e)),this.onTouchStart=e=>(Ce=Se.touch,this.handleDragStart(e)),this.onTouchEnd=e=>(Ce=Se.touch,this.handleDragStop(e))}componentDidMount(){this.mounted=!0;let e=this.findDOMNode();e&&M(e,Se.touch.start,this.onTouchStart,{passive:!1})}componentWillUnmount(){this.mounted=!1;let e=this.findDOMNode();if(e){let{ownerDocument:t}=e;N(t,Se.mouse.move,this.handleDrag),N(t,Se.touch.move,this.handleDrag),N(t,Se.mouse.stop,this.handleDragStop),N(t,Se.touch.stop,this.handleDragStop),N(e,Se.touch.start,this.onTouchStart,{passive:!1}),this.props.enableUserSelectHack&&z(t)}}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=be.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):(xe(`react-draggable: ReactDOM.findDOMNode is not available in React 19+. You must provide a nodeRef prop. See: https://github.com/react-grid-layout/react-draggable#noderef`),null)}render(){return B.cloneElement(B.Children.only(this.props.children),{onMouseDown:this.onMouseDown,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}};we.displayName=`DraggableCore`,we.propTypes={allowAnyClick:ye.default.bool,allowMobileScroll:ye.default.bool,children:ye.default.node.isRequired,disabled:ye.default.bool,enableUserSelectHack:ye.default.bool,offsetParent:function(e,t){if(e[t]&&e[t].nodeType!==1)throw Error(`Draggable's offsetParent must be a DOM Node.`)},grid:ye.default.arrayOf(ye.default.number),handle:ye.default.string,cancel:ye.default.string,nodeRef:ye.default.object,nonce:ye.default.string,onStart:ye.default.func,onDrag:ye.default.func,onStop:ye.default.func,onMouseDown:ye.default.func,scale:ye.default.number,className:C,style:C,transform:C},we.defaultProps={allowAnyClick:!1,allowMobileScroll:!1,disabled:!1,enableUserSelectHack:!0,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){},scale:1};var Te=class extends m.Component{constructor(e){super(e),this.onDragStart=(e,t)=>{if(xe(`Draggable: onDragStart: %j`,t),this.props.onStart(e,ge(this,t))===!1)return!1;this.setState({dragging:!0,dragged:!0})},this.onDrag=(e,t)=>{if(!this.state.dragging)return!1;xe(`Draggable: onDrag: %j`,t);let n=ge(this,t),r={x:n.x,y:n.y,slackX:0,slackY:0};if(this.props.bounds){let{x:e,y:t}=r;r.x+=this.state.slackX,r.y+=this.state.slackY;let[i,a]=ue(this,r.x,r.y);r.x=i,r.y=a,r.slackX=this.state.slackX+(e-r.x),r.slackY=this.state.slackY+(t-r.y),n.x=r.x,n.y=r.y,n.deltaX=r.x-this.state.x,n.deltaY=r.y-this.state.y}if(this.props.onDrag(e,n)===!1)return!1;this.setState(r)},this.onDragStop=(e,t)=>{if(!this.state.dragging||this.props.onStop(e,ge(this,t))===!1)return!1;xe(`Draggable: onDragStop: %j`,t);let n={dragging:!1,slackX:0,slackY:0};if(this.props.position){let{x:e,y:t}=this.props.position;n.x=e,n.y=t}this.setState(n)},this.state={dragging:!1,dragged:!1,x:e.position?e.position.x:e.defaultPosition.x,y:e.position?e.position.y:e.defaultPosition.y,prevPropsPosition:{...e.position},slackX:0,slackY:0,isElementSVG:!1},e.position&&!(e.onDrag||e.onStop)&&console.warn("A `position` was applied to this , without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}static getDerivedStateFromProps({position:e},{prevPropsPosition:t}){return e&&(!t||e.x!==t.x||e.y!==t.y)?(xe(`Draggable: getDerivedStateFromProps %j`,{position:e,prevPropsPosition:t}),{x:e.x,y:e.y,prevPropsPosition:{...e}}):null}componentDidMount(){window.SVGElement!==void 0&&this.findDOMNode()instanceof window.SVGElement&&this.setState({isElementSVG:!0})}componentWillUnmount(){this.state.dragging&&this.setState({dragging:!1})}findDOMNode(){if(this.props?.nodeRef)return this.props.nodeRef.current;let e=g.default;return typeof e.findDOMNode==`function`?e.findDOMNode(this):null}render(){let{axis:e,bounds:t,children:n,defaultPosition:r,defaultClassName:i,defaultClassNameDragging:a,defaultClassNameDragged:o,position:s,positionOffset:c,scale:l,...u}=this.props,d={},f=null,p=!s||this.state.dragging,h=s||r,g={x:fe(this)&&p?this.state.x:h.x,y:pe(this)&&p?this.state.y:h.y};this.state.isElementSVG?f=ne(g,c):d=te(g,c);let v=m.Children.only(n),y=(0,_.clsx)(v.props.className||``,i,{[a]:this.state.dragging,[o]:this.state.dragged});return m.createElement(we,{...u,onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop},m.cloneElement(v,{className:y,style:{...v.props.style,...d},transform:f}))}};Te.displayName=`Draggable`,Te.propTypes={...we.propTypes,axis:h.default.oneOf([`both`,`x`,`y`,`none`]),bounds:h.default.oneOfType([h.default.shape({left:h.default.number,right:h.default.number,top:h.default.number,bottom:h.default.number}),h.default.string,h.default.oneOf([!1])]),defaultClassName:h.default.string,defaultClassNameDragging:h.default.string,defaultClassNameDragged:h.default.string,defaultPosition:h.default.shape({x:h.default.number,y:h.default.number}),positionOffset:h.default.shape({x:h.default.oneOfType([h.default.number,h.default.string]),y:h.default.oneOfType([h.default.number,h.default.string])}),position:h.default.shape({x:h.default.number,y:h.default.number}),className:C,style:C,transform:C},Te.defaultProps={...we.defaultProps,axis:`both`,bounds:!1,defaultClassName:`react-draggable`,defaultClassNameDragging:`react-draggable-dragging`,defaultClassNameDragged:`react-draggable-dragged`,defaultPosition:{x:0,y:0},scale:1},0&&(n.exports={DraggableCore:we})})),Y6=e(((e,t)=>{var n=J6(),r=n.DraggableCore,i=n.default||n;t.exports=i,t.exports.default=i,t.exports.DraggableCore=r})),X6=e((e=>{e.__esModule=!0,e.cloneElement=l;var n=r(t());function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function a(e){for(var t=1;t{e.__esModule=!0,e.resizableProps=void 0;var t=n(e6());Y6();function n(e){return e&&e.__esModule?e:{default:e}}e.resizableProps={axis:t.default.oneOf([`both`,`x`,`y`,`none`]),className:t.default.string,children:t.default.element.isRequired,draggableOpts:t.default.shape({allowAnyClick:t.default.bool,cancel:t.default.string,children:t.default.node,disabled:t.default.bool,enableUserSelectHack:t.default.bool,offsetParent:typeof Element<`u`?t.default.instanceOf(Element):t.default.any,grid:t.default.arrayOf(t.default.number),handle:t.default.string,nodeRef:t.default.object,onStart:t.default.func,onDrag:t.default.func,onStop:t.default.func,onMouseDown:t.default.func,scale:t.default.number}),height:function(){var e=[...arguments];let n=e[0];return n.axis===`both`||n.axis===`y`?t.default.number.isRequired(...e):t.default.number(...e)},handle:t.default.oneOfType([t.default.node,t.default.func]),handleSize:t.default.arrayOf(t.default.number),lockAspectRatio:t.default.bool,maxConstraints:t.default.arrayOf(t.default.number),minConstraints:t.default.arrayOf(t.default.number),onResizeStop:t.default.func,onResizeStart:t.default.func,onResize:t.default.func,resizeHandles:t.default.arrayOf(t.default.oneOf([`s`,`w`,`e`,`n`,`sw`,`nw`,`se`,`ne`])),transformScale:t.default.number,width:function(){var e=[...arguments];let n=e[0];return n.axis===`both`||n.axis===`x`?t.default.number.isRequired(...e):t.default.number(...e)}}})),Q6=e((e=>{e.__esModule=!0,e.default=void 0;var n=s(t()),r=Y6(),i=X6(),a=Z6(),o=[`children`,`className`,`draggableOpts`,`width`,`height`,`handle`,`handleSize`,`lockAspectRatio`,`axis`,`minConstraints`,`maxConstraints`,`onResize`,`onResizeStop`,`onResizeStart`,`resizeHandles`,`transformScale`];function s(e,t){if(typeof WeakMap==`function`)var n=new WeakMap,r=new WeakMap;return(s=function(e,t){if(!t&&e&&e.__esModule)return e;var i,a,o={__proto__:null,default:e};if(e===null||typeof e!=`object`&&typeof e!=`function`)return o;if(i=t?r:n){if(i.has(e))return i.get(e);i.set(e,o)}for(let t in e)t!=="default"&&{}.hasOwnProperty.call(e,t)&&((a=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?i(o,t,a):o[t]=e[t]);return o})(e,t)}function c(){return c=Object.assign?Object.assign.bind():function(e){for(var t=1;tMath.abs(i*n)?t=e/n:e=t*n}let o=e,s=t,c=this.slack||[0,0],l=c[0],u=c[1];return e+=l,t+=u,r&&(e=Math.max(r[0],e),t=Math.max(r[1],t)),i&&(e=Math.min(i[0],e),t=Math.min(i[1],t)),this.slack=[l+(o-e),u+(s-t)],[e,t]}resizeHandler(e,t){return(n,r)=>{let i=r.node,a=r.deltaX,o=r.deltaY;e===`onResizeStart`&&this.resetData();let s=(this.props.axis===`both`||this.props.axis===`x`)&&t!==`n`&&t!==`s`,c=(this.props.axis===`both`||this.props.axis===`y`)&&t!==`e`&&t!==`w`;if(!s&&!c)return;let l=t[0],u=t[t.length-1],d=i.getBoundingClientRect();if(this.lastHandleRect!=null){if(u===`w`){let e=d.left-this.lastHandleRect.left;a+=e}if(l===`n`){let e=d.top-this.lastHandleRect.top;o+=e}}this.lastHandleRect=d,u===`w`&&(a=-a),l===`n`&&(o=-o);let f=this.lastSize?.width??this.props.width,p=this.lastSize?.height??this.props.height,m=f+(s?a/this.props.transformScale:0),h=p+(c?o/this.props.transformScale:0);var g=this.runConstraints(m,h);if(m=g[0],h=g[1],e===`onResizeStop`&&this.lastSize){var _=this.lastSize;m=_.width,h=_.height}let v=m!==f||h!==p;e!==`onResizeStop`&&(this.lastSize={width:m,height:h});let y=typeof this.props[e]==`function`?this.props[e]:null;y&&(e!==`onResize`||v)&&(n.persist==null||n.persist(),y(n,{node:i,size:{width:m,height:h},handle:t})),e===`onResizeStop`&&this.resetData()}}renderResizeHandle(e,t){let r=this.props.handle;if(!r)return n.createElement(`span`,{className:`react-resizable-handle react-resizable-handle-`+e,ref:t});if(typeof r==`function`)return r(e,t);let i=typeof r.type==`string`,a=d({ref:t},i?{}:{handleAxis:e});return n.cloneElement(r,a)}render(){let e=this.props,t=e.children,a=e.className,s=e.draggableOpts;e.width,e.height,e.handle,e.handleSize,e.lockAspectRatio,e.axis,e.minConstraints,e.maxConstraints,e.onResize,e.onResizeStop,e.onResizeStart;let u=e.resizeHandles;e.transformScale;let f=l(e,o);return(0,i.cloneElement)(t,d(d({},f),{},{className:(a?a+` `:``)+`react-resizable`,children:[...n.Children.toArray(t.props.children),...u.map(e=>{let t=this.handleRefs[e]??(this.handleRefs[e]=n.createRef());return n.createElement(r.DraggableCore,c({},s,{nodeRef:t,key:`resizableHandle-`+e,onStop:this.resizeHandler(`onResizeStop`,e),onStart:this.resizeHandler(`onResizeStart`,e),onDrag:this.resizeHandler(`onResize`,e)}),this.renderResizeHandle(e,t))})]}))}};e.default=h,h.propTypes=a.resizableProps,h.defaultProps={axis:`both`,handleSize:[20,20],lockAspectRatio:!1,minConstraints:[20,20],maxConstraints:[1/0,1/0],resizeHandles:[`se`],transformScale:1}})),$6=e((e=>{e.__esModule=!0,e.default=void 0;var n=c(t()),r=s(e6()),i=s(Q6()),a=Z6(),o=[`handle`,`handleSize`,`onResize`,`onResizeStart`,`onResizeStop`,`draggableOpts`,`minConstraints`,`maxConstraints`,`lockAspectRatio`,`axis`,`width`,`height`,`resizeHandles`,`style`,`transformScale`];function s(e){return e&&e.__esModule?e:{default:e}}function c(e,t){if(typeof WeakMap==`function`)var n=new WeakMap,r=new WeakMap;return(c=function(e,t){if(!t&&e&&e.__esModule)return e;var i,a,o={__proto__:null,default:e};if(e===null||typeof e!=`object`&&typeof e!=`function`)return o;if(i=t?r:n){if(i.has(e))return i.get(e);i.set(e,o)}for(let t in e)t!=="default"&&{}.hasOwnProperty.call(e,t)&&((a=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?i(o,t,a):o[t]=e[t]);return o})(e,t)}function l(){return l=Object.assign?Object.assign.bind():function(e){for(var t=1;t{let n=t.size;this.props.onResize?(e.persist==null||e.persist(),this.setState(n,()=>this.props.onResize&&this.props.onResize(e,t))):this.setState(n)}}static getDerivedStateFromProps(e,t){return t.propsWidth!==e.width||t.propsHeight!==e.height?{width:e.width,height:e.height,propsWidth:e.width,propsHeight:e.height}:null}render(){let e=this.props,t=e.handle,r=e.handleSize;e.onResize;let a=e.onResizeStart,s=e.onResizeStop,c=e.draggableOpts,u=e.minConstraints,f=e.maxConstraints,p=e.lockAspectRatio,m=e.axis;e.width,e.height;let g=e.resizeHandles,_=e.style,v=e.transformScale,y=h(e,o);return n.createElement(i.default,{axis:m,draggableOpts:c,handle:t,handleSize:r,height:this.state.height,lockAspectRatio:p,maxConstraints:f,minConstraints:u,onResizeStart:a,onResize:this.onResize,onResizeStop:s,resizeHandles:g,transformScale:v,width:this.state.width},n.createElement(`div`,l({},y,{style:d(d({},_),{},{width:this.state.width+`px`,height:this.state.height+`px`})})))}};e.default=g,g.propTypes=d(d({},a.resizableProps),{},{children:r.default.element})})),e8=e(((e,t)=>{t.exports=function(){throw Error(`Don't instantiate Resizable directly! Use require('react-resizable').Resizable`)},t.exports.Resizable=Q6().default,t.exports.ResizableBox=$6().default}))(),t8=Z3(),n8=50,r8=12;function i8(e){let t=e;for(;t;){let e=window.getComputedStyle(t).overflowY;if((e===`auto`||e===`scroll`)&&t.scrollHeight>t.clientHeight)return t;t=t.parentElement}return null}function a8(e){let t=i8(e),n=null,r=0,i=0,a=!1;function o(){let e=t;if(!e)return;let s=e.getBoundingClientRect(),{clientHeight:c,scrollTop:l,scrollHeight:u}=e,{scrollLeft:d,scrollWidth:f,clientWidth:p}=e,m=0,h=0;i0?m=-r8:i>s.bottom-n8&&l+c0?h=-r8:r>s.right-n8&&d+p({cols:n,containerPadding:a,containerWidth:r,margin:i,maxRows:s,rowHeight:o}),[n,a,r,i,s,o]),ye=(0,V.useMemo)(()=>({cols:n,maxRows:s,containerWidth:r,containerHeight:0,rowHeight:o,margin:i,layout:[]}),[n,s,r,o,i]),be=(0,V.useCallback)(e=>({...ye,containerHeight:e??ye.containerHeight,layout:fe.current}),[ye]),xe=(0,V.useMemo)(()=>I??{i:M,x:w,y:T,w:E,h:D,minW:O,maxW:k,minH:A,maxH:j},[I,M,w,T,E,D,O,k,A,j]),Se=(0,V.useCallback)(e=>{if(g?.calcStyle)return g.calcStyle(e);if(p)return v3(e);let t=y3(e);return m?{...t,left:b3(e.left/r),width:b3(e.width/r)}:t},[g,p,m,r]),Ce=(0,V.useCallback)((e,{node:t})=>{if(!ee)return;let{offsetParent:n}=t;if(!n)return;let r=n.getBoundingClientRect(),i=t.getBoundingClientRect(),a=i.left/h,o=r.left/h,s=i.top/h,c=r.top/h,l;if(g?.calcDragPosition){let t=e;l=g.calcDragPosition(t.clientX,t.clientY,t.clientX-i.left,t.clientY-i.top)}else l={left:a-o+n.scrollLeft,top:s-c+n.scrollTop};if(le.current=l,ve.current||=a8(t instanceof HTMLElement?t:null),v>0){let t=e;ge.current={x:t.clientX,y:t.clientY},he.current=!0,_e.current=!1,oe(!0);return}oe(!0);let u=Y4(B,l.top,l.left),{x:d,y:f}=g3(F,xe,u.x,u.y,be());ee(M,d,f,{e,node:t,newPosition:l})},[ee,h,B,g,v,F,xe,be,M]),we=(0,V.useCallback)((e,{node:t,deltaX:n,deltaY:a})=>{if(!te||!R)return;let s=e;if(he.current&&!_e.current){let n=s.clientX-ge.current.x,r=s.clientY-ge.current.y;if(Math.hypot(n,r){if(!ne||!R)return;ve.current?.stop(),ve.current=null;let n=he.current;if(he.current=!1,_e.current=!1,ge.current={x:0,y:0},n){oe(!1),le.current={left:0,top:0};return}let{left:r,top:i}=le.current,a={top:i,left:r};oe(!1),le.current={left:0,top:0};let o=Y4(B,i,r),{x:s,y:c}=g3(F,xe,o.x,o.y,be());ne(M,s,c,{e,node:t,newPosition:a})},[ne,R,B,F,xe,be,M]);pe.current=Ce,me.current=we;let Ee=(0,V.useCallback)((e,{node:t,size:n,handle:i},a,o)=>{let s=o===`onResizeStart`?re:o===`onResize`?ie:ae;if(!s)return;let c;c=t?A3(i,a,n,r):{...n,top:a.top,left:a.left},ue.current=c;let l=t?.offsetParent?.clientHeight??0,u=X4(B,c.width,c.height),{w:d,h:f}=_3(F,xe,u.w,u.h,i,be(l));s(M,d,f,{e:e.nativeEvent??e,node:t,size:c,handle:i})},[re,ie,ae,r,B,M,F,xe,be]),De=(0,V.useCallback)((e,t)=>{se(!0);let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResizeStart`)},[Ee,B,w,T,E,D]),Oe=(0,V.useCallback)((e,t)=>{let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResize`)},[Ee,B,w,T,E,D]),ke=(0,V.useCallback)((e,t)=>{se(!1),ue.current={top:0,left:0,width:0,height:0};let n=q4(B,w,T,E,D),r={...t,handle:t.handle};Ee(e,r,n,`onResizeStop`)},[Ee,B,w,T,E,D]);(0,V.useEffect)(()=>{if(!y)return;let e=ce.current;if(!e)return;let t=de.current||{left:0,top:0},n=R&&(y.left!==t.left||y.top!==t.top);if(!R){let t={node:e,deltaX:y.left,deltaY:y.top,lastX:0,lastY:0,x:y.left,y:y.top};pe.current?.(y.e,t)}else if(n){let t={node:e,deltaX:y.left-le.current.left,deltaY:y.top-le.current.top,lastX:le.current.left,lastY:le.current.top,x:y.left,y:y.top};me.current?.(y.e,t)}de.current=y},[y,R,M]);let Ae=q4(B,w,T,E,D,R?le.current:null,z?ue.current:null),je=V.Children.only(t),Me=G4(B),Ne=[K4(O,Me,i[0]),K4(A,o,i[1])],Pe=[K4(k,Me,i[0]),K4(j,o,i[1])],Fe=je.props,Ie=Fe.className,Le=Fe.style,Re=V.cloneElement(je,{ref:ce,className:_(`react-grid-item`,Ie,b,{static:f,resizing:z,"react-draggable":c,"react-draggable-dragging":R,dropping:!!y,cssTransforms:p}),style:{...x,...Le,...Se(Ae)}}),ze=P;return Re=(0,H.jsx)(e8.Resizable,{draggableOpts:{disabled:!l},className:l?void 0:`react-resizable-hide`,width:Ae.width,height:Ae.height,minConstraints:Ne,maxConstraints:Pe,onResizeStart:De,onResize:Oe,onResizeStop:ke,transformScale:h,resizeHandles:N,handle:ze,children:Re}),Re=(0,H.jsx)(G6,{disabled:!c,onStart:Ce,onDrag:we,onStop:Te,handle:S,cancel:`.react-resizable-handle`+(C?`,`+C:``),scale:h,allowMobileScroll:d,nodeRef:ce,children:Re}),Re}var s8=V.memo(o8,(e,t)=>e.x===t.x&&e.y===t.y&&e.w===t.w&&e.h===t.h&&e.minW===t.minW&&e.maxW===t.maxW&&e.minH===t.minH&&e.maxH===t.maxH&&e.cols===t.cols&&e.containerWidth===t.containerWidth&&e.rowHeight===t.rowHeight&&e.maxRows===t.maxRows&&e.margin===t.margin&&e.containerPadding===t.containerPadding&&e.transformScale===t.transformScale&&e.isDraggable===t.isDraggable&&e.isResizable===t.isResizable&&e.isBounded===t.isBounded&&e.allowMobileScroll===t.allowMobileScroll&&e.useCSSTransforms===t.useCSSTransforms&&e.usePercentages===t.usePercentages&&e.children===t.children&&e.onDrag===t.onDrag&&e.onDragStop===t.onDragStop&&e.onResize===t.onResize&&e.onResizeStop===t.onResizeStop&&e.droppingPosition===t.droppingPosition);s8.displayName=`GridItem`;function c8(e){let{clientX:t,clientY:n,gridElement:r,droppingItem:i,event:a,dragOffsetX:o=0,dragOffsetY:s=0,transformScale:c,cols:l,margin:u,maxRows:d,rowHeight:f,width:p,containerPadding:m}=e,h=r.getBoundingClientRect(),g={cols:l,margin:u,maxRows:d,rowHeight:f,containerWidth:p,containerPadding:m},_=G4(g),v=K4(i.w,_,u[0]),y=K4(i.h,f,u[1]),b=v/2,x=y/2,S=r.scrollLeft??0,C=r.scrollTop??0,w=t-h.left+S+o-b,T=n-h.top+C+s-x,E=Math.max(0,w),D=Math.max(0,T);return{newDroppingPosition:{left:E/c,top:D/c,e:a},calculatedXY:J4(g,D,E,i.w,i.h)}}var l8=()=>{},u8=`react-grid-layout`,d8=!1;try{d8=/firefox/i.test(navigator.userAgent)}catch{}function f8(e,t){let n=V.Children.toArray(e),r=V.Children.toArray(t);if(n.length!==r.length)return!1;for(let e=0;e{if(!V.isValidElement(t)||t.key===null)return;let n=String(t.key);a.add(n);let r=e.find(e=>e.i===n);if(r)i.push(s3(r));else{let e=t.props[`data-grid`];e?i.push({i:n,x:e.x??0,y:e.y??0,w:e.w??1,h:e.h??1,minW:e.minW,maxW:e.maxW,minH:e.minH,maxH:e.maxH,static:e.static,isDraggable:e.isDraggable,isResizable:e.isResizable,resizeHandles:e.resizeHandles,isBounded:e.isBounded}):i.push({i:n,x:0,y:i3(i),w:1,h:1})}});let o=d3(i,{cols:n});return r.compact(o,n)}function m8(e){let{children:t,width:n,gridConfig:r,dragConfig:i,resizeConfig:a,dropConfig:o,positionStrategy:s=j3,compactor:c,constraints:l=h3,layout:u=[],droppingItem:d,autoSize:f=!0,className:p=``,style:m={},innerRef:h,onLayoutChange:g=l8,onDragStart:v=l8,onDrag:y=l8,onDragStop:b=l8,onResizeStart:x=l8,onResize:S=l8,onResizeStop:C=l8,onDrop:w=l8,onDropDragOver:T=l8}=e,E=(0,V.useMemo)(()=>({...M3,...r}),[r]),D=(0,V.useMemo)(()=>({...N3,...i}),[i]),O=(0,V.useMemo)(()=>({...P3,...a}),[a]),k=(0,V.useMemo)(()=>({...F3,...o}),[o]),{cols:A,rowHeight:j,maxRows:M,margin:N,containerPadding:P}=E,{enabled:F,bounded:I,handle:L,cancel:ee,threshold:te,allowMobileScroll:ne}=D,{enabled:re,handles:ie,handleComponent:ae}=O,{enabled:R,defaultItem:oe,onDragOver:z,touchEnabled:se=!0,touchDragSource:ce=`[data-rgl-draggable]`}=k,le=c??G3(`vertical`),ue=le.type,de=le.allowOverlap,fe=le.preventCollision??!1,pe=(0,V.useMemo)(()=>d??{i:`__dropping-elem__`,...oe},[d,oe]),me=s.type===`transform`,he=s.scale,ge=P??N,[_e,ve]=(0,V.useState)(!1),[B,ye]=(0,V.useState)(()=>p8(u,t,A,le)),[be,xe]=(0,V.useState)(null),[Se,Ce]=(0,V.useState)(!1),[we,Te]=(0,V.useState)(null),[Ee,De]=(0,V.useState)(),Oe=(0,V.useRef)(void 0);Oe.current=Ee;let ke=(0,V.useRef)(null),Ae=(0,V.useRef)(null),je=(0,V.useRef)(null),Me=(0,V.useRef)(0),Ne=(0,V.useRef)(B),Pe=(0,V.useRef)(u),Fe=(0,V.useRef)(t),Ie=(0,V.useRef)(ue),Le=(0,V.useRef)(null),Re=(0,V.useRef)(!1),ze=(0,V.useRef)(null),Be=(0,V.useRef)(null);Be.current=we;let Ve=(0,V.useRef)(w);(0,V.useLayoutEffect)(()=>{Ve.current=w});let He=(0,V.useRef)(B);He.current=B,(0,V.useEffect)(()=>{ve(!0),(0,t8.deepEqual)(B,u)||g(B)},[]),(0,V.useEffect)(()=>{if(be||we)return;let e=!(0,t8.deepEqual)(u,Pe.current),n=!f8(t,Fe.current),r=ue!==Ie.current;if(e||n||r){let n=p8(e?u:B,t,A,le);(0,t8.deepEqual)(n,B)||ye(n)}Pe.current=u,Fe.current=t,Ie.current=ue},[u,t,A,ue,le,be,we,B]),(0,V.useEffect)(()=>{if(!be&&!we&&!(0,t8.deepEqual)(B,Ne.current)){Ne.current=B;let e=B.filter(e=>e.i!==pe.i);g(e)}},[B,be,we,g,pe.i]);let Ue=(0,V.useMemo)(()=>{if(!f)return;let e=i3(B),t=ge[1];return e*j+(e-1)*N[1]+t*2+`px`},[f,B,j,N,ge]),We=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=a3(i,e);if(!a)return;let o={w:a.w,h:a.h,x:a.x,y:a.y,i:e};ke.current=s3(a),je.current=i,xe(o),v(i,a,a,null,r.e,r.node)},[v]),Ge=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=ke.current,o=a3(i,e);if(!o)return;let s={w:o.w,h:o.h,x:o.x,y:o.y,i:e},c=f3(i,o,t,n,!0,fe,ue,A,de);y(c,a,o,s,r.e,r.node),ye(le.compact(c,A)),xe(s)},[fe,ue,A,de,le,y]),Ke=(0,V.useCallback)((e,t,n,r)=>{if(!ke.current)return;let i=He.current,a=ke.current,o=a3(i,e);if(!o)return;let s=f3(i,o,t,n,!0,fe,ue,A,de),c=le.compact(s,A);b(c,a,o,null,r.e,r.node);let l=je.current;ke.current=null,je.current=null,xe(null),ye(c),l&&!(0,t8.deepEqual)(l,c)&&g(c)},[fe,ue,A,de,le,b,g]),qe=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=a3(i,e);a&&(Ae.current=s3(a),je.current=i,Ce(!0),x(i,a,a,null,r.e,r.node))},[x]),Je=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=Ae.current,{handle:o}=r,s=!1,c,l,[u,d]=u3(i,e,e=>(c=e.x,l=e.y,[`sw`,`w`,`nw`,`n`,`ne`].includes(o)&&([`sw`,`nw`,`w`].includes(o)&&(c=e.x+(e.w-t),t=e.x!==c&&c<0?e.w:t,c=c<0?0:c),[`ne`,`n`,`nw`].includes(o)&&(l=e.y+(e.h-n),n=e.y!==l&&l<0?e.h:n,l=l<0?0:l),s=!0),fe&&!de&&e3(i,{...e,w:t,h:n,x:c??e.x,y:l??e.y}).filter(t=>t.i!==e.i).length>0&&(l=e.y,n=e.h,c=e.x,t=e.w,s=!1),e.w=t,e.h=n,(o===`n`||o===`nw`||o===`ne`)&&(e.y=l??e.y),e));if(!d)return;let f=u;s&&c!==void 0&&l!==void 0&&(f=f3(u,d,c,l,!0,fe,ue,A,de));let p={w:d.w,h:d.h,x:d.x,y:d.y,i:e,static:!0};S(f,a,d,p,r.e,r.node);let m=le.compact(f,A);if(o===`n`||o===`nw`||o===`ne`){let t=m.find(t=>t.i===e);t&&(t.y=d.y)}ye(m),xe(p)},[fe,ue,A,de,le,S]),Ye=(0,V.useCallback)((e,t,n,r)=>{let i=He.current,a=Ae.current,o=a3(i,e),s=le.compact(i,A);C(s,a,o??null,null,r.e,r.node);let c=je.current;Ae.current=null,je.current=null,xe(null),Ce(!1),ye(s),c&&!(0,t8.deepEqual)(c,s)&&g(s)},[A,le,C,g]),Xe=(0,V.useCallback)((e,t,n,r)=>{if(r)Oe.current&&(Oe.current.left!==t.left||Oe.current.top!==t.top)&&(De(t),ye(t=>t.map(t=>t.i===e.i&&(t.x!==n.x||t.y!==n.y)?{...t,x:n.x,y:n.y}:t)));else{Te((0,H.jsx)(`div`,{},e.i)),De(t);let r=He.current.filter(t=>t.i!==e.i);ye([...r,{...e,x:n.x,y:n.y,static:!1,isDraggable:!0}])}},[]),Ze=(0,V.useCallback)((e,t,r)=>{let i=Le.current;if(!i)return;let{newDroppingPosition:a,calculatedXY:o}=c8({clientX:e,clientY:t,gridElement:i,droppingItem:pe,event:r,transformScale:he,cols:A,margin:N,maxRows:M,rowHeight:j,width:n,containerPadding:ge});Xe(pe,a,o,!!Be.current)},[pe,he,A,N,M,j,n,ge,Xe]),Qe=(0,V.useCallback)(()=>{let e=He.current;if(!e.some(e=>e.i===pe.i)){Te(null),xe(null),De(void 0);return}let t=le.compact(e.filter(e=>e.i!==pe.i),A);ye(t),Te(null),xe(null),De(void 0)},[pe.i,A,le]),$e=(0,V.useCallback)(e=>{if(e.preventDefault(),e.stopPropagation(),d8&&!e.nativeEvent.target?.classList.contains(u8))return!1;let t=z?z(e.nativeEvent):T(e);if(t===!1)return we&&Qe(),!1;let{dragOffsetX:r=0,dragOffsetY:i=0,...a}=t??{},o={...pe,...a},{newDroppingPosition:s,calculatedXY:c}=c8({clientX:e.clientX,clientY:e.clientY,gridElement:e.currentTarget,droppingItem:o,event:e.nativeEvent,dragOffsetX:r,dragOffsetY:i,transformScale:he,cols:A,margin:N,maxRows:M,rowHeight:j,width:n,containerPadding:ge});Xe(o,s,c,!!we)},[we,pe,z,T,Qe,Xe,he,A,N,M,j,n,ge]),et=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current--,Me.current<0&&(Me.current=0),Me.current===0&&Qe()},[Qe]),tt=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current++},[]),nt=(0,V.useCallback)(e=>{let t=He.current,n=t.find(e=>e.i===pe.i);Qe(),Ve.current(t,n,e)},[pe.i,Qe]),rt=(0,V.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),Me.current=0,nt(e.nativeEvent)},[nt]);(0,V.useEffect)(()=>{if(!R||!se)return;let e=Le.current;if(!e)return;let t=(t,n)=>{let r=document.elementFromPoint(t,n);return r?e.contains(r):!1},n=e=>e instanceof HTMLElement&&e.closest(ce)!==null,r=e=>{let t=e.changedTouches;if(!t||t.length===0)return;let n=ze.current;if(n===null)return t[0];for(let e=0;e{if(!n(e.target)||ze.current!==null)return;e.preventDefault();let t=e.changedTouches?.[0];t&&(ze.current=t.identifier,Re.current=!0)},a=e=>{if(!Re.current)return;e.preventDefault();let n=r(e);if(n){if(!t(n.clientX,n.clientY)){Be.current&&Qe();return}Ze(n.clientX,n.clientY,e)}},o=e=>{if(!Re.current)return;e.preventDefault();let n=r(e);if(Re.current=!1,ze.current=null,n){if(!t(n.clientX,n.clientY)){Qe();return}nt(e)}},s=()=>{Re.current&&(Re.current=!1,ze.current=null,Qe())},c={passive:!1};return document.addEventListener(`touchstart`,i,c),document.addEventListener(`touchmove`,a,c),document.addEventListener(`touchend`,o,c),document.addEventListener(`touchcancel`,s,c),()=>{document.removeEventListener(`touchstart`,i,c),document.removeEventListener(`touchmove`,a,c),document.removeEventListener(`touchend`,o,c),document.removeEventListener(`touchcancel`,s,c)}},[R,se,ce,Ze,Qe,nt,pe.i]);let it=(0,V.useCallback)((e,t)=>{if(!e||!e.key)return null;let r=a3(B,String(e.key));if(!r)return null;let i=typeof r.isDraggable==`boolean`?r.isDraggable:!r.static&&F,a=typeof r.isResizable==`boolean`?r.isResizable:!r.static&&re,o=r.resizeHandles||[...ie],c=i&&I&&r.isBounded!==!1,u=ae;return(0,H.jsx)(s8,{containerWidth:n,cols:A,margin:N,containerPadding:ge,maxRows:M,rowHeight:j,cancel:ee,handle:L,onDragStart:We,onDrag:Ge,onDragStop:Ke,onResizeStart:qe,onResize:Je,onResizeStop:Ye,isDraggable:i,isResizable:a,isBounded:c,allowMobileScroll:ne,useCSSTransforms:me&&_e,usePercentages:!_e,transformScale:he,positionStrategy:s,dragThreshold:te,w:r.w,h:r.h,x:r.x,y:r.y,i:r.i,minH:r.minH,minW:r.minW,maxH:r.maxH,maxW:r.maxW,static:r.static,droppingPosition:t?Ee:void 0,resizeHandles:o,resizeHandle:u,constraints:l,layoutItem:r,layout:B,children:e},r.i)},[B,n,A,N,ge,M,j,ee,L,We,Ge,Ke,qe,Je,Ye,F,re,I,me,_e,he,s,te,Ee,ie,ae,l]),at=()=>be?(0,H.jsx)(s8,{w:be.w,h:be.h,x:be.x,y:be.y,i:be.i,className:`react-grid-placeholder ${Se?`placeholder-resizing`:``}`,containerWidth:n,cols:A,margin:N,containerPadding:ge,maxRows:M,rowHeight:j,isDraggable:!1,isResizable:!1,isBounded:!1,useCSSTransforms:me,transformScale:he,constraints:l,layout:B,children:(0,H.jsx)(`div`,{})}):null,ot=(0,V.useCallback)(e=>{Le.current=e,typeof h==`function`?h(e):h&&`current`in h&&(h.current=e)},[h]),st=_(u8,p),ct={height:Ue,...m};return(0,H.jsxs)(`div`,{ref:ot,className:st,style:ct,onDrop:R?rt:void 0,onDragLeave:R?et:void 0,onDragEnter:R?tt:void 0,onDragOver:R?$e:void 0,children:[V.Children.map(t,e=>V.isValidElement(e)?it(e):null),R&&we&&it(we,!0),at()]})}var h8={lg:1200,md:996,sm:768,xs:480,xxs:0},g8={lg:12,md:10,sm:6,xs:4,xxs:2},_8=()=>{};function v8(e,t,n,r,i=!1){let a=[];V.Children.forEach(t,t=>{if(!V.isValidElement(t)||t.key===null)return;let n=String(t.key),r=t.props[`data-grid`],o=e.find(e=>e.i===n);o?i&&r?a.push({...o,i:n,w:r.w??o.w,h:r.h??o.h,minW:r.minW??o.minW,maxW:r.maxW??o.maxW,minH:r.minH??o.minH,maxH:r.maxH??o.maxH}):a.push({...o,i:n}):r?a.push({i:n,x:r.x??0,y:r.y??0,w:r.w??1,h:r.h??1,minW:r.minW,maxW:r.maxW,minH:r.minH,maxH:r.maxH,static:r.static,isDraggable:r.isDraggable,isResizable:r.isResizable,resizeHandles:r.resizeHandles,isBounded:r.isBounded}):a.push({i:n,x:0,y:i3(a),w:1,h:1})});let o=d3(a,{cols:n});return r.compact(o,n)}function y8(e){let{children:t,width:n,breakpoint:r,breakpoints:i=h8,cols:a=g8,layouts:o={},rowHeight:s=150,maxRows:c=1/0,margin:l=[10,10],containerPadding:u=null,compactor:d,onBreakpointChange:f=_8,onLayoutChange:p=_8,onWidthChange:m=_8,...h}=e,g=d??G3(`vertical`),_=g.type,v=g.allowOverlap,y=(0,V.useMemo)(()=>r??q3(i,n),[]),b=(0,V.useMemo)(()=>J3(y,a),[y,a]),x=(0,V.useMemo)(()=>Y3(o,i,y,y,b,_),[]),[S,C]=(0,V.useState)(y),[w,T]=(0,V.useState)(b),[E,D]=(0,V.useState)(x),[O,k]=(0,V.useState)(o),A=(0,V.useRef)(n),j=(0,V.useRef)(r),M=(0,V.useRef)(i),N=(0,V.useRef)(a),P=(0,V.useRef)(o),F=(0,V.useRef)(_),I=(0,V.useRef)(O);(0,V.useEffect)(()=>{I.current=O},[O]);let L=(0,V.useMemo)(()=>(0,t8.deepEqual)(o,P.current)?null:Y3(o,i,S,S,w,g),[o,i,S,w,g]),ee=L??E;(0,V.useEffect)(()=>{L!==null&&(D(L),k(o),I.current=o,P.current=o)},[L,o]),(0,V.useEffect)(()=>{if(_!==F.current){let e=g.compact(c3(ee),w),t={...I.current,[S]:e};D(e),k(t),I.current=t,p(e,t),F.current=_}},[_,g,ee,w,v,S,p]),(0,V.useEffect)(()=>{let e=n!==A.current,o=r!==j.current,s=!(0,t8.deepEqual)(i,M.current),c=!(0,t8.deepEqual)(a,N.current);if(e||o||s||c){let e=r??q3(i,n),o=J3(e,a),d=S;if(d!==e||s||c){let n={...I.current};n[d]||(n[d]=c3(E));let r=Y3(n,i,e,d,o,g),a=!n[e];r=v8(r,t,o,g,a),n[e]=r,C(e),T(o),D(r),k(n),I.current=n,f(e,o),p(r,n)}let h=X3(l,e),_=u?X3(u,e):null;m(n,h,o,_),A.current=n,j.current=r,M.current=i,N.current=a}},[n,r,i,a,S,w,E,t,g,_,v,l,u,f,p,m]);let te=(0,V.useCallback)(e=>{let t={...I.current,[S]:e};D(e),k(t),I.current=t,p(e,t)},[S,p]),ne=(0,V.useMemo)(()=>X3(l,S),[l,S]),re=(0,V.useMemo)(()=>u===null?null:X3(u,S),[u,S]),ie=(0,V.useMemo)(()=>({cols:w,rowHeight:s,maxRows:c,margin:ne,containerPadding:re}),[w,s,c,ne,re]);return(0,H.jsx)(m8,{...h,width:n,gridConfig:ie,compactor:g,onLayoutChange:te,layout:ee,children:t})}var b8=V.forwardRef(function(e,t){let{innerRef:n,...r}=e,i=n??t;return(0,H.jsx)(y8,{...r,innerRef:i})});b8.displayName=`ResponsiveGridLayout`;function x8(e,t,n,r){let i=e=>t?.frame?.columns.some((n,r)=>n.name===e&&t.frame.values[r]?.some(e=>typeof e==`string`&&e!==``));return{onSelect:e.click&&(e.viz===`service_map`||!(e.drill&&r))?t=>n(e.click.set_variable,t):void 0,onPoint:r&&(e.viz===`service_map`||e.click||e.drill||i(`trace_id`)||e.options?.columns?.some(e=>e.format===`trace_link`&&i(e.field)))?r:void 0}}function S8(e,t,n,r){if(!t)return;let i=ot(e,t,n);if(!i)return;let a=Object.values(n.dimensions)[0],o=e.click?.set_variable;return{target:i,vars:o&&a!==void 0?{...r,[o]:a}:r}}function C8(e){return`Explain the panel “${e.title}”`}function w8(e){return`Fix the panel “${e.title}”`}function T8(e){return[{description:`Observed panel diagnostics`,value:JSON.stringify(e)}]}var E8=e=>e*40+(e-1)*12,D8={s:3,m:6,l:10},O8={stat:4},k8=e=>Math.max(O8[e.viz]??0,D8[e.height??(e.viz===`service_map`?`l`:e.viz===`stat`?`s`:`m`)]),A8=(0,V.lazy)(()=>ce(()=>import(`./panel-sql-editor-Cx5hjHge.js`),__vite__mapDeps([0,1,2,3,4,5,6,7]))),j8=0;function M8(e){let t;do t=`p_${Date.now().toString(36)}_${(++j8).toString(36)}_${Math.random().toString(36).slice(2,10)}`;while(e.some(e=>e.id===t));return t}function N8({dashboardId:e,version:t,spec:n,vars:r,results:i,fetching:a,annotations:o,fetchingIds:s=[],staleAt:c=new Map,time:l=n.time,onEditExit:u,editing:d,view:f,agentAvailable:p,canManage:m=!1,onOpenChat:h,onVariable:g,onRetry:_,onPoint:v,onZoom:b,onZoomReset:x,zoomed:S,onView:w,onVisible:E,onRangePending:D,shortcutScope:O,onShortcuts:k,overlayOpen:A,returnViewFocus:j}){let M=ct(),[N,P]=(0,V.useState)(),[F,I]=(0,V.useState)(()=>n.panels.map(e=>({i:e.id,x:e.grid?.x??0,y:e.grid?.y??0,w:e.grid?.w??6,h:e.grid?.h??k8(e)})));(0,V.useEffect)(()=>{I(n.panels.map(e=>({i:e.id,x:e.grid?.x??0,y:e.grid?.y??0,w:e.grid?.w??6,h:e.grid?.h??k8(e)})))},[n]);let[L,te]=(0,V.useState)(()=>window.innerHeight),[ne,re]=(0,V.useState)();(0,V.useEffect)(()=>{let e=()=>te(window.innerHeight);return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]);let ie=(0,V.useRef)(null),ae=(0,V.useRef)(new Map),R=(0,V.useRef)(null),oe=(0,V.useRef)(null),z=()=>{let e=N?.panel.id;P(void 0),requestAnimationFrame(()=>(oe.current?.isConnected?oe.current:ae.current.get(e??``))?.focus())},ce=(0,V.useRef)(f);f&&(ce.current=f);let[le,ue]=(0,V.useState)(0),de=le>0,fe=d&&(le>=1100?`lg`:le>=800?`md`:`sm`)==`lg`;(0,V.useLayoutEffect)(()=>{if(!ie.current)return;ue(Math.max(0,Math.round(ie.current.getBoundingClientRect().width)));let e=new ResizeObserver(([e])=>{e&&ue(Math.max(0,Math.round(e.contentRect.width)))});return e.observe(ie.current),()=>e.disconnect()},[]);let pe=(0,V.useRef)(E);pe.current=E,(0,V.useEffect)(()=>{if(!de||!ie.current||typeof IntersectionObserver>`u`)return;let e=new Set(n.panels.map(e=>e.id)),t=new IntersectionObserver(t=>{for(let n of t){let t=n.target.dataset.panel;t&&(n.isIntersecting?e.add(t):e.delete(t))}f&&n.panels.some(e=>e.id===f)&&e.add(f),pe.current([...e])},{rootMargin:`200px`});return ie.current.querySelectorAll(`.react-grid-item[data-panel]`).forEach(e=>t.observe(e)),()=>t.disconnect()},[n,f,de]);let me=(0,V.useMemo)(()=>n.panels.some(e=>{let t=F.find(t=>t.i===e.id);return t&&(t.x!==e.grid?.x||t.y!==e.grid?.y||t.w!==e.grid?.w||t.h!==e.grid?.h)}),[F,n]),he=e=>({...n,panels:e.map(e=>{let t=F.find(t=>t.i===e.id);return t?{...e,grid:{x:t.x,y:t.y,w:t.w,h:t.h}}:e})}),ge=Te({mutationFn:()=>Ke(e,he(n.panels),t,`Edited layout`),onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}}),_e=Te({mutationFn:r=>me?Ke(e,he(n.panels.filter(e=>e.id!==r)),t,`Removed a panel and saved layout`):Ae(e,[{op:`remove_panel`,id:r}],t,`Removed a panel`),onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}}),ve=Te({mutationFn:r=>{let i={...r,id:M8(n.panels),title:`${Array.from(r.title).slice(0,73).join(``)} (copy)`,grid:void 0};if(me){let a=[...n.panels];return a.splice(a.findIndex(e=>e.id===r.id)+1,0,i),Ke(e,he(a),t,`Duplicated a panel and saved layout`)}return Ae(e,[{op:`add_panel`,after:r.id,panel:i}],t,`Duplicated a panel`)},onSuccess:t=>{M.setQueryData([`dashboard`,e],t)}});(0,V.useEffect)(()=>{d||(ge.reset(),_e.reset(),ve.reset())},[d]);let B=()=>{ge.reset(),_e.reset(),ve.reset(),u?.(),M.invalidateQueries({queryKey:[`dashboard`,e]})},ye=async e=>{let t=new URL(window.location.href);t.searchParams.set(`view`,e),t.searchParams.delete(`edit`);try{await navigator.clipboard.writeText(t.toString()),re(`Link copied`)}catch{re(`Copy this URL: ${t.toString()}`)}},be=`dashboard-${e}`,xe=n=>({dashboard_id:e,version:t,panel_id:n.id,title:Yi(n.title,r),from_ms:i.get(n.id)?.from_ms,to_ms:i.get(n.id)?.to_ms,vars:r,error:i.get(n.id)?.error,status:i.get(n.id)?.status,diagnosis:i.get(n.id)?.diagnosis,stale_since:c.get(n.id),truncated:i.has(n.id)?!!(i.get(n.id)?.frame?.truncated||i.get(n.id)?.previous?.truncated):void 0,note:i.get(n.id)?.frame?.note,spec:{...n,dashboard_time:l}}),Se=(u,d,y=!1)=>(0,H.jsx)(V4,{panel:u,title:Yi(u.title,r),result:i.get(u.id),loading:a&&s.includes(u.id),height:d,group:be,editing:fe&&!y,agentAvailable:p,suspended:!y&&u.id===f,menuRef:y?R:e=>{e?ae.current.set(u.id,e):ae.current.delete(u.id)},compare:l.compare===`previous_period`,range:u.time?.range??l.range,annotations:o,vars:r,onVariable:g,...x8(u,i.get(u.id),g,v?e=>v(u,e):void 0),onRangePending:e=>D?.(u.id,e),onZoom:b,zoomed:S,onZoomReset:x,onRetry:_?()=>_(u.id):void 0,onView:()=>w(u.id),onCopyLink:()=>{ye(u.id)},onEditSQL:m&&typeof u.sql==`string`?()=>{oe.current=y?R.current:ae.current.get(u.id)??null,P({panel:u,spec:n,version:t})}:void 0,onExplain:p&&e?()=>h(C8(xe(u)),{answer_only:!0,context:T8(xe(u))}):void 0,onFix:p&&e&&m?()=>h(w8(xe(u)),{context:T8(xe(u))}):void 0,staleAt:c.get(u.id),onDuplicate:fe&&!y?()=>ve.mutate(u):void 0,onRemove:fe&&!y?()=>_e.mutate(u.id):void 0}),Ce=n.panels.find(e=>e.id===f),we=d?ge.error??_e.error??ve.error:null,Ee=we instanceof $e&&we.code===`dashboard_version_conflict`,De=e=>{fe&&I(e.map(({i:e,x:t,y:n,w:r,h:i})=>({i:e,x:t,y:n,w:r,h:i})))};return(0,H.jsxs)(`div`,{ref:ie,style:{minWidth:0},children:[d&&(0,H.jsxs)(y,{justify:`space-between`,mb:`sm`,p:`xs`,style:{border:`1px dashed var(--mantine-color-default-border)`,borderRadius:8},children:[(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:fe?`Drag a panel by its title and resize it from the corner. Changes are saved as a new version.`:`The layout can be edited only on a wider screen.`}),(0,H.jsx)(C,{size:`compact-sm`,disabled:!me||!fe,loading:ge.isPending,onClick:()=>ge.mutate(),children:`Save layout`})]}),Ee&&(0,H.jsxs)(ee,{color:`warn`,mb:`sm`,children:[`Someone saved this dashboard since you opened it. Load the latest version, then redo your change. `,(0,H.jsx)(C,{size:`compact-sm`,onClick:B,children:`Load latest`})]}),we&&!Ee&&(0,H.jsx)(ee,{color:`bad`,mb:`sm`,children:we.message}),ne&&(0,H.jsx)(ee,{role:`status`,mb:`sm`,children:ne}),!de&&(0,H.jsx)(`div`,{"data-grid-placeholder":!0,style:{height:E8(Math.max(1,...F.map(e=>e.y+e.h)))}}),de&&(0,H.jsx)(b8,{width:le,className:`dashboard-grid${fe?` dashboard-grid-editing`:``}`,layouts:{lg:F,md:F,sm:F.map(e=>({...e,x:0,w:12}))},breakpoints:{lg:1100,md:800,sm:0},cols:{lg:12,md:12,sm:12},rowHeight:40,margin:[12,12],containerPadding:[0,0],compactor:z3,dragConfig:{enabled:fe,handle:`.panel-drag`,cancel:`button`},resizeConfig:{enabled:fe},onDragStop:De,onResizeStop:De,children:n.panels.map(e=>{let t=F.find(t=>t.i===e.id);return(0,H.jsx)(`div`,{"data-panel":e.id,children:Se(e,E8(t?.h??6))},e.id)})}),(0,H.jsx)(B4,{shortcutScope:O,onShortcuts:k,escapeEnabled:!A&&!N,opened:!!f,onClose:()=>w(void 0),title:Ce?Yi(Ce.title,r):`Missing panel`,returnFocusTo:()=>j?.(ce.current)??ae.current.get(ce.current??``)??ae.current.values().next().value,children:Ce?(0,H.jsx)(`div`,{style:{height:`calc(100vh - 120px)`},children:Se(Ce,Math.max(40,L-140),!0)}):(0,H.jsx)(ee,{color:`warn`,children:`This panel is missing from the dashboard. The shared link may be out of date.`})}),N&&(0,H.jsx)(V.Suspense,{fallback:(0,H.jsx)(Ze,{opened:!0,onClose:z,title:`Loading SQL editor`,children:(0,H.jsx)(se,{size:`sm`,"aria-label":`Loading SQL editor`})}),children:(0,H.jsx)(A8,{dashboardId:e,version:N.version,spec:N.spec,panel:N.panel,time:l,vars:r,onClose:z})})]})}function P8(e,t=1,n=8){let r=(t-1)*n;return e.slice(r,r+n)}function F8({icon:e,title:t,children:n,tall:r=!1}){return(0,H.jsx)(ae,{mih:r?220:130,p:`xl`,children:(0,H.jsxs)(y,{wrap:`nowrap`,children:[(0,H.jsx)(ne,{variant:`light`,size:`xl`,radius:`md`,children:e}),(0,H.jsxs)(o,{children:[(0,H.jsx)(T,{fw:700,size:`sm`,children:t}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,mt:3,children:n})]})]})})}function I8(e,t=8){let[n,r]=(0,V.useState)(1),i=Math.max(1,Math.ceil(e.length/t));(0,V.useEffect)(()=>{n>i&&r(i)},[n,i]);let a=(n-1)*t;return{page:n,setPage:r,totalPages:i,pageItems:P8(e,n,t),from:e.length?a+1:0,to:Math.min(a+t,e.length),total:e.length}}function L8({page:e,totalPages:t,from:n,to:r,total:i,onChange:a}){return t<=1?null:(0,H.jsxs)(y,{justify:`space-between`,mt:`xs`,children:[(0,H.jsxs)(T,{c:`dimmed`,size:`xs`,children:[n,`–`,r,` of `,i]}),(0,H.jsx)(y,{gap:4,children:[{label:`First page`,page:1,disabled:e===1},{label:`Previous page`,page:e-1,disabled:e===1},{label:`Next page`,page:e+1,disabled:e===t},{label:`Last page`,page:t,disabled:e===t}].map(e=>(0,H.jsx)(C,{size:`compact-xs`,variant:`subtle`,"aria-label":e.label,disabled:e.disabled,onClick:()=>a(e.page),children:e.label},e.label))})]})}function R8({spans:e,dark:t,onSpan:n}){let r=Math.min(...e.map(e=>new Date(e.start).valueOf())),i=Math.max(...e.map(e=>new Date(e.start).valueOf()+e.duration_ms)),a=Math.max(i-r,1),s=[...new Set(e.map(e=>e.service))],c=I8(e);return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(B.ScrollContainer,{minWidth:680,children:(0,H.jsxs)(B,{highlightOnHover:!!n,verticalSpacing:`sm`,children:[(0,H.jsx)(B.Thead,{children:(0,H.jsxs)(B.Tr,{children:[(0,H.jsx)(B.Th,{w:230,children:`Operation`}),(0,H.jsx)(B.Th,{children:`Timeline`}),(0,H.jsx)(B.Th,{w:90,ta:`right`,children:`Duration`})]})}),(0,H.jsx)(B.Tbody,{children:c.pageItems.map(e=>{let i=(new Date(e.start).valueOf()-r)/a*100,c=Math.max(e.duration_ms/a*100,.6),l=e.status===`STATUS_CODE_ERROR`;return(0,H.jsxs)(B.Tr,{tabIndex:n?0:void 0,onClick:n?()=>n(e):void 0,onKeyDown:n?t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),n(e))}:void 0,style:{cursor:n?`pointer`:void 0},children:[(0,H.jsx)(B.Td,{children:(0,H.jsxs)(y,{gap:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(o,{w:8,h:8,bg:Ua(s.indexOf(e.service),t),style:{borderRadius:`50%`,flex:`0 0 auto`}}),(0,H.jsxs)(o,{miw:0,children:[(0,H.jsx)(T,{fw:600,size:`sm`,truncate:!0,children:e.operation}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,truncate:!0,children:e.service})]})]})}),(0,H.jsx)(B.Td,{children:(0,H.jsx)(pe,{label:`${e.service} · ${e.operation} · ${ve(e.duration_ms)}`,withArrow:!0,children:(0,H.jsx)(o,{pos:`relative`,h:14,bg:`var(--mantine-color-default-hover)`,role:`img`,"aria-label":`${e.operation} on ${e.service} took ${ve(e.duration_ms)}`,style:{borderRadius:`var(--mantine-radius-sm)`},children:(0,H.jsx)(o,{pos:`absolute`,left:`${i}%`,w:`${Math.min(c,100-i)}%`,h:`100%`,bg:l?`bad`:Ua(s.indexOf(e.service),t),style:{borderRadius:`var(--mantine-radius-sm)`,minWidth:3}})})})}),(0,H.jsx)(B.Td,{ta:`right`,children:(0,H.jsx)(T,{size:`sm`,ff:`monospace`,children:ve(e.duration_ms)})})]},e.span_id)})})]})}),(0,H.jsx)(L8,{...c,onChange:c.setPage})]})}function z8({result:e,dark:t,onSpan:n}){let[r,i]=(0,V.useState)(`waterfall`),a=e.data,s=(0,V.useMemo)(()=>({id:`correlated_logs`,status:a.logs.length?`ok`:`empty`,elapsed_ms:0,frame:{columns:[{name:`time`,type:`time`,role:`time`},...[`severity`,`service`,`body`].map(e=>({name:e,type:`string`,role:`dimension`}))],rows:a.logs.length,values:[a.logs.map(e=>Date.parse(e.time)),a.logs.map(e=>e.severity),a.logs.map(e=>e.service),a.logs.map(e=>e.body)]}}),[a.logs]);return(0,H.jsxs)(S,{gap:`sm`,children:[(0,H.jsxs)(y,{children:[(0,H.jsx)(T,{fw:600,children:a.trace_id}),(0,H.jsx)(T,{c:a.has_error?`bad`:`dimmed`,children:a.has_error?`■ Error`:`● OK`})]}),a.spans.length>0?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsxs)(y,{role:`group`,"aria-label":`Trace view`,children:[(0,H.jsx)(C,{"aria-pressed":r===`waterfall`,variant:r===`waterfall`?`light`:`subtle`,onClick:()=>i(`waterfall`),children:`Waterfall`}),(0,H.jsx)(C,{"aria-pressed":r===`flame`,variant:r===`flame`?`light`:`subtle`,onClick:()=>i(`flame`),children:`Flame graph`})]}),r===`waterfall`?(0,H.jsx)(R8,{spans:a.spans,dark:t,onSpan:n}):(0,H.jsx)(B8,{spans:a.spans,dark:t,onSpan:n})]}):(0,H.jsx)(T,{c:`dimmed`,children:`No spans were found for this trace.`}),(0,H.jsx)(T,{fw:600,children:`Correlated logs`}),a.logs.length?(0,H.jsx)(o,{style:{overflow:`auto`,minWidth:0},children:(0,H.jsx)(P4,{foldConstants:!1,panel:{id:`correlated_logs`,title:`Correlated logs`,viz:`logs`},result:s,dark:t,height:320})}):(0,H.jsx)(F8,{tall:!0,icon:(0,H.jsx)(zi,{size:20,weight:`duotone`}),title:`No correlated logs`,children:`No logs in this window carry the selected trace ID.`}),a.truncated&&(0,H.jsxs)(ee,{color:`warn`,children:[`This trace is truncated: `,a.spans.length,` of `,a.span_count,` spans, `,a.services.length,` of `,a.service_count,` services.`]})]})}function B8({spans:e,dark:t,onSpan:n}){let r=(0,V.useMemo)(()=>V8(e),[e]),i=[...new Set(e.map(e=>e.service))];return(0,H.jsxs)(S,{px:{base:`md`,sm:`lg`},pb:`md`,gap:`xs`,children:[(0,H.jsxs)(y,{justify:`space-between`,children:[(0,H.jsx)(y,{gap:`md`,children:i.map(e=>(0,H.jsxs)(y,{gap:5,children:[(0,H.jsx)(o,{w:8,h:8,bg:Ua(i.indexOf(e),t),style:{borderRadius:`50%`}}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,children:e})]},e))}),(0,H.jsx)(He,{variant:`light`,children:ve(r.total)})]}),(0,H.jsx)(z,{withBorder:!0,radius:`md`,p:`sm`,children:(0,H.jsx)(fe,{type:`auto`,offsetScrollbars:!0,children:(0,H.jsxs)(o,{miw:760,children:[(0,H.jsx)(o,{pos:`relative`,h:22,mb:4,children:[0,25,50,75,100].map(e=>(0,H.jsx)(T,{pos:`absolute`,left:`${e}%`,c:`dimmed`,size:`xs`,style:{transform:e===100?`translateX(-100%)`:e?`translateX(-50%)`:void 0},children:ve(r.total*e/100)},e))}),(0,H.jsxs)(o,{pos:`relative`,h:Math.max(150,r.laneCount*36+12),bg:`var(--mantine-color-default-hover)`,style:{overflow:`hidden`,borderRadius:`var(--mantine-radius-md)`},children:[[0,25,50,75,100].map(e=>(0,H.jsx)(o,{pos:`absolute`,left:`${e}%`,top:0,bottom:0,style:{borderLeft:`1px solid var(--mantine-color-default-border)`}},e)),r.frames.map(({span:e,lane:r,left:a,width:s})=>{let c=e.status===`STATUS_CODE_ERROR`,l=s<7,u=c?Ha(t).bad:Ua(i.indexOf(e.service),t),d=`${e.operation} · ${ve(e.duration_ms)} · ${e.service}`,f=(0,H.jsxs)(T,{component:`span`,size:`xs`,fw:700,truncate:!0,children:[l?``:e.operation,s>=12?` · ${ve(e.duration_ms)}`:``]}),p={position:`absolute`,left:`${a}%`,top:r*36+6,width:`${Math.max(s,.35)}%`,height:30,overflow:`hidden`,minWidth:3};return(0,H.jsx)(pe,{label:`${e.service} · ${e.operation} · ${ve(e.duration_ms)}`,withArrow:!0,events:{hover:!0,focus:!0,touch:!1},children:n?(0,H.jsx)(C,{variant:`filled`,color:u,"aria-label":d,px:l?2:`xs`,size:`compact-xs`,onClick:()=>n(e),style:p,children:f}):(0,H.jsx)(o,{role:`img`,tabIndex:0,"aria-label":d,style:{...p,display:`flex`,alignItems:`center`,paddingInline:l?2:8,borderRadius:`var(--mantine-radius-sm)`,background:u,color:Ot(u)},children:f})},e.span_id)})]})]})})}),(0,H.jsx)(T,{c:`dimmed`,size:`xs`,children:`Width represents wall-clock duration; lanes preserve span hierarchy without overlap.`})]})}function V8(e){let t=Math.min(...e.map(e=>new Date(e.start).valueOf())),n=Math.max(...e.map(e=>new Date(e.start).valueOf()+e.duration_ms)),r=Math.max(n-t,1),i=new Map(e.map(e=>[e.span_id,e])),a=(e,t=new Set)=>{if(!e.parent_span_id||t.has(e.span_id))return 0;let n=i.get(e.parent_span_id);return n?(t.add(e.span_id),1+a(n,t)):0},o=e.map(e=>{let n=new Date(e.start).valueOf();return{span:e,depth:a(e),start:n,end:n+e.duration_ms,left:(n-t)/r*100,width:e.duration_ms/r*100}}).sort((e,t)=>e.depth-t.depth||e.start-t.start||t.span.duration_ms-e.span.duration_ms),s=[],c=0;for(let e of[...new Set(o.map(e=>e.depth))].sort((e,t)=>e-t)){let t=[];for(let n of o.filter(t=>t.depth===e)){let e=t.findIndex(e=>e<=n.start);e===-1&&(e=t.length),t[e]=n.end,s.push({...n,lane:c+e})}c+=Math.max(t.length,1)}return{frames:s,laneCount:c,total:r}}function H8({client:e,spec:t,time:n,vars:r,target:i,onChange:a}){let o=ke(`light`)===`dark`,s=t.panels.find(e=>e.id===i?.panel_id),c=i?.kind===`logs`&&s?.query?.from===`logs`,l=dt({queryKey:[`exemplars`,t,i,r],queryFn:({signal:n})=>e.exemplars({dashboard:t,panel_id:i.panel_id,kind:c?`logs`:`traces`,time:{from:i.window_from,to:i.window_to,refresh:`off`},from:i.from,to:i.to,dimensions:i.dimensions,bucket:i.bucket,vars:r},n),enabled:!!(i&&s&&!i.trace_id),retry:!1}),u=dt({queryKey:[`drill-trace`,i],queryFn:({signal:t})=>e.trace(i,t),enabled:!!i?.trace_id,retry:!1});return(0,H.jsxs)(Qe,{opened:!!i,onClose:()=>a(void 0),title:s?`${s.title} · ${i?.kind}`:`Panel selection unavailable`,position:`right`,size:`xl`,children:[i?.trace_id&&(0,H.jsx)(C,{variant:`subtle`,mb:`sm`,onClick:()=>{let{trace_id:e,namespace:t,...n}=i;a(n)},children:`Back to traces`}),!s&&(0,H.jsx)(ee,{color:`bad`,children:`This panel is no longer in the dashboard.`}),(l.isFetching||u.isFetching)&&(0,H.jsx)(se,{role:`status`,"aria-label":`Loading drill data`,size:`sm`}),(l.error||u.error)&&(0,H.jsx)(ee,{color:`bad`,children:(l.error??u.error)?.message}),c&&l.data?.logs&&s&&(0,H.jsx)(P4,{panel:{...s,viz:`logs`},result:{id:s.id,status:l.data.logs.rows?`ok`:`empty`,frame:l.data.logs,elapsed_ms:0,from_ms:Date.parse(i.from),to_ms:Date.parse(i.to)},dark:o,height:500}),c&&l.data?.logs?.rows===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No logs match this selection.`}),!c&&!i?.trace_id&&l.data&&(0,H.jsxs)(S,{gap:`xs`,children:[l.data.traces.length===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No exemplar traces match this selection.`}),l.data.traces.map(e=>(0,H.jsxs)(C,{variant:`default`,justify:`space-between`,onClick:()=>a({...i,trace_id:e.trace_id,namespace:e.namespace}),children:[e.service,` · `,e.operation,` · `,e.duration_ms.toFixed(1),` ms`]},`${e.namespace}/${e.trace_id}`)),l.data.truncated&&(0,H.jsx)(T,{size:`xs`,c:`dimmed`,children:`Showing at most 20 exemplar traces.`})]}),u.data&&(0,H.jsx)(z8,{result:u.data,dark:o})]})}var U8={"5m":`Last 5 minutes`,"15m":`Last 15 minutes`,"1h":`Last hour`,"3h":`Last 3 hours`,"6h":`Last 6 hours`,"12h":`Last 12 hours`,"24h":`Last 24 hours`,"2d":`Last 2 days`,"7d":`Last 7 days`,"30d":`Last 30 days`};function W8(e){return e.from&&e.to?`${he(e.from)} – ${he(e.to)}`:U8[e.range??`1h`]??e.range??`Last hour`}function G8({time:e,refresh:t,compare:n,editing:r,fetching:i,updatedAt:a,onRange:o,onAbsolute:s,onZoomOut:c,onRefresh:l,onRefreshNow:u,onCompare:d,onEdit:f,onHistory:p,onShortcuts:m,selecting:h=!1}){let[g,_]=(0,V.useState)(``),[v,b]=(0,V.useState)(``),[x,S]=(0,V.useState)(!1);return(0,H.jsxs)(y,{gap:`xs`,wrap:`wrap`,role:`group`,"aria-label":`Dashboard controls`,children:[(0,H.jsxs)(Re,{position:`bottom-end`,withinPortal:!0,opened:x,onChange:S,children:[(0,H.jsx)(Re.Target,{children:(0,H.jsx)(C,{variant:`default`,size:`sm`,leftSection:(0,H.jsx)(ji,{size:15}),rightSection:(0,H.jsx)(ge,{size:12,weight:`bold`}),children:W8(e)})}),(0,H.jsxs)(Re.Dropdown,{miw:260,children:[(0,H.jsx)(Re.Label,{children:`Relative`}),rt.map(t=>(0,H.jsx)(Re.Item,{onClick:()=>o(t),fw:e.range===t?600:void 0,children:U8[t]},t)),(0,H.jsx)(Re.Divider,{}),(0,H.jsx)(Re.Label,{children:`Absolute (your time zone)`}),(0,H.jsxs)(y,{gap:6,px:`xs`,pb:`xs`,wrap:`nowrap`,children:[(0,H.jsx)(Me,{type:`datetime-local`,size:`xs`,"aria-label":`From`,value:g,onChange:e=>_(e.currentTarget.value)}),(0,H.jsx)(Me,{type:`datetime-local`,size:`xs`,"aria-label":`To`,value:v,onChange:e=>b(e.currentTarget.value)})]}),(0,H.jsx)(y,{px:`xs`,pb:`xs`,justify:`flex-end`,children:(0,H.jsx)(C,{size:`compact-sm`,disabled:!g||!v||g>=v,onClick:()=>{s(new Date(g).toISOString(),new Date(v).toISOString()),S(!1)},children:`Apply range`})})]})]}),(0,H.jsx)(pe,{label:`Zoom out`,children:(0,H.jsx)(C,{variant:`default`,size:`sm`,px:10,"aria-label":`Zoom out`,onClick:c,children:(0,H.jsx)(Ui,{size:15})})}),(0,H.jsxs)(y,{"data-refresh-controls":!0,gap:4,wrap:`nowrap`,children:[(0,H.jsx)(pe,{label:a?`Updated ${he(a)}`:`Refresh now`,children:(0,H.jsx)(C,{variant:`default`,size:`sm`,px:10,"aria-label":`Refresh now`,loading:i,onClick:u,children:(0,H.jsx)(xi,{size:15})})}),(0,H.jsx)(Hr,{size:`xs`,"aria-label":`Auto refresh`,value:t,onChange:l,data:jt.map(e=>({value:e,label:e===`off`?`Off`:e}))})]}),(0,H.jsx)(oi,{size:`sm`,label:`Compare with previous period`,checked:n,onChange:e=>d(e.currentTarget.checked)}),(0,H.jsx)(C,{variant:r?`filled`:`default`,size:`sm`,leftSection:(0,H.jsx)(qe,{size:15}),onClick:f,children:r?`Done`:`Edit layout`}),(0,H.jsx)(C,{variant:`default`,size:`sm`,leftSection:(0,H.jsx)(Ni,{size:15}),onClick:p,children:`History`}),m&&(0,H.jsx)(R4,{onClick:m}),a&&(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,visibleFrom:`md`,children:[`Updated `,new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`,second:`2-digit`}).format(a)]}),h&&(0,H.jsx)(T,{"data-range-paused":!0,size:`xs`,c:`dimmed`,role:`status`,children:`Paused while selecting`})]})}var K8=(e,t)=>!(t instanceof $e&&t.status<500)&&e<2,q8=(e,t)=>!(t instanceof $e&&t.code===`timeout`)&&K8(e,t),J8=e=>({panels:e.panels.map(({grid:e,...t})=>t),variables:e.variables,time:e.time,annotations:e.annotations});function Y8(e,t,n,r,i){return[`panels`,JSON.stringify([e,J8(t),n,r,i])]}function X8(e,t,n,r){return[`variables`,e,J8(t),n,r]}async function Z8(e,t){let n=await We(e,t),r=new Set(e.dashboard.panels.filter(e=>[`timeseries`,`heatmap`,`state_timeline`].includes(e.viz)).map(e=>e.id)),i=n.filter(e=>r.has(e.id)&&e.from_ms!==void 0&&e.to_ms!==void 0&&e.from_mse.from_ms)),o=Math.max(...i.map(e=>e.to_ms));try{return{results:n,annotations:await ht({from:new Date(a).toISOString(),to:new Date(o).toISOString()},t)}}catch(e){if(t?.aborted)throw e;return{results:n,annotation_error:e instanceof Error?e.message:`Annotations unavailable`}}}var Q8={off:!1,"10s":1e4,"30s":3e4,"1m":6e4,"5m":3e5},$8=0;function e5(e,t){let[n,r]=e.queryKey;if(n!==`panels`||typeof r!=`string`)return!1;try{return JSON.parse(r)[0]===t}catch{return!1}}function t5({dashboardId:e,spec:t,time:n,vars:r,compare:i,widths:a,visible:o,refresh:s,enabled:c=!0}){let l=(0,V.useMemo)(()=>Object.fromEntries(Object.entries(a).map(([e,t])=>[e,Math.max(100,Math.round(t/100)*100)])),[a]),u=Y8(e,t,n,r,i),d=u[1],f=o.filter(e=>t.panels.some(t=>t.id===e)),p=(0,V.useRef)([]),m=(0,V.useRef)(void 0),h=(0,V.useRef)(null),g=(0,V.useRef)(!1),_=(0,V.useRef)(null),v=(0,V.useRef)({key:d,ids:new Set}),[y,b]=(0,V.useState)({key:d}),[x,S]=(0,V.useState)({key:d,results:new Map,updated:new Map,stale:new Set,receivedAt:0}),C=f.length===0&&x.key===d&&x.receivedAt>0,w=c&&t.panels.some(e=>e.viz!==`text`),T=dt({queryKey:u,queryFn:({signal:e})=>{if(C&&h.current?.key!==d)return p.current=[],Promise.resolve({results:[],hasTimePanels:!1,batch:++$8});let a=h.current?.key===d?h.current.ids:f;p.current=(a.length?[...a]:t.panels.map(e=>e.id)).sort(),v.current.key!==d&&(v.current={key:d,ids:new Set});for(let e of p.current)v.current.ids.add(e);let o=[...p.current];return Z8({dashboard:t,panels:o,time:n,vars:r,widths:l,compare:i},e).then(e=>{let n=new Set(e.results.map(e=>e.id)),r=o.filter(e=>!n.has(e)&&t.panels.find(t=>t.id===e)?.viz!==`text`).map(e=>({id:e,status:`error`,elapsed_ms:0,error:`No result was returned for this panel; refresh to retry.`,request_error:o}));return{...e,batch:++$8,results:[...e.results.map(e=>W4(e,o)),...r],hasTimePanels:t.panels.some(e=>o.includes(e.id)&&[`timeseries`,`heatmap`,`state_timeline`].includes(e.viz))}}).catch(n=>{throw e.aborted||(m.current={key:d,ids:o.filter(e=>t.panels.find(t=>t.id===e)?.viz!==`text`),error:n instanceof Error?n.message:String(n),retryable:!(n instanceof $e)||n.status===408||n.status===429||n.status>=500}),n})},retry:q8,enabled:w,refetchInterval:C?!1:Q8[s]??3e4,staleTime:5e3,placeholderData:e=>e}),E=T.error&&m.current?.key===d?m.current:void 0,D=(0,V.useMemo)(()=>n5(x,d,T.isPlaceholderData?void 0:T.data?.results,T.dataUpdatedAt,T.data?.batch,E),[x,d,T.data,T.dataUpdatedAt,T.isPlaceholderData,T.error,T.errorUpdatedAt]),O=D.results,k=T.isPlaceholderData?void 0:T.data?.hasTimePanels?T.data:y.key===d?y:void 0;(0,V.useEffect)(()=>{!T.isPlaceholderData&&T.data?.hasTimePanels&&b({key:d,annotations:T.data.annotations,annotation_error:T.data.annotation_error})},[d,T.data,T.isPlaceholderData]),(0,V.useEffect)(()=>{T.isPlaceholderData||S(e=>n5(e,d,T.data?.results,T.dataUpdatedAt,T.data?.batch,E))},[d,T.data,T.dataUpdatedAt,T.isPlaceholderData,T.error,T.errorUpdatedAt]);let A=new Map([...D.stale].flatMap(e=>{let t=D.updated.get(e);return t?[[e,t]]:[]})),j=(T.data?.results??[]).find(e=>e.status===`error`&&D.stale.has(e.id));(0,V.useEffect)(()=>{if(!w||T.isFetching||g.current||_.current?.key===d||h.current?.key===d)return;let e=v.current.key===d?v.current.ids:new Set,n=[...new Set(f.filter(n=>!O.has(n)&&!e.has(n)&&t.panels.find(e=>e.id===n)?.viz!==`text`))].sort();if(!n.length)return;let r={key:d,ids:n};h.current=r,T.refetch({cancelRefetch:!1}).finally(()=>{h.current===r&&(h.current=null)})},[o,w,d,T.isFetching,T.error,T.refetch,O,t.panels]),(0,V.useEffect)(()=>{!T.isFetching&&_.current?.key!==d&&g.current&&(g.current=!1,h.current=null,w&&!C&&T.refetch({cancelRefetch:!1}))},[T.isFetching,d,w,C,T.refetch]);let M=e=>{let t={key:d,ids:e};h.current=t,T.refetch({cancelRefetch:!1}).finally(()=>{h.current===t&&(h.current=null)})};return(0,V.useEffect)(()=>{if(T.isFetching||!_.current)return;let e=_.current;if(_.current=null,e.key!==d||!w)return;let n=[...e.ids].filter(e=>t.panels.some(t=>t.id===e&&t.viz!==`text`)&&O.get(e)?.request_error).sort();n.length&&M(n)},[T.isFetching,d,w,O,t.panels]),{retry:e=>{if(!w)return;let n=e?O.get(e)?.request_error??[]:[...O.values()].flatMap(e=>e.request_error??[]),r=[...new Set(n)].filter(e=>t.panels.some(t=>t.id===e&&t.viz!==`text`)&&O.get(e)?.request_error).sort();if(r.length){if(T.isFetching){_.current?.key!==d&&(_.current={key:d,ids:new Set});for(let e of r)_.current.ids.add(e);return}M(r)}},results:O,staleAt:A,annotations:k?.annotations,annotationError:k?.annotation_error,fetchingIds:T.isFetching?p.current:[],fetching:T.isFetching,error:T.error??(j?Error(j.error??`Panel refresh failed`):null),updatedAt:T.isPlaceholderData?null:T.dataUpdatedAt||null,refetch:()=>{if(w&&!C){if(T.isFetching){h.current?.key===d&&(g.current=!0);return}T.refetch({cancelRefetch:!1})}}}}function n5(e,t,n,r,i,a){let o=e.key===t?{key:t,results:new Map(e.results),updated:new Map(e.updated),stale:new Set(e.stale),receivedAt:e.receivedAt,receivedBatch:e.receivedBatch}:{key:t,results:new Map,updated:new Map,stale:new Set,receivedAt:0};for(let e of n&&i!==o.receivedBatch?n:[])e.status===`error`&&o.results.get(e.id)?.frame?(o.stale.add(e.id),o.results.set(e.id,{...o.results.get(e.id),error:e.error,request_error:e.request_error})):(o.results.set(e.id,e),o.updated.set(e.id,r),o.stale.delete(e.id));n&&(o.receivedAt=r,o.receivedBatch=i);for(let e of a?.ids??[]){let t=o.results.get(e);t?.frame?(o.stale.add(e),o.results.set(e,{...t,error:a.error,request_error:a.retryable?a.ids:void 0})):o.results.set(e,{id:e,status:`error`,elapsed_ms:0,error:a.error,request_error:a.retryable?a.ids:void 0})}return o}function r5(e,t){return e.queryKey[0]===`variables`&&e.queryKey[1]===t}function i5(e,t,n,r,i,a=!1){let o=!!t.variables?.some(e=>e.kind===`query`),s=dt({queryKey:X8(e,t,n,r),queryFn:async({signal:e})=>{let a=await i({dashboard:t,time:n,vars:r},e);return Object.fromEntries((t.variables??[]).map(e=>[e.name,a[e.name]??(e.kind===`custom`?e.options?.map(e=>({value:e})):void 0)??[]]))},enabled:o,retry:a,staleTime:6e4,placeholderData:e=>e}),c=s.isPlaceholderData?void 0:s.data,l=s.isError||(t.variables??[]).every(e=>e.kind!==`query`||r[e.name]!==void 0&&r[e.name]!==`$__all`&&(e.multi||!Array.isArray(r[e.name])||r[e.name].length>0)||!!e.default||e.include_all||c?.[e.name]!==void 0);return{...s,currentData:c,ready:l}}function a5(e){return t=>e5(t,e)||r5(t,`dashboard-${e}`)}function o5({id:e,currentVersion:t,opened:n,onClose:r,onRestored:i}){let a=ct(),[o,s]=(0,V.useState)(),[c,l]=(0,V.useState)(``),[u,d]=(0,V.useState)(!1),[f,p]=(0,V.useState)(n),m=(0,V.useRef)(0),h=(0,V.useRef)(n);h.current=n;let g=(0,V.useRef)(!1),_=(0,V.useRef)(!1),v=(0,V.useRef)(i);v.current=i,(0,V.useEffect)(()=>(_.current=!0,()=>{_.current=!1}),[]);let y=Te({mutationFn:({version:t})=>ze(e,t),retry:!1,onSuccess:(t,{version:n,generation:r})=>{a.cancelQueries({queryKey:[`dashboard`,e],exact:!0}),a.cancelQueries({predicate:a5(e)}),a.cancelQueries({queryKey:[`exemplars`]}),a.cancelQueries({queryKey:[`drill-trace`]}),a.setQueryData([`dashboard`,e],t),a.invalidateQueries({predicate:a5(e),refetchType:`none`}),_.current&&(h.current&&r===m.current&&l(`Restored v${n} as v${t.version}`),v.current(t)),a.invalidateQueries({queryKey:Ne}),a.invalidateQueries({queryKey:[`dashboard-versions`,e]},{cancelRefetch:!1}),a.invalidateQueries({queryKey:[`exemplars`],refetchType:`none`}),a.invalidateQueries({queryKey:[`drill-trace`],refetchType:`none`})},onError:t=>{t instanceof $e&&t.code===`dashboard_version_not_found`&&a.invalidateQueries({queryKey:[`dashboard-versions`,e]})},onSettled:()=>{g.current=!1,_.current&&d(!1)}}),b=()=>{m.current++,y.reset(),l(``)};(0,V.useEffect)(()=>{if(n){p(!0);return}m.current++,y.reset(),l(``),a.cancelQueries({queryKey:[`dashboard-versions`,e]}),a.cancelQueries({queryKey:[`dashboard-version`,e]})},[n,e,a,y.reset]);let x=(0,V.useRef)(t);return(0,V.useEffect)(()=>{x.current!==t&&(x.current=t,a.invalidateQueries({queryKey:[`dashboard-versions`,e]},{cancelRefetch:!1}))},[t,e,a]),(0,H.jsx)(Qe,{opened:n,onClose:()=>{b(),r()},onExitTransitionEnd:()=>p(!1),title:`Version history`,position:`right`,size:`xl`,children:(n||f)&&(0,H.jsx)(s5,{id:e,opened:n,currentVersion:t,selected:o,onSelect:e=>{b(),s(e)},pending:u,error:y.error,failedVersion:y.variables?.version,success:c,onRestore:e=>{g.current||(g.current=!0,d(!0),l(``),y.mutate({version:e,generation:m.current}))}})})}function s5({id:e,opened:t,currentVersion:n,selected:r,onSelect:i,pending:a,error:s,failedVersion:c,success:l,onRestore:u}){let d=dt({queryKey:[`dashboard-versions`,e],queryFn:({signal:t})=>gt(e,t),enabled:t,retry:!1}),f=r??d.data?.[0]?.version,p=dt({queryKey:[`dashboard-version`,e,f],queryFn:({signal:t})=>Pe(e,f,t),enabled:t&&f!==void 0,retry:!1});return(0,H.jsxs)(S,{gap:`md`,"data-version-history":!0,children:[(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:`Inspect saved specs and changes. Restoring adds a new version.`}),l&&(0,H.jsx)(ee,{color:`ok`,role:`status`,children:l}),s&&c===f&&(0,H.jsx)(d5,{error:s,version:f}),(0,H.jsxs)(o,{mih:160,children:[d.isPending&&(0,H.jsxs)(y,{gap:`xs`,role:`status`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{size:`sm`,children:`Loading history…`})]}),d.error&&(0,H.jsxs)(ee,{color:`bad`,title:`History unavailable`,children:[d.error.message,(0,H.jsx)(C,{mt:`xs`,variant:`default`,size:`xs`,onClick:()=>void d.refetch(),children:`Retry history`})]}),d.data?.length===0&&(0,H.jsx)(T,{c:`dimmed`,children:`No versions available.`}),!!d.data?.length&&(0,H.jsx)(fe,{h:200,type:`auto`,children:(0,H.jsx)(S,{gap:`xs`,pr:`sm`,role:`list`,"aria-label":`Saved versions`,children:d.data.map(e=>(0,H.jsxs)(z,{role:`listitem`,withBorder:!0,p:`xs`,radius:`sm`,style:{borderColor:f===e.version?`var(--mantine-color-brand-filled)`:void 0},children:[(0,H.jsxs)(y,{justify:`space-between`,gap:`xs`,children:[(0,H.jsxs)(C,{variant:f===e.version?`light`:`subtle`,size:`compact-sm`,"aria-pressed":f===e.version,onClick:()=>i(e.version),children:[`Version `,e.version]}),e.version===n&&(0,H.jsx)(He,{color:`gray`,variant:`light`,tt:`none`,children:`Current`}),(0,H.jsx)(l5,{at:e.created_at})]}),(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,mt:4,children:[c5(e),` · `,e.message||`No edit message`]})]},e.version))})})]}),(0,H.jsx)(Je,{role:`status`,"aria-live":`polite`,children:f===void 0?`Select a version.`:p.isFetching?`Loading version ${f}…`:p.error?`Version ${f} unavailable.`:`Version ${f} ready.`}),(0,H.jsxs)(o,{mih:280,"aria-busy":p.isFetching,children:[f!==void 0&&p.isPending&&(0,H.jsxs)(y,{gap:`xs`,role:`status`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{size:`sm`,children:`Loading version…`})]}),p.error&&(0,H.jsxs)(ee,{color:`bad`,title:p.error instanceof $e&&p.error.code===`dashboard_version_not_found`?`This version is no longer available`:`Version unavailable`,children:[p.error.message,(0,H.jsx)(C,{mt:`xs`,variant:`default`,size:`xs`,onClick:()=>void p.refetch(),children:`Retry version`})]}),p.data&&!p.error&&(0,H.jsx)(u5,{record:p.data,currentVersion:n,pending:a,onRestore:()=>u(p.data.dashboard.version)})]})]})}function c5(e){return e.author_kind===`agent`?`Agent`:e.author_kind===`user`?`You`:`System`}function l5({at:e}){let t=(Date.parse(e)-Date.now())/1e3,[n,r]=Math.abs(t)<60?[1,`second`]:Math.abs(t)<3600?[60,`minute`]:Math.abs(t)<86400?[3600,`hour`]:[86400,`day`];return(0,H.jsx)(T,{component:`time`,dateTime:e,title:he(e),size:`xs`,c:`dimmed`,children:new Intl.RelativeTimeFormat(void 0,{numeric:`auto`}).format(Math.round(t/n),r)})}function u5({record:e,currentVersion:t,pending:n,onRestore:r}){let{dashboard:i}=e,a=Xe(e);return(0,H.jsxs)(S,{gap:`sm`,"data-history-version":i.version,children:[(0,H.jsxs)(y,{justify:`space-between`,align:`flex-start`,children:[(0,H.jsxs)(o,{miw:0,children:[(0,H.jsxs)(I,{order:2,fz:`lg`,children:[i.name,` · v`,i.version]}),(0,H.jsxs)(T,{size:`sm`,c:`dimmed`,children:[c5(e),` · `,e.message||`No edit message`]}),(0,H.jsx)(l5,{at:e.created_at})]}),i.version===t?(0,H.jsx)(C,{size:`sm`,variant:`default`,disabled:!0,children:`Current version`}):(0,H.jsxs)(C,{size:`sm`,disabled:n,loading:n,onClick:r,children:[`Restore version `,i.version]})]}),i.description&&(0,H.jsx)(T,{size:`sm`,children:i.description}),e.changes_available?(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(Ce,{labels:a}),!a.length&&!e.layout_changed&&(0,H.jsx)(T,{size:`sm`,c:`dimmed`,children:`No authored changes.`})]}):(0,H.jsx)(ee,{color:`warn`,title:`Changes unavailable`,children:`The preceding version is no longer retained. This saved spec is still available.`}),(0,H.jsxs)(T,{size:`sm`,c:`dimmed`,children:[`Read-only · `,i.spec.panels.length,` panels. Historical data is not queried.`]}),(0,H.jsxs)(pn,{variant:`contained`,children:[(0,H.jsxs)(pn.Item,{value:`spec`,children:[(0,H.jsx)(pn.Control,{children:`Spec`}),(0,H.jsx)(pn.Panel,{children:(0,H.jsx)(Le,{block:!0,tabIndex:0,style:{maxHeight:320,overflow:`auto`},children:JSON.stringify(i.spec,null,2)})})]}),(0,H.jsxs)(pn.Item,{value:`data`,children:[(0,H.jsx)(pn.Control,{children:`Data`}),(0,H.jsx)(pn.Panel,{children:(0,H.jsx)(S,{gap:`xs`,children:i.spec.panels.map(e=>(0,H.jsxs)(o,{children:[(0,H.jsxs)(T,{size:`sm`,fw:500,children:[e.title,` · `,e.viz]}),(0,H.jsx)(Le,{block:!0,tabIndex:0,children:e.content??e.sql??JSON.stringify(e.query??{},null,2)})]},e.id))})})]})]})]})}function d5({error:e,version:t}){let n=e instanceof $e?e.code:void 0,r=!(e instanceof $e)||e.status>=500?`Try again with the restore button.`:n===`invalid_spec`?`This saved spec is invalid. Review the fields below and choose another version.`:n===`dashboard_version_not_found`?`Reload history and choose a retained version.`:[`already_current`,`dashboard_version_conflict`,`conflict`].includes(n??``)?`This dashboard changed or its name conflicts. Reload history and choose another version.`:`Check your access and reload history.`;return(0,H.jsxs)(ee,{color:`bad`,title:`Restore of version ${t} failed`,children:[(0,H.jsx)(T,{size:`sm`,children:e.message}),e instanceof $e&&e.problems.length>0&&(0,H.jsx)(`ul`,{children:e.problems.map((e,t)=>(0,H.jsxs)(`li`,{children:[e.path,`: `,e.message,e.hint?` (${e.hint})`:``]},t))}),(0,H.jsx)(T,{size:`sm`,mt:`xs`,children:r})]})}function f5(e,t){let n=JSON.stringify([e.range,e.from,e.to]),r=(0,V.useRef)({search:e,onSearch:t,scope:n}),i=(0,V.useRef)(``),a=(0,V.useRef)(void 0),[o,s]=(0,V.useState)(!1);r.current.scope!==n&&(i.current!==`${e.from}/${e.to}`&&(a.current=void 0,o&&s(!1)),i.current=``),r.current={search:e,onSearch:t,scope:n};let c=(0,V.useCallback)(()=>{i.current=``,a.current=void 0,s(!1)},[]),l=(0,V.useCallback)(()=>{if(!a.current)return;let e=a.current;c(),r.current.onSearch({...r.current.search,...e},!1)},[c]);return{zoom:(0,V.useCallback)((e,t)=>{let n=la(e,t);if(!n)return;let o=r.current,c=`${n.from}/${n.to}`;o.search.from===n.from&&o.search.to===n.to||i.current===c||(a.current??={range:o.search.range,from:o.search.from,to:o.search.to},s(!0),i.current=c,o.onSearch({...o.search,range:void 0,...n},!1))},[]),reset:c,resetZoom:l,zoomed:o}}function p5({variables:e,vars:t,options:n,onChange:r}){return e.length===0?null:(0,H.jsx)(y,{gap:`sm`,wrap:`wrap`,role:`group`,"aria-label":`Dashboard variables`,children:e.map(e=>{let i=Ji(e,t,n[e.name]),a=[...e.include_all?[{value:qi,label:`All`}]:[],...(n[e.name]??e.options?.map(e=>({value:e}))??[]).map(e=>({value:e.value,label:e.value}))],o=(0,H.jsxs)(T,{size:`xs`,c:`dimmed`,ff:`monospace`,children:[`$`,e.name]});return e.kind===`constant`?(0,H.jsx)(Me,{label:o,size:`xs`,value:e.value,readOnly:!0,w:160},e.name):e.kind===`text`?(0,H.jsx)(Me,{label:o,size:`xs`,w:200,defaultValue:typeof i==`string`?i:``,onBlur:t=>r(e.name,t.currentTarget.value),onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()}},`${e.name}:${JSON.stringify(i)}`):e.multi?(0,H.jsx)(kr,{label:o,size:`xs`,w:260,searchable:!0,clearable:!0,data:a.filter(e=>e.value!==qi),value:Array.isArray(i)?i:i&&i!==`$__all`?[i]:[],placeholder:e.include_all?`All`:`None`,onChange:t=>r(e.name,t.length?t:e.include_all?qi:[])},e.name):(0,H.jsx)(Wr,{label:o,size:`xs`,w:220,searchable:!0,allowDeselect:!1,data:a,value:Array.isArray(i)?i[0]??null:i||null,onChange:t=>t!==null&&r(e.name,t)},e.name)})})}function m5(e,t,n=!1){let r=e.target;return t||e.defaultPrevented||e.repeat||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey&&e.key!==`?`||r instanceof Element&&r.closest(`input,textarea,select,[contenteditable]:not([contenteditable="false"]),[role="textbox"],[role="menu"]`)||r instanceof Element&&r.closest(`[role="dialog"]`)&&!(n&&r.closest(`[data-panel-fullscreen]`))?null:[`r`,`e`,`h`,`f`,`?`].includes(e.key)?e.key:null}function h5(e,t,n={}){let r=(0,V.useRef)({actions:t,options:n});r.current={actions:t,options:n},(0,V.useEffect)(()=>{let t=t=>{let n=e.current,i=t.target,{actions:a,options:o}=r.current;if(!n||!(i instanceof Element)||o.enabled===!1)return;let s=o.fullscreenScope?[...document.querySelectorAll(`[data-shortcut-scope]`)].find(e=>e.dataset.shortcutScope===o.fullscreenScope&&e.hasAttribute(`data-panel-fullscreen`)):void 0,c=n.contains(i)&&n.contains(document.activeElement),l=i===document.body&&document.activeElement===document.body,u=s?.contains(i)&&s.contains(document.activeElement);if(!c&&!l&&!u)return;let d=m5(t,!!(o.modalOpen||[...document.querySelectorAll(`[role="dialog"]`)].some(e=>e!==s)),!!s);if(!d||s&&![`r`,`f`,`?`].includes(d))return;let f=a[d];f&&(t.preventDefault(),f(i))};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[e])}function g5({opened:e,onClose:t,fullscreen:n=!1,enabled:r,onEnabled:i}){let a=[[`r`,`Refresh now`],...n?[]:[[`e`,`Toggle layout mode`],[`h`,`Open history`]],[`f`,n?`Exit full-screen`:`Open the focused panel in full-screen`],[`?`,`Open keyboard shortcuts`],[`Escape`,`Cancel a range, then leave the chart or close full-screen`]];return(0,H.jsx)(Ze,{opened:e,onClose:t,title:`Keyboard shortcuts`,trapFocus:!0,returnFocus:!0,closeOnEscape:!0,children:(0,H.jsxs)(S,{gap:`xs`,children:[(0,H.jsx)(oi,{label:`Single-key shortcuts`,checked:r,onChange:e=>i(e.currentTarget.checked)}),a.map(([e,t])=>(0,H.jsxs)(y,{gap:`sm`,children:[(0,H.jsx)(Ye,{children:e}),(0,H.jsx)(T,{size:`sm`,children:t})]},e)),!n&&(0,H.jsx)(T,{size:`sm`,children:`Focus a chart or a panel control before pressing f. Without a focused panel, f does nothing.`}),(0,H.jsx)(T,{size:`sm`,children:`Tab directly to a chart. Left/Right moves between points; Up/Down changes series at the same time or category. Home/End jumps to the first/last point. Enter drills or applies the panel filter. Comparison and Other values can be read even when selection is unavailable.`}),(0,H.jsx)(T,{size:`sm`,children:`On time charts, Shift+Left/Right extends a range and pauses auto-refresh. Review the shaded range and compact UTC label, then choose Zoom to range. Use the time picker after zooming for precise edits. Escape or Cancel cancels it and resumes refresh. The next Escape leaves the chart or closes full-screen. Reset zoom, Zoom out and browser Back preserve comparison and filters.`}),(0,H.jsxs)(T,{size:`sm`,children:[n?`In full-screen, r refreshes, f exits and ? opens help; e and h are inactive.`:`Shortcuts work in the dashboard.`,` Typing, menus and other dialogs or drawers pause shortcuts. Modifier shortcuts keep their browser behavior. Turning off single-key shortcuts keeps chart navigation and visible controls available.`]}),(0,H.jsx)(T,{size:`sm`,children:`The global / shortcut focuses the chat composer.`})]})})}function _5(e){let t=`fanout:single-key-shortcuts:`+e,n=()=>{try{return localStorage.getItem(t)!==`off`}catch{return!0}},[r,i]=(0,V.useState)(n);return(0,V.useEffect)(()=>{i(n())},[t]),(0,V.useEffect)(()=>{let e=e=>{e.key===t&&i(n())};return window.addEventListener(`storage`,e),()=>window.removeEventListener(`storage`,e)},[t]),{enabled:r,change:e=>{i(e);try{localStorage.setItem(t,e?`on`:`off`)}catch{}}}}function v5(e){let t=(0,V.useRef)(void 0),n=t=>[...e.current?.querySelectorAll(`[data-panel]`)??[]].find(e=>e.dataset.panel===t&&!e.closest(`[data-panel-fullscreen],[data-fragment-fullscreen]`));return(0,V.useEffect)(()=>{t.current&&!n(t.current.panel)&&(t.current=void 0)}),{remember(n){t.current=void 0;let r=document.activeElement;if(!(r instanceof HTMLElement)||!e.current?.contains(r)||r.closest(`[data-panel]`)?.dataset.panel!==n)return;let i=r.getAttribute(`data-panel-view`),a=r.getAttribute(`aria-label`),o=r.hasAttribute(`data-chart-plot`)?`[data-chart-plot]`:i?`[data-panel-view=${JSON.stringify(i)}]`:a?`[aria-label=${JSON.stringify(a)}]`:void 0;t.current={element:r,panel:n,selector:o}},restore(e){let r=t.current;if(t.current=void 0,r&&(e===void 0||r.panel===e)&&n(r.panel))return r.element.isConnected&&!r.element.closest(`[hidden]`)?r.element:r.selector?n(r.panel)?.querySelector(r.selector)??void 0:void 0}}}var y5={exemplars:Ue,trace:Fe},b5={"5m":`15m`,"15m":`1h`,"1h":`3h`,"3h":`6h`,"6h":`12h`,"12h":`24h`,"24h":`2d`,"2d":`7d`,"7d":`30d`,"30d":`30d`};function x5({dashboardId:e,search:t,onSearch:n,onOpen:r}){let{agentAvailable:i,openChat:a}=je(),o=dt({queryKey:Ne,queryFn:Ge,staleTime:15e3});(0,V.useEffect)(()=>{!e&&o.data?.length&&r((o.data.find(e=>e.is_default)??o.data[0]).id,!0)},[e,o.data]);let s=dt({queryKey:[`dashboard`,e],queryFn:({signal:t})=>Mt(e,t),enabled:!!e,retry:(e,t)=>!(t instanceof $e&&t.code===`not_found`)&&e<2});return!e&&o.error?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsx)(ee,{color:`bad`,title:`Dashboards could not be loaded`,children:o.error.message})}):!e&&o.data?.length===0?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsxs)(S,{align:`center`,gap:`xs`,children:[(0,H.jsx)(I,{order:1,fz:24,children:`No dashboards yet`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ta:`center`,children:`Create a dashboard to explore your services.`}),i&&(0,H.jsx)(C,{mt:`sm`,size:`sm`,onClick:()=>a(`Build me a dashboard for my services, showing request volume, latency, and errors. Ask me which services to monitor first.`),children:`Create with AI`})]})}):!e||s.isLoading?(0,H.jsxs)(ae,{mih:`50vh`,children:[(0,H.jsx)(se,{size:`sm`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ml:`sm`,children:`Loading your dashboard…`})]}):s.error instanceof $e&&s.error.code===`not_found`?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsxs)(S,{align:`center`,gap:`xs`,children:[(0,H.jsx)(I,{order:1,fz:24,children:`This dashboard isn't here`}),(0,H.jsx)(T,{c:`dimmed`,size:`sm`,ta:`center`,children:`The link may be out of date, or the dashboard may have been deleted.`}),o.data?.length?(0,H.jsx)(C,{mt:`sm`,variant:`default`,size:`sm`,onClick:()=>r((o.data.find(e=>e.is_default)??o.data[0]).id,!0),children:`Open your default dashboard`}):null]})}):s.error||!s.data?(0,H.jsx)(ae,{mih:`50vh`,children:(0,H.jsx)(T,{c:`dimmed`,size:`sm`,children:`Your dashboard is unavailable. Try refreshing.`})}):(0,H.jsx)(S5,{id:s.data.id,version:s.data.version,spec:s.data.spec,search:t,onSearch:n,agentAvailable:i,openChat:a},s.data.id)}function S5({id:e,version:t,spec:n,search:r,onSearch:i,agentAvailable:a,openChat:s}){let[c,l]=(0,V.useState)(!1),[u,d]=(0,V.useState)(!1),f=(0,V.useRef)(null),p=(0,V.useId)(),m=_5(Be().id),h=v5(f),[g,_]=(0,V.useState)(()=>new Set),v=(0,V.useCallback)((e,t)=>_(n=>{if(n.has(e)===t)return n;let r=new Set(n);return t?r.add(e):r.delete(e),r}),[]),b=ct(),[x,w]=(0,V.useState)(),{zoom:E,reset:D,resetZoom:O,zoomed:k}=f5(r,i),A=ft(n,r),[j,M]=(0,V.useState)(A.refresh??`30s`),N=r.compare?r.compare===`1`:n.time.compare===`previous_period`,P=r.vars??{},F=i5(`dashboard-${e}`,n,A,P,Ie,K8),L=(0,V.useMemo)(()=>Xi(n.variables,P,F.currentData),[n.variables,P,F.currentData]),[te,ne]=(0,V.useState)(()=>window.innerWidth);(0,V.useEffect)(()=>{let e=0,t=()=>{window.clearTimeout(e),e=window.setTimeout(()=>ne(window.innerWidth),300)};return window.addEventListener(`resize`,t),()=>{window.removeEventListener(`resize`,t),window.clearTimeout(e)}},[]);let re=(0,V.useMemo)(()=>{let e=Math.max(320,Math.min(te-64,1600));return Object.fromEntries(n.panels.map(t=>[t.id,e/12*(t.grid?.w??t.width??6)]))},[te,n]),[ie,ae]=(0,V.useState)(()=>n.panels.map(e=>e.id)),R=t5({dashboardId:e,version:t,spec:n,time:A,vars:L,compare:N,widths:re,visible:(0,V.useMemo)(()=>ie.filter(e=>n.panels.some(t=>t.id===e)),[ie,n.panels]),refresh:g.size?`off`:j,enabled:F.ready});(0,V.useEffect)(()=>{x===t&&b.refetchQueries({predicate:a5(e),type:`active`,stale:!0},{cancelRefetch:!1})},[x,t,e,b]);let oe=(0,V.useMemo)(()=>R.annotations?{...R.annotations,deploys:n.annotations?.deploys===!1?[]:R.annotations.deploys,anomalies:n.annotations?.anomalies===!1?[]:R.annotations.anomalies}:void 0,[R.annotations,n.annotations?.deploys,n.annotations?.anomalies]),z=F.error??R.error,se=(e,t)=>{let n={...P};t===void 0?delete n[e]:n[e]=t,i({...r,vars:n},!0)},ce=()=>i({...r,edit:r.edit===`1`?void 0:`1`}),le=e=>{e&&h.remember(e),i({...r,view:e},e===void 0)};return h5(f,{r:()=>R.refetch(),e:ce,h:()=>l(!0),"?":()=>d(!0),f:e=>{if(r.view){le();return}let t=e.closest(`[data-panel]`)?.dataset.panel;t&&n.panels.some(e=>e.id===t)&&le(t)}},{modalOpen:c||u||!!r.drill,fullscreenScope:r.view?p:void 0,enabled:m.enabled}),(0,H.jsxs)(o,{component:`main`,ref:f,"aria-label":`Dashboard`,maw:1600,mx:`auto`,px:{base:`md`,sm:`xl`},pt:`lg`,pb:`xl`,children:[(0,H.jsxs)(S,{gap:`sm`,mb:`md`,children:[(0,H.jsxs)(y,{justify:`space-between`,align:`flex-start`,wrap:`wrap`,gap:`sm`,children:[(0,H.jsxs)(o,{miw:0,children:[(0,H.jsx)(I,{order:1,fz:28,lts:`-0.02em`,children:n.name}),n.description&&(0,H.jsx)(T,{c:`dimmed`,size:`sm`,mt:2,children:n.description})]}),(0,H.jsx)(G8,{selecting:g.size>0,time:A,refresh:j,compare:N,editing:r.edit===`1`,fetching:R.fetching,updatedAt:R.updatedAt,onRange:e=>{D(),i({...r,range:e,from:void 0,to:void 0})},onAbsolute:(e,t)=>{D(),i({...r,range:void 0,from:e,to:t})},onZoomOut:()=>{if(A.from&&A.to){let e=Date.parse(A.from),t=Date.parse(A.to),n=(t-e)/2;i({...r,range:void 0,from:new Date(e-n).toISOString(),to:new Date(t+n).toISOString()})}else i({...r,range:b5[A.range??`1h`]??`1h`,from:void 0,to:void 0})},onRefresh:M,onRefreshNow:R.refetch,onCompare:e=>i({...r,compare:e?`1`:`0`},!0),onEdit:ce,onHistory:()=>l(!0),onShortcuts:()=>d(!0)})]}),(0,H.jsx)(p5,{variables:n.variables??[],vars:P,options:F.data??{},onChange:se}),Object.entries(P).filter(([,e])=>e!==`$__all`).length>0&&(0,H.jsx)(y,{gap:6,children:Object.entries(P).filter(([,e])=>e!==`$__all`).map(([e,t])=>(0,H.jsxs)(C,{size:`compact-xs`,variant:`light`,"aria-label":`$${e} = ${Array.isArray(t)?t.join(`, `):t} ×: remove filter`,onClick:()=>se(e,void 0),children:[`$`,e,` = `,Array.isArray(t)?t.join(`, `):t,` ×`]},e))}),R.annotationError&&(0,H.jsx)(ee,{color:`warn`,title:`Annotations unavailable`,children:R.annotationError}),R.annotations?.truncated&&(0,H.jsx)(T,{size:`xs`,c:`warn`,role:`status`,children:`Annotation history is limited.`})]}),z&&(0,H.jsxs)(ee,{color:`bad`,icon:(0,H.jsx)(De,{size:18,weight:`fill`}),mb:`md`,title:F.error?`Variables could not be loaded`:`Panels could not be loaded`,children:[z.message,z instanceof $e&&(0,H.jsx)(`ul`,{children:z.problems.map((e,t)=>(0,H.jsxs)(`li`,{children:[e.path,`: `,e.message,e.hint?` (${e.hint})`:``]},t))})]}),(0,H.jsx)(N8,{dashboardId:e,version:t,spec:n,vars:L,results:R.results,annotations:oe,fetching:R.fetching,fetchingIds:R.fetchingIds,staleAt:R.staleAt,time:{...A,compare:N?`previous_period`:void 0},onEditExit:()=>i({...r,edit:void 0}),editing:r.edit===`1`,view:r.view,canManage:!0,agentAvailable:a,onOpenChat:s,onRetry:R.retry,onVariable:se,onZoom:E,zoomed:k,onZoomReset:O,onView:le,onRangePending:v,shortcutScope:p,onShortcuts:()=>d(!0),overlayOpen:c||u||!!r.drill,returnViewFocus:h.restore,onVisible:ae,onPoint:(e,t)=>{let n=S8(e,R.results.get(e.id),t,P);n&&i({...r,vars:n.vars,drill:JSON.stringify(n.target)},!1)}}),(0,H.jsx)(H8,{client:y5,spec:n,time:A,vars:L,target:Nt(r.drill),onChange:e=>i({...r,drill:e?JSON.stringify(e):void 0},!1)}),(0,H.jsx)(o5,{id:e,currentVersion:t,opened:c,onClose:()=>l(!1),onRestored:e=>{w(e.version);let t=new Set(e.spec.panels.map(e=>e.id)),n=Nt(r.drill),a=r.view&&!t.has(r.view)?void 0:r.view,o=n&&!t.has(n.panel_id)?void 0:r.drill;(a!==r.view||o!==r.drill)&&i({...r,view:a,drill:o},!0)}}),(0,H.jsx)(g5,{opened:u,onClose:()=>d(!1),fullscreen:!!r.view,enabled:m.enabled,onEnabled:m.change})]})}export{Yi as i,W4 as n,V4 as r,x5 as t}; \ No newline at end of file diff --git a/internal/ui/dist/assets/panel-sql-editor-Cs-4yfrn.js b/internal/ui/dist/assets/panel-sql-editor-Cx5hjHge.js similarity index 99% rename from internal/ui/dist/assets/panel-sql-editor-Cs-4yfrn.js rename to internal/ui/dist/assets/panel-sql-editor-Cx5hjHge.js index f1dd4a8c..89ff6af2 100644 --- a/internal/ui/dist/assets/panel-sql-editor-Cs-4yfrn.js +++ b/internal/ui/dist/assets/panel-sql-editor-Cx5hjHge.js @@ -1,4 +1,4 @@ -import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{C as r,_ as i,c as a,d as o,f as s,p as c}from"./brand-DUaZkIz1.js";import{i as l,n as u,r as d}from"./page-DjMwsK0m.js";import{A as f,C as p,N as m,T as h,Vt as g,X as _,ct as v,et as y,o as b}from"./index-eh4vL-r5.js";var x=n(e(),1),S=[],ee=[];(()=>{let e=`lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,1n,9,16,o,,x,1i,3,,i,,7,a,2,t,3,1k,,,7,2,2,2,3,9,,a,2,q,,2,3,1k,,,5,4,2,2,3,3,,u,2,3,,b,3,1k,,,8,,3,,3,k,2,m,6,,3,1k,,,7,2,2,2,3,7,3,a,2,u,,1n,5,3,3,,4,9,,14,5,1j,,,7,,3,,4,7,2,b,2,t,3,1k,,,7,,3,,4,7,2,b,2,f,,c,4,1j,2,,7,,3,,4,9,,a,2,t,3,1y,,4,6,,,,8,i,2,1p,,,8,c,8,2q,,,a,b,7,21,2,r,,,,,,4,2,1d,k,,2,5,b,,10,9,,2u,b,,6,n,4,4,3,g,4,d,,,3,6,,f,,jj,3,qa,4,s,3,t,2,u,2,1s,w,9,,19,3,,,39,2,y,,3a,c,4,c,63,5,1l,a,,,,,2,o,2,,1c,1a,2,c,k,5,1b,h,12,9,c,3,u,d,1k,e,1c,k,48,3,,l,4,,6,,2,3,5i,1s,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,n,5,4,,2b,2,1e,i,q,i,d,,12,8,p,d,18,4,1b,e,10,,1v,e,c,,8,2,1a,,1f,,,3,2,2,5,2,,,15,5,5,2,6k,8,,2,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,1t,5,8t,2,25,6,1y,b,1d,4,3e,3,1h,f,15,,2,2,a,4,19,b,7,,1p,3,10,e,g,2,18,,c,3,1c,e,8,4,,2,2k,c,6,,2,,4d,c,l,4,1j,2,,7,2,2,2,3,9,,a,2,2,7,3,5,1v,9,,,2,,,4,,5,,,e,2,2a,i,n,,29,k,6j,7,2,9,r,2,2a,h,2y,d,2t,3,2,a,74,f,6t,6,,2,2,4,,,,2,3x,7,2,7,3,,s,a,14,7,,4,8,,9,b,1a,g,5i,8,5j,8,,8,2a,m,,e,3e,6,3,,,2,,7,,,1u,5,,2,,5,9n,4,9,2,,,1c,7,3,5,n,,44l,,6,f,8ug,i,1xc,5,1n,7,t4,,,1j,7,4,29,,b,2,f57,2,3mp,1a,2,n,f2,5,3,6,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,2s,,4g,7,af,,1p,4,e4,4,72,2,6r,,2,,7,2,5,,d6,7,31,7,240,5`.split(`,`).map(e=>e?parseInt(e,36):1);for(let t=0,n=0;t>1;if(e=ee[r])t=r+1;else return!0;if(t==n)return!1}}function ne(e){return e>=127462&&e<=127487}var re=8205;function ie(e,t,n=!0,r=!0){return(n?ae:oe)(e,t,r)}function ae(e,t,n){if(t==e.length)return t;t&&ce(e.charCodeAt(t))&&le(e.charCodeAt(t-1))&&t--;let r=se(e,t);for(t+=ue(r);t=0&&ne(se(e,r));)n++,r-=2;if(n%2==0)break;t+=2}else break}return t}function oe(e,t,n){for(;t>1;){let r=ae(e,t-2,n);if(r=56320&&e<57344}function le(e){return e>=55296&&e<56320}function ue(e){return e<65536?1:2}var C=class e{lineAt(e){if(e<0||e>this.length)throw RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,n){[e,t]=w(this,e,t);let r=[];return this.decompose(0,e,r,2),n.length&&n.decompose(0,n.length,r,3),this.decompose(t,this.length,r,1),fe.from(r,this.length-(t-e)+n.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=w(this,e,t);let n=[];return this.decompose(e,t,n,0),fe.from(n,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),n=this.length-this.scanIdentical(e,-1),r=new ge(this),i=new ge(e);for(let e=t,a=t;;){if(r.next(e),i.next(e),e=0,r.lineBreak!=i.lineBreak||r.done!=i.done||r.value!=i.value)return!1;if(a+=r.value.length,r.done||a>=n)return!0}}iter(e=1){return new ge(this,e)}iterRange(e,t=this.length){return new _e(this,e,t)}iterLines(e,t){let n;if(e==null)n=this.iter();else{t??=this.lines+1;let r=this.line(e).from;n=this.iterRange(r,Math.max(r,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new ve(n)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(t){if(t.length==0)throw RangeError(`A document must have at least one line`);return t.length==1&&!t[0]?e.empty:t.length<=32?new de(t):fe.from(de.split(t,[]))}},de=class e extends C{constructor(e,t=pe(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,n,r){for(let i=0;;i++){let a=this.text[i],o=r+a.length;if((t?n:o)>=e)return new ye(r,o,n,a);r=o+1,n++}}decompose(t,n,r,i){let a=t<=0&&n>=this.length?this:new e(he(this.text,t,n),Math.min(n,this.length)-Math.max(0,t));if(i&1){let t=r.pop(),n=me(a.text,t.text.slice(),0,a.length);if(n.length<=32)r.push(new e(n,t.length+a.length));else{let t=n.length>>1;r.push(new e(n.slice(0,t)),new e(n.slice(t)))}}else r.push(a)}replace(t,n,r){if(!(r instanceof e))return super.replace(t,n,r);[t,n]=w(this,t,n);let i=me(this.text,me(r.text,he(this.text,0,t)),n),a=this.length+r.length-(n-t);return i.length<=32?new e(i,a):fe.from(e.split(i,[]),a)}sliceString(e,t=this.length,n=` +import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{C as r,_ as i,c as a,d as o,f as s,p as c}from"./brand-DUaZkIz1.js";import{i as l,n as u,r as d}from"./page-BJZPrXpH.js";import{A as f,C as p,N as m,T as h,Vt as g,X as _,ct as v,et as y,o as b}from"./index-B7LmyWZW.js";var x=n(e(),1),S=[],ee=[];(()=>{let e=`lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,1n,9,16,o,,x,1i,3,,i,,7,a,2,t,3,1k,,,7,2,2,2,3,9,,a,2,q,,2,3,1k,,,5,4,2,2,3,3,,u,2,3,,b,3,1k,,,8,,3,,3,k,2,m,6,,3,1k,,,7,2,2,2,3,7,3,a,2,u,,1n,5,3,3,,4,9,,14,5,1j,,,7,,3,,4,7,2,b,2,t,3,1k,,,7,,3,,4,7,2,b,2,f,,c,4,1j,2,,7,,3,,4,9,,a,2,t,3,1y,,4,6,,,,8,i,2,1p,,,8,c,8,2q,,,a,b,7,21,2,r,,,,,,4,2,1d,k,,2,5,b,,10,9,,2u,b,,6,n,4,4,3,g,4,d,,,3,6,,f,,jj,3,qa,4,s,3,t,2,u,2,1s,w,9,,19,3,,,39,2,y,,3a,c,4,c,63,5,1l,a,,,,,2,o,2,,1c,1a,2,c,k,5,1b,h,12,9,c,3,u,d,1k,e,1c,k,48,3,,l,4,,6,,2,3,5i,1s,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,n,5,4,,2b,2,1e,i,q,i,d,,12,8,p,d,18,4,1b,e,10,,1v,e,c,,8,2,1a,,1f,,,3,2,2,5,2,,,15,5,5,2,6k,8,,2,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,1t,5,8t,2,25,6,1y,b,1d,4,3e,3,1h,f,15,,2,2,a,4,19,b,7,,1p,3,10,e,g,2,18,,c,3,1c,e,8,4,,2,2k,c,6,,2,,4d,c,l,4,1j,2,,7,2,2,2,3,9,,a,2,2,7,3,5,1v,9,,,2,,,4,,5,,,e,2,2a,i,n,,29,k,6j,7,2,9,r,2,2a,h,2y,d,2t,3,2,a,74,f,6t,6,,2,2,4,,,,2,3x,7,2,7,3,,s,a,14,7,,4,8,,9,b,1a,g,5i,8,5j,8,,8,2a,m,,e,3e,6,3,,,2,,7,,,1u,5,,2,,5,9n,4,9,2,,,1c,7,3,5,n,,44l,,6,f,8ug,i,1xc,5,1n,7,t4,,,1j,7,4,29,,b,2,f57,2,3mp,1a,2,n,f2,5,3,6,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,2s,,4g,7,af,,1p,4,e4,4,72,2,6r,,2,,7,2,5,,d6,7,31,7,240,5`.split(`,`).map(e=>e?parseInt(e,36):1);for(let t=0,n=0;t>1;if(e=ee[r])t=r+1;else return!0;if(t==n)return!1}}function ne(e){return e>=127462&&e<=127487}var re=8205;function ie(e,t,n=!0,r=!0){return(n?ae:oe)(e,t,r)}function ae(e,t,n){if(t==e.length)return t;t&&ce(e.charCodeAt(t))&&le(e.charCodeAt(t-1))&&t--;let r=se(e,t);for(t+=ue(r);t=0&&ne(se(e,r));)n++,r-=2;if(n%2==0)break;t+=2}else break}return t}function oe(e,t,n){for(;t>1;){let r=ae(e,t-2,n);if(r=56320&&e<57344}function le(e){return e>=55296&&e<56320}function ue(e){return e<65536?1:2}var C=class e{lineAt(e){if(e<0||e>this.length)throw RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,n){[e,t]=w(this,e,t);let r=[];return this.decompose(0,e,r,2),n.length&&n.decompose(0,n.length,r,3),this.decompose(t,this.length,r,1),fe.from(r,this.length-(t-e)+n.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=w(this,e,t);let n=[];return this.decompose(e,t,n,0),fe.from(n,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),n=this.length-this.scanIdentical(e,-1),r=new ge(this),i=new ge(e);for(let e=t,a=t;;){if(r.next(e),i.next(e),e=0,r.lineBreak!=i.lineBreak||r.done!=i.done||r.value!=i.value)return!1;if(a+=r.value.length,r.done||a>=n)return!0}}iter(e=1){return new ge(this,e)}iterRange(e,t=this.length){return new _e(this,e,t)}iterLines(e,t){let n;if(e==null)n=this.iter();else{t??=this.lines+1;let r=this.line(e).from;n=this.iterRange(r,Math.max(r,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new ve(n)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(t){if(t.length==0)throw RangeError(`A document must have at least one line`);return t.length==1&&!t[0]?e.empty:t.length<=32?new de(t):fe.from(de.split(t,[]))}},de=class e extends C{constructor(e,t=pe(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,n,r){for(let i=0;;i++){let a=this.text[i],o=r+a.length;if((t?n:o)>=e)return new ye(r,o,n,a);r=o+1,n++}}decompose(t,n,r,i){let a=t<=0&&n>=this.length?this:new e(he(this.text,t,n),Math.min(n,this.length)-Math.max(0,t));if(i&1){let t=r.pop(),n=me(a.text,t.text.slice(),0,a.length);if(n.length<=32)r.push(new e(n,t.length+a.length));else{let t=n.length>>1;r.push(new e(n.slice(0,t)),new e(n.slice(t)))}}else r.push(a)}replace(t,n,r){if(!(r instanceof e))return super.replace(t,n,r);[t,n]=w(this,t,n);let i=me(this.text,me(r.text,he(this.text,0,t)),n),a=this.length+r.length-(n-t);return i.length<=32?new e(i,a):fe.from(e.split(i,[]),a)}sliceString(e,t=this.length,n=` `){[e,t]=w(this,e,t);let r=``;for(let i=0,a=0;i<=t&&ae&&a&&(r+=n),ei&&(r+=o.slice(Math.max(0,e-i),t-i)),i=s+1}return r}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(t,n){let r=[],i=-1;for(let a of t)r.push(a),i+=a.length+1,r.length==32&&(n.push(new e(r,i)),r=[],i=-1);return i>-1&&n.push(new e(r,i)),n}},fe=class e extends C{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let t of e)this.lines+=t.lines}lineInner(e,t,n,r){for(let i=0;;i++){let a=this.children[i],o=r+a.length,s=n+a.lines-1;if((t?s:o)>=e)return a.lineInner(e,t,n,r);r=o+1,n=s+1}}decompose(e,t,n,r){for(let i=0,a=0;a<=t&&i=a){let i=r&(a<=e|(s>=t?2:0));a>=e&&s<=t&&!i?n.push(o):o.decompose(e-a,t-a,n,i)}a=s+1}}replace(t,n,r){if([t,n]=w(this,t,n),r.lines=a&&n<=s){let c=o.replace(t-a,n-a,r),l=this.lines-o.lines+c.lines;if(c.lines>4&&c.lines>l>>6){let a=this.children.slice();return a[i]=c,new e(a,this.length-(n-t)+r.length)}return super.replace(a,s,c)}a=s+1}return super.replace(t,n,r)}sliceString(e,t=this.length,n=` `){[e,t]=w(this,e,t);let r=``;for(let i=0,a=0;ie&&i&&(r+=n),ea&&(r+=o.sliceString(e-a,t-a,n)),a=s+1}return r}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(t,n){if(!(t instanceof e))return 0;let r=0,[i,a,o,s]=n>0?[0,0,this.children.length,t.children.length]:[this.children.length-1,t.children.length-1,-1,-1];for(;;i+=n,a+=n){if(i==o||a==s)return r;let e=this.children[i],c=t.children[a];if(e!=c)return r+e.scanIdentical(c,n);r+=e.length+1}}static from(t,n=t.reduce((e,t)=>e+t.length+1,-1)){let r=0;for(let e of t)r+=e.lines;if(r<32){let e=[];for(let n of t)n.flatten(e);return new de(e,n)}let i=Math.max(32,r>>5),a=i<<1,o=i>>1,s=[],c=0,l=-1,u=[];function d(t){let n;if(t.lines>a&&t instanceof e)for(let e of t.children)d(e);else t.lines>o&&(c>o||!c)?(f(),s.push(t)):t instanceof de&&c&&(n=u[u.length-1])instanceof de&&t.lines+n.lines<=32?(c+=t.lines,l+=t.length+1,u[u.length-1]=new de(n.text.concat(t.text),n.length+1+t.length)):(c+t.lines>i&&f(),c+=t.lines,l+=t.length+1,u.push(t))}function f(){c!=0&&(s.push(u.length==1?u[0]:e.from(u,l)),l=-1,c=u.length=0)}for(let e of t)d(e);return f(),s.length==1?s[0]:new e(s,n)}};C.empty=new de([``],0);function pe(e){let t=-1;for(let n of e)t+=n.length+1;return t}function me(e,t,n=0,r=1e9){for(let i=0,a=0,o=!0;a=n&&(c>r&&(s=s.slice(0,r-i)),i0?1:(e instanceof de?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let n=this.nodes.length-1,r=this.nodes[n],i=this.offsets[n],a=i>>1,o=r instanceof de?r.text.length:r.children.length;if(a==(t>0?o:0)){if(n==0)return this.done=!0,this.value=``,this;t>0&&this.offsets[n-1]++,this.nodes.pop(),this.offsets.pop()}else if((i&1)==(t>0?0:1)){if(this.offsets[n]+=t,e==0)return this.lineBreak=!0,this.value=` `,this;e--}else if(r instanceof de){let i=r.text[a+(t<0?-1:0)];if(this.offsets[n]+=t,i.length>Math.max(0,e))return this.value=e==0?i:t>0?i.slice(e):i.slice(0,i.length-e),this;e-=i.length}else{let i=r.children[a+(t<0?-1:0)];e>i.length?(e-=i.length,this.offsets[n]+=t):(t<0&&this.offsets[n]--,this.nodes.push(i),this.offsets.push(t>0?1:(i instanceof de?i.text.length:i.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}},_e=class{constructor(e,t,n){this.value=``,this.done=!1,this.cursor=new ge(e,t>n?-1:1),this.pos=t>n?e.length:0,this.from=Math.min(t,n),this.to=Math.max(t,n)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value=``,this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let n=t<0?this.pos-this.from:this.to-this.pos;e>n&&(e=n),n-=e;let{value:r}=this.cursor.next(e);return this.pos+=(r.length+e)*t,this.value=r.length<=n?r:t<0?r.slice(r.length-n):r.slice(0,n),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=``}},ve=class{constructor(e){this.inner=e,this.afterBreak=!0,this.value=``,this.done=!1}next(e=0){let{done:t,lineBreak:n,value:r}=this.inner.next(e);return t&&this.afterBreak?(this.value=``,this.afterBreak=!1):t?(this.done=!0,this.value=``):n?this.afterBreak?this.value=``:(this.afterBreak=!0,this.next()):(this.value=r,this.afterBreak=!1),this}get lineBreak(){return!1}};typeof Symbol<`u`&&(C.prototype[Symbol.iterator]=function(){return this.iter()},ge.prototype[Symbol.iterator]=_e.prototype[Symbol.iterator]=ve.prototype[Symbol.iterator]=function(){return this});var ye=class{constructor(e,t,n,r){this.from=e,this.to=t,this.number=n,this.text=r}get length(){return this.to-this.from}};function w(e,t,n){return t=Math.max(0,Math.min(e.length,t)),[t,Math.max(t,Math.min(e.length,n))]}function T(e,t,n=!0,r=!0){return ie(e,t,n,r)}function be(e){return e>=56320&&e<57344}function xe(e){return e>=55296&&e<56320}function Se(e,t){let n=e.charCodeAt(t);if(!xe(n)||t+1==e.length)return n;let r=e.charCodeAt(t+1);return be(r)?(n-55296<<10)+(r-56320)+65536:n}function Ce(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode((e>>10)+55296,(e&1023)+56320))}function we(e){return e<65536?1:2}var Te=/\r\n?|\n/,E=(function(e){return e[e.Simple=0]=`Simple`,e[e.TrackDel=1]=`TrackDel`,e[e.TrackBefore=2]=`TrackBefore`,e[e.TrackAfter=3]=`TrackAfter`,e})(E||={}),Ee=class e{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;te)return i+(e-r);i+=o}else{if(n!=E.Simple&&c>=e&&(n==E.TrackDel&&re||n==E.TrackBefore&&re))return null;if(c>e||c==e&&t<0&&!o)return e==r||t<0?i:i+s;i+=s}r=c}if(e>r)throw RangeError(`Position ${e} is out of range for changeset of length ${r}`);return i}touchesRange(e,t=e){for(let n=0,r=0;n=0&&r<=t&&o>=e)return rt?`cover`:!0;r=o}return!1}toString(){let e=``;for(let t=0;t=0?`:`+r:``)}return e}toJSON(){return this.sections}static fromJSON(t){if(!Array.isArray(t)||t.length%2||t.some(e=>typeof e!=`number`))throw RangeError(`Invalid JSON representation of ChangeDesc`);return new e(t)}static create(t){return new e(t)}},De=class e extends Ee{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw RangeError(`Applying change set to a document with the wrong length`);return ke(this,(t,n,r,i,a)=>e=e.replace(r,r+(n-t),a),!1),e}mapDesc(e,t=!1){return Ae(this,e,t,!0)}invert(t){let n=this.sections.slice(),r=[];for(let e=0,i=0;e=0){n[e]=o,n[e+1]=a;let s=e>>1;for(;r.length0&&Oe(r,n,a.text),a.forward(e),o+=e}let c=t[e++];for(;o>1].toJSON()))}return e}static of(t,n,r){let i=[],a=[],o=0,s=null;function c(t=!1){if(!t&&!i.length)return;os||e<0||s>n)throw RangeError(`Invalid change range ${e} to ${s} (in doc of length ${n})`);let u=l?typeof l==`string`?C.of(l.split(r||Te)):l:C.empty,d=u.length;if(e==s&&d==0)return;eo&&D(i,e-o,-1),D(i,s-e,d),Oe(a,i,u),o=s}}return l(t),c(!s),s}static empty(t){return new e(t?[t,-1]:[],[])}static fromJSON(t){if(!Array.isArray(t))throw RangeError(`Invalid JSON representation of ChangeSet`);let n=[],r=[];for(let e=0;et&&typeof e!=`string`))throw RangeError(`Invalid JSON representation of ChangeSet`);else if(i.length==1)n.push(i[0],0);else{for(;r.length=0&&n<=0&&n==e[i+1]?e[i]+=t:i>=0&&t==0&&e[i]==0?e[i+1]+=n:r?(e[i]+=t,e[i+1]+=n):e.push(t,n)}function Oe(e,t,n){if(n.length==0)return;let r=t.length-2>>1;if(r>1])),!(n||o==e.sections.length||e.sections[o+1]<0);)s=e.sections[o++],c=e.sections[o++];t(i,l,a,u,d),i=l,a=u}}}function Ae(e,t,n,r=!1){let i=[],a=r?[]:null,o=new Me(e),s=new Me(t);for(let e=-1;;)if(o.done&&s.len||s.done&&o.len)throw Error(`Mismatched change set lengths`);else if(o.ins==-1&&s.ins==-1){let e=Math.min(o.len,s.len);D(i,e,-1),o.forward(e),s.forward(e)}else if(s.ins>=0&&(o.ins<0||e==o.i||o.off==0&&(s.len=0&&e=0){let t=0,n=o.len;for(;n;)if(s.ins==-1){let e=Math.min(n,s.len);t+=e,n-=e,s.forward(e)}else if(s.ins==0&&s.lent||o.ins>=0&&o.len>t)&&(e||r.length>n),a.forward2(t),o.forward(t)}}var Me=class{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i>1;return t>=e.length?C.empty:e[t]}textBit(e){let{inserted:t}=this.set,n=this.i-2>>1;return n>=t.length&&!e?C.empty:t[n].slice(this.off,e==null?void 0:this.off+e)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){this.ins==-1?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}},Ne=class e{constructor(e,t,n,r){this.from=e,this.to=t,this.flags=n,this.goalColumn=r}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get undirectional(){return(this.flags&64)>0}get bidiLevel(){let e=this.flags&7;return e==7?null:e}map(t,n=-1){let r,i;return this.empty?r=i=t.mapPos(this.from,n):(r=t.mapPos(this.from,1),i=t.mapPos(this.to,-1)),r==this.from&&i==this.to?this:new e(r,i,this.flags,this.goalColumn)}extend(e,t=e,n=0){if(e<=this.anchor&&t>=this.anchor)return O.range(e,t,void 0,void 0,n);let r=Math.abs(e-this.anchor)>Math.abs(t-this.anchor)?e:t;return O.range(this.anchor,r,void 0,void 0,n)}eq(e,t=!1){return this.anchor==e.anchor&&this.head==e.head&&this.goalColumn==e.goalColumn&&(!t||!this.empty||this.assoc==e.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||typeof e.anchor!=`number`||typeof e.head!=`number`)throw RangeError(`Invalid JSON representation for SelectionRange`);return O.range(e.anchor,e.head)}static create(t,n,r,i){return new e(t,n,r,i)}},O=class e{constructor(e,t){this.ranges=e,this.mainIndex=t}map(t,n=-1){return t.empty?this:e.create(this.ranges.map(e=>e.map(t,n)),this.mainIndex)}eq(e,t=!1){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let n=0;ne.toJSON()),main:this.mainIndex}}static fromJSON(t){if(!t||!Array.isArray(t.ranges)||typeof t.main!=`number`||t.main>=t.ranges.length)throw RangeError(`Invalid JSON representation for EditorSelection`);return new e(t.ranges.map(e=>Ne.fromJSON(e)),t.main)}static single(t,n=t){return new e([e.range(t,n)],0)}static create(t,n=0){if(t.length==0)throw RangeError(`A selection needs at least one range`);for(let r=0,i=0;ie.from-t.from),n=t.indexOf(r);for(let r=1;ri.head?e.range(s,o):e.range(o,s))}}return new e(t,n)}};function Pe(e,t){for(let n of e.ranges)if(n.to>t)throw RangeError(`Selection points outside of document`)}var Fe=0,k=class e{constructor(e,t,n,r,i){this.combine=e,this.compareInput=t,this.compare=n,this.isStatic=r,this.id=Fe++,this.default=e([]),this.extensions=typeof i==`function`?i(this):i}get reader(){return this}static define(t={}){return new e(t.combine||(e=>e),t.compareInput||((e,t)=>e===t),t.compare||(t.combine?(e,t)=>e===t:Ie),!!t.static,t.enables)}of(e){return new Le([],this,0,e)}compute(e,t){if(this.isStatic)throw Error(`Can't compute a static facet`);return new Le(e,this,1,t)}computeN(e,t){if(this.isStatic)throw Error(`Can't compute a static facet`);return new Le(e,this,2,t)}from(e,t){return t||=e=>e,this.compute([e],n=>t(n.field(e)))}};function Ie(e,t){return e==t||e.length==t.length&&e.every((e,n)=>e===t[n])}var Le=class{constructor(e,t,n,r){this.dependencies=e,this.facet=t,this.type=n,this.value=r,this.id=Fe++}dynamicSlot(e){let t=this.value,n=this.facet.compareInput,r=this.id,i=e[r]>>1,a=this.type==2,o=!1,s=!1,c=[];for(let t of this.dependencies)t==`doc`?o=!0:t==`selection`?s=!0:(e[t.id]??1)&1||c.push(e[t.id]);return{create(e){return e.values[i]=t(e),1},update(e,r){if(o&&r.docChanged||s&&(r.docChanged||r.selection)||ze(e,c)){let r=t(e);if(a?!Re(r,e.values[i],n):!n(r,e.values[i]))return e.values[i]=r,1}return 0},reconfigure:(e,o)=>{let s,c=o.config.address[r];if(c!=null){let r=Qe(o,c);if(this.dependencies.every(t=>t instanceof k?o.facet(t)===e.facet(t):t instanceof He?o.field(t,!1)==e.field(t,!1):!0)||(a?Re(s=t(e),r,n):n(s=t(e),r)))return e.values[i]=r,0}else s=t(e);return e.values[i]=s,1}}}get extension(){return this}};function Re(e,t,n){if(e.length!=t.length)return!1;for(let r=0;re[t.id]),i=n.map(e=>e.type),a=r.filter(e=>!(e&1)),o=e[t.id]>>1;function s(e){let n=[];for(let t=0;te===t),t);return t.provide&&(n.provides=t.provide(n)),n}create(e){return(e.facet(Ve).find(e=>e.field==this)?.create||this.createF)(e)}slot(e){let t=e[this.id]>>1;return{create:e=>(e.values[t]=this.create(e),1),update:(e,n)=>{let r=e.values[t],i=this.updateF(r,n);return this.compareF(r,i)?0:(e.values[t]=i,1)},reconfigure:(e,n)=>{let r=e.facet(Ve),i=n.facet(Ve),a;return(a=r.find(e=>e.field==this))&&a!=i.find(e=>e.field==this)?(e.values[t]=a.create(e),1):n.config.address[this.id]==null?(e.values[t]=this.create(e),1):(e.values[t]=n.field(this),0)}}}init(e){return[this,Ve.of({field:this,create:e})]}get extension(){return this}},Ue={lowest:4,low:3,default:2,high:1,highest:0};function We(e){return t=>new Ke(t,e)}var Ge={highest:We(Ue.highest),high:We(Ue.high),default:We(Ue.default),low:We(Ue.low),lowest:We(Ue.lowest)},Ke=class{constructor(e,t){this.inner=e,this.prec=t}get extension(){return this}},qe=class e{of(e){return new Je(this,e)}reconfigure(t){return e.reconfigure.of({compartment:this,extension:t})}get(e){return e.config.compartments.get(this)}},Je=class{constructor(e,t){this.compartment=e,this.inner=t}get extension(){return this}},Ye=class e{constructor(e,t,n,r,i,a){for(this.base=e,this.compartments=t,this.dynamicSlots=n,this.address=r,this.staticValues=i,this.facets=a,this.statusTemplate=[];this.statusTemplate.length>1]}static resolve(t,n,r){let i=[],a=Object.create(null),o=new Map;for(let e of Xe(t,n,o))e instanceof He?i.push(e):(a[e.facet.id]||(a[e.facet.id]=[])).push(e);let s=Object.create(null),c=[],l=[];for(let e of i)s[e.id]=l.length<<1,l.push(t=>e.slot(t));let u=r?.config.facets;for(let e in a){let t=a[e],n=t[0].facet,i=u&&u[e]||[];if(t.every(e=>e.type==0)){if(s[n.id]=c.length<<1|1,Ie(i,t))c.push(r.facet(n));else{let e=n.combine(t.map(e=>e.value));c.push(r&&n.compare(e,r.facet(n))?r.facet(n):e)}}else{for(let e of t)e.type==0?(s[e.id]=c.length<<1|1,c.push(e.value)):(s[e.id]=l.length<<1,l.push(t=>e.dynamicSlot(t)));s[n.id]=l.length<<1,l.push(e=>Be(e,n,t))}}let d=l.map(e=>e(s));return new e(t,o,d,s,c,a)}};function Xe(e,t,n){let r=[[],[],[],[],[]],i=new Map;function a(e,o){let s=i.get(e);if(s!=null){if(s<=o)return;let t=r[s].indexOf(e);t>-1&&r[s].splice(t,1),e instanceof Je&&n.delete(e.compartment)}if(i.set(e,o),Array.isArray(e))for(let t of e)a(t,o);else if(e instanceof Je){if(n.has(e.compartment))throw RangeError(`Duplicate use of compartment in extensions`);let r=t.get(e.compartment)||e.inner;n.set(e.compartment,r),a(r,o)}else if(e instanceof Ke)a(e.inner,e.prec);else if(e instanceof He)r[o].push(e),e.provides&&a(e.provides,o);else if(e instanceof Le)r[o].push(e),e.facet.extensions&&a(e.facet.extensions,Ue.default);else{let t=e.extension;if(!t)throw Error(`Unrecognized extension value in extension set (${e}).`);if(t==e)throw Error(`Unrecognized extension value in extension set (${e}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);a(t,o)}}return a(e,Ue.default),r.reduce((e,t)=>e.concat(t))}function Ze(e,t){if(t&1)return 2;let n=t>>1,r=e.status[n];if(r==4)throw Error(`Cyclic dependency between fields and/or facets`);if(r&2)return r;e.status[n]=4;let i=e.computeSlot(e,e.config.dynamicSlots[n]);return e.status[n]=2|i}function Qe(e,t){return t&1?e.config.staticValues[t>>1]:e.values[t>>1]}var $e=k.define(),et=k.define({combine:e=>e.some(e=>e),static:!0}),tt=k.define({combine:e=>e.length?e[0]:void 0,static:!0}),nt=k.define(),rt=k.define(),it=k.define(),at=k.define({combine:e=>e.length?e[0]:!1}),ot=class{constructor(e,t){this.type=e,this.value=t}static define(){return new st}},st=class{of(e){return new ot(this,e)}},ct=class{constructor(e){this.map=e}of(e){return new A(this,e)}},A=class e{constructor(e,t){this.type=e,this.value=t}map(t){let n=this.type.map(this.value,t);return n===void 0?void 0:n==this.value?this:new e(this.type,n)}is(e){return this.type==e}static define(e={}){return new ct(e.map||(e=>e))}static mapEffects(e,t){if(!e.length)return e;let n=[];for(let r of e){let e=r.map(t);e&&n.push(e)}return n}};A.reconfigure=A.define(),A.appendConfig=A.define();var lt=class e{constructor(t,n,r,i,a,o){this.startState=t,this.changes=n,this.selection=r,this.effects=i,this.annotations=a,this.scrollIntoView=o,this._doc=null,this._state=null,r&&Pe(r,n.newLength),a.some(t=>t.type==e.time)||(this.annotations=a.concat(e.time.of(Date.now())))}static create(t,n,r,i,a,o){return new e(t,n,r,i,a,o)}get newDoc(){return this._doc||=this.changes.apply(this.startState.doc)}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let t of this.annotations)if(t.type==e)return t.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(t){let n=this.annotation(e.userEvent);return!!(n&&(n==t||n.length>t.length&&n.slice(0,t.length)==t&&n[t.length]==`.`))}};lt.time=ot.define(),lt.userEvent=ot.define(),lt.addToHistory=ot.define(),lt.remote=ot.define();function ut(e,t){let n=[];for(let r=0,i=0;;){let a,o;if(r=e[r]))a=e[r++],o=e[r++];else if(i=0;n--){let i=r[n](e);e=i instanceof lt?i:Array.isArray(i)&&i.length==1&&i[0]instanceof lt?i[0]:pt(t,_t(i),!1)}return e}function ht(e){let t=e.startState,n=t.facet(it),r=e;for(let i=n.length-1;i>=0;i--){let a=n[i](e);a&&Object.keys(a).length&&(r=dt(r,ft(t,a,e.changes.newLength),!0))}return r==e?e:lt.create(t,e.changes,e.selection,r.effects,r.annotations,r.scrollIntoView)}var gt=[];function _t(e){return e==null?gt:Array.isArray(e)?e:[e]}var vt=(function(e){return e[e.Word=0]=`Word`,e[e.Space=1]=`Space`,e[e.Other=2]=`Other`,e})(vt||={}),yt=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,bt;try{bt=RegExp(`[\\p{Alphabetic}\\p{Number}_]`,`u`)}catch{}function xt(e){if(bt)return bt.test(e);for(let t=0;t`€`&&(n.toUpperCase()!=n.toLowerCase()||yt.test(n)))return!0}return!1}function St(e){return t=>{if(!/\S/.test(t))return vt.Space;if(xt(t))return vt.Word;for(let n=0;n-1)return vt.Word;return vt.Other}}var j=class e{constructor(e,t,n,r,i,a){this.config=e,this.doc=t,this.selection=n,this.values=r,this.status=e.statusTemplate.slice(),this.computeSlot=i,a&&(a._state=this);for(let e=0;ei.set(t,e)),null),i.set(e.value.compartment,e.value.extension)):e.is(A.reconfigure)?(n=null,r=e.value):e.is(A.appendConfig)&&(n=null,r=_t(r).concat(e.value));let a;n?a=t.startState.values.slice():(n=Ye.resolve(r,i,this),a=new e(n,this.doc,this.selection,n.dynamicSlots.map(()=>null),(e,t)=>t.reconfigure(e,this),null).values);let o=t.startState.facet(et)?t.newSelection:t.newSelection.asSingle();new e(n,t.newDoc,o,a,(e,n)=>n.update(e,t),t)}replaceSelection(e){return typeof e==`string`&&(e=this.toText(e)),this.changeByRange(t=>({changes:{from:t.from,to:t.to,insert:e},range:O.cursor(t.from+e.length,-1)}))}changeByRange(e){let t=this.selection,n=e(t.ranges[0]),r=this.changes(n.changes),i=[n.range],a=_t(n.effects);for(let n=1;nn.spec.fromJSON(a,e)))}}return e.create({doc:t.doc,selection:O.fromJSON(t.selection),extensions:n.extensions?i.concat([n.extensions]):i})}static create(t={}){let n=Ye.resolve(t.extensions||[],new Map),r=t.doc instanceof C?t.doc:C.of((t.doc||``).split(n.staticFacet(e.lineSeparator)||Te)),i=t.selection?t.selection instanceof O?t.selection:O.single(t.selection.anchor,t.selection.head):O.single(0);return Pe(i,r.length),n.staticFacet(et)||(i=i.asSingle()),new e(n,r,i,n.dynamicSlots.map(()=>null),(e,t)=>t.create(e),null)}get tabSize(){return this.facet(e.tabSize)}get lineBreak(){return this.facet(e.lineSeparator)||` diff --git a/internal/ui/dist/assets/settings-BolmPCiI.js b/internal/ui/dist/assets/settings-D2EYPvK1.js similarity index 99% rename from internal/ui/dist/assets/settings-BolmPCiI.js rename to internal/ui/dist/assets/settings-D2EYPvK1.js index e216e791..d4de93b2 100644 --- a/internal/ui/dist/assets/settings-BolmPCiI.js +++ b/internal/ui/dist/assets/settings-D2EYPvK1.js @@ -1,4 +1,4 @@ -import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{C as r,M as i,_ as a,a as o,c as s,d as c,f as l,i as u,o as d,p as f,r as p,x as m,y as h}from"./brand-DUaZkIz1.js";import{t as g}from"./Tooltip-B3r3s_B9.js";import{n as _,r as v,t as y}from"./WarningCircle.es-e9h3eY6B.js";import{B as b,Bt as x,Gt as S,J as C,S as w,Vt as T,Y as E,ct as D,et as O,q as k}from"./index-eh4vL-r5.js";var A=n(e(),1);function j(e={}){let t=e.timeout??2e3,[n,r]=(0,A.useState)(null),[i,a]=(0,A.useState)(!1),o=(0,A.useRef)(null);(0,A.useEffect)(()=>()=>{window.clearTimeout(o.current)},[]);let s=e=>{window.clearTimeout(o.current),o.current=window.setTimeout(()=>a(!1),t),a(e)};return{copy:e=>{`clipboard`in navigator?navigator.clipboard.writeText(e).then(()=>{r(null),s(!0)}).catch(e=>r(e)):r(Error(`useClipboard: navigator.clipboard is not supported`))},reset:()=>{a(!1),r(null),window.clearTimeout(o.current)},error:n,copied:i}}var M=t(),N={timeout:1e3};function P(e){let{children:t,timeout:n,value:r,...a}=i(`CopyButton`,N,e),o=j({timeout:n});return(0,M.jsx)(M.Fragment,{children:t({copy:()=>o.copy(r),copied:o.copied,...a})})}P.displayName=`@mantine/core/CopyButton`;var F=new Map([[`bold`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M228,48V96a12,12,0,0,1-12,12H168a12,12,0,0,1,0-24h19l-7.8-7.8a75.55,75.55,0,0,0-53.32-22.26h-.43A75.49,75.49,0,0,0,72.39,75.57,12,12,0,1,1,55.61,58.41a99.38,99.38,0,0,1,69.87-28.47H126A99.42,99.42,0,0,1,196.2,59.23L204,67V48a12,12,0,0,1,24,0ZM183.61,180.43a75.49,75.49,0,0,1-53.09,21.63h-.43A75.55,75.55,0,0,1,76.77,179.8L69,172H88a12,12,0,0,0,0-24H40a12,12,0,0,0-12,12v48a12,12,0,0,0,24,0V189l7.8,7.8A99.42,99.42,0,0,0,130,226.06h.56a99.38,99.38,0,0,0,69.87-28.47,12,12,0,0,0-16.78-17.16Z`}))],[`duotone`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1,0-16h28.69L182.06,73.37a79.56,79.56,0,0,0-56.13-23.43h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27a96,96,0,0,1,135,.79L208,76.69V48a8,8,0,0,1,16,0ZM186.41,183.29a80,80,0,0,1-112.47-.66L59.31,168H88a8,8,0,0,0,0-16H40a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V179.31l14.63,14.63A95.43,95.43,0,0,0,130,222.06h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`fill`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1-5.66-13.66L180.65,72a79.48,79.48,0,0,0-54.72-22.09h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27,96,96,0,0,1,192,60.7l18.36-18.36A8,8,0,0,1,224,48ZM186.41,183.29A80,80,0,0,1,75.35,184l18.31-18.31A8,8,0,0,0,88,152H40a8,8,0,0,0-8,8v48a8,8,0,0,0,13.66,5.66L64,195.3a95.42,95.42,0,0,0,66,26.76h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`light`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M222,48V96a6,6,0,0,1-6,6H168a6,6,0,0,1,0-12h33.52L183.47,72a81.51,81.51,0,0,0-57.53-24h-.46A81.5,81.5,0,0,0,68.19,71.28a6,6,0,1,1-8.38-8.58,93.38,93.38,0,0,1,65.67-26.76H126a93.45,93.45,0,0,1,66,27.53l18,18V48a6,6,0,0,1,12,0ZM187.81,184.72a81.5,81.5,0,0,1-57.29,23.34h-.46a81.51,81.51,0,0,1-57.53-24L54.48,166H88a6,6,0,0,0,0-12H40a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V174.48l18,18.05a93.45,93.45,0,0,0,66,27.53h.52a93.38,93.38,0,0,0,65.67-26.76,6,6,0,1,0-8.38-8.58Z`}))],[`regular`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1,0-16h28.69L182.06,73.37a79.56,79.56,0,0,0-56.13-23.43h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27a96,96,0,0,1,135,.79L208,76.69V48a8,8,0,0,1,16,0ZM186.41,183.29a80,80,0,0,1-112.47-.66L59.31,168H88a8,8,0,0,0,0-16H40a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V179.31l14.63,14.63A95.43,95.43,0,0,0,130,222.06h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`thin`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M220,48V96a4,4,0,0,1-4,4H168a4,4,0,0,1,0-8h38.34L184.89,70.54A84,84,0,0,0,66.8,69.85a4,4,0,1,1-5.6-5.72,92,92,0,0,1,129.34.76L212,86.34V48a4,4,0,0,1,8,0ZM189.2,186.15a83.44,83.44,0,0,1-58.68,23.91h-.47a83.52,83.52,0,0,1-58.94-24.6L49.66,164H88a4,4,0,0,0,0-8H40a4,4,0,0,0-4,4v48a4,4,0,0,0,8,0V169.66l21.46,21.45A91.43,91.43,0,0,0,130,218.06h.51a91.45,91.45,0,0,0,64.28-26.19,4,4,0,1,0-5.6-5.72Z`}))]]),I=A.forwardRef((e,t)=>A.createElement(o,{ref:t,...e,weights:F}));I.displayName=`ArrowsClockwiseIcon`;var L=I,R=[`settings`,`ingest`],z=[`settings`,`oauth`,`connections`];function B(){let e=D(),t=O({queryKey:z,queryFn:()=>k(`/api/auth/oauth/connections`)}),[n,i]=(0,A.useState)(null),[o,u]=(0,A.useState)(``),p=_({onMutate:async()=>{u(``),await e.cancelQueries({queryKey:z})},mutationFn:async e=>{if(!(await E(`/api/auth/oauth/connections/${encodeURIComponent(e.client_id)}/revoke`,{method:`POST`})).ok)throw Error(`Fanout could not disconnect this agent. Try again.`)},onSuccess:(t,n)=>{e.setQueryData(z,e=>e&&{connections:e.connections.filter(e=>e.client_id!==n.client_id)}),i(null),u(`${n.client_name} disconnected.`)}});return(0,M.jsxs)(s,{gap:`sm`,children:[(0,M.jsxs)(r,{children:[(0,M.jsx)(d,{order:2,fz:22,lts:`-0.02em`,children:`Connected agents`}),(0,M.jsx)(l,{c:`dimmed`,size:`sm`,mt:2,children:`Agents you have authorized to access Fanout through MCP.`})]}),(0,M.jsx)(m,{withBorder:!0,radius:`lg`,p:`lg`,children:t.data?t.data.connections.length===0?(0,M.jsxs)(l,{c:`dimmed`,size:`sm`,children:[`No agents connected. `,(0,M.jsx)(v,{href:w.connect,target:`_blank`,rel:`noopener noreferrer`,inherit:!0,children:`Connect an agent over MCP`}),` to get started.`]}):(0,M.jsx)(s,{gap:`md`,children:t.data.connections.map(e=>(0,M.jsxs)(a,{justify:`space-between`,align:`center`,children:[(0,M.jsxs)(r,{style:{minWidth:0,overflowWrap:`anywhere`},children:[(0,M.jsx)(l,{size:`sm`,fw:600,children:e.client_name}),(0,M.jsxs)(l,{size:`xs`,c:`dimmed`,children:[`Connected `,(0,M.jsx)(`time`,{dateTime:e.connected_at,children:new Date(e.connected_at).toLocaleDateString()})]})]}),(0,M.jsx)(c,{variant:`default`,size:`sm`,onClick:()=>{p.reset(),i(e)},disabled:p.isPending,children:`Disconnect`})]},e.client_id))}):t.isLoading?(0,M.jsx)(l,{c:`dimmed`,size:`sm`,role:`status`,children:`Loading connected agents…`}):(0,M.jsxs)(s,{gap:`sm`,align:`flex-start`,children:[(0,M.jsx)(f,{color:`bad`,radius:`md`,icon:(0,M.jsx)(y,{size:18,weight:`fill`}),children:`Fanout could not load your connected agents.`}),(0,M.jsx)(c,{size:`compact-sm`,variant:`light`,onClick:()=>void t.refetch(),children:`Try again`})]})}),(0,M.jsx)(l,{size:`sm`,c:`dimmed`,role:`status`,"aria-live":`polite`,children:o}),(0,M.jsx)(T,{opened:n!==null,onClose:()=>!p.isPending&&i(null),title:`Disconnect ${n?.client_name??`agent`}?`,centered:!0,radius:`md`,children:(0,M.jsxs)(s,{gap:`md`,children:[(0,M.jsx)(l,{size:`sm`,c:`dimmed`,children:`This agent loses access immediately. Your other agents and browser session stay connected. You can authorize the agent again to reconnect.`}),p.isError&&(0,M.jsx)(f,{color:`bad`,radius:`md`,icon:(0,M.jsx)(y,{size:18,weight:`fill`}),children:`Fanout could not disconnect this agent. Try again.`}),(0,M.jsxs)(a,{justify:`flex-end`,gap:`sm`,children:[(0,M.jsx)(c,{variant:`default`,size:`sm`,onClick:()=>{p.reset(),i(null)},disabled:p.isPending,children:`Cancel`}),(0,M.jsx)(c,{color:`bad`,size:`sm`,loading:p.isPending,onClick:()=>n&&p.mutate(n),children:`Disconnect`})]})]})})]})}function V(e,t){let n=e.trim();return t||/^https:\/\//i.test(n)||/:443$/.test(n)}function H(e,t,n){if(/^https?:\/\//i.test(e.trim()))try{let t=new URL(e);e=`${t.protocol}//${t.hostname}:${t.port||(t.protocol===`https:`?`443`:`80`)}`}catch{}let r=V(e,n)?``:` +import{i as e,r as t,s as n}from"./useRouter-ByJ6_rwb.js";import{C as r,M as i,_ as a,a as o,c as s,d as c,f as l,i as u,o as d,p as f,r as p,x as m,y as h}from"./brand-DUaZkIz1.js";import{t as g}from"./Tooltip-B3r3s_B9.js";import{n as _,r as v,t as y}from"./WarningCircle.es-eZ--e_KS.js";import{B as b,Bt as x,Gt as S,J as C,S as w,Vt as T,Y as E,ct as D,et as O,q as k}from"./index-B7LmyWZW.js";var A=n(e(),1);function j(e={}){let t=e.timeout??2e3,[n,r]=(0,A.useState)(null),[i,a]=(0,A.useState)(!1),o=(0,A.useRef)(null);(0,A.useEffect)(()=>()=>{window.clearTimeout(o.current)},[]);let s=e=>{window.clearTimeout(o.current),o.current=window.setTimeout(()=>a(!1),t),a(e)};return{copy:e=>{`clipboard`in navigator?navigator.clipboard.writeText(e).then(()=>{r(null),s(!0)}).catch(e=>r(e)):r(Error(`useClipboard: navigator.clipboard is not supported`))},reset:()=>{a(!1),r(null),window.clearTimeout(o.current)},error:n,copied:i}}var M=t(),N={timeout:1e3};function P(e){let{children:t,timeout:n,value:r,...a}=i(`CopyButton`,N,e),o=j({timeout:n});return(0,M.jsx)(M.Fragment,{children:t({copy:()=>o.copy(r),copied:o.copied,...a})})}P.displayName=`@mantine/core/CopyButton`;var F=new Map([[`bold`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M228,48V96a12,12,0,0,1-12,12H168a12,12,0,0,1,0-24h19l-7.8-7.8a75.55,75.55,0,0,0-53.32-22.26h-.43A75.49,75.49,0,0,0,72.39,75.57,12,12,0,1,1,55.61,58.41a99.38,99.38,0,0,1,69.87-28.47H126A99.42,99.42,0,0,1,196.2,59.23L204,67V48a12,12,0,0,1,24,0ZM183.61,180.43a75.49,75.49,0,0,1-53.09,21.63h-.43A75.55,75.55,0,0,1,76.77,179.8L69,172H88a12,12,0,0,0,0-24H40a12,12,0,0,0-12,12v48a12,12,0,0,0,24,0V189l7.8,7.8A99.42,99.42,0,0,0,130,226.06h.56a99.38,99.38,0,0,0,69.87-28.47,12,12,0,0,0-16.78-17.16Z`}))],[`duotone`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z`,opacity:`0.2`}),A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1,0-16h28.69L182.06,73.37a79.56,79.56,0,0,0-56.13-23.43h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27a96,96,0,0,1,135,.79L208,76.69V48a8,8,0,0,1,16,0ZM186.41,183.29a80,80,0,0,1-112.47-.66L59.31,168H88a8,8,0,0,0,0-16H40a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V179.31l14.63,14.63A95.43,95.43,0,0,0,130,222.06h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`fill`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1-5.66-13.66L180.65,72a79.48,79.48,0,0,0-54.72-22.09h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27,96,96,0,0,1,192,60.7l18.36-18.36A8,8,0,0,1,224,48ZM186.41,183.29A80,80,0,0,1,75.35,184l18.31-18.31A8,8,0,0,0,88,152H40a8,8,0,0,0-8,8v48a8,8,0,0,0,13.66,5.66L64,195.3a95.42,95.42,0,0,0,66,26.76h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`light`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M222,48V96a6,6,0,0,1-6,6H168a6,6,0,0,1,0-12h33.52L183.47,72a81.51,81.51,0,0,0-57.53-24h-.46A81.5,81.5,0,0,0,68.19,71.28a6,6,0,1,1-8.38-8.58,93.38,93.38,0,0,1,65.67-26.76H126a93.45,93.45,0,0,1,66,27.53l18,18V48a6,6,0,0,1,12,0ZM187.81,184.72a81.5,81.5,0,0,1-57.29,23.34h-.46a81.51,81.51,0,0,1-57.53-24L54.48,166H88a6,6,0,0,0,0-12H40a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V174.48l18,18.05a93.45,93.45,0,0,0,66,27.53h.52a93.38,93.38,0,0,0,65.67-26.76,6,6,0,1,0-8.38-8.58Z`}))],[`regular`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M224,48V96a8,8,0,0,1-8,8H168a8,8,0,0,1,0-16h28.69L182.06,73.37a79.56,79.56,0,0,0-56.13-23.43h-.45A79.52,79.52,0,0,0,69.59,72.71,8,8,0,0,1,58.41,61.27a96,96,0,0,1,135,.79L208,76.69V48a8,8,0,0,1,16,0ZM186.41,183.29a80,80,0,0,1-112.47-.66L59.31,168H88a8,8,0,0,0,0-16H40a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V179.31l14.63,14.63A95.43,95.43,0,0,0,130,222.06h.53a95.36,95.36,0,0,0,67.07-27.33,8,8,0,0,0-11.18-11.44Z`}))],[`thin`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M220,48V96a4,4,0,0,1-4,4H168a4,4,0,0,1,0-8h38.34L184.89,70.54A84,84,0,0,0,66.8,69.85a4,4,0,1,1-5.6-5.72,92,92,0,0,1,129.34.76L212,86.34V48a4,4,0,0,1,8,0ZM189.2,186.15a83.44,83.44,0,0,1-58.68,23.91h-.47a83.52,83.52,0,0,1-58.94-24.6L49.66,164H88a4,4,0,0,0,0-8H40a4,4,0,0,0-4,4v48a4,4,0,0,0,8,0V169.66l21.46,21.45A91.43,91.43,0,0,0,130,218.06h.51a91.45,91.45,0,0,0,64.28-26.19,4,4,0,1,0-5.6-5.72Z`}))]]),I=A.forwardRef((e,t)=>A.createElement(o,{ref:t,...e,weights:F}));I.displayName=`ArrowsClockwiseIcon`;var L=I,R=[`settings`,`ingest`],z=[`settings`,`oauth`,`connections`];function B(){let e=D(),t=O({queryKey:z,queryFn:()=>k(`/api/auth/oauth/connections`)}),[n,i]=(0,A.useState)(null),[o,u]=(0,A.useState)(``),p=_({onMutate:async()=>{u(``),await e.cancelQueries({queryKey:z})},mutationFn:async e=>{if(!(await E(`/api/auth/oauth/connections/${encodeURIComponent(e.client_id)}/revoke`,{method:`POST`})).ok)throw Error(`Fanout could not disconnect this agent. Try again.`)},onSuccess:(t,n)=>{e.setQueryData(z,e=>e&&{connections:e.connections.filter(e=>e.client_id!==n.client_id)}),i(null),u(`${n.client_name} disconnected.`)}});return(0,M.jsxs)(s,{gap:`sm`,children:[(0,M.jsxs)(r,{children:[(0,M.jsx)(d,{order:2,fz:22,lts:`-0.02em`,children:`Connected agents`}),(0,M.jsx)(l,{c:`dimmed`,size:`sm`,mt:2,children:`Agents you have authorized to access Fanout through MCP.`})]}),(0,M.jsx)(m,{withBorder:!0,radius:`lg`,p:`lg`,children:t.data?t.data.connections.length===0?(0,M.jsxs)(l,{c:`dimmed`,size:`sm`,children:[`No agents connected. `,(0,M.jsx)(v,{href:w.connect,target:`_blank`,rel:`noopener noreferrer`,inherit:!0,children:`Connect an agent over MCP`}),` to get started.`]}):(0,M.jsx)(s,{gap:`md`,children:t.data.connections.map(e=>(0,M.jsxs)(a,{justify:`space-between`,align:`center`,children:[(0,M.jsxs)(r,{style:{minWidth:0,overflowWrap:`anywhere`},children:[(0,M.jsx)(l,{size:`sm`,fw:600,children:e.client_name}),(0,M.jsxs)(l,{size:`xs`,c:`dimmed`,children:[`Connected `,(0,M.jsx)(`time`,{dateTime:e.connected_at,children:new Date(e.connected_at).toLocaleDateString()})]})]}),(0,M.jsx)(c,{variant:`default`,size:`sm`,onClick:()=>{p.reset(),i(e)},disabled:p.isPending,children:`Disconnect`})]},e.client_id))}):t.isLoading?(0,M.jsx)(l,{c:`dimmed`,size:`sm`,role:`status`,children:`Loading connected agents…`}):(0,M.jsxs)(s,{gap:`sm`,align:`flex-start`,children:[(0,M.jsx)(f,{color:`bad`,radius:`md`,icon:(0,M.jsx)(y,{size:18,weight:`fill`}),children:`Fanout could not load your connected agents.`}),(0,M.jsx)(c,{size:`compact-sm`,variant:`light`,onClick:()=>void t.refetch(),children:`Try again`})]})}),(0,M.jsx)(l,{size:`sm`,c:`dimmed`,role:`status`,"aria-live":`polite`,children:o}),(0,M.jsx)(T,{opened:n!==null,onClose:()=>!p.isPending&&i(null),title:`Disconnect ${n?.client_name??`agent`}?`,centered:!0,radius:`md`,children:(0,M.jsxs)(s,{gap:`md`,children:[(0,M.jsx)(l,{size:`sm`,c:`dimmed`,children:`This agent loses access immediately. Your other agents and browser session stay connected. You can authorize the agent again to reconnect.`}),p.isError&&(0,M.jsx)(f,{color:`bad`,radius:`md`,icon:(0,M.jsx)(y,{size:18,weight:`fill`}),children:`Fanout could not disconnect this agent. Try again.`}),(0,M.jsxs)(a,{justify:`flex-end`,gap:`sm`,children:[(0,M.jsx)(c,{variant:`default`,size:`sm`,onClick:()=>{p.reset(),i(null)},disabled:p.isPending,children:`Cancel`}),(0,M.jsx)(c,{color:`bad`,size:`sm`,loading:p.isPending,onClick:()=>n&&p.mutate(n),children:`Disconnect`})]})]})})]})}function V(e,t){let n=e.trim();return t||/^https:\/\//i.test(n)||/:443$/.test(n)}function H(e,t,n){if(/^https?:\/\//i.test(e.trim()))try{let t=new URL(e);e=`${t.protocol}//${t.hostname}:${t.port||(t.protocol===`https:`?`443`:`80`)}`}catch{}let r=V(e,n)?``:` tls: insecure: true`;return`exporters: otlp/fanout: diff --git a/internal/ui/dist/index.html b/internal/ui/dist/index.html index 523064a8..d71ebe5f 100644 --- a/internal/ui/dist/index.html +++ b/internal/ui/dist/index.html @@ -21,7 +21,7 @@ document.documentElement.setAttribute("data-mantine-color-scheme", computed); } catch (e) {} - + diff --git a/scripts/dashboard-eval/mock.ts b/scripts/dashboard-eval/mock.ts index 89106e83..9b06c2b8 100644 --- a/scripts/dashboard-eval/mock.ts +++ b/scripts/dashboard-eval/mock.ts @@ -31,7 +31,7 @@ export function startMock(failure?:Failure,intents?:EvaluationConfig['prompts']) if(path.startsWith('/api/agent/threads/'))return Response.json({id:path.split('/').at(-1)!,messages:threads.get(path.split('/').at(-1)!)??[],updated_at:'2026-10-01 13:00:00'}); if(path.startsWith('/api/agent/runs/')&&req.method==='GET'){stats.status_reads++;return Response.json({status:statuses.get(path.split('/').at(-1)!)??'unknown'});} if(path.endsWith('/versions')) {stats.version_reads++;const id=path.split('/').at(-2)!;return Response.json({versions:Array.from({length:boards.get(id)?.version??0},(_,i)=>({version:i+1,author_kind:'agent'}))});} - if(path==='/api/panels/query') { + if(path==='/api/queries/run') { stats.queries++;const {dashboard}=await req.json(); if(failure==='invalid')return Response.json({code:'invalid_dashboard',message:'Synthetic validation',problems:[{path:'panels'}]},{status:400}); if(failure==='unchecked')return Response.json({},{status:503}); diff --git a/scripts/dashboard-eval/transport.ts b/scripts/dashboard-eval/transport.ts index b26eac76..107dc946 100644 --- a/scripts/dashboard-eval/transport.ts +++ b/scripts/dashboard-eval/transport.ts @@ -142,7 +142,7 @@ export function mutationEvidence(state:StreamState,messages:ObjectValue[]|undefi } export async function executePanels(request:(path:string,init?:RequestInit)=>Promise,spec:Spec,signal:AbortSignal):Promise<{valid:boolean;checked:boolean;checks:Check[]}> { try { - const data=await request('/api/panels/query',{method:'POST',body:JSON.stringify({dashboard:spec}),signal}); + const data=await request('/api/queries/run',{method:'POST',body:JSON.stringify({dashboard:spec}),signal}); if(!Array.isArray(data.results))throw new Error('missing_checks'); const checks=data.results.map((r:any)=>({id:r.id,status:r.status,rows:r.frame?.rows??0,...(typeof r.diagnosis==='string'?{diagnosis:r.diagnosis}:{}),...(typeof r.error==='string'?{error:r.error}:{})})); if(checks.some((c:Check)=>typeof c.id!=='string'||typeof c.status!=='string'||!Number.isFinite(c.rows)||c.rows<0))throw new Error('invalid_checks'); diff --git a/site/src/content/docs/docs/reference/api.mdx b/site/src/content/docs/docs/reference/api.mdx index 92b5b77a..7268d625 100644 --- a/site/src/content/docs/docs/reference/api.mdx +++ b/site/src/content/docs/docs/reference/api.mdx @@ -130,9 +130,9 @@ Operational responses at `/healthz`, `/readyz` and `/metrics` keep their bodies. | `GET` | `/api/fanql/reference` | `telemetry:read` | | `GET` | `/api/intelligence` | `telemetry:read` | | `Any` | `/api/mcp` | `telemetry:read` | -| `POST` | `/api/panels/exemplars` | `telemetry:read` | -| `POST` | `/api/panels/query` | `telemetry:read` | -| `POST` | `/api/panels/variables/resolve` | `telemetry:read` | +| `POST` | `/api/queries/exemplars` | `telemetry:read` | +| `POST` | `/api/queries/run` | `telemetry:read` | +| `POST` | `/api/queries/variables/resolve` | `telemetry:read` | | `GET` | `/api/settings/ingest` | `ingest:read-metadata` | | `POST` | `/api/settings/ingest/token/rotate` | `ingest:manage` | | `GET` | `/api/telemetry/schema` | `telemetry:read` | diff --git a/site/src/content/docs/docs/reference/fanql.md b/site/src/content/docs/docs/reference/fanql.md index fef661e9..6fd1d035 100644 --- a/site/src/content/docs/docs/reference/fanql.md +++ b/site/src/content/docs/docs/reference/fanql.md @@ -12,7 +12,7 @@ generated: true Preview: the syntax may change before GA -FanQL is the text form of a structured telemetry query. It produces the same `panel.Query` that dashboards store and the panel engine executes. Panels store the query; text is derived. Problems prevent execution; notices never block it. Each diagnostic says what happened and what to write instead, using a valid example from that field. Diagnostics use display names without internal visualization identifiers and report all independent problems in one pass, in source order. Only follow-on cascades are suppressed. +FanQL is the text form of a structured telemetry query. It produces the same `query.Spec` that dashboards store and the engine executes. Panels store the query; text is derived. Problems prevent execution; notices never block it. Each diagnostic says what happened and what to write instead, using a valid example from that field. Diagnostics use display names without internal visualization identifiers and report all independent problems in one pass, in source order. Only follow-on cascades are suppressed. ## Shape and entry points diff --git a/ui/host/e2e/specs/app/landing-recordings.spec.ts b/ui/host/e2e/specs/app/landing-recordings.spec.ts index 485907b3..ff457ec3 100644 --- a/ui/host/e2e/specs/app/landing-recordings.spec.ts +++ b/ui/host/e2e/specs/app/landing-recordings.spec.ts @@ -138,7 +138,7 @@ for (const view of ["chat", "dashboard"] as const) { expect(saved.ok()).toBe(true); const { spec } = await saved.json() as { spec: DashboardSpec }; expect(spec.panels.length, "The created dashboard must contain at least six panels").toBeGreaterThanOrEqual(6); - const preview = await context.request.post("/api/panels/query", { + const preview = await context.request.post("/api/queries/run", { headers: { "Fanout-Request": "1" }, data: { dashboard: spec }, }); expect(preview.ok()).toBe(true); diff --git a/ui/host/e2e/specs/app/performance.spec.ts b/ui/host/e2e/specs/app/performance.spec.ts index f83ee4f7..8409f351 100644 --- a/ui/host/e2e/specs/app/performance.spec.ts +++ b/ui/host/e2e/specs/app/performance.spec.ts @@ -63,7 +63,7 @@ async function evidence(observed: ReturnType, start = 0): Promis for (const event of events) { expect(event.finished, `Complete body: ${event.path}`).toBe(true); expect(event.response?.ok(), `HTTP success: ${event.path}`).toBe(true); - if (event.path !== "/api/panels/query") continue; + if (event.path !== "/api/queries/run") continue; const body = await event.response!.json() as { results: PanelResult[] }; const selected = (event.request.postDataJSON() as { panels?: string[] }).panels ?? panelIds; const returned = body.results.map(result => result.id).sort(); @@ -90,7 +90,7 @@ async function evidence(observed: ReturnType, start = 0): Promis async function assertInitial(page: Page, observed: ReturnType) { await settled(page, observed); - await expect.poll(() => observed.events.filter(event => event.path === "/api/panels/variables/resolve" && event.finished).length).toBe(1); + await expect.poll(() => observed.events.filter(event => event.path === "/api/queries/variables/resolve" && event.finished).length).toBe(1); await expect.poll(() => observed.events.filter(event => event.path === "/api/annotations" && event.finished).length).toBeGreaterThan(0); const initial = await evidence(observed); expect([...new Set(initial.batches.flatMap(batch => batch.results.map(result => result.id)))].sort()).toEqual(panelIds); @@ -189,16 +189,16 @@ test("refreshes once per batch and resolves variables once per range", async ({ const start = observed.events.length; await page.getByRole("group", { name: "Dashboard controls", exact: true }).getByRole("button").first().click(); await page.getByRole("menuitem", { name: "Last 12 hours", exact: true }).click(); - await expect.poll(() => observed.events.slice(start).filter(event => event.path === "/api/panels/variables/resolve" && event.finished).length).toBe(1); + await expect.poll(() => observed.events.slice(start).filter(event => event.path === "/api/queries/variables/resolve" && event.finished).length).toBe(1); await page.waitForFunction(allPanelsPainted, spec.panels, { polling: "raf" }).then(handle => handle.dispose()); await settled(page, observed); - await expect.poll(() => observed.events.slice(start).filter(event => event.path === "/api/panels/variables/resolve").length).toBe(1); + await expect.poll(() => observed.events.slice(start).filter(event => event.path === "/api/queries/variables/resolve").length).toBe(1); await attach("range-change.json", await evidence(observed, start)); } for (let cycle = 1; cycle <= 3; cycle++) { const start = observed.events.length; await page.getByRole("button", { name: "Refresh now", exact: true }).click(); - for (const path of ["/api/panels/query", "/api/annotations"]) { + for (const path of ["/api/queries/run", "/api/annotations"]) { await expect.poll(() => observed.events.slice(start).filter(event => event.path === path && event.finished).length).toBe(1); } await page.waitForFunction(allPanelsPainted, spec.panels, { polling: "raf" }).then(handle => handle.dispose()); diff --git a/ui/host/e2e/specs/app/smoke.spec.ts b/ui/host/e2e/specs/app/smoke.spec.ts index a9e77549..3a07d062 100644 --- a/ui/host/e2e/specs/app/smoke.spec.ts +++ b/ui/host/e2e/specs/app/smoke.spec.ts @@ -18,7 +18,7 @@ const expectedElements: Record = { }; test("resolves dashboard variables through the panel route", async ({ request }) => { - const response = await request.post("/api/panels/variables/resolve", { + const response = await request.post("/api/queries/variables/resolve", { headers: { "Fanout-Request": "1" }, data: { dashboard: spec }, }); expect(response.status()).toBe(200); @@ -94,7 +94,7 @@ async function mapGeometry(card: Locator) { test("all fifteen dashboard panels settle with valid geometry", async ({ page }) => { const results = new Map(); page.on("response", async response => { - if (new URL(response.url()).pathname !== "/api/panels/query") return; + if (new URL(response.url()).pathname !== "/api/queries/run") return; try { const body = await response.json(); for (const result of body.results ?? []) results.set(result.id, result); diff --git a/ui/host/e2e/specs/app/system-overview.spec.ts b/ui/host/e2e/specs/app/system-overview.spec.ts index 5d566855..1f9d300c 100644 --- a/ui/host/e2e/specs/app/system-overview.spec.ts +++ b/ui/host/e2e/specs/app/system-overview.spec.ts @@ -32,7 +32,7 @@ test("default system overview shows all six self-observation scenarios within tw // before navigating so the pinned document's initial results are included. const responses: Response[] = []; const collectResponse = (response: Response) => { - if (new URL(response.url()).pathname !== "/api/panels/query" || !response.ok()) return; + if (new URL(response.url()).pathname !== "/api/queries/run" || !response.ok()) return; const time = (response.request().postDataJSON() as { time?: DashboardTime }).time; if (time?.from === pinned.searchParams.get("from") && time?.to === pinned.searchParams.get("to")) responses.push(response); }; @@ -43,7 +43,7 @@ test("default system overview shows all six self-observation scenarios within tw // existing visibility-based query and verifies that its renderer is populated. for (const panel of panels) await readyCard(page, panel); for (let refresh = 0; refresh < 2; refresh++) { - const response = page.waitForResponse(response => new URL(response.url()).pathname === "/api/panels/query" && response.ok()); + const response = page.waitForResponse(response => new URL(response.url()).pathname === "/api/queries/run" && response.ok()); await page.getByRole("button", { name: "Refresh now", exact: true }).click(); await response; for (const panel of panels) await readyCard(page, panel); diff --git a/ui/host/e2e/support/accessibility-support.ts b/ui/host/e2e/support/accessibility-support.ts index 286ed339..0dbbefda 100644 --- a/ui/host/e2e/support/accessibility-support.ts +++ b/ui/host/e2e/support/accessibility-support.ts @@ -57,7 +57,7 @@ function alter(result: PanelResult, scenario?: Scenario): PanelResult { export async function openSurface(page: Page, request: APIRequestContext, info: TestInfo, surface: Surface, panel?: Panel, scenario?: Scenario): Promise { const theme = themeFor(info); if (surface === "dashboard") { - if (scenario && scenario !== "stale") await page.route("**/api/panels/query", async route => { + if (scenario && scenario !== "stale") await page.route("**/api/queries/run", async route => { const response = await route.fetch(); const body = await response.json() as { results: PanelResult[] }; body.results = body.results.map(result => result.id === panel!.id ? alter(result, scenario) : result); @@ -73,7 +73,7 @@ export async function openSurface(page: Page, request: APIRequestContext, info: // State mutations below are explicitly synthetic, not telemetry. const panels = panel ? [panel] : spec.panels; const dashboard: DashboardSpec = { ...spec, variables: [{ name: "service", kind: "custom", options: ["checkout"], multi: true, include_all: true, default: "$__all" }], panels }; - const response = await request.post("/api/panels/query", { headers: { "Fanout-Request": "1" }, data: { dashboard, vars: { service: "$__all" } } }); + const response = await request.post("/api/queries/run", { headers: { "Fanout-Request": "1" }, data: { dashboard, vars: { service: "$__all" } } }); expect(response.status()).toBe(200); const body = await response.json() as { results: PanelResult[] }; expect(body.results).toHaveLength(panels.length); @@ -115,7 +115,7 @@ export async function chooseView(surface: Page | Frame, card: Locator, mode: "Da } export async function staleSurface(page: Page, surface: Page | Frame, kind: Surface, card: Locator) { if (kind === "dashboard") { - await page.route("**/api/panels/query", route => route.fulfill({ status: 503, json: { code: "query_unavailable", message: "Synthetic fixture: refresh unavailable." } })); + await page.route("**/api/queries/run", route => route.fulfill({ status: 503, json: { code: "query_unavailable", message: "Synthetic fixture: refresh unavailable." } })); await page.getByRole("button", { name: "Refresh now", exact: true }).click(); // Only panels in view refresh; clicking the toolbar scrolled the card away. await card.scrollIntoViewIfNeeded(); diff --git a/ui/host/e2e/support/global-setup.ts b/ui/host/e2e/support/global-setup.ts index 6ed63da8..4294e978 100644 --- a/ui/host/e2e/support/global-setup.ts +++ b/ui/host/e2e/support/global-setup.ts @@ -134,7 +134,7 @@ export default async function globalSetup({ signalCleanup = true, onSignal = () ] }; const deadline = Date.now() + 90_000; await waitUntilReady(deadline, async () => { - const { body } = await requestJSON("/api/panels/query", { dashboard }, Math.max(1, Math.min(20_000, deadline - Date.now()))); + const { body } = await requestJSON("/api/queries/run", { dashboard }, Math.max(1, Math.min(20_000, deadline - Date.now()))); // Counts can precede log flushes and edge publication; inspect kind, not total rows. return readinessCause(body); }); @@ -154,7 +154,7 @@ export default async function globalSetup({ signalCleanup = true, onSignal = () performanceSpec.time = { from: seedWindow[1], to: seedWindow[2], refresh: "off" }; const performanceDeadline = Date.now() + 90_000; await waitUntilReady(performanceDeadline, async () => { - const { body } = await requestJSON("/api/panels/query", { dashboard: performanceSpec }, Math.max(1, Math.min(20_000, performanceDeadline - Date.now()))); + const { body } = await requestJSON("/api/queries/run", { dashboard: performanceSpec }, Math.max(1, Math.min(20_000, performanceDeadline - Date.now()))); return performanceReadinessCause(body, performanceSpec.panels.map((panel: { id: string }) => panel.id)); }); const { response: performanceCreated, body: performanceRecord } = await requestJSON("/api/dashboards", { spec: performanceSpec }); diff --git a/ui/host/e2e/support/performance-support.test.ts b/ui/host/e2e/support/performance-support.test.ts index f7122add..329ba4cc 100644 --- a/ui/host/e2e/support/performance-support.test.ts +++ b/ui/host/e2e/support/performance-support.test.ts @@ -13,9 +13,9 @@ it("uses nearest-rank p95 without dropping slow samples or mutating input", () = }); it("counts completed refresh requests including duplicates and variable reloads", () => { - const valid = ["/api/panels/query", "/api/annotations"]; + const valid = ["/api/queries/run", "/api/annotations"]; expect(() => assertRefreshRequests(valid)).not.toThrow(); - for (const extra of ["/api/panels/query", "/api/annotations", "/api/panels/variables/resolve"]) { + for (const extra of ["/api/queries/run", "/api/annotations", "/api/queries/variables/resolve"]) { expect(() => assertRefreshRequests([...valid, extra])).toThrow(); } expect(() => assertRefreshRequests(valid.slice(0, 1))).toThrow(); diff --git a/ui/host/e2e/support/performance-support.ts b/ui/host/e2e/support/performance-support.ts index 4adfb60f..a17e57ce 100644 --- a/ui/host/e2e/support/performance-support.ts +++ b/ui/host/e2e/support/performance-support.ts @@ -14,7 +14,7 @@ export function p95(values: number[]): number { export function assertRefreshRequests(paths: string[]) { const count = (path: string) => paths.filter(value => value === path).length; - if (count("/api/panels/query") !== 1 || count("/api/annotations") !== 1 || count("/api/panels/variables/resolve") !== 0) { + if (count("/api/queries/run") !== 1 || count("/api/annotations") !== 1 || count("/api/queries/variables/resolve") !== 0) { throw new Error("Refresh request budget exceeded"); } } diff --git a/ui/host/src/auth-session.test.ts b/ui/host/src/auth-session.test.ts index 9db8dbbd..4171c45c 100644 --- a/ui/host/src/auth-session.test.ts +++ b/ui/host/src/auth-session.test.ts @@ -102,7 +102,7 @@ describe("authorizedFetch", () => { fetchMock.mockResolvedValueOnce(json({ code: "forbidden", message: "insufficient permissions" }, 403)); await expect(authorizedFetch("/api/data")).rejects.toThrow("insufficient permissions"); fetchMock.mockResolvedValueOnce(json({ code: "forbidden", message: "insufficient permissions" }, 403)); - await expect(authorizedFetch("/api/panels/query")).rejects.toEqual(new ApiError("insufficient permissions", 403, [], "forbidden")); + await expect(authorizedFetch("/api/queries/run")).rejects.toEqual(new ApiError("insufficient permissions", 403, [], "forbidden")); fetchMock.mockResolvedValueOnce(new Response("", { status: 503 })); expect((await authorizedFetch("/api/data")).status).toBe(503); expect(unauthorized).not.toHaveBeenCalled(); diff --git a/ui/host/src/dashboards/api.test.ts b/ui/host/src/dashboards/api.test.ts index e64d3100..d0cd4911 100644 --- a/ui/host/src/dashboards/api.test.ts +++ b/ui/host/src/dashboards/api.test.ts @@ -56,7 +56,7 @@ describe("dashboard api", () => { }); it("posts panel batches using the shared JSON request path",async()=>{ - fetchMock.mockResolvedValue(json(200,{results:[]}));await expect(queryPanels({dashboard:spec})).resolves.toEqual([]);expect(lastCall()[0]).toBe("/api/panels/query");expect(lastCall()[1].method).toBe("POST");expect(JSON.parse(String(lastCall()[1].body))).toEqual({dashboard:spec}); + fetchMock.mockResolvedValue(json(200,{results:[]}));await expect(queryPanels({dashboard:spec})).resolves.toEqual([]);expect(lastCall()[0]).toBe("/api/queries/run");expect(lastCall()[1].method).toBe("POST");expect(JSON.parse(String(lastCall()[1].body))).toEqual({dashboard:spec}); }); it("posts annotation windows as JSON and forwards the abort signal", async () => { const annotations = { deploys: [], anomalies: [], truncated: true }; @@ -83,7 +83,7 @@ it("uses the captured full window for trace lookups and passes cancellation to b expect(lastCall()[1].signal).toBe(signal); const body = { dashboard: spec, panel_id: target.panel_id, kind: "traces" as const, from: target.from, to: target.to, time: { from: target.window_from, to: target.window_to, refresh: "off" }, dimensions: target.dimensions, bucket: target.bucket }; await queryExemplars(body, signal); - expect(lastCall()[0]).toBe("/api/panels/exemplars"); + expect(lastCall()[0]).toBe("/api/queries/exemplars"); expect(lastCall()[1].method).toBe("POST"); expect(lastCall()[1].signal).toBe(signal); expect(JSON.parse(String(lastCall()[1].body))).toEqual(body); diff --git a/ui/host/src/dashboards/api.ts b/ui/host/src/dashboards/api.ts index 2f5a1e5e..757558cf 100644 --- a/ui/host/src/dashboards/api.ts +++ b/ui/host/src/dashboards/api.ts @@ -52,16 +52,16 @@ export const replaceDashboard = (id: string, spec: DashboardSpec, baseVersion: n request(path(id), { method: "PUT", json: { spec, base_version: baseVersion, message } }); export const patchDashboard = (id: string, operations: Operation[], baseVersion: number, message?: string) => request(path(id), { method: "PATCH", json: { operations, base_version: baseVersion, message } }); -export const queryPanels = (body: QueryBody, signal?: AbortSignal) => request<{ results: PanelResult[] }>("/api/panels/query", { method: "POST", json: body, signal }).then((r) => r.results); +export const queryPanels = (body: QueryBody, signal?: AbortSignal) => request<{ results: PanelResult[] }>("/api/queries/run", { method: "POST", json: body, signal }).then((r) => r.results); export const getTelemetrySchema = (signal?: AbortSignal) => request("/api/telemetry/schema", { signal }); export const queryAnnotations = (body: AnnotationBody, signal?: AbortSignal) => request("/api/annotations", { method: "POST", json: body, signal }); export const resolveVariables = (body: Omit, signal?: AbortSignal) => - request<{ options: Record }>("/api/panels/variables/resolve", { method: "POST", json: body, signal }).then((r) => r.options); + request<{ options: Record }>("/api/queries/variables/resolve", { method: "POST", json: body, signal }).then((r) => r.options); export type ExemplarBody = { dashboard: DashboardSpec; panel_id: string; kind?: "traces" | "logs"; time?: DashboardTime; from: string; to: string; dimensions?: Record; bucket?: Selection["bucket"]; vars?: Record }; export type Exemplar = { trace_id: string; namespace: string; service: string; operation: string; duration_ms: number; status: string; start: string }; export type ExemplarResponse = { traces: Exemplar[]; logs?: Frame; truncated?: boolean }; -export const queryExemplars = (body: ExemplarBody, signal?: AbortSignal) => request("/api/panels/exemplars", { method: "POST", json: body, signal }); +export const queryExemplars = (body: ExemplarBody, signal?: AbortSignal) => request("/api/queries/exemplars", { method: "POST", json: body, signal }); export function getTrace(target: DrillTarget, signal?: AbortSignal): Promise> { const params = new URLSearchParams({ namespace: target.namespace ?? "", from: target.window_from, to: target.window_to, limit: "200" }); return request>(`/api/traces/${encodeURIComponent(target.trace_id ?? "")}?${params}`, { signal }); diff --git a/ui/host/src/dashboards/fullscreen.test.tsx b/ui/host/src/dashboards/fullscreen.test.tsx index f340d5cd..7364ee89 100644 --- a/ui/host/src/dashboards/fullscreen.test.tsx +++ b/ui/host/src/dashboards/fullscreen.test.tsx @@ -94,7 +94,7 @@ it.each(["Back", "Escape then Back"])("opens shared URL state (%s) without a que const path = new URL(String(input), "http://localhost").pathname; if (path === "/api/dashboards") return Response.json({ dashboards: [{ id: "board", name: "Observed" }] }); if (path === "/api/dashboards/board") return Response.json({ id: "board", version: 7, spec: { ...spec, time: { ...spec.time, refresh: "off" } } }); - if (path === "/api/panels/query") { queries++; return Response.json({ results: [result] }); } + if (path === "/api/queries/run") { queries++; return Response.json({ results: [result] }); } if (path === "/api/annotations") return Response.json({ deploys: [], anomalies: [] }); return Response.json({ options: {} }); })); diff --git a/ui/host/src/dashboards/page.test.tsx b/ui/host/src/dashboards/page.test.tsx index 070e98d2..9264300a 100644 --- a/ui/host/src/dashboards/page.test.tsx +++ b/ui/host/src/dashboards/page.test.tsx @@ -87,9 +87,9 @@ beforeEach(() => { if (url.pathname === "/api/dashboards") return listResponse(); if (url.pathname === "/api/dashboards/d1") return json(servedRecord); if (url.pathname === "/api/dashboards/missing") return json({ code: "not_found", message: "dashboard not found" }, 404); - if (url.pathname === "/api/panels/variables/resolve") return variableResponse(); + if (url.pathname === "/api/queries/variables/resolve") return variableResponse(); if (url.pathname === "/api/annotations") return annotationResponse(); - if (url.pathname === "/api/panels/query") { + if (url.pathname === "/api/queries/run") { const body = JSON.parse(String(init?.body)) as { panels: string[]; dashboard: { panels: { id: string }[] } }; queryBodies.push(body); if (body.panels.some((id) => !body.dashboard.panels.some((panel) => panel.id === id))) return json({ message: "no panel has id" }, 400); @@ -235,13 +235,13 @@ describe("DashboardPage", () => { if (path === "/api/dashboards/d1/versions") return json({ versions: [{ version: 2, author_kind: "agent", message: "Earlier edit", created_at: "2026-10-01T12:00:00Z" }] }); if (path === "/api/dashboards/d1/versions/2") return json({ dashboard: { ...restored, version: 2, name: "Historical" }, author_kind: "agent", message: "Earlier edit", created_at: "2026-10-01T12:00:00Z", changes: [], layout_changed: false, dashboard_fields: [], changes_available: true }); if (path === "/api/dashboards/d1/versions/2/restore") { servedRecord = restored; return json(restored); } - if (path === "/api/panels/exemplars") return json({ traces: [] }); + if (path === "/api/queries/exemplars") return json({ traces: [] }); return existing(input, init); }); const search: DashboardSearch = { from: "2026-10-01T12:00:00Z", to: "2026-10-01T13:00:00Z", vars: { service: "cart" }, compare: "1", view: "latency", drill: JSON.stringify({ panel_id: "latency", kind: "traces", from: "2026-10-01T12:00:00Z", to: "2026-10-01T13:00:00Z", window_from: "2026-10-01T12:00:00Z", window_to: "2026-10-01T13:00:00Z", dimensions: {} }) }; const { client, onSearch } = await render(search); const count = queryBodies.length; - const variableCount = fetchMock.mock.calls.filter(([input]) => String(input) === "/api/panels/variables/resolve").length; + const variableCount = fetchMock.mock.calls.filter(([input]) => String(input) === "/api/queries/variables/resolve").length; await act(async () => [...document.querySelectorAll("button")].find(button => button.textContent === "History")!.click()); await settle(client); expect(queryBodies).toHaveLength(count); @@ -253,7 +253,7 @@ describe("DashboardPage", () => { if (removed) expect(onSearch).toHaveBeenCalledWith({ ...search, view: undefined, drill: undefined }, true); else expect(onSearch).not.toHaveBeenCalled(); expect(queryBodies.length).toBeGreaterThan(count); - expect(fetchMock.mock.calls.filter(([input]) => String(input) === "/api/panels/variables/resolve").length).toBeGreaterThan(variableCount); + expect(fetchMock.mock.calls.filter(([input]) => String(input) === "/api/queries/variables/resolve").length).toBeGreaterThan(variableCount); const laterBatches = queryBodies.slice(count) as { dashboard: { panels: { id: string }[] } }[]; if (removed) expect(laterBatches.every(body => body.dashboard.panels.every(panel => panel.id !== "latency"))).toBe(true); }); @@ -519,8 +519,8 @@ describe("DashboardPage", () => { variableResponse = () => new Promise(() => {}); panelResponse = () => new Promise(() => {}); const { rerender } = await render({}, "d1", false); - await vi.waitFor(() => expect(fetchMock.mock.calls.filter(([input]) => /\/api\/(panels\/(query|variables\/resolve))$/.test(String(input)))).toHaveLength(2), { interval: 5, timeout: 3000 }); - const signals = fetchMock.mock.calls.filter(([input]) => /\/api\/(panels\/(query|variables\/resolve))$/.test(String(input))) + await vi.waitFor(() => expect(fetchMock.mock.calls.filter(([input]) => /\/api\/queries\/(run|variables\/resolve)$/.test(String(input)))).toHaveLength(2), { interval: 5, timeout: 3000 }); + const signals = fetchMock.mock.calls.filter(([input]) => /\/api\/queries\/(run|variables\/resolve)$/.test(String(input))) .map(([, init]) => init?.signal); expect(signals).toHaveLength(2); expect(signals.every((signal) => signal instanceof AbortSignal)).toBe(true); @@ -613,7 +613,7 @@ describe("dashboard batch regressions", () => { else variableResponse = async () => json({ message: "Invalid" }, 400); const { client } = await render(); await settle(client); - const path = kind === "panels" ? "/api/panels/query" : "/api/panels/variables/resolve"; + const path = kind === "panels" ? "/api/queries/run" : "/api/queries/variables/resolve"; await vi.waitFor(() => expect(fetchMock.mock.calls.filter(([input]) => String(input) === path)).toHaveLength(1), { interval: 5, timeout: 3000 }); }); }); @@ -638,7 +638,7 @@ it.each(["panels", "variables"])("retries server errors at most twice for %s", a else variableResponse = async () => json({ message: "Server failed" }, 500); const { host, client } = await render(); await settle(client); - const path = kind === "panels" ? "/api/panels/query" : "/api/panels/variables/resolve"; + const path = kind === "panels" ? "/api/queries/run" : "/api/queries/variables/resolve"; await vi.waitFor(() => expect(fetchMock.mock.calls.filter(([input]) => String(input) === path)).toHaveLength(3), { interval: 5, timeout: 3000 }); await vi.waitFor(() => expect(host.textContent).toContain("Server failed"), { interval: 5, timeout: 3000 }); }); @@ -728,9 +728,9 @@ it("pushes drill and click variables atomically while preserving the captured pa const target = JSON.parse(next.drill!); expect(target).toMatchObject({ panel_id: "latency", kind: "traces", from: new Date(1000).toISOString(), to: new Date(10000).toISOString(), window_from: new Date(0).toISOString(), window_to: new Date(10000).toISOString(), dimensions: { service: "cart" } }); const implementation = fetchMock.getMockImplementation()!; - fetchMock.mockImplementation(async (input, init) => String(input) === "/api/panels/exemplars" ? json({ traces: [] }) : implementation(input, init)); + fetchMock.mockImplementation(async (input, init) => String(input) === "/api/queries/exemplars" ? json({ traces: [] }) : implementation(input, init)); await rerender(next); await settle(client); - const request = fetchMock.mock.calls.find(([url]) => String(url) === "/api/panels/exemplars")!; + const request = fetchMock.mock.calls.find(([url]) => String(url) === "/api/queries/exemplars")!; expect(JSON.parse(String(request[1]?.body))).toMatchObject({ kind: "traces", from: target.from, to: target.to, time: { from: target.window_from, to: target.window_to, refresh: "off" }, vars: { service: "cart" } }); await vi.waitFor(() => expect(document.body.textContent).toContain("No exemplar traces match this selection."), { interval: 5, timeout: 3000 }); }); diff --git a/ui/host/src/dashboards/panel-sql-editor.test.tsx b/ui/host/src/dashboards/panel-sql-editor.test.tsx index 76f2e2a2..c4bab1e6 100644 --- a/ui/host/src/dashboards/panel-sql-editor.test.tsx +++ b/ui/host/src/dashboards/panel-sql-editor.test.tsx @@ -32,7 +32,7 @@ beforeEach(() => { save = async () => json({ id: "d1", version: 8, spec: { ...spec, panels: spec.panels.map(p => p.id === "count" ? { ...p, sql: edited } : p) } }); fetchMock.mockImplementation(async (input, init) => { if (String(input) === "/api/telemetry/schema") return json({ signals: { spans: { columns: [{ name: "start_time", type: "time" }] } }, sql_relations: {} }); - if (String(input) === "/api/panels/query") return preview(); + if (String(input) === "/api/queries/run") return preview(); if (String(input) === "/api/dashboards/d1" && init?.method === "PATCH") return save(); throw new Error(`Unexpected request: ${input}`); }); @@ -61,7 +61,7 @@ it("edits, runs through the existing query API, renders the result and saves onl expect((ui.getByRole("button", { name: "Save SQL" }) as HTMLButtonElement).disabled).toBe(true); await change(edited); await click("Run"); await wait(() => expect(ui.getByText("42")).toBeDefined()); - const query = fetchMock.mock.calls.find(([url]) => String(url) === "/api/panels/query")!; + const query = fetchMock.mock.calls.find(([url]) => String(url) === "/api/queries/run")!; expect(JSON.parse(String(query[1]?.body))).toEqual({ dashboard: { ...spec, panels: [spec.panels[0], { ...spec.panels[1], sql: edited }] }, panels: ["count"], time, vars, compare: true, widths: { count: 800 } }); await click("Save SQL"); await wait(() => expect(onClose).toHaveBeenCalledOnce()); @@ -171,7 +171,7 @@ it("aborts an in-flight preview on unmount", async () => { const pending = new Promise(() => {}); fetchMock.mockImplementation(async (input, init) => { if (String(input) === "/api/telemetry/schema") return json({ signals: {}, sql_relations: {} }); - if (String(input) === "/api/panels/query") { signal = init?.signal ?? undefined; return pending; } + if (String(input) === "/api/queries/run") { signal = init?.signal ?? undefined; return pending; } return pending; }); const { click } = await render(); diff --git a/ui/panels/types.ts b/ui/panels/types.ts index d9529b3d..063425f1 100644 --- a/ui/panels/types.ts +++ b/ui/panels/types.ts @@ -1,4 +1,4 @@ -/* The v1 dashboard spec and panel results, mirroring internal/panel. Pure +/* The v1 dashboard spec and panel results, mirroring internal/query. Pure * types: this directory has no node_modules and imports only siblings. */ export const ALL = "$__all"; diff --git a/ui/panels/variables.ts b/ui/panels/variables.ts index f876be2c..6508eb8a 100644 --- a/ui/panels/variables.ts +++ b/ui/panels/variables.ts @@ -1,6 +1,6 @@ import { ALL, type Variable, type VarValue } from "./types"; -/** internal/panel/variables.go chooseValue precedence, with stale URL choices +/** internal/query/variables.go chooseValue precedence, with stale URL choices * filtered against options once available. Text values are free-form. */ export function currentValue(variable: Variable, vars: Record, options?: { value: string }[] | null): VarValue { if (variable.kind === "constant") return variable.value ?? "";