diff --git a/README.md b/README.md index 569a47d..75d558e 100644 --- a/README.md +++ b/README.md @@ -258,11 +258,11 @@ AST is the default extractor. It is a **framework overlay**, not an import graph | Surface | What Loadpath extracts | | --- | --- | | Models | Fields, FK / M2M / O2O, `on_delete`, string refs (`ForeignKey("accounts.User")`) as residuals | -| Serializers | `Meta.fields` / `exclude`, declared fields, `serializes` edges, queryset-in-serializer flag | -| Views | DRF ViewSets / APIViews, `serializer_class`, `get_serializer_class` (residual), `permission_classes`, `get_queryset`, `filterset_class`, `authentication_classes`, `pagination_class` | +| Serializers | `Meta.fields` / `exclude`, declared fields, nested serializers, `SerializerMethodField`, parsed `to_representation` keys, `serializes` edges, queryset-in-serializer flag | +| Views | DRF ViewSets / APIViews, `serializer_class`, `get_serializer_class` (resolved returns; residual only when unresolved), `permission_classes`, `get_queryset`, `filterset_class`, `authentication_classes`, `pagination_class` | | Function views | `@api_view`, `@login_required`, `@csrf_exempt`, … | -| Django Ninja | `@router.get/post/…` routes and views | -| FastAPI (same repo) | `@app.get/post/…` and Pydantic `BaseModel` — only when the file imports FastAPI, so Ninja is not stolen | +| Django Ninja | `@router.get/post/…` routes and views, `Schema` / `ModelSchema` fields (including nested), response annotation → schema | +| FastAPI (same repo) | `@app.get/post/…` and Pydantic `BaseModel` (nested annotations) — only when the file imports FastAPI, so Ninja is not stolen | | GraphQL | Strawberry `@strawberry.type` / `@strawberry.field` and Graphene `ObjectType` / `Mutation`; client `gql` documents stitch by operation/selection name | | Channels | `WebsocketConsumer` subclasses and `path(..., Consumer.as_asgi())` websocket routes | | Templates + HTMX | `.html` files, `{% url %}` / include / extends, `hx-get/post/…` stitched to Django routes | @@ -301,9 +301,9 @@ AST is enough for review. If you need live `_meta` (db_table, resolved relations ## React + stitch -**React:** react-router tables, composition, TanStack Query `queryKey` + fetch/axios URL templates, Zod schemas, feature-folder imports, RTL `render()` as `tested_by`. +**React:** react-router tables, Next.js App Router (`app/**/page.tsx`) and Pages Router, Server Actions, composition, TanStack Query `queryKey` + fetch/axios URL templates, RTK Query `createApi` endpoints, openapi-fetch `client.GET/POST`, tRPC procedures, ts-rest `path:` contracts, Zod schemas, GraphQL codegen types, feature-folder imports, RTL `render()` and Playwright/Cypress `page.goto` / `cy.visit` as `tested_by`. -**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) as high-confidence `consumed_by_client`; FastAPI routes and GraphQL operations stitch the same way; HTMX URLs match Django routes; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. +**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) and typed clients (RTK Query, openapi-fetch, ts-rest, tRPC) as high-confidence `consumed_by_client`; FastAPI routes, Ninja/Pydantic schemas, and GraphQL operations (including codegen types) stitch the same way; HTMX URLs and Playwright/Cypress visits match Django/React routes; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. Frontend roots prefer `frontend/src`, `frontend`, `web/src`, `client/src`, `ui/src`, `src-ui/src` — not a Python package `src/` and not `docs` / docs-site trees. `app/` is a Django root candidate. diff --git a/fixtures/demo_monorepo/backend/billing/api.py b/fixtures/demo_monorepo/backend/billing/api.py index 4f0afa6..90ef7cd 100644 --- a/fixtures/demo_monorepo/backend/billing/api.py +++ b/fixtures/demo_monorepo/backend/billing/api.py @@ -1,11 +1,21 @@ -from ninja import Router +from ninja import Router, Schema from billing.models import Invoice router = Router() +class LedgerLineSchema(Schema): + amount: str + kind: str + + +class InvoiceSchema(Schema): + total: str + lines: list[LedgerLineSchema] + + @router.get("/invoices/{invoice_id}/ledger") -def invoice_ledger(request, invoice_id: int): +def invoice_ledger(request, invoice_id: int) -> InvoiceSchema: invoice = Invoice.objects.get(pk=invoice_id) - return {"total": str(invoice.total)} + return InvoiceSchema(total=str(invoice.total), lines=[]) diff --git a/fixtures/demo_monorepo/backend/billing/serializers.py b/fixtures/demo_monorepo/backend/billing/serializers.py index 485530b..3f61acc 100644 --- a/fixtures/demo_monorepo/backend/billing/serializers.py +++ b/fixtures/demo_monorepo/backend/billing/serializers.py @@ -7,3 +7,28 @@ class InvoiceSerializer(serializers.ModelSerializer): class Meta: model = Invoice fields = ["id", "customer_id", "total", "status"] + + +class LineSerializer(serializers.Serializer): + amount = serializers.DecimalField(max_digits=10, decimal_places=2) + kind = serializers.CharField() + + +class InvoiceDetailSerializer(serializers.ModelSerializer): + lines = LineSerializer(many=True) + display_total = serializers.SerializerMethodField() + + class Meta: + model = Invoice + fields = ["id", "customer_id", "total", "status", "lines", "display_total"] + + def get_display_total(self, obj): + return str(obj.total) + + def to_representation(self, instance): + return { + "id": instance.id, + "total": str(instance.total), + "status": instance.status, + "display_total": str(instance.total), + } diff --git a/fixtures/demo_monorepo/backend/billing/views.py b/fixtures/demo_monorepo/backend/billing/views.py index bdb6e41..7aeb8af 100644 --- a/fixtures/demo_monorepo/backend/billing/views.py +++ b/fixtures/demo_monorepo/backend/billing/views.py @@ -9,7 +9,7 @@ from billing.actors import rebuild_ledger from billing.models import Invoice -from billing.serializers import InvoiceSerializer +from billing.serializers import InvoiceDetailSerializer, InvoiceSerializer from billing.tasks import send_invoice_email @@ -37,6 +37,16 @@ def perform_create(self, serializer): return invoice +class InvoiceDetailViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [IsAuthenticated] + queryset = Invoice.objects.all() + + def get_serializer_class(self): + if self.action == "list": + return InvoiceSerializer + return InvoiceDetailSerializer + + class InvoiceBoardView(TemplateView): template_name = "billing/invoice_board.html" diff --git a/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts b/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts new file mode 100644 index 0000000..f5d5033 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts @@ -0,0 +1,7 @@ +import { expect, test } from "@playwright/test"; + +test("invoice page load path", async ({ page }) => { + await page.goto("/invoices/1"); + await page.request.get("/api/invoices/1"); + await expect(page.getByRole("heading")).toBeVisible(); +}); diff --git a/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts new file mode 100644 index 0000000..9eda193 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts @@ -0,0 +1,6 @@ +"use server"; + +export async function saveInvoice(formData: FormData) { + const id = String(formData.get("id") || ""); + return id; +} diff --git a/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx new file mode 100644 index 0000000..ee978bd --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx @@ -0,0 +1,13 @@ +import { InvoiceForm } from "../../../features/billing/InvoiceForm"; +import { saveInvoice } from "./actions"; + +export default function InvoicesPage({ params }: { params: { id: string } }) { + return ( +
+ +
+ +
+
+ ); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql b/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql new file mode 100644 index 0000000..ef81b93 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql @@ -0,0 +1,6 @@ +query Invoice($id: ID!) { + invoice { + total + status + } +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts new file mode 100644 index 0000000..7d5a61d --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts @@ -0,0 +1,14 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; + +export const invoiceApi = createApi({ + reducerPath: "invoiceApi", + baseQuery: fetchBaseQuery({ baseUrl: "/api" }), + endpoints: (builder) => ({ + getInvoice: builder.query({ + query: (id: string) => `/invoices/${id}`, + }), + saveInvoice: builder.mutation({ + query: (body: unknown) => ({ url: "/invoices", method: "POST", body }), + }), + }), +}); diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts b/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts new file mode 100644 index 0000000..a707424 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts @@ -0,0 +1,7 @@ +declare const client: { + GET: (path: string, init?: unknown) => Promise; +}; + +export function getInvoiceTyped(id: string) { + return client.GET("/api/invoices/{id}", { params: { path: { id } } }); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts b/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts new file mode 100644 index 0000000..5851fac --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts @@ -0,0 +1,7 @@ +declare const trpc: { + invoice: { get: { useQuery: (args: { id: string }) => unknown } }; +}; + +export function useInvoiceRpc(id: string) { + return trpc.invoice.get.useQuery({ id }); +} diff --git a/fixtures/demo_monorepo/frontend/src/generated/graphql.ts b/fixtures/demo_monorepo/frontend/src/generated/graphql.ts new file mode 100644 index 0000000..d0cc75a --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/generated/graphql.ts @@ -0,0 +1,12 @@ +/** graphql-codegen types — stitch to InvoiceType by field overlap. */ +export type InvoiceType = { + __typename?: "InvoiceType"; + id: number; + total: number; + status: string; +}; + +export type InvoiceQuery = { + __typename?: "Query"; + invoice?: InvoiceType | null; +}; diff --git a/fixtures/demo_monorepo/loadpath.yml b/fixtures/demo_monorepo/loadpath.yml index 7e49888..9c04a46 100644 --- a/fixtures/demo_monorepo/loadpath.yml +++ b/fixtures/demo_monorepo/loadpath.yml @@ -2,7 +2,7 @@ contexts: billing: django_apps: [billing] - react: [src/features/billing, frontend/src/features/billing] + react: [src/features/billing, frontend/src/features/billing, frontend/src/app/invoices] public_api: - "GET /api/invoices" - "POST /api/invoices" diff --git a/src/loadpath/architecture/snapshot.py b/src/loadpath/architecture/snapshot.py index 0c6ac98..d4ca208 100644 --- a/src/loadpath/architecture/snapshot.py +++ b/src/loadpath/architecture/snapshot.py @@ -30,6 +30,7 @@ NodeType.HOOK.value, NodeType.API_CLIENT.value, NodeType.FORM_SCHEMA.value, + NodeType.SERVER_ACTION.value, NodeType.GRAPHQL_TYPE.value, NodeType.GRAPHQL_OPERATION.value, NodeType.FASTAPI_ROUTE.value, diff --git a/src/loadpath/config.py b/src/loadpath/config.py index aa5e509..671a5bf 100644 --- a/src/loadpath/config.py +++ b/src/loadpath/config.py @@ -55,6 +55,7 @@ class LoadpathConfig: "**/generated/**/*.{ts,tsx,js}", "**/*openapi*.{ts,js}", "**/orval/**/*.{ts,js}", + "**/*graphql*.{ts,tsx,js}", ] ) extra: dict[str, Any] = field(default_factory=dict) diff --git a/src/loadpath/detect.py b/src/loadpath/detect.py index 48ac662..315b7a9 100644 --- a/src/loadpath/detect.py +++ b/src/loadpath/detect.py @@ -176,6 +176,7 @@ def _detect_django_root(repo_root: Path) -> str: "client/src", "ui/src", "ui", + "src/app", ) SKIP_REACT_PARTS = { diff --git a/src/loadpath/extractors/django.py b/src/loadpath/extractors/django.py index b26d58b..3315444 100644 --- a/src/loadpath/extractors/django.py +++ b/src/loadpath/extractors/django.py @@ -74,6 +74,7 @@ CELERY_TASK_BASES = {"Task"} DRAMATIQ_TASK_BASES = {"GenericActor"} NINJA_HTTP = {"get", "post", "put", "patch", "delete", "api_operation"} +NINJA_SCHEMA_BASES = {"Schema", "ModelSchema"} FASTAPI_HTTP = {"get", "post", "put", "patch", "delete", "options", "head", "trace", "api_route", "websocket"} CONSUMER_BASES = { "WebsocketConsumer", @@ -154,6 +155,34 @@ def _list_names(node: ast.AST | None) -> list[str]: return [n.split(".")[-1]] if n else [] +def _ann_class_names(node: ast.AST | None) -> list[str]: + if node is None: + return [] + if isinstance(node, ast.Name): + return [node.id] if node.id[:1].isupper() else [] + if isinstance(node, ast.Attribute): + n = _name(node) + short = n.split(".")[-1] if n else "" + return [short] if short[:1].isupper() else [] + if isinstance(node, ast.Subscript): + return _ann_class_names(node.value) + _ann_class_names(node.slice) + if isinstance(node, ast.Tuple): + names: list[str] = [] + for elt in node.elts: + names.extend(_ann_class_names(elt)) + return names + if isinstance(node, ast.BinOp): + return _ann_class_names(node.left) + _ann_class_names(node.right) + if isinstance(node, ast.Constant) and isinstance(node.value, str) and node.value[:1].isupper(): + return [node.value.split(".")[-1]] + return [] + + +def _looks_like_ninja_blob(imports: dict[str, str], from_imports: dict[str, str]) -> bool: + blob = " ".join(imports.values()) + " " + " ".join(from_imports.values()) + return "ninja" in blob.lower() + + def _bases(node: ast.ClassDef) -> list[str]: return [b for b in (_name(base) for base in node.bases) if b] @@ -409,6 +438,8 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None: self._graphql_type(node) elif _has_base(node, {"BaseModel"}) and not _has_base(node, MODEL_BASES): self._pydantic_model(node) + elif self._is_ninja_schema(node): + self._pydantic_model(node, ninja=True) elif _has_base(node, ADMIN_BASES) or node.name.endswith("Admin"): self._admin(node) elif any(x.endswith("Config") for x in _bases(node)) or node.name.endswith("Config"): @@ -577,6 +608,9 @@ def _serializer( declared.append((fname, stmt.lineno)) if isinstance(stmt, ast.FunctionDef) and "queryset" in ast.dump(stmt): queryset_in_serializer = True + nested_by_name = self._nested_serializer_fields(node) + method_fields = self._method_field_names(node) + to_repr_fields = self._to_representation_fields(node) body = self._slice(node) if queryset_in_serializer or ".objects." in body or "objects.filter" in body: ser.extra["queryset_in_serializer"] = True @@ -586,10 +620,27 @@ def _serializer( for f in meta_fields: if f not in existing: fields.append((f, node.lineno)) + existing_names = {n for n, _ in fields} + for fname in to_repr_fields: + if fname not in existing_names: + fields.append((fname, node.lineno)) + existing_names.add(fname) for fname, lineno in fields: fq = f"{qname}.{fname}" - fn = self.add_node(NodeType.SERIALIZER_FIELD, fname, fq, lineno, {"app": self.app}) + field_extra: dict = {"app": self.app} + nested = nested_by_name.get(fname) + if nested: + field_extra["nested_serializer"] = nested + if fname in method_fields: + field_extra["method_field"] = True + if fname in to_repr_fields: + field_extra["from_to_representation"] = True + fn = self.add_node(NodeType.SERIALIZER_FIELD, fname, fq, lineno, field_extra) self.add_edge(ser.id, fn.id, EdgeType.HAS_FIELD) + if nested: + nested_q = nested if "." in nested else f"{self.app}.{nested.split('.')[-1]}" + self.add_edge(fn.id, node_id(NodeType.SERIALIZER, nested_q), EdgeType.USES_SERIALIZER, extra={"nested": True}) + self.add_edge(ser.id, node_id(NodeType.SERIALIZER, nested_q), EdgeType.CALLS, extra={"nested": True}) if meta_model: model_q = meta_model if "." in meta_model else f"{self.app}.{meta_model.split('.')[-1]}" self.add_edge(fn.id, node_id(NodeType.FIELD, f"{model_q}.{fname}"), EdgeType.SERIALIZES, confidence=0.85) @@ -598,6 +649,17 @@ def _serializer( self.add_edge(ser.id, node_id(NodeType.MODEL, model_q), EdgeType.SERIALIZES) if meta_exclude: ser.extra["exclude"] = meta_exclude + if nested_by_name: + ser.extra["nested_serializers"] = sorted(set(nested_by_name.values())) + if method_fields: + ser.extra["method_fields"] = sorted(method_fields) + if to_repr_fields: + ser.extra["to_representation_fields"] = to_repr_fields + elif any(isinstance(s, ast.FunctionDef) and s.name == "to_representation" for s in node.body): + ser.extra["to_representation"] = True + self.graph.residuals.append( + f"to_representation on {qname} ({self.rel_path}:{node.lineno}) — published fields not parsed" + ) def _view(self, node: ast.ClassDef) -> None: qname = f"{self.app}.{node.name}" @@ -637,9 +699,14 @@ def _view(self, node: ast.ClassDef) -> None: if isinstance(stmt, ast.FunctionDef) and stmt.name == "get_serializer_class": dynamic_serializer = True extra["get_serializer_class"] = True - self.graph.residuals.append( - f"Dynamic get_serializer_class on {qname} ({self.rel_path}:{stmt.lineno})" - ) + resolved = self._serializer_names_in(stmt) + extra["serializer_classes"] = resolved + if resolved: + extra["get_serializer_class_resolved"] = True + else: + self.graph.residuals.append( + f"Dynamic get_serializer_class on {qname} ({self.rel_path}:{stmt.lineno})" + ) if isinstance(stmt, ast.FunctionDef) and stmt.name in { "list", "create", @@ -662,6 +729,14 @@ def _view(self, node: ast.ClassDef) -> None: else f"{self.app}.{serializer_class.split('.')[-1]}" ) self.add_edge(view.id, node_id(NodeType.SERIALIZER, ser_q), EdgeType.USES_SERIALIZER) + for name in extra.get("serializer_classes") or []: + ser_q = name if "." in name and not name.startswith("serializers") else f"{self.app}.{name.split('.')[-1]}" + self.add_edge( + view.id, + node_id(NodeType.SERIALIZER, ser_q), + EdgeType.USES_SERIALIZER, + extra={"from": "get_serializer_class"}, + ) if extra.get("filterset") and extra["filterset"] not in {True, False}: fs = str(extra["filterset"]) fs_q = fs if "." in fs and not fs.startswith("filter") else f"{self.app}.{fs.split('.')[-1]}" @@ -987,6 +1062,21 @@ def _maybe_ninja(self, node: ast.FunctionDef) -> bool: {"app": self.app, "route": route, "ninja": True, "method": short.upper()}, ) self.add_edge(rn.id, view.id, EdgeType.PUBLISHES_ROUTE) + for schema_name in self._ninja_response_schemas(node, dec): + schema_q = f"{self.app}.{schema_name.split('.')[-1]}" + self.add_edge( + view.id, + node_id(NodeType.PYDANTIC_MODEL, schema_q), + EdgeType.USES_SERIALIZER, + extra={"ninja_schema": True}, + ) + if route: + self.add_edge( + rn.id, + node_id(NodeType.PYDANTIC_MODEL, schema_q), + EdgeType.USES_SERIALIZER, + extra={"ninja_schema": True}, + ) return hit def _owner_id(self) -> tuple[NodeType, str]: @@ -1095,6 +1185,7 @@ def _graphql_type(self, node: ast.ClassDef) -> None: {"app": self.app}, ) self.add_edge(gql.id, field.id, EdgeType.HAS_FIELD) + extra.setdefault("fields", []).append(fname) if root and not any( n.type is NodeType.GRAPHQL_OPERATION and n.name == fname for n in self.graph.nodes ): @@ -1147,21 +1238,182 @@ def _maybe_graphql_operation(self, node: ast.FunctionDef) -> None: EdgeType.PUBLISHES_GRAPHQL, ) - def _pydantic_model(self, node: ast.ClassDef) -> None: + def _pydantic_model(self, node: ast.ClassDef, *, ninja: bool = False) -> None: qname = f"{self.app}.{node.name}" - extra: dict = _with_doc({"app": self.app, "pydantic": True}, node) + extra: dict = _with_doc({"app": self.app, "pydantic": True, "ninja_schema": ninja}, node) + meta_fields: list[str] = [] + for stmt in node.body: + if isinstance(stmt, ast.ClassDef) and stmt.name == "Meta": + for m in stmt.body: + if isinstance(m, ast.Assign) and m.targets and isinstance(m.targets[0], ast.Name) and m.targets[0].id == "fields": + if isinstance(m.value, (ast.List, ast.Tuple)): + meta_fields = [ + elt.value + for elt in m.value.elts + if isinstance(elt, ast.Constant) and isinstance(elt.value, str) + ] + extra["fields"] = [] model = self.add_node(NodeType.PYDANTIC_MODEL, node.name, qname, node.lineno, extra) + seen: set[str] = set() for stmt in node.body: if isinstance(stmt, ast.AnnAssign) and isinstance(stmt.target, ast.Name): fname = stmt.target.id + if fname.startswith("_") or fname in seen: + continue + seen.add(fname) + extra["fields"].append(fname) field = self.add_node( NodeType.SERIALIZER_FIELD, fname, f"{qname}.{fname}", stmt.lineno, - {"app": self.app, "pydantic": True}, + {"app": self.app, "pydantic": True, "ninja_schema": ninja}, ) self.add_edge(model.id, field.id, EdgeType.HAS_FIELD) + for nested in _ann_class_names(stmt.annotation): + if nested in {"Optional", "List", "Dict", "Union", "Any", "Schema", "BaseModel", node.name}: + continue + self.add_edge( + field.id, + node_id(NodeType.PYDANTIC_MODEL, f"{self.app}.{nested}"), + EdgeType.USES_SERIALIZER, + extra={"nested": True}, + ) + self.add_edge( + model.id, + node_id(NodeType.PYDANTIC_MODEL, f"{self.app}.{nested}"), + EdgeType.CALLS, + extra={"nested": True}, + ) + for fname in meta_fields: + if fname in seen: + continue + seen.add(fname) + extra["fields"].append(fname) + field = self.add_node( + NodeType.SERIALIZER_FIELD, + fname, + f"{qname}.{fname}", + node.lineno, + {"app": self.app, "pydantic": True, "ninja_schema": ninja}, + ) + self.add_edge(model.id, field.id, EdgeType.HAS_FIELD) + + def _looks_like_ninja(self) -> bool: + return _looks_like_ninja_blob(self.imports, self.from_imports) + + def _is_ninja_schema(self, node: ast.ClassDef) -> bool: + for base in _bases(node): + short = base.split(".")[-1] + if short not in NINJA_SCHEMA_BASES: + continue + resolved = self._resolve(base) + if "ninja" in resolved.lower(): + return True + return False + + def _ninja_response_schemas(self, node: ast.FunctionDef, dec: ast.Call) -> list[str]: + names = _ann_class_names(node.returns) + names.extend(_ann_class_names(_kw(dec, "response"))) + resp = _kw(dec, "response") + if isinstance(resp, ast.Dict): + for val in resp.values: + names.extend(_ann_class_names(val)) + skip = { + "dict", + "list", + "Dict", + "List", + "Any", + "None", + "int", + "str", + "bool", + "float", + "Optional", + "Union", + "HttpResponse", + "HttpRequest", + } + out: list[str] = [] + seen: set[str] = set() + for name in names: + short = name.split(".")[-1] + if short in skip or short in seen or not short[:1].isupper(): + continue + seen.add(short) + out.append(short) + return out + + def _nested_serializer_fields(self, node: ast.ClassDef) -> dict[str, str]: + found: dict[str, str] = {} + for stmt in node.body: + if not isinstance(stmt, ast.Assign) or not stmt.targets or not isinstance(stmt.targets[0], ast.Name): + continue + fname = stmt.targets[0].id + call = stmt.value if isinstance(stmt.value, ast.Call) else None + raw = _name(call.func if call else stmt.value) + if not raw: + continue + short = raw.split(".")[-1] + if short.endswith("Serializer") and short not in SERIALIZER_BASES: + found[fname] = short + return found + + def _method_field_names(self, node: ast.ClassDef) -> set[str]: + names: set[str] = set() + for stmt in node.body: + if not isinstance(stmt, ast.Assign) or not stmt.targets or not isinstance(stmt.targets[0], ast.Name): + continue + call = stmt.value if isinstance(stmt.value, ast.Call) else None + raw = _name(call.func if call else None) or "" + if raw.split(".")[-1] == "SerializerMethodField": + names.add(stmt.targets[0].id) + return names + + def _to_representation_fields(self, node: ast.ClassDef) -> list[str]: + for stmt in node.body: + if isinstance(stmt, ast.FunctionDef) and stmt.name == "to_representation": + keys: list[str] = [] + seen: set[str] = set() + for child in ast.walk(stmt): + if not isinstance(child, ast.Return) or not isinstance(child.value, ast.Dict): + continue + for key in child.value.keys: + if isinstance(key, ast.Constant) and isinstance(key.value, str): + if key.value not in seen: + seen.add(key.value) + keys.append(key.value) + return keys + return [] + + def _serializer_names_in(self, node: ast.AST) -> list[str]: + names: list[str] = [] + seen: set[str] = set() + for child in ast.walk(node): + candidates: list[str] = [] + if isinstance(child, ast.Return) and child.value is not None: + n = _name(child.value) + if n: + candidates.append(n) + if isinstance(child.value, ast.Dict): + for val in child.value.values: + vn = _name(val) + if vn: + candidates.append(vn) + if isinstance(child.value, ast.Subscript): + inner = child.value.value + if isinstance(inner, ast.Dict): + for val in inner.values: + vn = _name(val) + if vn: + candidates.append(vn) + for n in candidates: + short = n.split(".")[-1] + if short.endswith("Serializer") and short not in SERIALIZER_BASES and short not in seen: + seen.add(short) + names.append(short) + return names def _consumer(self, node: ast.ClassDef) -> None: qname = f"{self.app}.{node.name}" diff --git a/src/loadpath/extractors/react.py b/src/loadpath/extractors/react.py index 4c5af2b..741a41e 100644 --- a/src/loadpath/extractors/react.py +++ b/src/loadpath/extractors/react.py @@ -65,13 +65,51 @@ DEFAULT_VALUE_RE = re.compile(r"""(?:defaultValue|name)\s*=\s*(?:\{[^}]*\.(\w+)|['"](\w+)['"])""") BOUNDARY_RE = re.compile(r"""\b(ErrorBoundary|Suspense)\b""") RTK_RE = re.compile(r"""createApi\s*\(\s*\{""") +RTK_ENDPOINT_RE = re.compile( + r"""(?P[A-Za-z_]\w*)\s*:\s*builder\.(?Pquery|mutation|infiniteQuery)\b""" +) +RTK_BASE_URL_RE = re.compile(r"""baseUrl\s*:\s*['"`]([^'"`]+)""") +OPENAPI_FETCH_RE = re.compile( + r"""\.(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\(\s*['"`]([^'"`]+)""" +) +TRPC_RE = re.compile( + r"""\btrpc\.((?:[A-Za-z_]\w*\.)+)use(?:Query|Mutation|InfiniteQuery|SuspenseQuery)\b""" +) +TS_REST_ROUTE_RE = re.compile( + r"""method\s*:\s*['"](?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)['"][^}]*?path\s*:\s*['"]([^'"]+)['"]""" + r"""|path\s*:\s*['"]([^'"]+)['"][^}]*?method\s*:\s*['"](?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)['"]""", + re.S, +) +E2E_VISIT_RE = re.compile( + r"""(?:page\.goto|cy\.visit|cy\.request|page\.request\.(?:get|post|put|patch|delete)|request\.(?:get|post))\(\s*(?:['"`]([^'"`]+)['"`]|`([^`]+)`)""", + re.I, +) +E2E_GOTO_RE = re.compile( + r"""(?:page\.goto|cy\.visit)\(\s*(?:['"`]([^'"`]+)['"`]|`([^`]+)`)""", + re.I, +) +SERVER_ACTION_FN_RE = re.compile( + r"""export\s+(?:async\s+)?function\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(""" + r"""|export\s+const\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z_]\w*)\s*=>""" +) +CODEGEN_TYPE_RE = re.compile(r"""export\s+type\s+([A-Z][A-Za-z0-9_]*)\s*=\s*\{""") +CODEGEN_FIELD_RE = re.compile(r"""^\s{1,6}([A-Za-z_]\w*)\s*\??\s*:""", re.M) FEATURE_FOLDER_RE = re.compile(r"""features/([^/]+)""") GQL_DOC_RE = re.compile( r"""(?:gql|graphql)\s*(?:<[^>]*>)?\s*`([^`]+)`""", re.S, ) +GQL_FILE_OP_RE = re.compile( + r"""^\s*(query|mutation|subscription)\s+([A-Za-z_]\w*)""", + re.M, +) GQL_OP_RE = re.compile(r"""\b(query|mutation|subscription)\s+([A-Za-z_]\w*)""") GQL_SELECTION_RE = re.compile(r"""\{\s*([A-Za-z_]\w*)""") +APP_SPECIAL = {"page", "layout", "route", "loading", "error", "default", "template"} +HTTP_VERBS = {"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"} +E2E_TEST_RE = re.compile( + r"""(\.test|\.spec|\.cy)\.(t|j)sx?$""" +) def _feature_from_path(rel: str) -> str | None: @@ -94,14 +132,163 @@ def normalize_url_template(url: str) -> str: return url.rstrip("/") or "/" +def _feature_from_app_segments(segments: list[str]) -> str | None: + for seg in segments: + if seg.startswith("[") or seg.startswith("(") or seg.startswith("@"): + continue + return seg + return None + + +def _dynamic_to_template(seg: str) -> str: + if seg.startswith("[[...") or seg.startswith("[..."): + return "{id}" + if seg.startswith("[") and seg.endswith("]"): + inner = seg.strip("[]") + if inner in {"id", "pk", "slug", "uuid"}: + return "{id}" + return "{" + inner + "}" + return seg + + +def app_router_info(rel: str) -> dict | None: + """Map app/**/page.tsx (and layout/route) to a URL template.""" + parts = rel.replace("\\", "/").split("/") + stem = Path(rel).stem + if stem not in APP_SPECIAL: + return None + if "app" not in parts: + return None + idx = len(parts) - 1 - parts[::-1].index("app") + segs = [p for p in parts[idx + 1 : -1] if not (p.startswith("(") and p.endswith(")")) and not p.startswith("@")] + url_parts = [_dynamic_to_template(s) for s in segs] + route = "/" + "/".join(url_parts) if url_parts else "/" + return {"route": normalize_url_template(route), "kind": stem, "segments": segs} + + +def pages_router_info(rel: str) -> dict | None: + parts = rel.replace("\\", "/").split("/") + if "pages" not in parts: + return None + idx = parts.index("pages") + rest = parts[idx + 1 :] + if not rest: + return None + filename = rest[-1] + if filename.startswith("_"): + return None + stem = Path(filename).stem + segs = list(rest[:-1]) + api = bool(segs and segs[0] == "api") + if stem != "index": + segs.append(stem) + if api and segs[:1] == ["api"]: + segs = segs[1:] + url_parts = [_dynamic_to_template(s) for s in segs] + if api: + url_parts = ["api", *url_parts] + route = "/" + "/".join(url_parts) if url_parts else "/" + return {"route": normalize_url_template(route), "kind": "api" if api else "page", "segments": segs, "api": api} + + +def _e2e_template(url: str) -> str: + url = normalize_url_template(url) + url = re.sub(r"/\d+(?=/|$)", "/{id}", url) + return url + + +def is_e2e_file(rel: str) -> bool: + path = rel.replace("\\", "/") + if E2E_TEST_RE.search(path): + if any(part in path for part in ("/e2e/", "/cypress/", "/playwright/", ".cy.")): + return True + return any(f"/{part}/" in f"/{path}/" for part in ("e2e", "cypress", "playwright")) and path.endswith( + (".ts", ".tsx", ".js", ".jsx") + ) + + +def is_frontend_test(rel: str) -> bool: + path = rel.replace("\\", "/") + return bool( + re.search(r"""(\.test|\.spec|\.cy)\.(t|j)sx?$""", path) + or "/__tests__/" in path + or is_e2e_file(path) + ) + + +def _join_base(base: str, path: str) -> str: + path = path.strip() + if path.startswith("http") or path.startswith("/api/"): + return normalize_url_template(path) + base = (base or "").rstrip("/") + if not path.startswith("/"): + path = "/" + path + if base: + return normalize_url_template(base + path) + return normalize_url_template(path) + + +def _page_name_for_route(route: str, kind: str) -> str: + parts = [p for p in route.strip("/").split("/") if p and not p.startswith("{")] + if not parts: + stem = "Home" + else: + stem = "".join(p[:1].upper() + p[1:] for p in parts[-1].replace("-", "_").split("_") if p) + suffix = {"layout": "Layout", "route": "Route", "loading": "Loading", "error": "Error"}.get(kind, "Page") + return f"{stem}{suffix}" + + +def _looks_like_graphql_codegen(rel: str, source: str) -> bool: + path = rel.replace("\\", "/").lower() + if any(tok in path for tok in ("/generated/", "gql.ts", "graphql.ts", "graphql-codegen")): + return True + head = source[:2500].lower() + return "typeddocumentnode" in head or "graphql-codegen" in head or ( + "generated by" in head and "graphql" in head + ) + + +def _extract_graphql_document(graph: ExtractedGraph, add, edge, body: str, line: int, feature, hooks, components, stem: str) -> None: + ops = GQL_OP_RE.findall(body) or GQL_FILE_OP_RE.findall(body) + if not ops: + ops = [("query", f"{stem}Query")] + selections = GQL_SELECTION_RE.findall(body) + for kind, op_name in ops: + extra = { + "kind": kind.lower(), + "feature": feature, + "client": True, + "selections": [s for s in selections if s not in {"query", "mutation", "subscription"}][:8], + } + op = add( + NodeType.GRAPHQL_OPERATION, + op_name, + f"graphql.{op_name}", + line, + extra, + ) + for owner in hooks or components: + edge(owner.id, op.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), op.id, EdgeType.CALLS) + + def extract_react_file(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: rel = rel_path.replace("\\", "/") graph = ExtractedGraph() + app_info = app_router_info(rel) + pages_info = pages_router_info(rel) if not app_info else None feature = _feature_from_path(rel) + if not feature and app_info: + feature = _feature_from_app_segments(app_info.get("segments") or []) + if not feature and pages_info: + feature = _feature_from_app_segments(pages_info.get("segments") or []) context = config.context_for_react_path(rel) is_shared = config.is_shared_react(rel) - is_test = bool(re.search(r"""(\.test|\.spec)\.(t|j)sx?$""", rel) or "/__tests__/" in rel) + is_test = is_frontend_test(rel) + e2e = is_e2e_file(rel) stem = Path(rel).stem + graphql_file = Path(rel).suffix.lower() in {".graphql", ".gql"} def add(ntype: NodeType, name: str, qname: str, line: int = 1, extra: dict | None = None) -> Node: n = Node( @@ -120,8 +307,16 @@ def add(ntype: NodeType, name: str, qname: str, line: int = 1, extra: dict | Non def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: dict | None = None) -> None: graph.edges.append(Edge(src=src, dst=dst, type=etype, confidence=confidence, extra=extra or {})) + if graphql_file: + _extract_graphql_document(graph, add, edge, source, 1, feature, [], [], stem) + return graph + if feature: - feat = add(NodeType.FEATURE_MODULE, feature, f"features.{feature}", extra={"shared": is_shared}) + add(NodeType.FEATURE_MODULE, feature, f"features.{feature}", extra={"shared": is_shared}) + + if e2e: + _extract_e2e(add, edge, rel, source, feature, stem) + return graph imports: list[tuple[str, str]] = [] import_feature: dict[str, str] = {} @@ -165,10 +360,25 @@ def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: di components: list[Node] = [] for m in COMPONENT_RE.finditer(source): name = m.group(1) + if name in HTTP_VERBS: + continue line = source[: m.start()].count("\n") + 1 - is_page = name.endswith("Page") or "pages/" in rel or name.endswith("Screen") + is_page = ( + name.endswith("Page") + or "pages/" in rel + or name.endswith("Screen") + or (app_info and app_info.get("kind") == "page") + or (pages_info and pages_info.get("kind") == "page" and not pages_info.get("api")) + ) ntype = NodeType.PAGE if is_page else NodeType.COMPONENT extra: dict = {"feature": feature} + if app_info: + extra["next_app"] = True + extra["next_kind"] = app_info["kind"] + extra["route"] = app_info["route"] + if pages_info and not pages_info.get("api"): + extra["next_pages"] = True + extra["route"] = pages_info["route"] if is_page: extra["has_error_boundary"] = bool(BOUNDARY_RE.search(source)) defaults = [a or b for a, b in DEFAULT_VALUE_RE.findall(source)] @@ -397,4 +607,293 @@ def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: di confidence=0.5, ) + _extract_next_routes(add, edge, graph, rel, source, feature, app_info, pages_info, components) + _extract_typed_clients(add, edge, graph, rel, source, feature, hooks, components) + _extract_server_actions(add, edge, rel, source, feature, components) + if _looks_like_graphql_codegen(rel, source): + _extract_graphql_codegen(add, edge, source, feature, components) + return graph + + +def _add_client(add, edge, graph, rel, feature, hooks, components, url: str, line: int, extra: dict) -> Node | None: + norm = normalize_url_template(url) + qname = f"client:{rel}:{norm}" + if any(n.qualified_name == qname for n in graph.nodes): + existing = next(n for n in graph.nodes if n.qualified_name == qname) + if extra.get("typed_client") and not existing.extra.get("typed_client"): + existing.extra.update(extra) + existing.extra["inferred"] = False + return existing + payload = { + "raw": url, + "feature": feature, + "file": rel, + **extra, + } + client = add(NodeType.API_CLIENT, norm, qname, line, payload) + for owner in hooks or components: + edge(owner.id, client.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), client.id, EdgeType.CALLS) + return client + + +def _extract_next_routes(add, edge, graph, rel, source, feature, app_info, pages_info, components) -> None: + info = app_info or pages_info + if not info: + return + route = info["route"] + kind = info["kind"] + line = 1 + if info.get("api") or kind == "route": + url = route if route.startswith("/") else "/" + route + if info.get("api") and not url.startswith("/api"): + url = "/api" + url + _add_client( + add, + edge, + graph, + rel, + feature, + [], + components, + url, + line, + {"typed_client": "next-api", "generated": False, "inferred": False, "next_api": True}, + ) + return + page_name = _page_name_for_route(route, kind) + extra = { + "feature": feature, + "route": route, + "next_app": bool(app_info), + "next_pages": bool(pages_info), + "next_kind": kind, + "has_error_boundary": bool(BOUNDARY_RE.search(source)), + } + ntype = NodeType.PAGE if kind in {"page", "route"} else NodeType.COMPONENT + if kind == "layout": + ntype = NodeType.COMPONENT + extra["next_layout"] = True + existing = [n for n in graph.nodes if n.type is ntype and n.extra.get("route") == route] + if not existing: + page = add(ntype, page_name, f"{feature or 'app'}.{page_name}", line, extra) + components.append(page) + if feature: + edge(page.id, node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), EdgeType.BELONGS_TO) + else: + page = existing[0] + rn = add( + NodeType.REACT_ROUTE, + route, + f"react.route:{route}", + line, + {"element": page_name, "next_app": bool(app_info), "next_kind": kind}, + ) + edge(rn.id, page.id, EdgeType.PUBLISHES_ROUTE) + if kind == "layout": + # layout wraps pages under this prefix — linked later if a page route starts with this path + for other in list(graph.nodes): + if other.type is NodeType.PAGE and str((other.extra or {}).get("route") or "").startswith(route.rstrip("/") or "/"): + edge(page.id, other.id, EdgeType.RENDERS, confidence=0.7) + + +def _extract_typed_clients(add, edge, graph, rel, source, feature, hooks, components) -> None: + if RTK_RE.search(source) or "injectEndpoints" in source: + base = "" + bm = RTK_BASE_URL_RE.search(source) + if bm: + base = bm.group(1) + for m in RTK_ENDPOINT_RE.finditer(source): + name = m.group("name") + kind = m.group("kind") + window = source[m.end() : m.end() + 500] + raw = _rtk_endpoint_url(window) + if not raw or raw.upper() in HTTP_VERBS: + continue + if raw.startswith("http") and "/api/" not in raw and not raw.startswith("/"): + continue + url = _join_base(base, raw) + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + url, + line, + { + "typed_client": "rtk", + "generated": True, + "inferred": False, + "endpoint": name, + "kind": kind, + }, + ) + if "createClient" in source or "openapi-fetch" in source or "openapifetch" in rel.replace("\\", "/").lower().replace("-", ""): + for m in OPENAPI_FETCH_RE.finditer(source): + method, raw = m.group(1), m.group(2) + if not raw.startswith("/") and "/api/" not in raw: + continue + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + raw, + line, + { + "typed_client": "openapi-fetch", + "generated": True, + "inferred": False, + "method": method, + }, + ) + if "initContract" in source or "@ts-rest" in source or "ts-rest" in rel: + for m in TS_REST_ROUTE_RE.finditer(source): + raw = m.group(1) or m.group(2) or "" + if not raw.startswith("/") and "/api/" not in raw: + continue + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + raw, + line, + {"typed_client": "ts-rest", "generated": True, "inferred": False}, + ) + for m in TRPC_RE.finditer(source): + proc = m.group(1).rstrip(".") + line = source[: m.start()].count("\n") + 1 + qname = f"client:{rel}:trpc.{proc}" + if any(n.qualified_name == qname for n in graph.nodes): + continue + client = add( + NodeType.API_CLIENT, + proc, + qname, + line, + { + "typed_client": "trpc", + "generated": True, + "inferred": False, + "trpc": True, + "procedure": proc, + "feature": feature, + "file": rel, + }, + ) + for owner in hooks or components: + edge(owner.id, client.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), client.id, EdgeType.CALLS) + + +def _extract_server_actions(add, edge, rel, source, feature, components) -> None: + if '"use server"' not in source and "'use server'" not in source: + return + for m in SERVER_ACTION_FN_RE.finditer(source): + name = m.group(1) or m.group(2) + if not name or name in HTTP_VERBS: + continue + line = source[: m.start()].count("\n") + 1 + action = add( + NodeType.SERVER_ACTION, + name, + f"{feature or 'app'}.{name}", + line, + {"feature": feature, "server_action": True, "next_app": True}, + ) + for owner in components: + edge(owner.id, action.id, EdgeType.CALLS, confidence=0.8) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), action.id, EdgeType.CALLS) + + +def _extract_graphql_codegen(add, edge, source, feature, components) -> None: + for m in CODEGEN_TYPE_RE.finditer(source): + name = m.group(1) + start = m.end() + depth = 1 + i = start + while i < len(source) and depth: + if source[i] == "{": + depth += 1 + elif source[i] == "}": + depth -= 1 + i += 1 + body = source[start : i - 1] + fields = [f for f in CODEGEN_FIELD_RE.findall(body) if f not in {"__typename", "Query", "Mutation", "Subscription"}] + if not fields: + continue + line = source[: m.start()].count("\n") + 1 + schema = add( + NodeType.FORM_SCHEMA, + name, + f"{feature or 'app'}.{name}", + line, + {"fields": fields, "kind": "graphql-codegen", "feature": feature, "generated": True, "typed_client": "graphql-codegen"}, + ) + for owner in components: + edge(owner.id, schema.id, EdgeType.CALLS, confidence=0.6) + + +def _extract_e2e(add, edge, rel, source, feature, stem) -> None: + visits: list[str] = [] + for m in E2E_VISIT_RE.finditer(source): + raw = m.group(1) or m.group(2) or "" + if not raw: + continue + if raw.startswith("http"): + raw = re.sub(r"""https?://[^/]+""", "", raw) + if not raw.startswith("/") and "/api/" not in raw: + continue + visits.append(_e2e_template(raw)) + tn = add( + NodeType.REACT_TEST, + stem, + f"test.{rel}", + 1, + { + "file": rel, + "e2e": True, + "visits": visits, + "kind": "cypress" if ".cy." in rel or "/cypress/" in rel else "playwright", + "mentions": sorted(set(re.findall(r"""['"](\w+)['"]""", source))), + }, + ) + for tmpl in visits: + edge(node_id(NodeType.REACT_ROUTE, f"react.route:{tmpl}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}) + # common react-router param form + alt = tmpl.replace("{id}", ":id") + if alt != tmpl: + edge(node_id(NodeType.REACT_ROUTE, f"react.route:{alt}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}) + page_name = _page_name_for_route(tmpl, "page") + edge(node_id(NodeType.PAGE, f"{feature or 'app'}.{page_name}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}, confidence=0.7) + + +def _rtk_endpoint_url(window: str) -> str: + nxt = re.search(r"""\b[A-Za-z_]\w*\s*:\s*builder\.(?:query|mutation|infiniteQuery)\b""", window) + if nxt: + window = window[: nxt.start()] + labeled = re.search(r"""url\s*:\s*(?:['"`]([^'"`]+)['"`])""", window) + if labeled: + return labeled.group(1) or "" + template = re.search(r"""=>\s*`([^`]+)`""", window) + if template: + return template.group(1) or "" + literal = re.search(r"""=>\s*['"]([^'"]+)['"]""", window) + return (literal.group(1) if literal else "") or "" diff --git a/src/loadpath/index.py b/src/loadpath/index.py index 19c937b..28736b7 100644 --- a/src/loadpath/index.py +++ b/src/loadpath/index.py @@ -21,9 +21,9 @@ from loadpath.types import GENERATED_PATH_MARKERS, ExtractedGraph, Node, NodeType, node_id PY_SKIP = {"migrations"} # still extract migrations, just not skip -INDEX_EXTENSIONS = {".py", ".ts", ".tsx", ".js", ".jsx", ".html", ".htm"} +INDEX_EXTENSIONS = {".py", ".ts", ".tsx", ".js", ".jsx", ".html", ".htm", ".graphql", ".gql"} # Bump when extractor/stitch node identity changes so incremental indexes rebuild. -INDEX_REVISION = "13" +INDEX_REVISION = "14" _UPSERT_BATCH = 25 ProgressCallback = Callable[[dict[str, Any]], None] diff --git a/src/loadpath/review/cluster.py b/src/loadpath/review/cluster.py index ddd8630..6e914cf 100644 --- a/src/loadpath/review/cluster.py +++ b/src/loadpath/review/cluster.py @@ -20,6 +20,7 @@ NodeType.FORM_SCHEMA, NodeType.HOOK, NodeType.COMPONENT, + NodeType.SERVER_ACTION, NodeType.GRAPHQL_TYPE, NodeType.GRAPHQL_OPERATION, NodeType.FASTAPI_ROUTE, diff --git a/src/loadpath/review/engine.py b/src/loadpath/review/engine.py index eda2375..4df62c4 100644 --- a/src/loadpath/review/engine.py +++ b/src/loadpath/review/engine.py @@ -49,6 +49,7 @@ NodeType.API_CLIENT, NodeType.QUERY_KEY, NodeType.COMPONENT, + NodeType.SERVER_ACTION, NodeType.TEST, NodeType.REACT_TEST, NodeType.GRAPHQL_TYPE, @@ -274,7 +275,7 @@ def collect_residuals(store: GraphStore, impact_nodes: list[dict], diff: DiffSet fields_by_name.setdefault(field["name"], []).append(field) for n in impact_nodes: extra = n.get("extra") or {} - if extra.get("get_serializer_class"): + if extra.get("get_serializer_class") and not extra.get("serializer_classes"): residuals.append(f"Dynamic get_serializer_class on {n['qualified_name']}") if extra.get("string_ref"): residuals.append(f"String model ref {n['qualified_name']}") @@ -551,6 +552,8 @@ def _sink_summaries(nodes: list[dict], store: GraphStore) -> list[dict]: NodeType.TASK.value, NodeType.PAGE.value, NodeType.FORM_SCHEMA.value, + NodeType.SERVER_ACTION.value, + NodeType.REACT_ROUTE.value, NodeType.FORM.value, NodeType.PERMISSION.value, NodeType.MIGRATION_OP.value, diff --git a/src/loadpath/review/suggested_tests.py b/src/loadpath/review/suggested_tests.py index 31c328c..6b71f7c 100644 --- a/src/loadpath/review/suggested_tests.py +++ b/src/loadpath/review/suggested_tests.py @@ -57,6 +57,20 @@ def _sketch(ntype: str, name: str, node: dict) -> dict | None: f" assert response.status_code < 500\n" ), } + if ntype == NodeType.PAGE.value and ((node.get("extra") or {}).get("next_app") or (node.get("extra") or {}).get("route")): + route = (node.get("extra") or {}).get("route") or name + return { + "sink": name, + "type": ntype, + "kind": "playwright", + "title": f"Hit {route} through the App Router page", + "body": ( + f"test('{name} load path', async ({{ page }}) => {{\n" + f" await page.goto({route!r})\n" + f" await expect(page.getByRole('heading')).toBeVisible()\n" + f"}})\n" + ), + } if ntype in {NodeType.PAGE.value, NodeType.FORM_SCHEMA.value}: component = name if ntype == NodeType.PAGE.value else name.replace("Schema", "Form") return { @@ -162,6 +176,20 @@ def _sketch(ntype: str, name: str, node: dict) -> dict | None: f" {name}(1) # pass a model pk, not a deserialized object\n" ), } + if ntype == NodeType.SERVER_ACTION.value: + return { + "sink": name, + "type": ntype, + "kind": "playwright", + "title": f"Submit server action {name}", + "body": ( + f"test('{name} server action', async ({{ page }}) => {{\n" + f" await page.goto('/')\n" + f" await page.getByRole('button').click()\n" + f" await expect(page.getByRole('alert')).not.toBeVisible()\n" + f"}})\n" + ), + } return None diff --git a/src/loadpath/static/assets/LayeredGraph3D-BkYe4qmj.js b/src/loadpath/static/assets/LayeredGraph3D-Ch8n5xd0.js similarity index 99% rename from src/loadpath/static/assets/LayeredGraph3D-BkYe4qmj.js rename to src/loadpath/static/assets/LayeredGraph3D-Ch8n5xd0.js index a77784c..276baf9 100644 --- a/src/loadpath/static/assets/LayeredGraph3D-BkYe4qmj.js +++ b/src/loadpath/static/assets/LayeredGraph3D-Ch8n5xd0.js @@ -1,4 +1,4 @@ -import{r as un,l as tc,c as nc,a as ic,L as sc,j as ei,t as rc}from"./index-cvBsmXkd.js";/** +import{r as un,l as tc,c as nc,a as ic,L as sc,j as ei,t as rc}from"./index-BuTg-qls.js";/** * @license * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT diff --git a/src/loadpath/static/assets/index-BuTg-qls.js b/src/loadpath/static/assets/index-BuTg-qls.js new file mode 100644 index 0000000..6f3ec9c --- /dev/null +++ b/src/loadpath/static/assets/index-BuTg-qls.js @@ -0,0 +1,62 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const u of a)if(u.type==="childList")for(const c of u.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function o(a){const u={};return a.integrity&&(u.integrity=a.integrity),a.referrerPolicy&&(u.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?u.credentials="include":a.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(a){if(a.ep)return;a.ep=!0;const u=o(a);fetch(a.href,u)}})();function Pp(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Du={exports:{}},Xi={},Ou={exports:{}},Ae={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var th;function l0(){if(th)return Ae;th=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),c=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),v=Symbol.iterator;function g(R){return R===null||typeof R!="object"?null:(R=v&&R[v]||R["@@iterator"],typeof R=="function"?R:null)}var _={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,N={};function b(R,z,ne){this.props=R,this.context=z,this.refs=N,this.updater=ne||_}b.prototype.isReactComponent={},b.prototype.setState=function(R,z){if(typeof R!="object"&&typeof R!="function"&&R!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,R,z,"setState")},b.prototype.forceUpdate=function(R){this.updater.enqueueForceUpdate(this,R,"forceUpdate")};function E(){}E.prototype=b.prototype;function I(R,z,ne){this.props=R,this.context=z,this.refs=N,this.updater=ne||_}var w=I.prototype=new E;w.constructor=I,S(w,b.prototype),w.isPureReactComponent=!0;var j=Array.isArray,A=Object.prototype.hasOwnProperty,$={current:null},F={key:!0,ref:!0,__self:!0,__source:!0};function Y(R,z,ne){var oe,fe={},he=null,pe=null;if(z!=null)for(oe in z.ref!==void 0&&(pe=z.ref),z.key!==void 0&&(he=""+z.key),z)A.call(z,oe)&&!F.hasOwnProperty(oe)&&(fe[oe]=z[oe]);var Z=arguments.length-2;if(Z===1)fe.children=ne;else if(1>>1,z=M[R];if(0>>1;Ra(fe,H))hea(pe,fe)?(M[R]=pe,M[he]=H,R=he):(M[R]=fe,M[oe]=H,R=oe);else if(hea(pe,H))M[R]=pe,M[he]=H,R=he;else break e}}return D}function a(M,D){var H=M.sortIndex-D.sortIndex;return H!==0?H:M.id-D.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;t.unstable_now=function(){return u.now()}}else{var c=Date,h=c.now();t.unstable_now=function(){return c.now()-h}}var p=[],y=[],x=1,v=null,g=3,_=!1,S=!1,N=!1,b=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,I=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function w(M){for(var D=o(y);D!==null;){if(D.callback===null)s(y);else if(D.startTime<=M)s(y),D.sortIndex=D.expirationTime,r(p,D);else break;D=o(y)}}function j(M){if(N=!1,w(M),!S)if(o(p)!==null)S=!0,W(A);else{var D=o(y);D!==null&&U(j,D.startTime-M)}}function A(M,D){S=!1,N&&(N=!1,E(Y),Y=-1),_=!0;var H=g;try{for(w(D),v=o(p);v!==null&&(!(v.expirationTime>D)||M&&!J());){var R=v.callback;if(typeof R=="function"){v.callback=null,g=v.priorityLevel;var z=R(v.expirationTime<=D);D=t.unstable_now(),typeof z=="function"?v.callback=z:v===o(p)&&s(p),w(D)}else s(p);v=o(p)}if(v!==null)var ne=!0;else{var oe=o(y);oe!==null&&U(j,oe.startTime-D),ne=!1}return ne}finally{v=null,g=H,_=!1}}var $=!1,F=null,Y=-1,q=5,re=-1;function J(){return!(t.unstable_now()-reM||125R?(M.sortIndex=H,r(y,M),o(p)===null&&M===o(y)&&(N?(E(Y),Y=-1):N=!0,U(j,H-R))):(M.sortIndex=z,r(p,M),S||_||(S=!0,W(A))),M},t.unstable_shouldYield=J,t.unstable_wrapCallback=function(M){var D=g;return function(){var H=g;g=D;try{return M.apply(this,arguments)}finally{g=H}}}})(Bu)),Bu}var sh;function h0(){return sh||(sh=1,Hu.exports=f0()),Hu.exports}/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var ah;function p0(){if(ah)return Dt;ah=1;var t=hs(),r=h0();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,i=1;i"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,y=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,x={},v={};function g(e){return p.call(v,e)?!0:p.call(x,e)?!1:y.test(e)?v[e]=!0:(x[e]=!0,!1)}function _(e,n,i,l){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return l?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,n,i,l){if(n===null||typeof n>"u"||_(e,n,i,l))return!0;if(l)return!1;if(i!==null)switch(i.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function N(e,n,i,l,f,m,k){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=l,this.attributeNamespace=f,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=m,this.removeEmptyString=k}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){b[e]=new N(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];b[n]=new N(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){b[e]=new N(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){b[e]=new N(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){b[e]=new N(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){b[e]=new N(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){b[e]=new N(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){b[e]=new N(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){b[e]=new N(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function I(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(E,I);b[n]=new N(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(E,I);b[n]=new N(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(E,I);b[n]=new N(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){b[e]=new N(e,1,!1,e.toLowerCase(),null,!1,!1)}),b.xlinkHref=new N("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){b[e]=new N(e,1,!1,e.toLowerCase(),null,!0,!0)});function w(e,n,i,l){var f=b.hasOwnProperty(n)?b[n]:null;(f!==null?f.type!==0:l||!(2T||f[k]!==m[T]){var O=` +`+f[k].replace(" at new "," at ");return e.displayName&&O.includes("")&&(O=O.replace("",e.displayName)),O}while(1<=k&&0<=T);break}}}finally{ne=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?z(e):""}function fe(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("SuspenseList");case 0:case 2:case 15:return e=oe(e.type,!1),e;case 11:return e=oe(e.type.render,!1),e;case 1:return e=oe(e.type,!0),e;default:return""}}function he(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case F:return"Fragment";case $:return"Portal";case q:return"Profiler";case Y:return"StrictMode";case Q:return"Suspense";case C:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case J:return(e.displayName||"Context")+".Consumer";case re:return(e._context.displayName||"Context")+".Provider";case te:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case V:return n=e.displayName||null,n!==null?n:he(e.type)||"Memo";case W:n=e._payload,e=e._init;try{return he(e(n))}catch{}}return null}function pe(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return he(n);case 8:return n===Y?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Z(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function se(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function me(e){var n=se(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),l=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var f=i.get,m=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return f.call(this)},set:function(k){l=""+k,m.call(this,k)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return l},setValue:function(k){l=""+k},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function Ne(e){e._valueTracker||(e._valueTracker=me(e))}function we(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),l="";return e&&(l=se(e)?e.checked?"true":"false":e.value),e=l,e!==i?(n.setValue(e),!0):!1}function ve(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Pe(e,n){var i=n.checked;return H({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function ue(e,n){var i=n.defaultValue==null?"":n.defaultValue,l=n.checked!=null?n.checked:n.defaultChecked;i=Z(n.value!=null?n.value:i),e._wrapperState={initialChecked:l,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function je(e,n){n=n.checked,n!=null&&w(e,"checked",n,!1)}function Le(e,n){je(e,n);var i=Z(n.value),l=n.type;if(i!=null)l==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(l==="submit"||l==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?lt(e,n.type,i):n.hasOwnProperty("defaultValue")&<(e,n.type,Z(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function nt(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var l=n.type;if(!(l!=="submit"&&l!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,i||n===e.value||(e.value=n),e.defaultValue=n}i=e.name,i!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,i!==""&&(e.name=i)}function lt(e,n,i){(n!=="number"||ve(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var ut=Array.isArray;function Ye(e,n,i,l){if(e=e.options,n){n={};for(var f=0;f"+n.valueOf().toString()+"",n=et.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function Mt(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var kn={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ui=["Webkit","ms","Moz","O"];Object.keys(kn).forEach(function(e){ui.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),kn[n]=kn[e]})});function Fn(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||kn.hasOwnProperty(e)&&kn[e]?(""+n).trim():n+"px"}function vo(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var l=i.indexOf("--")===0,f=Fn(i,n[i],l);i==="float"&&(i="cssFloat"),l?e.setProperty(i,f):e[i]=f}}var lr=H({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Or(e,n){if(n){if(lr[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(o(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(o(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(o(61))}if(n.style!=null&&typeof n.style!="object")throw Error(o(62))}}function Hn(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Fr=null;function ur(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var cr=null,Ft=null,dt=null;function Bn(e){if(e=Ti(e)){if(typeof cr!="function")throw Error(o(280));var n=e.stateNode;n&&(n=$s(n),cr(e.stateNode,e.type,n))}}function Vn(e){Ft?dt?dt.push(e):dt=[e]:Ft=e}function Nn(){if(Ft){var e=Ft,n=dt;if(dt=Ft=null,Bn(e),n)for(e=0;e>>=0,e===0?32:31-(hi(e)/pi|0)|0}var Mn=64,qn=4194304;function Pn(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function qt(e,n){var i=e.pendingLanes;if(i===0)return 0;var l=0,f=e.suspendedLanes,m=e.pingedLanes,k=i&268435455;if(k!==0){var T=k&~f;T!==0?l=Pn(T):(m&=k,m!==0&&(l=Pn(m)))}else k=i&~f,k!==0?l=Pn(k):m!==0&&(l=Pn(m));if(l===0)return 0;if(n!==0&&n!==l&&(n&f)===0&&(f=l&-l,m=n&-n,f>=m||f===16&&(m&4194240)!==0))return n;if((l&4)!==0&&(l|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=l;0i;i++)n.push(e);return n}function Kn(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-yt(n),e[n]=i}function No(e,n){var i=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var l=e.eventTimes;for(e=e.expirationTimes;0=Ni),Yc=" ",Xc=!1;function qc(e,n){switch(e){case"keyup":return ry.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Kc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Mo=!1;function iy(e,n){switch(e){case"compositionend":return Kc(n);case"keypress":return n.which!==32?null:(Xc=!0,Yc);case"textInput":return e=n.data,e===Yc&&Xc?null:e;default:return null}}function sy(e,n){if(Mo)return e==="compositionend"||!vl&&qc(e,n)?(e=Hc(),js=fl=yr=null,Mo=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:i,offset:n-e};e=l}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=rd(i)}}function id(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?id(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function sd(){for(var e=window,n=ve();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=ve(e.document)}return n}function _l(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function gy(e){var n=sd(),i=e.focusedElem,l=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&id(i.ownerDocument.documentElement,i)){if(l!==null&&_l(i)){if(n=l.start,e=l.end,e===void 0&&(e=n),"selectionStart"in i)i.selectionStart=n,i.selectionEnd=Math.min(e,i.value.length);else if(e=(n=i.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var f=i.textContent.length,m=Math.min(l.start,f);l=l.end===void 0?m:Math.min(l.end,f),!e.extend&&m>l&&(f=l,l=m,m=f),f=od(i,m);var k=od(i,l);f&&k&&(e.rangeCount!==1||e.anchorNode!==f.node||e.anchorOffset!==f.offset||e.focusNode!==k.node||e.focusOffset!==k.offset)&&(n=n.createRange(),n.setStart(f.node,f.offset),e.removeAllRanges(),m>l?(e.addRange(n),e.extend(k.node,k.offset)):(n.setEnd(k.node,k.offset),e.addRange(n)))}}for(n=[],e=i;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof i.focus=="function"&&i.focus(),i=0;i=document.documentMode,Po=null,Sl=null,Ci=null,kl=!1;function ad(e,n,i){var l=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;kl||Po==null||Po!==ve(l)||(l=Po,"selectionStart"in l&&_l(l)?l={start:l.selectionStart,end:l.selectionEnd}:(l=(l.ownerDocument&&l.ownerDocument.defaultView||window).getSelection(),l={anchorNode:l.anchorNode,anchorOffset:l.anchorOffset,focusNode:l.focusNode,focusOffset:l.focusOffset}),Ci&&Ei(Ci,l)||(Ci=l,l=Ts(Sl,"onSelect"),0Ao||(e.current=Al[Ao],Al[Ao]=null,Ao--)}function Be(e,n){Ao++,Al[Ao]=e.current,e.current=n}var _r={},St=wr(_r),Tt=wr(!1),Kr=_r;function $o(e,n){var i=e.type.contextTypes;if(!i)return _r;var l=e.stateNode;if(l&&l.__reactInternalMemoizedUnmaskedChildContext===n)return l.__reactInternalMemoizedMaskedChildContext;var f={},m;for(m in i)f[m]=n[m];return l&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=f),f}function Lt(e){return e=e.childContextTypes,e!=null}function zs(){Ue(Tt),Ue(St)}function Sd(e,n,i){if(St.current!==_r)throw Error(o(168));Be(St,n),Be(Tt,i)}function kd(e,n,i){var l=e.stateNode;if(n=n.childContextTypes,typeof l.getChildContext!="function")return i;l=l.getChildContext();for(var f in l)if(!(f in n))throw Error(o(108,pe(e)||"Unknown",f));return H({},i,l)}function Ds(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||_r,Kr=St.current,Be(St,e),Be(Tt,Tt.current),!0}function Nd(e,n,i){var l=e.stateNode;if(!l)throw Error(o(169));i?(e=kd(e,n,Kr),l.__reactInternalMemoizedMergedChildContext=e,Ue(Tt),Ue(St),Be(St,e)):Ue(Tt),Be(Tt,i)}var Zn=null,Os=!1,$l=!1;function jd(e){Zn===null?Zn=[e]:Zn.push(e)}function Ey(e){Os=!0,jd(e)}function Sr(){if(!$l&&Zn!==null){$l=!0;var e=0,n=Fe;try{var i=Zn;for(Fe=1;e>=k,f-=k,Jn=1<<32-yt(n)+f|i<Me?(pt=Ee,Ee=null):pt=Ee.sibling;var Oe=ie(X,Ee,K[Me],de);if(Oe===null){Ee===null&&(Ee=pt);break}e&&Ee&&Oe.alternate===null&&n(X,Ee),B=m(Oe,B,Me),be===null?Se=Oe:be.sibling=Oe,be=Oe,Ee=pt}if(Me===K.length)return i(X,Ee),Xe&&Zr(X,Me),Se;if(Ee===null){for(;MeMe?(pt=Ee,Ee=null):pt=Ee.sibling;var Ir=ie(X,Ee,Oe.value,de);if(Ir===null){Ee===null&&(Ee=pt);break}e&&Ee&&Ir.alternate===null&&n(X,Ee),B=m(Ir,B,Me),be===null?Se=Ir:be.sibling=Ir,be=Ir,Ee=pt}if(Oe.done)return i(X,Ee),Xe&&Zr(X,Me),Se;if(Ee===null){for(;!Oe.done;Me++,Oe=K.next())Oe=le(X,Oe.value,de),Oe!==null&&(B=m(Oe,B,Me),be===null?Se=Oe:be.sibling=Oe,be=Oe);return Xe&&Zr(X,Me),Se}for(Ee=l(X,Ee);!Oe.done;Me++,Oe=K.next())Oe=ge(Ee,X,Me,Oe.value,de),Oe!==null&&(e&&Oe.alternate!==null&&Ee.delete(Oe.key===null?Me:Oe.key),B=m(Oe,B,Me),be===null?Se=Oe:be.sibling=Oe,be=Oe);return e&&Ee.forEach(function(a0){return n(X,a0)}),Xe&&Zr(X,Me),Se}function tt(X,B,K,de){if(typeof K=="object"&&K!==null&&K.type===F&&K.key===null&&(K=K.props.children),typeof K=="object"&&K!==null){switch(K.$$typeof){case A:e:{for(var Se=K.key,be=B;be!==null;){if(be.key===Se){if(Se=K.type,Se===F){if(be.tag===7){i(X,be.sibling),B=f(be,K.props.children),B.return=X,X=B;break e}}else if(be.elementType===Se||typeof Se=="object"&&Se!==null&&Se.$$typeof===W&&Id(Se)===be.type){i(X,be.sibling),B=f(be,K.props),B.ref=Li(X,be,K),B.return=X,X=B;break e}i(X,be);break}else n(X,be);be=be.sibling}K.type===F?(B=so(K.props.children,X.mode,de,K.key),B.return=X,X=B):(de=ha(K.type,K.key,K.props,null,X.mode,de),de.ref=Li(X,B,K),de.return=X,X=de)}return k(X);case $:e:{for(be=K.key;B!==null;){if(B.key===be)if(B.tag===4&&B.stateNode.containerInfo===K.containerInfo&&B.stateNode.implementation===K.implementation){i(X,B.sibling),B=f(B,K.children||[]),B.return=X,X=B;break e}else{i(X,B);break}else n(X,B);B=B.sibling}B=Tu(K,X.mode,de),B.return=X,X=B}return k(X);case W:return be=K._init,tt(X,B,be(K._payload),de)}if(ut(K))return xe(X,B,K,de);if(D(K))return _e(X,B,K,de);Vs(X,K)}return typeof K=="string"&&K!==""||typeof K=="number"?(K=""+K,B!==null&&B.tag===6?(i(X,B.sibling),B=f(B,K),B.return=X,X=B):(i(X,B),B=Ru(K,X.mode,de),B.return=X,X=B),k(X)):i(X,B)}return tt}var Fo=Rd(!0),Td=Rd(!1),Ws=wr(null),Us=null,Ho=null,Bl=null;function Vl(){Bl=Ho=Us=null}function Wl(e){var n=Ws.current;Ue(Ws),e._currentValue=n}function Ul(e,n,i){for(;e!==null;){var l=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,l!==null&&(l.childLanes|=n)):l!==null&&(l.childLanes&n)!==n&&(l.childLanes|=n),e===i)break;e=e.return}}function Bo(e,n){Us=e,Bl=Ho=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(At=!0),e.firstContext=null)}function Zt(e){var n=e._currentValue;if(Bl!==e)if(e={context:e,memoizedValue:n,next:null},Ho===null){if(Us===null)throw Error(o(308));Ho=e,Us.dependencies={lanes:0,firstContext:e}}else Ho=Ho.next=e;return n}var Jr=null;function Gl(e){Jr===null?Jr=[e]:Jr.push(e)}function Ld(e,n,i,l){var f=n.interleaved;return f===null?(i.next=i,Gl(n)):(i.next=f.next,f.next=i),n.interleaved=i,tr(e,l)}function tr(e,n){e.lanes|=n;var i=e.alternate;for(i!==null&&(i.lanes|=n),i=e,e=e.return;e!==null;)e.childLanes|=n,i=e.alternate,i!==null&&(i.childLanes|=n),i=e,e=e.return;return i.tag===3?i.stateNode:null}var kr=!1;function Yl(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ad(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function nr(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function Nr(e,n,i){var l=e.updateQueue;if(l===null)return null;if(l=l.shared,(ze&2)!==0){var f=l.pending;return f===null?n.next=n:(n.next=f.next,f.next=n),l.pending=n,tr(e,i)}return f=l.interleaved,f===null?(n.next=n,Gl(l)):(n.next=f.next,f.next=n),l.interleaved=n,tr(e,i)}function Gs(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,gr(e,i)}}function $d(e,n){var i=e.updateQueue,l=e.alternate;if(l!==null&&(l=l.updateQueue,i===l)){var f=null,m=null;if(i=i.firstBaseUpdate,i!==null){do{var k={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};m===null?f=m=k:m=m.next=k,i=i.next}while(i!==null);m===null?f=m=n:m=m.next=n}else f=m=n;i={baseState:l.baseState,firstBaseUpdate:f,lastBaseUpdate:m,shared:l.shared,effects:l.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function Ys(e,n,i,l){var f=e.updateQueue;kr=!1;var m=f.firstBaseUpdate,k=f.lastBaseUpdate,T=f.shared.pending;if(T!==null){f.shared.pending=null;var O=T,ee=O.next;O.next=null,k===null?m=ee:k.next=ee,k=O;var ae=e.alternate;ae!==null&&(ae=ae.updateQueue,T=ae.lastBaseUpdate,T!==k&&(T===null?ae.firstBaseUpdate=ee:T.next=ee,ae.lastBaseUpdate=O))}if(m!==null){var le=f.baseState;k=0,ae=ee=O=null,T=m;do{var ie=T.lane,ge=T.eventTime;if((l&ie)===ie){ae!==null&&(ae=ae.next={eventTime:ge,lane:0,tag:T.tag,payload:T.payload,callback:T.callback,next:null});e:{var xe=e,_e=T;switch(ie=n,ge=i,_e.tag){case 1:if(xe=_e.payload,typeof xe=="function"){le=xe.call(ge,le,ie);break e}le=xe;break e;case 3:xe.flags=xe.flags&-65537|128;case 0:if(xe=_e.payload,ie=typeof xe=="function"?xe.call(ge,le,ie):xe,ie==null)break e;le=H({},le,ie);break e;case 2:kr=!0}}T.callback!==null&&T.lane!==0&&(e.flags|=64,ie=f.effects,ie===null?f.effects=[T]:ie.push(T))}else ge={eventTime:ge,lane:ie,tag:T.tag,payload:T.payload,callback:T.callback,next:null},ae===null?(ee=ae=ge,O=le):ae=ae.next=ge,k|=ie;if(T=T.next,T===null){if(T=f.shared.pending,T===null)break;ie=T,T=ie.next,ie.next=null,f.lastBaseUpdate=ie,f.shared.pending=null}}while(!0);if(ae===null&&(O=le),f.baseState=O,f.firstBaseUpdate=ee,f.lastBaseUpdate=ae,n=f.shared.interleaved,n!==null){f=n;do k|=f.lane,f=f.next;while(f!==n)}else m===null&&(f.shared.lanes=0);no|=k,e.lanes=k,e.memoizedState=le}}function zd(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var l=Zl.transition;Zl.transition={};try{e(!1),n()}finally{Fe=i,Zl.transition=l}}function nf(){return Jt().memoizedState}function Iy(e,n,i){var l=Cr(e);if(i={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null},rf(e))of(n,i);else if(i=Ld(e,n,i,l),i!==null){var f=Et();gn(i,e,l,f),sf(i,n,l)}}function Ry(e,n,i){var l=Cr(e),f={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null};if(rf(e))of(n,f);else{var m=e.alternate;if(e.lanes===0&&(m===null||m.lanes===0)&&(m=n.lastRenderedReducer,m!==null))try{var k=n.lastRenderedState,T=m(k,i);if(f.hasEagerState=!0,f.eagerState=T,cn(T,k)){var O=n.interleaved;O===null?(f.next=f,Gl(n)):(f.next=O.next,O.next=f),n.interleaved=f;return}}catch{}finally{}i=Ld(e,n,f,l),i!==null&&(f=Et(),gn(i,e,l,f),sf(i,n,l))}}function rf(e){var n=e.alternate;return e===Ke||n!==null&&n===Ke}function of(e,n){Di=Ks=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function sf(e,n,i){if((i&4194240)!==0){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,gr(e,i)}}var Js={readContext:Zt,useCallback:kt,useContext:kt,useEffect:kt,useImperativeHandle:kt,useInsertionEffect:kt,useLayoutEffect:kt,useMemo:kt,useReducer:kt,useRef:kt,useState:kt,useDebugValue:kt,useDeferredValue:kt,useTransition:kt,useMutableSource:kt,useSyncExternalStore:kt,useId:kt,unstable_isNewReconciler:!1},Ty={readContext:Zt,useCallback:function(e,n){return Tn().memoizedState=[e,n===void 0?null:n],e},useContext:Zt,useEffect:Xd,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,Qs(4194308,4,Qd.bind(null,n,e),i)},useLayoutEffect:function(e,n){return Qs(4194308,4,e,n)},useInsertionEffect:function(e,n){return Qs(4,2,e,n)},useMemo:function(e,n){var i=Tn();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var l=Tn();return n=i!==void 0?i(n):n,l.memoizedState=l.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},l.queue=e,e=e.dispatch=Iy.bind(null,Ke,e),[l.memoizedState,e]},useRef:function(e){var n=Tn();return e={current:e},n.memoizedState=e},useState:Gd,useDebugValue:iu,useDeferredValue:function(e){return Tn().memoizedState=e},useTransition:function(){var e=Gd(!1),n=e[0];return e=Py.bind(null,e[1]),Tn().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var l=Ke,f=Tn();if(Xe){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),ht===null)throw Error(o(349));(to&30)!==0||Hd(l,n,i)}f.memoizedState=i;var m={value:i,getSnapshot:n};return f.queue=m,Xd(Vd.bind(null,l,m,e),[e]),l.flags|=2048,Hi(9,Bd.bind(null,l,m,i,n),void 0,null),i},useId:function(){var e=Tn(),n=ht.identifierPrefix;if(Xe){var i=er,l=Jn;i=(l&~(1<<32-yt(l)-1)).toString(32)+i,n=":"+n+"R"+i,i=Oi++,0<\/script>",e=e.removeChild(e.firstChild)):typeof l.is=="string"?e=k.createElement(i,{is:l.is}):(e=k.createElement(i),i==="select"&&(k=e,l.multiple?k.multiple=!0:l.size&&(k.size=l.size))):e=k.createElementNS(e,i),e[In]=n,e[Ri]=l,bf(e,n,!1,!1),n.stateNode=e;e:{switch(k=Hn(i,l),i){case"dialog":We("cancel",e),We("close",e),f=l;break;case"iframe":case"object":case"embed":We("load",e),f=l;break;case"video":case"audio":for(f=0;fYo&&(n.flags|=128,l=!0,Bi(m,!1),n.lanes=4194304)}else{if(!l)if(e=Xs(k),e!==null){if(n.flags|=128,l=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),Bi(m,!0),m.tail===null&&m.tailMode==="hidden"&&!k.alternate&&!Xe)return Nt(n),null}else 2*Ve()-m.renderingStartTime>Yo&&i!==1073741824&&(n.flags|=128,l=!0,Bi(m,!1),n.lanes=4194304);m.isBackwards?(k.sibling=n.child,n.child=k):(i=m.last,i!==null?i.sibling=k:n.child=k,m.last=k)}return m.tail!==null?(n=m.tail,m.rendering=n,m.tail=n.sibling,m.renderingStartTime=Ve(),n.sibling=null,i=qe.current,Be(qe,l?i&1|2:i&1),n):(Nt(n),null);case 22:case 23:return Mu(),l=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==l&&(n.flags|=8192),l&&(n.mode&1)!==0?(Wt&1073741824)!==0&&(Nt(n),n.subtreeFlags&6&&(n.flags|=8192)):Nt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function Hy(e,n){switch(Dl(n),n.tag){case 1:return Lt(n.type)&&zs(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Vo(),Ue(Tt),Ue(St),Ql(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return ql(n),null;case 13:if(Ue(qe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));Oo()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return Ue(qe),null;case 4:return Vo(),null;case 10:return Wl(n.type._context),null;case 22:case 23:return Mu(),null;case 24:return null;default:return null}}var ra=!1,jt=!1,By=typeof WeakSet=="function"?WeakSet:Set,ye=null;function Uo(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(l){Je(e,n,l)}else i.current=null}function yu(e,n,i){try{i()}catch(l){Je(e,n,l)}}var Mf=!1;function Vy(e,n){if(Ml=ks,e=sd(),_l(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var l=i.getSelection&&i.getSelection();if(l&&l.rangeCount!==0){i=l.anchorNode;var f=l.anchorOffset,m=l.focusNode;l=l.focusOffset;try{i.nodeType,m.nodeType}catch{i=null;break e}var k=0,T=-1,O=-1,ee=0,ae=0,le=e,ie=null;t:for(;;){for(var ge;le!==i||f!==0&&le.nodeType!==3||(T=k+f),le!==m||l!==0&&le.nodeType!==3||(O=k+l),le.nodeType===3&&(k+=le.nodeValue.length),(ge=le.firstChild)!==null;)ie=le,le=ge;for(;;){if(le===e)break t;if(ie===i&&++ee===f&&(T=k),ie===m&&++ae===l&&(O=k),(ge=le.nextSibling)!==null)break;le=ie,ie=le.parentNode}le=ge}i=T===-1||O===-1?null:{start:T,end:O}}else i=null}i=i||{start:0,end:0}}else i=null;for(Pl={focusedElem:e,selectionRange:i},ks=!1,ye=n;ye!==null;)if(n=ye,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,ye=e;else for(;ye!==null;){n=ye;try{var xe=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(xe!==null){var _e=xe.memoizedProps,tt=xe.memoizedState,X=n.stateNode,B=X.getSnapshotBeforeUpdate(n.elementType===n.type?_e:fn(n.type,_e),tt);X.__reactInternalSnapshotBeforeUpdate=B}break;case 3:var K=n.stateNode.containerInfo;K.nodeType===1?K.textContent="":K.nodeType===9&&K.documentElement&&K.removeChild(K.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(de){Je(n,n.return,de)}if(e=n.sibling,e!==null){e.return=n.return,ye=e;break}ye=n.return}return xe=Mf,Mf=!1,xe}function Vi(e,n,i){var l=n.updateQueue;if(l=l!==null?l.lastEffect:null,l!==null){var f=l=l.next;do{if((f.tag&e)===e){var m=f.destroy;f.destroy=void 0,m!==void 0&&yu(n,i,m)}f=f.next}while(f!==l)}}function oa(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var l=i.create;i.destroy=l()}i=i.next}while(i!==n)}}function vu(e){var n=e.ref;if(n!==null){var i=e.stateNode;switch(e.tag){case 5:e=i;break;default:e=i}typeof n=="function"?n(e):n.current=e}}function Pf(e){var n=e.alternate;n!==null&&(e.alternate=null,Pf(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[In],delete n[Ri],delete n[Ll],delete n[jy],delete n[by])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function If(e){return e.tag===5||e.tag===3||e.tag===4}function Rf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||If(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function xu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.nodeType===8?i.parentNode.insertBefore(e,n):i.insertBefore(e,n):(i.nodeType===8?(n=i.parentNode,n.insertBefore(e,i)):(n=i,n.appendChild(e)),i=i._reactRootContainer,i!=null||n.onclick!==null||(n.onclick=As));else if(l!==4&&(e=e.child,e!==null))for(xu(e,n,i),e=e.sibling;e!==null;)xu(e,n,i),e=e.sibling}function wu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(l!==4&&(e=e.child,e!==null))for(wu(e,n,i),e=e.sibling;e!==null;)wu(e,n,i),e=e.sibling}var vt=null,hn=!1;function jr(e,n,i){for(i=i.child;i!==null;)Tf(e,n,i),i=i.sibling}function Tf(e,n,i){if(_t&&typeof _t.onCommitFiberUnmount=="function")try{_t.onCommitFiberUnmount(Cn,i)}catch{}switch(i.tag){case 5:jt||Uo(i,n);case 6:var l=vt,f=hn;vt=null,jr(e,n,i),vt=l,hn=f,vt!==null&&(hn?(e=vt,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):vt.removeChild(i.stateNode));break;case 18:vt!==null&&(hn?(e=vt,i=i.stateNode,e.nodeType===8?Tl(e.parentNode,i):e.nodeType===1&&Tl(e,i),_i(e)):Tl(vt,i.stateNode));break;case 4:l=vt,f=hn,vt=i.stateNode.containerInfo,hn=!0,jr(e,n,i),vt=l,hn=f;break;case 0:case 11:case 14:case 15:if(!jt&&(l=i.updateQueue,l!==null&&(l=l.lastEffect,l!==null))){f=l=l.next;do{var m=f,k=m.destroy;m=m.tag,k!==void 0&&((m&2)!==0||(m&4)!==0)&&yu(i,n,k),f=f.next}while(f!==l)}jr(e,n,i);break;case 1:if(!jt&&(Uo(i,n),l=i.stateNode,typeof l.componentWillUnmount=="function"))try{l.props=i.memoizedProps,l.state=i.memoizedState,l.componentWillUnmount()}catch(T){Je(i,n,T)}jr(e,n,i);break;case 21:jr(e,n,i);break;case 22:i.mode&1?(jt=(l=jt)||i.memoizedState!==null,jr(e,n,i),jt=l):jr(e,n,i);break;default:jr(e,n,i)}}function Lf(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new By),n.forEach(function(l){var f=Zy.bind(null,e,l);i.has(l)||(i.add(l),l.then(f,f))})}}function pn(e,n){var i=n.deletions;if(i!==null)for(var l=0;lf&&(f=k),l&=~m}if(l=f,l=Ve()-l,l=(120>l?120:480>l?480:1080>l?1080:1920>l?1920:3e3>l?3e3:4320>l?4320:1960*Uy(l/1960))-l,10e?16:e,Er===null)var l=!1;else{if(e=Er,Er=null,ua=0,(ze&6)!==0)throw Error(o(331));var f=ze;for(ze|=4,ye=e.current;ye!==null;){var m=ye,k=m.child;if((ye.flags&16)!==0){var T=m.deletions;if(T!==null){for(var O=0;OVe()-ku?oo(e,0):Su|=i),zt(e,n)}function Yf(e,n){n===0&&((e.mode&1)===0?n=1:(n=qn,qn<<=1,(qn&130023424)===0&&(qn=4194304)));var i=Et();e=tr(e,n),e!==null&&(Kn(e,n,i),zt(e,i))}function Qy(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Yf(e,i)}function Zy(e,n){var i=0;switch(e.tag){case 13:var l=e.stateNode,f=e.memoizedState;f!==null&&(i=f.retryLane);break;case 19:l=e.stateNode;break;default:throw Error(o(314))}l!==null&&l.delete(n),Yf(e,i)}var Xf;Xf=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||Tt.current)At=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return At=!1,Oy(e,n,i);At=(e.flags&131072)!==0}else At=!1,Xe&&(n.flags&1048576)!==0&&bd(n,Hs,n.index);switch(n.lanes=0,n.tag){case 2:var l=n.type;na(e,n),e=n.pendingProps;var f=$o(n,St.current);Bo(n,i),f=eu(null,n,l,e,f,i);var m=tu();return n.flags|=1,typeof f=="object"&&f!==null&&typeof f.render=="function"&&f.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,Lt(l)?(m=!0,Ds(n)):m=!1,n.memoizedState=f.state!==null&&f.state!==void 0?f.state:null,Yl(n),f.updater=ea,n.stateNode=f,f._reactInternals=n,au(n,l,e,i),n=du(null,n,l,!0,m,i)):(n.tag=0,Xe&&m&&zl(n),bt(null,n,f,i),n=n.child),n;case 16:l=n.elementType;e:{switch(na(e,n),e=n.pendingProps,f=l._init,l=f(l._payload),n.type=l,f=n.tag=e0(l),e=fn(l,e),f){case 0:n=cu(null,n,l,e,i);break e;case 1:n=wf(null,n,l,e,i);break e;case 11:n=gf(null,n,l,e,i);break e;case 14:n=mf(null,n,l,fn(l.type,e),i);break e}throw Error(o(306,l,""))}return n;case 0:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),cu(e,n,l,f,i);case 1:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),wf(e,n,l,f,i);case 3:e:{if(_f(n),e===null)throw Error(o(387));l=n.pendingProps,m=n.memoizedState,f=m.element,Ad(e,n),Ys(n,l,null,i);var k=n.memoizedState;if(l=k.element,m.isDehydrated)if(m={element:l,isDehydrated:!1,cache:k.cache,pendingSuspenseBoundaries:k.pendingSuspenseBoundaries,transitions:k.transitions},n.updateQueue.baseState=m,n.memoizedState=m,n.flags&256){f=Wo(Error(o(423)),n),n=Sf(e,n,l,i,f);break e}else if(l!==f){f=Wo(Error(o(424)),n),n=Sf(e,n,l,i,f);break e}else for(Vt=xr(n.stateNode.containerInfo.firstChild),Bt=n,Xe=!0,dn=null,i=Td(n,null,l,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(Oo(),l===f){n=rr(e,n,i);break e}bt(e,n,l,i)}n=n.child}return n;case 5:return Dd(n),e===null&&Fl(n),l=n.type,f=n.pendingProps,m=e!==null?e.memoizedProps:null,k=f.children,Il(l,f)?k=null:m!==null&&Il(l,m)&&(n.flags|=32),xf(e,n),bt(e,n,k,i),n.child;case 6:return e===null&&Fl(n),null;case 13:return kf(e,n,i);case 4:return Xl(n,n.stateNode.containerInfo),l=n.pendingProps,e===null?n.child=Fo(n,null,l,i):bt(e,n,l,i),n.child;case 11:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),gf(e,n,l,f,i);case 7:return bt(e,n,n.pendingProps,i),n.child;case 8:return bt(e,n,n.pendingProps.children,i),n.child;case 12:return bt(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(l=n.type._context,f=n.pendingProps,m=n.memoizedProps,k=f.value,Be(Ws,l._currentValue),l._currentValue=k,m!==null)if(cn(m.value,k)){if(m.children===f.children&&!Tt.current){n=rr(e,n,i);break e}}else for(m=n.child,m!==null&&(m.return=n);m!==null;){var T=m.dependencies;if(T!==null){k=m.child;for(var O=T.firstContext;O!==null;){if(O.context===l){if(m.tag===1){O=nr(-1,i&-i),O.tag=2;var ee=m.updateQueue;if(ee!==null){ee=ee.shared;var ae=ee.pending;ae===null?O.next=O:(O.next=ae.next,ae.next=O),ee.pending=O}}m.lanes|=i,O=m.alternate,O!==null&&(O.lanes|=i),Ul(m.return,i,n),T.lanes|=i;break}O=O.next}}else if(m.tag===10)k=m.type===n.type?null:m.child;else if(m.tag===18){if(k=m.return,k===null)throw Error(o(341));k.lanes|=i,T=k.alternate,T!==null&&(T.lanes|=i),Ul(k,i,n),k=m.sibling}else k=m.child;if(k!==null)k.return=m;else for(k=m;k!==null;){if(k===n){k=null;break}if(m=k.sibling,m!==null){m.return=k.return,k=m;break}k=k.return}m=k}bt(e,n,f.children,i),n=n.child}return n;case 9:return f=n.type,l=n.pendingProps.children,Bo(n,i),f=Zt(f),l=l(f),n.flags|=1,bt(e,n,l,i),n.child;case 14:return l=n.type,f=fn(l,n.pendingProps),f=fn(l.type,f),mf(e,n,l,f,i);case 15:return yf(e,n,n.type,n.pendingProps,i);case 17:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),na(e,n),n.tag=1,Lt(l)?(e=!0,Ds(n)):e=!1,Bo(n,i),lf(n,l,f),au(n,l,f,i),du(null,n,l,!0,e,i);case 19:return jf(e,n,i);case 22:return vf(e,n,i)}throw Error(o(156,n.tag))};function qf(e,n){return Yn(e,n)}function Jy(e,n,i,l){this.tag=e,this.key=i,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=l,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function tn(e,n,i,l){return new Jy(e,n,i,l)}function Iu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function e0(e){if(typeof e=="function")return Iu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===te)return 11;if(e===V)return 14}return 2}function Pr(e,n){var i=e.alternate;return i===null?(i=tn(e.tag,n,e.key,e.mode),i.elementType=e.elementType,i.type=e.type,i.stateNode=e.stateNode,i.alternate=e,e.alternate=i):(i.pendingProps=n,i.type=e.type,i.flags=0,i.subtreeFlags=0,i.deletions=null),i.flags=e.flags&14680064,i.childLanes=e.childLanes,i.lanes=e.lanes,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,n=e.dependencies,i.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},i.sibling=e.sibling,i.index=e.index,i.ref=e.ref,i}function ha(e,n,i,l,f,m){var k=2;if(l=e,typeof e=="function")Iu(e)&&(k=1);else if(typeof e=="string")k=5;else e:switch(e){case F:return so(i.children,f,m,n);case Y:k=8,f|=8;break;case q:return e=tn(12,i,n,f|2),e.elementType=q,e.lanes=m,e;case Q:return e=tn(13,i,n,f),e.elementType=Q,e.lanes=m,e;case C:return e=tn(19,i,n,f),e.elementType=C,e.lanes=m,e;case U:return pa(i,f,m,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case re:k=10;break e;case J:k=9;break e;case te:k=11;break e;case V:k=14;break e;case W:k=16,l=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=tn(k,i,n,f),n.elementType=e,n.type=l,n.lanes=m,n}function so(e,n,i,l){return e=tn(7,e,l,n),e.lanes=i,e}function pa(e,n,i,l){return e=tn(22,e,l,n),e.elementType=U,e.lanes=i,e.stateNode={isHidden:!1},e}function Ru(e,n,i){return e=tn(6,e,null,n),e.lanes=i,e}function Tu(e,n,i){return n=tn(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function t0(e,n,i,l,f){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=sn(0),this.expirationTimes=sn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=sn(0),this.identifierPrefix=l,this.onRecoverableError=f,this.mutableSourceEagerHydrationData=null}function Lu(e,n,i,l,f,m,k,T,O){return e=new t0(e,n,i,T,O),n===1?(n=1,m===!0&&(n|=8)):n=0,m=tn(3,null,null,n),e.current=m,m.stateNode=e,m.memoizedState={element:l,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},Yl(m),e}function n0(e,n,i){var l=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),Fu.exports=p0(),Fu.exports}var uh;function g0(){if(uh)return _a;uh=1;var t=Ip();return _a.createRoot=t.createRoot,_a.hydrateRoot=t.hydrateRoot,_a}var m0=g0();function Rp(t,r="Request failed"){const o=(t||"").trim();if(!o)return r;try{const a=JSON.parse(o).detail;if(typeof a=="string"&&a.trim())return a;if(Array.isArray(a)){const u=a.map(c=>typeof c=="string"?c:c&&typeof c=="object"&&"msg"in c?String(c.msg):"").filter(Boolean);if(u.length)return u.join("; ")}}catch{}return o}async function $e(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const s=await o.text();throw new Error(Rp(s,o.statusText||"Request failed"))}return o.json()}const y0=["github_token","gitlab_token","gitlab_oauth_client_secret","bitbucket_token","bitbucket_oauth_client_secret","ai_api_key","ai_model","ai_base_url"],Te={health:()=>$e("/api/health"),settings:()=>$e("/api/settings"),saveSettings:t=>{const r={...t};for(const o of y0)r[o]===""&&delete r[o];return $e("/api/settings",{method:"PUT",body:JSON.stringify(r)})},repos:()=>$e("/api/repos"),browse:t=>$e(`/api/fs${t?`?path=${encodeURIComponent(t)}`:""}`),gitRefs:(t,r=50)=>$e(`/api/git/refs?repo_path=${encodeURIComponent(t)}&limit=${r}`),index:(t,r=!0)=>$e("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>$e(`/api/index?repo_path=${encodeURIComponent(t)}`),indexProgress:t=>$e(`/api/index/progress?repo_path=${encodeURIComponent(t)}`),architecture:(t,r=!0)=>$e(`/api/architecture?repo_path=${encodeURIComponent(t)}&graph=${r?"1":"0"}`),architectureGraph:t=>$e(`/api/architecture/graph?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,s=!0,a=!1)=>$e("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:s,incremental:!0,three_dot:!0,dirty:a})}),whatIf:(t,r)=>$e("/api/whatif",{method:"POST",body:JSON.stringify({repo_path:t,node_id:r})}),reviewPr:(t,r,o,s)=>$e("/api/prs/review",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,repo_path:s||null})}),init:(t,r=!1)=>$e("/api/init",{method:"POST",body:JSON.stringify({repo_path:t,overwrite:r})}),postComment:(t,r,o,s)=>$e("/api/prs/comment",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,markdown:s})}),graph:(t,r="full")=>$e(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open",s)=>$e("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o,repo_path:s||null})}),scmRepos:t=>$e(`/api/scm/repos?provider=${encodeURIComponent(t)}`),oauthStatus:()=>$e("/api/oauth/status"),githubOAuthStart:()=>$e("/api/oauth/github/start",{method:"POST",body:"{}"}),githubOAuthPoll:t=>$e("/api/oauth/github/poll",{method:"POST",body:JSON.stringify({flow_id:t})}),bitbucketOAuthStart:()=>$e("/api/oauth/bitbucket/start"),gitlabOAuthStart:()=>$e("/api/oauth/gitlab/start"),oauthDisconnect:t=>$e("/api/oauth/disconnect",{method:"POST",body:JSON.stringify({provider:t})}),residual:t=>$e("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})}),reviews:t=>$e(`/api/reviews?repo_path=${encodeURIComponent(t)}`),getReview:(t,r)=>$e(`/api/reviews/${encodeURIComponent(r)}?repo_path=${encodeURIComponent(t)}`),reviewDiff:(t,r,o)=>$e(`/api/reviews/${encodeURIComponent(r)}/diff?repo_path=${encodeURIComponent(t)}&other=${encodeURIComponent(o)}`),config:t=>$e(`/api/config?repo_path=${encodeURIComponent(t)}`),saveConfig:(t,r)=>$e("/api/config",{method:"PUT",body:JSON.stringify({repo_path:t,...r})}),addWaiver:(t,r,o,s)=>$e("/api/config/waiver",{method:"POST",body:JSON.stringify({repo_path:t,rule:r,node:o||null,reason:s||""})}),marks:(t,r)=>$e(`/api/marks?repo_path=${encodeURIComponent(t)}${r?`&review_id=${encodeURIComponent(r)}`:""}`),architectureHealth:t=>$e(`/api/architecture/health?repo_path=${encodeURIComponent(t)}`),workspaceStatus:t=>$e(`/api/workspace/status?repo_path=${encodeURIComponent(t)}`),openEditor:(t,r,o,s)=>$e("/api/open",{method:"POST",body:JSON.stringify({repo_path:t,path:r,line:o||null,editor:s||null})}),exportHtml:t=>fetch("/api/export/html",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({review:t})}).then(async r=>{if(!r.ok){const o=await r.text();throw new Error(Rp(o,r.statusText||"Request failed"))}return r.blob()}),isolate:(t,r,o,s)=>$e("/api/graph/isolate",{method:"POST",body:JSON.stringify({nodes:t,edges:r,source_id:o,target_id:s||null})})};function v0(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.label.toLowerCase().includes(o)||(s.hint||"").toLowerCase().includes(o)||(s.group||"").toLowerCase().includes(o)):t}function x0({open:t,actions:r,onClose:o}){const[s,a]=L.useState(""),[u,c]=L.useState(0),h=L.useRef(null),p=L.useMemo(()=>v0(r,s),[r,s]);if(L.useEffect(()=>{if(!t)return;a(""),c(0);const g=window.setTimeout(()=>{var _;return(_=h.current)==null?void 0:_.focus()},0);return()=>window.clearTimeout(g)},[t]),L.useEffect(()=>{c(0)},[s]),!t)return null;const y=p.slice(0,40),x=y[Math.min(u,Math.max(y.length-1,0))],v=g=>{g&&(o(),g.run())};return d.jsx("div",{className:"palette-scrim","data-testid":"command-palette",onClick:g=>{g.target===g.currentTarget&&o()},children:d.jsxs("div",{className:"palette",role:"dialog","aria-label":"Command palette",children:[d.jsx("input",{ref:h,"data-testid":"command-palette-input",placeholder:"Jump to a node, run a review, toggle overlays…",value:s,onChange:g=>a(g.target.value),onKeyDown:g=>{g.key==="Escape"?(g.preventDefault(),o()):g.key==="ArrowDown"?(g.preventDefault(),c(_=>Math.min(Math.max(y.length-1,0),_+1))):g.key==="ArrowUp"?(g.preventDefault(),c(_=>Math.max(0,_-1))):g.key==="Enter"&&(g.preventDefault(),v(x))}}),d.jsxs("ul",{children:[y.length===0?d.jsx("li",{className:"muted",children:"No matches"}):null,y.map((g,_)=>d.jsx("li",{children:d.jsxs("button",{type:"button",className:_===u?"active":"",onMouseEnter:()=>c(_),onClick:()=>v(g),children:[d.jsx("span",{children:g.label}),g.hint?d.jsx("span",{className:"muted",children:g.hint}):null]})},g.id))]}),d.jsxs("div",{className:"palette-foot muted",children:[d.jsx("kbd",{children:"↑"}),d.jsx("kbd",{children:"↓"})," move · ",d.jsx("kbd",{children:"Enter"})," run · ",d.jsx("kbd",{children:"Esc"})," close"]})]})})}function w0({config:t,busy:r,onSave:o,onWaiver:s}){const[a,u]=L.useState(t),[c,h]=L.useState(t.available_rules[0]||""),[p,y]=L.useState(""),[x,v]=L.useState("");L.useEffect(()=>{u(t)},[t]);const g=Object.entries(a.contexts||{}),_=(I,w,j)=>{const A=a.contexts[I];if(!A)return;const $=F=>F.split(",").map(Y=>Y.trim()).filter(Boolean);u({...a,contexts:{...a.contexts,[I]:{...A,[w]:w==="name"?j:$(j)}}})},S=(I,w)=>{const j=w.trim();if(!j||j===I)return;const{[I]:A,...$}=a.contexts;A&&u({...a,contexts:{...$,[j]:{...A,name:j}}})},N=()=>{let I=1;for(;a.contexts[`context-${I}`];)I+=1;const w=`context-${I}`;u({...a,contexts:{...a.contexts,[w]:{name:w,django_apps:[],react:[],public_api:[],owners:[]}}})},b=I=>{const{[I]:w,...j}=a.contexts;u({...a,contexts:j})},E=I=>{const w=a.rules.includes(I);u({...a,rules:w?a.rules.filter(j=>j!==I):[...a.rules,I]})};return d.jsxs("div",{className:"config-editor","data-testid":"config-editor",children:[d.jsx("p",{className:"muted",children:a.exists?a.path:"No loadpath.yml yet — saving writes one at the repo root."}),g.map(([I,w])=>d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Context ",d.jsx("span",{className:"count",children:I})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Name"}),d.jsx("input",{defaultValue:I,"data-testid":`config-context-name-${I}`,onBlur:j=>S(I,j.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Django apps"}),d.jsx("input",{value:(w.django_apps||[]).join(", "),onChange:j=>_(I,"django_apps",j.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"React folders"}),d.jsx("input",{value:(w.react||[]).join(", "),onChange:j=>_(I,"react",j.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Public API"}),d.jsx("input",{value:(w.public_api||[]).join(", "),onChange:j=>_(I,"public_api",j.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Owners"}),d.jsx("input",{value:(w.owners||[]).join(", "),onChange:j=>_(I,"owners",j.target.value)})]}),d.jsx("button",{type:"button",className:"btn",onClick:()=>b(I),children:"Remove context"})]},I)),d.jsx("div",{className:"btn-row",children:d.jsx("button",{type:"button",className:"btn","data-testid":"config-add-context",onClick:N,children:"Add context"})}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Rules ",d.jsx("span",{className:"count",children:a.rules.length})]}),(a.available_rules.length?a.available_rules:a.rules).map(I=>d.jsxs("label",{className:"check-row",children:[d.jsx("input",{type:"checkbox",checked:a.rules.includes(I),onChange:()=>E(I)}),I]},I))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Waivers ",d.jsx("span",{className:"count",children:(a.waivers||[]).length})]}),(a.waivers||[]).map((I,w)=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:I.rule}),I.node?` · ${I.node}`:"",I.reason?` — ${I.reason}`:""]},`${I.rule}:${I.node}:${w}`)),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Rule"}),d.jsx("select",{value:c,onChange:I=>h(I.target.value),children:(a.available_rules.length?a.available_rules:a.rules).map(I=>d.jsx("option",{value:I,children:I},I))})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Node id (optional)"}),d.jsx("input",{value:p,onChange:I=>y(I.target.value),placeholder:"django.view:…"})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Reason"}),d.jsx("input",{value:x,onChange:I=>v(I.target.value)})]}),d.jsx("button",{type:"button",className:"btn","data-testid":"config-add-waiver",disabled:r||!c,onClick:()=>s==null?void 0:s(c,p,x),children:"Add waiver"})]}),d.jsx("div",{className:"btn-row",children:d.jsx("button",{type:"button",className:"btn primary","data-testid":"config-save",disabled:r,onClick:()=>o(a),children:"Save loadpath.yml"})})]})}function ns(t){return t.replaceAll("_"," ")}function _0(t){return t.replaceAll("_"," ")}function li(t){return t.split(".").pop()||t}function ic(t){if(!t)return"";const r=new Date(t);return Number.isNaN(r.getTime())?t:r.toLocaleString()}function S0(t){return t.split(/[\\/]/).filter(Boolean).pop()||t}function Ar(t){return t.replace(/([/\\._:@-])/g,"$1​")}function yo({className:t,children:r}){return d.jsx("svg",{className:t,width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r})}function k0({className:t}){return d.jsxs(yo,{className:t,children:[d.jsx("path",{d:"M3 3.5h6.5L13 7v5.5H3z"}),d.jsx("path",{d:"M9.5 3.5V7H13"}),d.jsx("path",{d:"M5.5 9.5h5M5.5 11.5h3.5"})]})}function N0({className:t}){return d.jsxs(yo,{className:t,children:[d.jsx("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"9",y:"9",width:"4.5",height:"4.5",rx:"0.8"})]})}function j0({className:t}){return d.jsxs(yo,{className:t,children:[d.jsx("circle",{cx:"4",cy:"8",r:"1.6"}),d.jsx("circle",{cx:"12",cy:"4",r:"1.6"}),d.jsx("circle",{cx:"12",cy:"12",r:"1.6"}),d.jsx("path",{d:"M5.5 7.2 10.4 4.8M5.5 8.8 10.4 11.2"})]})}function b0({className:t}){return d.jsxs(yo,{className:t,children:[d.jsx("circle",{cx:"4.5",cy:"4",r:"1.4"}),d.jsx("circle",{cx:"4.5",cy:"12",r:"1.4"}),d.jsx("circle",{cx:"11.5",cy:"12",r:"1.4"}),d.jsx("path",{d:"M4.5 5.5v5M4.5 8h4.2a3 3 0 0 1 3 3"})]})}function E0({className:t}){return d.jsxs(yo,{className:t,children:[d.jsx("circle",{cx:"8",cy:"8",r:"2.1"}),d.jsx("path",{d:"M8 2.5v1.6M8 11.9v1.6M2.5 8h1.6M11.9 8h1.6M4.1 4.1l1.1 1.1M10.8 10.8l1.1 1.1M11.9 4.1l-1.1 1.1M5.2 10.8l-1.1 1.1"})]})}function Tp({className:t}){return d.jsx(yo,{className:t,children:d.jsx("path",{d:"M2.5 4.5h4L8 6h5.5v6.5h-11z"})})}function C0({className:t}){return d.jsx(yo,{className:t,children:d.jsx("path",{d:"M4 6.5 8 10.5 12 6.5"})})}const M0="modulepreload",P0=function(t,r){return new URL(t,r).href},ch={},I0=function(r,o,s){let a=Promise.resolve();if(o&&o.length>0){let c=function(x){return Promise.all(x.map(v=>Promise.resolve(v).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};const h=document.getElementsByTagName("link"),p=document.querySelector("meta[property=csp-nonce]"),y=(p==null?void 0:p.nonce)||(p==null?void 0:p.getAttribute("nonce"));a=c(o.map(x=>{if(x=P0(x,s),x in ch)return;ch[x]=!0;const v=x.endsWith(".css"),g=v?'[rel="stylesheet"]':"";if(!!s)for(let N=h.length-1;N>=0;N--){const b=h[N];if(b.href===x&&(!v||b.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${x}"]${g}`))return;const S=document.createElement("link");if(S.rel=v?"stylesheet":M0,v||(S.as="script"),S.crossOrigin="",S.href=x,y&&S.setAttribute("nonce",y),document.head.appendChild(S),v)return new Promise((N,b)=>{S.addEventListener("load",N),S.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${x}`)))})}))}function u(c){const h=new Event("vite:preloadError",{cancelable:!0});if(h.payload=c,window.dispatchEvent(h),!h.defaultPrevented)throw c}return a.then(c=>{for(const h of c||[])h.status==="rejected"&&u(h.reason);return r().catch(u)})};function ot(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,s;o{}};function Za(){for(var t=0,r=arguments.length,o={},s;t=0&&(s=o.slice(a+1),o=o.slice(0,a)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:s}})}Ta.prototype=Za.prototype={constructor:Ta,on:function(t,r){var o=this._,s=T0(t+"",o),a,u=-1,c=s.length;if(arguments.length<2){for(;++u0)for(var o=new Array(a),s=0,a,u;s=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),fh.hasOwnProperty(r)?{space:fh[r],local:t}:t}function A0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===sc&&r.documentElement.namespaceURI===sc?r.createElement(t):r.createElementNS(o,t)}}function $0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Lp(t){var r=Ja(t);return(r.local?$0:A0)(r)}function z0(){}function wc(t){return t==null?z0:function(){return this.querySelector(t)}}function D0(t){typeof t!="function"&&(t=wc(t));for(var r=this._groups,o=r.length,s=new Array(o),a=0;a=w&&(w=I+1);!(A=b[w])&&++w=0;)(c=s[a])&&(u&&c.compareDocumentPosition(u)^4&&u.parentNode.insertBefore(c,u),u=c);return this}function uv(t){t||(t=cv);function r(v,g){return v&&g?t(v.__data__,g.__data__):!v-!g}for(var o=this._groups,s=o.length,a=new Array(s),u=0;ur?1:t>=r?0:NaN}function dv(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function fv(){return Array.from(this)}function hv(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?Nv:typeof r=="function"?bv:jv)(t,r,o??"")):Jo(this.node(),t)}function Jo(t,r){return t.style.getPropertyValue(r)||Op(t).getComputedStyle(t,null).getPropertyValue(r)}function Cv(t){return function(){delete this[t]}}function Mv(t,r){return function(){this[t]=r}}function Pv(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function Iv(t,r){return arguments.length>1?this.each((r==null?Cv:typeof r=="function"?Pv:Mv)(t,r)):this.node()[t]}function Fp(t){return t.trim().split(/^|\s+/)}function _c(t){return t.classList||new Hp(t)}function Hp(t){this._node=t,this._names=Fp(t.getAttribute("class")||"")}Hp.prototype={add:function(t){var r=this._names.indexOf(t);r<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var r=this._names.indexOf(t);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function Bp(t,r){for(var o=_c(t),s=-1,a=r.length;++s=0&&(o=r.slice(s+1),r=r.slice(0,s)),{type:r,name:o}})}function ix(t){return function(){var r=this.__on;if(r){for(var o=0,s=-1,a=r.length,u;o()=>t;function ac(t,{sourceEvent:r,subject:o,target:s,identifier:a,active:u,x:c,y:h,dx:p,dy:y,dispatch:x}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:o,enumerable:!0,configurable:!0},target:{value:s,enumerable:!0,configurable:!0},identifier:{value:a,enumerable:!0,configurable:!0},active:{value:u,enumerable:!0,configurable:!0},x:{value:c,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:x}})}ac.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function gx(t){return!t.ctrlKey&&!t.button}function mx(){return this.parentNode}function yx(t,r){return r??{x:t.x,y:t.y}}function vx(){return navigator.maxTouchPoints||"ontouchstart"in this}function Xp(){var t=gx,r=mx,o=yx,s=vx,a={},u=Za("start","drag","end"),c=0,h,p,y,x,v=0;function g(j){j.on("mousedown.drag",_).filter(s).on("touchstart.drag",b).on("touchmove.drag",E,px).on("touchend.drag touchcancel.drag",I).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function _(j,A){if(!(x||!t.call(this,j,A))){var $=w(this,r.call(this,j,A),j,A,"mouse");$&&(Ut(j.view).on("mousemove.drag",S,rs).on("mouseup.drag",N,rs),Gp(j.view),Vu(j),y=!1,h=j.clientX,p=j.clientY,$("start",j))}}function S(j){if(Qo(j),!y){var A=j.clientX-h,$=j.clientY-p;y=A*A+$*$>v}a.mouse("drag",j)}function N(j){Ut(j.view).on("mousemove.drag mouseup.drag",null),Yp(j.view,y),Qo(j),a.mouse("end",j)}function b(j,A){if(t.call(this,j,A)){var $=j.changedTouches,F=r.call(this,j,A),Y=$.length,q,re;for(q=0;q>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?ka(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?ka(r>>12&15|r>>8&240,r>>8&15|r>>4&240,r>>4&15|r&240,((r&15)<<4|r&15)/255):null):(r=wx.exec(t))?new Ot(r[1],r[2],r[3],1):(r=_x.exec(t))?new Ot(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=Sx.exec(t))?ka(r[1],r[2],r[3],r[4]):(r=kx.exec(t))?ka(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=Nx.exec(t))?xh(r[1],r[2]/100,r[3]/100,1):(r=jx.exec(t))?xh(r[1],r[2]/100,r[3]/100,r[4]):hh.hasOwnProperty(t)?mh(hh[t]):t==="transparent"?new Ot(NaN,NaN,NaN,0):null}function mh(t){return new Ot(t>>16&255,t>>8&255,t&255,1)}function ka(t,r,o,s){return s<=0&&(t=r=o=NaN),new Ot(t,r,o,s)}function Cx(t){return t instanceof gs||(t=fo(t)),t?(t=t.rgb(),new Ot(t.r,t.g,t.b,t.opacity)):new Ot}function lc(t,r,o,s){return arguments.length===1?Cx(t):new Ot(t,r,o,s??1)}function Ot(t,r,o,s){this.r=+t,this.g=+r,this.b=+o,this.opacity=+s}Sc(Ot,lc,qp(gs,{brighter(t){return t=t==null?Oa:Math.pow(Oa,t),new Ot(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?os:Math.pow(os,t),new Ot(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ot(uo(this.r),uo(this.g),uo(this.b),Fa(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:yh,formatHex:yh,formatHex8:Mx,formatRgb:vh,toString:vh}));function yh(){return`#${lo(this.r)}${lo(this.g)}${lo(this.b)}`}function Mx(){return`#${lo(this.r)}${lo(this.g)}${lo(this.b)}${lo((isNaN(this.opacity)?1:this.opacity)*255)}`}function vh(){const t=Fa(this.opacity);return`${t===1?"rgb(":"rgba("}${uo(this.r)}, ${uo(this.g)}, ${uo(this.b)}${t===1?")":`, ${t})`}`}function Fa(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function uo(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function lo(t){return t=uo(t),(t<16?"0":"")+t.toString(16)}function xh(t,r,o,s){return s<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new yn(t,r,o,s)}function Kp(t){if(t instanceof yn)return new yn(t.h,t.s,t.l,t.opacity);if(t instanceof gs||(t=fo(t)),!t)return new yn;if(t instanceof yn)return t;t=t.rgb();var r=t.r/255,o=t.g/255,s=t.b/255,a=Math.min(r,o,s),u=Math.max(r,o,s),c=NaN,h=u-a,p=(u+a)/2;return h?(r===u?c=(o-s)/h+(o0&&p<1?0:c,new yn(c,h,p,t.opacity)}function Px(t,r,o,s){return arguments.length===1?Kp(t):new yn(t,r,o,s??1)}function yn(t,r,o,s){this.h=+t,this.s=+r,this.l=+o,this.opacity=+s}Sc(yn,Px,qp(gs,{brighter(t){return t=t==null?Oa:Math.pow(Oa,t),new yn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?os:Math.pow(os,t),new yn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,r=isNaN(t)||isNaN(this.s)?0:this.s,o=this.l,s=o+(o<.5?o:1-o)*r,a=2*o-s;return new Ot(Wu(t>=240?t-240:t+120,a,s),Wu(t,a,s),Wu(t<120?t+240:t-120,a,s),this.opacity)},clamp(){return new yn(wh(this.h),Na(this.s),Na(this.l),Fa(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Fa(this.opacity);return`${t===1?"hsl(":"hsla("}${wh(this.h)}, ${Na(this.s)*100}%, ${Na(this.l)*100}%${t===1?")":`, ${t})`}`}}));function wh(t){return t=(t||0)%360,t<0?t+360:t}function Na(t){return Math.max(0,Math.min(1,t||0))}function Wu(t,r,o){return(t<60?r+(o-r)*t/60:t<180?o:t<240?r+(o-r)*(240-t)/60:r)*255}const kc=t=>()=>t;function Ix(t,r){return function(o){return t+o*r}}function Rx(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(s){return Math.pow(t+s*r,o)}}function Tx(t){return(t=+t)==1?Qp:function(r,o){return o-r?Rx(r,o,t):kc(isNaN(r)?o:r)}}function Qp(t,r){var o=r-t;return o?Ix(t,o):kc(isNaN(t)?r:t)}const Ha=(function t(r){var o=Tx(r);function s(a,u){var c=o((a=lc(a)).r,(u=lc(u)).r),h=o(a.g,u.g),p=o(a.b,u.b),y=Qp(a.opacity,u.opacity);return function(x){return a.r=c(x),a.g=h(x),a.b=p(x),a.opacity=y(x),a+""}}return s.gamma=t,s})(1);function Lx(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,s=r.slice(),a;return function(u){for(a=0;ao&&(u=r.slice(o,u),h[c]?h[c]+=u:h[++c]=u),(s=s[0])===(a=a[0])?h[c]?h[c]+=a:h[++c]=a:(h[++c]=null,p.push({i:c,x:An(s,a)})),o=Uu.lastIndex;return o180?x+=360:x-y>180&&(y+=360),g.push({i:v.push(a(v)+"rotate(",null,s)-2,x:An(y,x)})):x&&v.push(a(v)+"rotate("+x+s)}function h(y,x,v,g){y!==x?g.push({i:v.push(a(v)+"skewX(",null,s)-2,x:An(y,x)}):x&&v.push(a(v)+"skewX("+x+s)}function p(y,x,v,g,_,S){if(y!==v||x!==g){var N=_.push(a(_)+"scale(",null,",",null,")");S.push({i:N-4,x:An(y,v)},{i:N-2,x:An(x,g)})}else(v!==1||g!==1)&&_.push(a(_)+"scale("+v+","+g+")")}return function(y,x){var v=[],g=[];return y=t(y),x=t(x),u(y.translateX,y.translateY,x.translateX,x.translateY,v,g),c(y.rotate,x.rotate,v,g),h(y.skewX,x.skewX,v,g),p(y.scaleX,y.scaleY,x.scaleX,x.scaleY,v,g),y=x=null,function(_){for(var S=-1,N=g.length,b;++S=0&&t._call.call(void 0,r),t=t._next;--ei}function kh(){ho=(Va=ss.now())+el,ei=Qi=0;try{qx()}finally{ei=0,Qx(),ho=0}}function Kx(){var t=ss.now(),r=t-Va;r>tg&&(el-=r,Va=t)}function Qx(){for(var t,r=Ba,o,s=1/0;r;)r._call?(s>r._time&&(s=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:Ba=o);Zi=t,dc(s)}function dc(t){if(!ei){Qi&&(Qi=clearTimeout(Qi));var r=t-ho;r>24?(t<1/0&&(Qi=setTimeout(kh,t-ss.now()-el)),qi&&(qi=clearInterval(qi))):(qi||(Va=ss.now(),qi=setInterval(Kx,tg)),ei=1,ng(kh))}}function Nh(t,r,o){var s=new Wa;return r=r==null?0:+r,s.restart(a=>{s.stop(),t(a+r)},r,o),s}var Zx=Za("start","end","cancel","interrupt"),Jx=[],og=0,jh=1,fc=2,Aa=3,bh=4,hc=5,$a=6;function tl(t,r,o,s,a,u){var c=t.__transition;if(!c)t.__transition={};else if(o in c)return;ew(t,o,{name:r,index:s,group:a,on:Zx,tween:Jx,time:u.time,delay:u.delay,duration:u.duration,ease:u.ease,timer:null,state:og})}function jc(t,r){var o=_n(t,r);if(o.state>og)throw new Error("too late; already scheduled");return o}function Dn(t,r){var o=_n(t,r);if(o.state>Aa)throw new Error("too late; already running");return o}function _n(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function ew(t,r,o){var s=t.__transition,a;s[r]=o,o.timer=rg(u,0,o.time);function u(y){o.state=jh,o.timer.restart(c,o.delay,o.time),o.delay<=y&&c(y-o.delay)}function c(y){var x,v,g,_;if(o.state!==jh)return p();for(x in s)if(_=s[x],_.name===o.name){if(_.state===Aa)return Nh(c);_.state===bh?(_.state=$a,_.timer.stop(),_.on.call("interrupt",t,t.__data__,_.index,_.group),delete s[x]):+xfc&&s.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function Pw(t,r,o){var s,a,u=Mw(r)?jc:Dn;return function(){var c=u(this,t),h=c.on;h!==s&&(a=(s=h).copy()).on(r,o),c.on=a}}function Iw(t,r){var o=this._id;return arguments.length<2?_n(this.node(),o).on.on(t):this.each(Pw(o,t,r))}function Rw(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function Tw(){return this.on("end.remove",Rw(this._id))}function Lw(t){var r=this._name,o=this._id;typeof t!="function"&&(t=wc(t));for(var s=this._groups,a=s.length,u=new Array(a),c=0;c()=>t;function i1(t,{sourceEvent:r,target:o,transform:s,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:o,enumerable:!0,configurable:!0},transform:{value:s,enumerable:!0,configurable:!0},_:{value:a}})}function sr(t,r,o){this.k=t,this.x=r,this.y=o}sr.prototype={constructor:sr,scale:function(t){return t===1?this:new sr(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new sr(this.k,this.x+this.k*t,this.y+this.k*r)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var nl=new sr(1,0,0);lg.prototype=sr.prototype;function lg(t){for(;!t.__zoom;)if(!(t=t.parentNode))return nl;return t.__zoom}function Gu(t){t.stopImmediatePropagation()}function Ki(t){t.preventDefault(),t.stopImmediatePropagation()}function s1(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function a1(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function Eh(){return this.__zoom||nl}function l1(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function u1(){return navigator.maxTouchPoints||"ontouchstart"in this}function c1(t,r,o){var s=t.invertX(r[0][0])-o[0][0],a=t.invertX(r[1][0])-o[1][0],u=t.invertY(r[0][1])-o[0][1],c=t.invertY(r[1][1])-o[1][1];return t.translate(a>s?(s+a)/2:Math.min(0,s)||Math.max(0,a),c>u?(u+c)/2:Math.min(0,u)||Math.max(0,c))}function ug(){var t=s1,r=a1,o=c1,s=l1,a=u1,u=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],h=250,p=La,y=Za("start","zoom","end"),x,v,g,_=500,S=150,N=0,b=10;function E(C){C.property("__zoom",Eh).on("wheel.zoom",Y,{passive:!1}).on("mousedown.zoom",q).on("dblclick.zoom",re).filter(a).on("touchstart.zoom",J).on("touchmove.zoom",te).on("touchend.zoom touchcancel.zoom",Q).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(C,V,W,U){var M=C.selection?C.selection():C;M.property("__zoom",Eh),C!==M?A(C,V,W,U):M.interrupt().each(function(){$(this,arguments).event(U).start().zoom(null,typeof V=="function"?V.apply(this,arguments):V).end()})},E.scaleBy=function(C,V,W,U){E.scaleTo(C,function(){var M=this.__zoom.k,D=typeof V=="function"?V.apply(this,arguments):V;return M*D},W,U)},E.scaleTo=function(C,V,W,U){E.transform(C,function(){var M=r.apply(this,arguments),D=this.__zoom,H=W==null?j(M):typeof W=="function"?W.apply(this,arguments):W,R=D.invert(H),z=typeof V=="function"?V.apply(this,arguments):V;return o(w(I(D,z),H,R),M,c)},W,U)},E.translateBy=function(C,V,W,U){E.transform(C,function(){return o(this.__zoom.translate(typeof V=="function"?V.apply(this,arguments):V,typeof W=="function"?W.apply(this,arguments):W),r.apply(this,arguments),c)},null,U)},E.translateTo=function(C,V,W,U,M){E.transform(C,function(){var D=r.apply(this,arguments),H=this.__zoom,R=U==null?j(D):typeof U=="function"?U.apply(this,arguments):U;return o(nl.translate(R[0],R[1]).scale(H.k).translate(typeof V=="function"?-V.apply(this,arguments):-V,typeof W=="function"?-W.apply(this,arguments):-W),D,c)},U,M)};function I(C,V){return V=Math.max(u[0],Math.min(u[1],V)),V===C.k?C:new sr(V,C.x,C.y)}function w(C,V,W){var U=V[0]-W[0]*C.k,M=V[1]-W[1]*C.k;return U===C.x&&M===C.y?C:new sr(C.k,U,M)}function j(C){return[(+C[0][0]+ +C[1][0])/2,(+C[0][1]+ +C[1][1])/2]}function A(C,V,W,U){C.on("start.zoom",function(){$(this,arguments).event(U).start()}).on("interrupt.zoom end.zoom",function(){$(this,arguments).event(U).end()}).tween("zoom",function(){var M=this,D=arguments,H=$(M,D).event(U),R=r.apply(M,D),z=W==null?j(R):typeof W=="function"?W.apply(M,D):W,ne=Math.max(R[1][0]-R[0][0],R[1][1]-R[0][1]),oe=M.__zoom,fe=typeof V=="function"?V.apply(M,D):V,he=p(oe.invert(z).concat(ne/oe.k),fe.invert(z).concat(ne/fe.k));return function(pe){if(pe===1)pe=fe;else{var Z=he(pe),se=ne/Z[2];pe=new sr(se,z[0]-Z[0]*se,z[1]-Z[1]*se)}H.zoom(null,pe)}})}function $(C,V,W){return!W&&C.__zooming||new F(C,V)}function F(C,V){this.that=C,this.args=V,this.active=0,this.sourceEvent=null,this.extent=r.apply(C,V),this.taps=0}F.prototype={event:function(C){return C&&(this.sourceEvent=C),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(C,V){return this.mouse&&C!=="mouse"&&(this.mouse[1]=V.invert(this.mouse[0])),this.touch0&&C!=="touch"&&(this.touch0[1]=V.invert(this.touch0[0])),this.touch1&&C!=="touch"&&(this.touch1[1]=V.invert(this.touch1[0])),this.that.__zoom=V,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(C){var V=Ut(this.that).datum();y.call(C,this.that,new i1(C,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:y}),V)}};function Y(C,...V){if(!t.apply(this,arguments))return;var W=$(this,V).event(C),U=this.__zoom,M=Math.max(u[0],Math.min(u[1],U.k*Math.pow(2,s.apply(this,arguments)))),D=mn(C);if(W.wheel)(W.mouse[0][0]!==D[0]||W.mouse[0][1]!==D[1])&&(W.mouse[1]=U.invert(W.mouse[0]=D)),clearTimeout(W.wheel);else{if(U.k===M)return;W.mouse=[D,U.invert(D)],za(this),W.start()}Ki(C),W.wheel=setTimeout(H,S),W.zoom("mouse",o(w(I(U,M),W.mouse[0],W.mouse[1]),W.extent,c));function H(){W.wheel=null,W.end()}}function q(C,...V){if(g||!t.apply(this,arguments))return;var W=C.currentTarget,U=$(this,V,!0).event(C),M=Ut(C.view).on("mousemove.zoom",z,!0).on("mouseup.zoom",ne,!0),D=mn(C,W),H=C.clientX,R=C.clientY;Gp(C.view),Gu(C),U.mouse=[D,this.__zoom.invert(D)],za(this),U.start();function z(oe){if(Ki(oe),!U.moved){var fe=oe.clientX-H,he=oe.clientY-R;U.moved=fe*fe+he*he>N}U.event(oe).zoom("mouse",o(w(U.that.__zoom,U.mouse[0]=mn(oe,W),U.mouse[1]),U.extent,c))}function ne(oe){M.on("mousemove.zoom mouseup.zoom",null),Yp(oe.view,U.moved),Ki(oe),U.event(oe).end()}}function re(C,...V){if(t.apply(this,arguments)){var W=this.__zoom,U=mn(C.changedTouches?C.changedTouches[0]:C,this),M=W.invert(U),D=W.k*(C.shiftKey?.5:2),H=o(w(I(W,D),U,M),r.apply(this,V),c);Ki(C),h>0?Ut(this).transition().duration(h).call(A,H,U,C):Ut(this).call(E.transform,H,U,C)}}function J(C,...V){if(t.apply(this,arguments)){var W=C.touches,U=W.length,M=$(this,V,C.changedTouches.length===U).event(C),D,H,R,z;for(Gu(C),H=0;H`Seems like you have not used ${t==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${t}flow.dev/error#001`,error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:t=>`Node type "${t}" not found. Using fallback type "default".`,error004:()=>"The parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:t=>`The old edge with id=${t} does not exist.`,error009:t=>`Marker type "${t}" doesn't exist.`,error008:(t,{id:r,sourceHandle:o,targetHandle:s})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:s}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:t=>`Edge type "${t}" not found. Using fallback type "default".`,error012:t=>`Node with id "${t}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(t="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${t}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.",error016:t=>`Edge with id "${t}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},as=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],cg=["Enter"," ","Escape"],dg={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:t,x:r,y:o})=>`Moved selected node ${t}. New position, x: ${r}, y: ${o}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var ti;(function(t){t.Strict="strict",t.Loose="loose"})(ti||(ti={}));var co;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(co||(co={}));var ls;(function(t){t.Partial="partial",t.Full="full"})(ls||(ls={}));const fg={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var $r;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})($r||($r={}));var us;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(us||(us={}));var ke;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(ke||(ke={}));const Ch={[ke.Left]:ke.Right,[ke.Right]:ke.Left,[ke.Top]:ke.Bottom,[ke.Bottom]:ke.Top};function hg(t){return t===null?null:t?"valid":"invalid"}const pg=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,d1=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),Ec=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),ms=(t,r=[0,0])=>{const{width:o,height:s}=Sn(t),a=t.origin??r,u=o*a[0],c=s*a[1];return{x:t.position.x-u,y:t.position.y-c}},f1=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const s=t.reduce((a,u)=>{const c=typeof u=="string";let h=!r.nodeLookup&&!c?u:void 0;return r.nodeLookup&&(h=c?r.nodeLookup.get(u):Ec(u)?u:r.nodeLookup.get(u.id)),h?(o=!0,rl(a,Ua(h,r.nodeOrigin))):a},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?ol(s):{x:0,y:0,width:0,height:0}},ys=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},s=!1;return t.forEach(a=>{(r.filter===void 0||r.filter(a))&&(o=rl(o,Ua(a)),s=!0)}),s?ol(o):{x:0,y:0,width:0,height:0}},Cc=(t,r,[o,s,a]=[0,0,1],u=!1,c=!1)=>{const h=(r.x-o)/a,p=(r.y-s)/a,y=r.width/a,x=r.height/a,v=[];for(const g of t.values()){const{measured:_,selectable:S=!0,hidden:N=!1}=g;if(c&&!S||N)continue;const b=_.width??g.width??g.initialWidth??0,E=_.height??g.height??g.initialHeight??0,{x:I,y:w}=g.internals.positionAbsolute,j=vg(h,p,y,x,I,w,b,E),A=b*E,$=u&&j>0;(!g.internals.handleBounds||$||j>=A||g.dragging)&&v.push(g)}return v},h1=(t,r)=>{const o=new Set;return t.forEach(s=>{o.add(s.id)}),r.filter(s=>o.has(s.source)||o.has(s.target))};function p1(t,r){const o=new Map,s=r!=null&&r.nodes?new Set(r.nodes.map(a=>a.id)):null;return t.forEach(a=>{let u;if(r!=null&&r.includeHiddenNodes){const{width:c,height:h}=Sn(a);u=c>0&&h>0}else u=!!(a.measured.width&&a.measured.height&&!a.hidden);u&&(!s||s.has(a.id))&&o.set(a.id,a)}),o}async function g1({nodes:t,width:r,height:o,panZoom:s,minZoom:a,maxZoom:u},c){if(t.size===0)return!0;const h=p1(t,c),p=ys(h),y=Pc(p,r,o,(c==null?void 0:c.minZoom)??a,(c==null?void 0:c.maxZoom)??u,(c==null?void 0:c.padding)??.1);return await s.setViewport(y,{duration:c==null?void 0:c.duration,ease:c==null?void 0:c.ease,interpolate:c==null?void 0:c.interpolate}),!0}function gg({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:s=[0,0],nodeExtent:a,onError:u}){const c=o.get(t),h=c.parentId?o.get(c.parentId):void 0,{x:p,y}=h?h.internals.positionAbsolute:{x:0,y:0},x=c.origin??s;let v=c.extent||a;if(c.extent==="parent"&&!c.expandParent)if(!h)u==null||u("005",wn.error005());else{const{width:_,height:S}=Sn(h);_&&S&&(v=[[p,y],[p+_,y+S]])}else h&&go(c.extent)&&(v=[[c.extent[0][0]+p,c.extent[0][1]+y],[c.extent[1][0]+p,c.extent[1][1]+y]]);const g=go(v)?po(r,v,c.measured):r;return(c.measured.width===void 0||c.measured.height===void 0)&&(u==null||u("015",wn.error015())),{position:{x:g.x-p+(c.measured.width??0)*x[0],y:g.y-y+(c.measured.height??0)*x[1]},positionAbsolute:g}}async function m1({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:s,onBeforeDelete:a}){const u=new Set(t.map(g=>g.id)),c=[];for(const g of o){if(g.deletable===!1)continue;const _=u.has(g.id),S=!_&&g.parentId&&c.find(N=>N.id===g.parentId);(_||S)&&c.push(g)}const h=new Set(r.map(g=>g.id)),p=s.filter(g=>g.deletable!==!1),x=h1(c,p);for(const g of p)h.has(g.id)&&!x.find(S=>S.id===g.id)&&x.push(g);if(!a)return{edges:x,nodes:c};const v=await a({nodes:c,edges:x});return typeof v=="boolean"?v?{edges:x,nodes:c}:{edges:[],nodes:[]}:v}const ni=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),po=(t={x:0,y:0},r,o)=>({x:ni(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:ni(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function mg(t,r,o){const{width:s,height:a}=Sn(o),{x:u,y:c}=o.internals.positionAbsolute;return po(t,[[u,c],[u+s,c+a]],r)}const Mh=(t,r,o)=>to?-ni(Math.abs(t-o),1,r)/r:0,Mc=(t,r,o=15,s=40)=>{const a=Mh(t.x,s,r.width-s)*o,u=Mh(t.y,s,r.height-s)*o;return[a,u]},rl=(t,r)=>({x:Math.min(t.x,r.x),y:Math.min(t.y,r.y),x2:Math.max(t.x2,r.x2),y2:Math.max(t.y2,r.y2)}),pc=({x:t,y:r,width:o,height:s})=>({x:t,y:r,x2:t+o,y2:r+s}),ol=({x:t,y:r,x2:o,y2:s})=>({x:t,y:r,width:o-t,height:s-r}),cs=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=Ec(t)?t.internals.positionAbsolute:ms(t,r);return{x:o,y:s,width:((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0,height:((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0}},Ua=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=Ec(t)?t.internals.positionAbsolute:ms(t,r);return{x:o,y:s,x2:o+(((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0),y2:s+(((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0)}},yg=(t,r)=>ol(rl(pc(t),pc(r))),vg=(t,r,o,s,a,u,c,h)=>{const p=Math.max(0,Math.min(t+o,a+c)-Math.max(t,a)),y=Math.max(0,Math.min(r+s,u+h)-Math.max(r,u));return Math.ceil(p*y)},Ga=(t,r)=>vg(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),Ph=t=>vn(t.width)&&vn(t.height)&&vn(t.x)&&vn(t.y),vn=t=>!isNaN(t)&&isFinite(t),xg=(t,r)=>(o,s)=>{},vs=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),xs=({x:t,y:r},[o,s,a],u=!1,c=[1,1])=>{const h={x:(t-o)/a,y:(r-s)/a};return u?vs(h,c):h},ri=({x:t,y:r},[o,s,a])=>({x:t*a+o,y:r*a+s});function qo(t,r){if(typeof t=="number")return Math.floor((r-r/(1+t))*.5);if(typeof t=="string"&&t.endsWith("px")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(o)}if(typeof t=="string"&&t.endsWith("%")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(r*o*.01)}return console.error(`The padding value "${t}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function y1(t,r,o){if(typeof t=="string"||typeof t=="number"){const s=qo(t,o),a=qo(t,r);return{top:s,right:a,bottom:s,left:a,x:a*2,y:s*2}}if(typeof t=="object"){const s=qo(t.top??t.y??0,o),a=qo(t.bottom??t.y??0,o),u=qo(t.left??t.x??0,r),c=qo(t.right??t.x??0,r);return{top:s,right:c,bottom:a,left:u,x:u+c,y:s+a}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function v1(t,r,o,s,a,u){const{x:c,y:h}=ri(t,[r,o,s]),{x:p,y}=ri({x:t.x+t.width,y:t.y+t.height},[r,o,s]),x=a-p,v=u-y;return{left:Math.floor(c),top:Math.floor(h),right:Math.floor(x),bottom:Math.floor(v)}}const Pc=(t,r,o,s,a,u)=>{const c=y1(u,r,o),h=(r-c.x)/t.width,p=(o-c.y)/t.height,y=Math.min(h,p),x=ni(y,s,a),v=t.x+t.width/2,g=t.y+t.height/2,_=r/2-v*x,S=o/2-g*x,N=v1(t,_,S,x,r,o),b={left:Math.min(N.left-c.left,0),top:Math.min(N.top-c.top,0),right:Math.min(N.right-c.right,0),bottom:Math.min(N.bottom-c.bottom,0)};return{x:_-b.left+b.right,y:S-b.top+b.bottom,zoom:x}},ds=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function go(t){return t!=null&&t!=="parent"}function Sn(t){var r,o;return{width:((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth??0,height:((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight??0}}function wg(t){var r,o;return(((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth)!==void 0&&(((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight)!==void 0}function _g(t,r={width:0,height:0},o,s,a){const u={...t},c=s.get(o);if(c){const h=c.origin||a;u.x+=c.internals.positionAbsolute.x-(r.width??0)*h[0],u.y+=c.internals.positionAbsolute.y-(r.height??0)*h[1]}return u}function Ih(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function x1(){let t,r;return{promise:new Promise((s,a)=>{t=s,r=a}),resolve:t,reject:r}}function w1(t){return{...dg,...t||{}}}function es(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:s,containerBounds:a}){const{x:u,y:c}=xn(t),h=xs({x:u-((a==null?void 0:a.left)??0),y:c-((a==null?void 0:a.top)??0)},s),{x:p,y}=o?vs(h,r):h;return{xSnapped:p,ySnapped:y,...h}}const Ic=t=>({width:t.offsetWidth,height:t.offsetHeight}),Sg=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},_1=["INPUT","SELECT","TEXTAREA"];function kg(t){var s,a;const r=((a=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:a[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:_1.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Ng=t=>"clientX"in t,xn=(t,r)=>{var u,c;const o=Ng(t),s=o?t.clientX:(u=t.touches)==null?void 0:u[0].clientX,a=o?t.clientY:(c=t.touches)==null?void 0:c[0].clientY;return{x:s-((r==null?void 0:r.left)??0),y:a-((r==null?void 0:r.top)??0)}},Rh=(t,r,o,s,a)=>{const u=r.querySelectorAll(`.${t}`);return!u||!u.length?null:Array.from(u).map(c=>{const h=c.getBoundingClientRect();return{id:c.getAttribute("data-handleid"),type:t,nodeId:a,position:c.getAttribute("data-handlepos"),x:(h.left-o.left)/s,y:(h.top-o.top)/s,...Ic(c)}})};function jg({sourceX:t,sourceY:r,targetX:o,targetY:s,sourceControlX:a,sourceControlY:u,targetControlX:c,targetControlY:h}){const p=t*.125+a*.375+c*.375+o*.125,y=r*.125+u*.375+h*.375+s*.125,x=Math.abs(p-t),v=Math.abs(y-r);return[p,y,x,v]}function Ea(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function Th({pos:t,x1:r,y1:o,x2:s,y2:a,c:u}){switch(t){case ke.Left:return[r-Ea(r-s,u),o];case ke.Right:return[r+Ea(s-r,u),o];case ke.Top:return[r,o-Ea(o-a,u)];case ke.Bottom:return[r,o+Ea(a-o,u)]}}function bg({sourceX:t,sourceY:r,sourcePosition:o=ke.Bottom,targetX:s,targetY:a,targetPosition:u=ke.Top,curvature:c=.25}){const[h,p]=Th({pos:o,x1:t,y1:r,x2:s,y2:a,c}),[y,x]=Th({pos:u,x1:s,y1:a,x2:t,y2:r,c}),[v,g,_,S]=jg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:h,sourceControlY:p,targetControlX:y,targetControlY:x});return[`M${t},${r} C${h},${p} ${y},${x} ${s},${a}`,v,g,_,S]}function Eg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const a=Math.abs(o-t)/2,u=o0}const N1=({source:t,sourceHandle:r,target:o,targetHandle:s})=>`xy-edge__${t}${r||""}-${o}${s||""}`,j1=(t,r)=>r.some(o=>o.source===t.source&&o.target===t.target&&(o.sourceHandle===t.sourceHandle||!o.sourceHandle&&!t.sourceHandle)&&(o.targetHandle===t.targetHandle||!o.targetHandle&&!t.targetHandle)),b1=(t,r,o={})=>{var u;if(!t.source||!t.target)return(u=o.onError)==null||u.call(o,"006",wn.error006()),r;const s=o.getEdgeId||N1;let a;return pg(t)?a={...t}:a={...t,id:s(t)},j1(a,r)?r:(a.sourceHandle===null&&delete a.sourceHandle,a.targetHandle===null&&delete a.targetHandle,r.concat(a))};function Cg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const[a,u,c,h]=Eg({sourceX:t,sourceY:r,targetX:o,targetY:s});return[`M ${t},${r}L ${o},${s}`,a,u,c,h]}const Lh={[ke.Left]:{x:-1,y:0},[ke.Right]:{x:1,y:0},[ke.Top]:{x:0,y:-1},[ke.Bottom]:{x:0,y:1}},E1=({source:t,sourcePosition:r=ke.Bottom,target:o})=>r===ke.Left||r===ke.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function C1({source:t,sourcePosition:r=ke.Bottom,target:o,targetPosition:s=ke.Top,center:a,offset:u,stepPosition:c}){const h=Lh[r],p=Lh[s],y={x:t.x+h.x*u,y:t.y+h.y*u},x={x:o.x+p.x*u,y:o.y+p.y*u},v=E1({source:y,sourcePosition:r,target:x}),g=v.x!==0?"x":"y",_=v[g];let S=[],N,b;const E={x:0,y:0},I={x:0,y:0},[,,w,j]=Eg({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(h[g]*p[g]===-1){g==="x"?(N=a.x??y.x+(x.x-y.x)*c,b=a.y??(y.y+x.y)/2):(N=a.x??(y.x+x.x)/2,b=a.y??y.y+(x.y-y.y)*c);const Y=[{x:N,y:y.y},{x:N,y:x.y}],q=[{x:y.x,y:b},{x:x.x,y:b}];h[g]===_?S=g==="x"?Y:q:S=g==="x"?q:Y}else{const Y=[{x:y.x,y:x.y}],q=[{x:x.x,y:y.y}];if(g==="x"?S=h.x===_?q:Y:S=h.y===_?Y:q,r===s){const C=Math.abs(t[g]-o[g]);if(C<=u){const V=Math.min(u-1,u-C);h[g]===_?E[g]=(y[g]>t[g]?-1:1)*V:I[g]=(x[g]>o[g]?-1:1)*V}}if(r!==s){const C=g==="x"?"y":"x",V=h[g]===p[C],W=y[C]>x[C],U=y[C]=Q?(N=(re.x+J.x)/2,b=S[0].y):(N=S[0].x,b=(re.y+J.y)/2)}const A={x:y.x+E.x,y:y.y+E.y},$={x:x.x+I.x,y:x.y+I.y};return[[t,...A.x!==S[0].x||A.y!==S[0].y?[A]:[],...S,...$.x!==S[S.length-1].x||$.y!==S[S.length-1].y?[$]:[],o],N,b,w,j]}function M1(t,r,o,s){const a=Math.min(Ah(t,r)/2,Ah(r,o)/2,s),{x:u,y:c}=r;if(t.x===u&&u===o.x||t.y===c&&c===o.y)return`L${u} ${c}`;if(t.y===c){const y=t.xo.id===r):t[0])||null}function gc(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(s=>`${s}=${t[s]}`).join("&")}`:""}function I1(t,{id:r,defaultColor:o,defaultMarkerStart:s,defaultMarkerEnd:a}){const u=new Set;return t.reduce((c,h)=>([h.markerStart||s,h.markerEnd||a].forEach(p=>{if(p&&typeof p=="object"){const y=gc(p,r);u.has(y)||(c.push({id:y,color:p.color||o,...p}),u.add(y))}}),c),[]).sort((c,h)=>c.id.localeCompare(h.id))}const Mg=1e3,R1=10,Rc={nodeOrigin:[0,0],nodeExtent:as,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},T1={...Rc,checkEquality:!0};function Tc(t,r){const o={...t};for(const s in r)r[s]!==void 0&&(o[s]=r[s]);return o}function L1(t,r,o){const s=Tc(Rc,o);for(const a of t.values())if(a.parentId)Ac(a,t,r,s);else{const u=ms(a,s.nodeOrigin),c=go(a.extent)?a.extent:s.nodeExtent,h=po(u,c,Sn(a));a.internals.positionAbsolute=h}}function A1(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],s=[];for(const a of t.handles){const u={id:a.id,width:a.width??1,height:a.height??1,nodeId:t.id,x:a.x,y:a.y,position:a.position,type:a.type};a.type==="source"?o.push(u):a.type==="target"&&s.push(u)}return{source:o,target:s}}function Lc(t){return t==="manual"}function mc(t,r,o,s={}){var x,v;const a=Tc(T1,s),u={i:0},c=new Map(r),h=a!=null&&a.elevateNodesOnSelect&&!Lc(a.zIndexMode)?Mg:0;let p=t.length>0,y=!1;r.clear(),o.clear();for(const g of t){let _=c.get(g.id);if(a.checkEquality&&g===(_==null?void 0:_.internals.userNode))r.set(g.id,_);else{const S=ms(g,a.nodeOrigin),N=go(g.extent)?g.extent:a.nodeExtent,b=po(S,N,Sn(g));_={...a.defaults,...g,measured:{width:(x=g.measured)==null?void 0:x.width,height:(v=g.measured)==null?void 0:v.height},internals:{positionAbsolute:b,handleBounds:A1(g,_),z:Pg(g,h,a.zIndexMode),userNode:g}},r.set(g.id,_)}(_.measured===void 0||_.measured.width===void 0||_.measured.height===void 0)&&!_.hidden&&(p=!1),g.parentId&&Ac(_,r,o,s,u),y||(y=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:y}}function $1(t,r){if(!t.parentId)return;const o=r.get(t.parentId);o?o.set(t.id,t):r.set(t.parentId,new Map([[t.id,t]]))}function Ac(t,r,o,s,a){const{elevateNodesOnSelect:u,nodeOrigin:c,nodeExtent:h,zIndexMode:p}=Tc(Rc,s),y=t.parentId,x=r.get(y);if(!x){console.warn(`Parent node ${y} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}$1(t,o),a&&!x.parentId&&x.internals.rootParentIndex===void 0&&p==="auto"&&(x.internals.rootParentIndex=++a.i,x.internals.z=x.internals.z+a.i*R1),a&&x.internals.rootParentIndex!==void 0&&(a.i=x.internals.rootParentIndex);const v=u&&!Lc(p)?Mg:0,{x:g,y:_,z:S}=z1(t,x,c,h,v,p),{positionAbsolute:N}=t.internals,b=g!==N.x||_!==N.y;(b||S!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:b?{x:g,y:_}:N,z:S}})}function Pg(t,r,o){const s=vn(t.zIndex)?t.zIndex:0;return Lc(o)?s:s+(t.selected?r:0)}function z1(t,r,o,s,a,u){const{x:c,y:h}=r.internals.positionAbsolute,p=Sn(t),y=ms(t,o),x=go(t.extent)?po(y,t.extent,p):y;let v=po({x:c+x.x,y:h+x.y},s,p);t.extent==="parent"&&(v=mg(v,p,r));const g=Pg(t,a,u),_=r.internals.z??0;return{x:v.x,y:v.y,z:_>=g?_+1:g}}function $c(t,r,o,s=[0,0]){var c;const a=[],u=new Map;for(const h of t){const p=r.get(h.parentId);if(!p)continue;const y=((c=u.get(h.parentId))==null?void 0:c.expandedRect)??cs(p),x=yg(y,h.rect);u.set(h.parentId,{expandedRect:x,parent:p})}return u.size>0&&u.forEach(({expandedRect:h,parent:p},y)=>{var w;const x=p.internals.positionAbsolute,v=Sn(p),g=p.origin??s,_=h.x0||S>0||E||I)&&(a.push({id:y,type:"position",position:{x:p.position.x-_+E,y:p.position.y-S+I}}),(w=o.get(y))==null||w.forEach(j=>{t.some(A=>A.id===j.id)||a.push({id:j.id,type:"position",position:{x:j.position.x+_,y:j.position.y+S}})})),(v.width0){const _=$c(g,r,o,a);y.push(..._)}return{changes:y,updatedInternals:p}}async function O1({delta:t,panZoom:r,transform:o,translateExtent:s,width:a,height:u}){if(!r||!t.x&&!t.y)return!1;const c=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[a,u]],s);return!!c&&(c.x!==o[0]||c.y!==o[1]||c.k!==o[2])}function Oh(t,r,o,s,a,u){let c=a;const h=s.get(c)||new Map;s.set(c,h.set(o,r)),c=`${a}-${t}`;const p=s.get(c)||new Map;if(s.set(c,p.set(o,r)),u){c=`${a}-${t}-${u}`;const y=s.get(c)||new Map;s.set(c,y.set(o,r))}}function Ig(t,r,o){t.clear(),r.clear();for(const s of o){const{source:a,target:u,sourceHandle:c=null,targetHandle:h=null}=s,p={edgeId:s.id,source:a,target:u,sourceHandle:c,targetHandle:h},y=`${a}-${c}--${u}-${h}`,x=`${u}-${h}--${a}-${c}`;Oh("source",p,x,t,a,c),Oh("target",p,y,t,u,h),r.set(s.id,s)}}function Rg(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:Rg(o,r):!1}function Fh(t,r,o){var a;let s=t;do{if((a=s==null?void 0:s.matches)!=null&&a.call(s,r))return!0;if(s===o)return!1;s=s==null?void 0:s.parentElement}while(s);return!1}function F1(t,r,o,s){const a=new Map;for(const[u,c]of t)if((c.selected||c.id===s)&&(!c.parentId||!Rg(c,t))&&(c.draggable||r&&typeof c.draggable>"u")){const h=t.get(u);h&&a.set(u,{id:u,position:h.position||{x:0,y:0},distance:{x:o.x-h.internals.positionAbsolute.x,y:o.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return a}function Yu({nodeId:t,dragItems:r,nodeLookup:o,dragging:s=!0}){var c,h,p;const a=[];for(const[y,x]of r){const v=(c=o.get(y))==null?void 0:c.internals.userNode;v&&a.push({...v,position:x.position,dragging:s})}if(!t)return[a[0],a];const u=(h=o.get(t))==null?void 0:h.internals.userNode;return[u?{...u,position:((p=r.get(t))==null?void 0:p.position)||u.position,dragging:s}:a[0],a]}function H1({dragItems:t,snapGrid:r,x:o,y:s}){const a=t.values().next().value;if(!a)return null;const u={x:o-a.distance.x,y:s-a.distance.y},c=vs(u,r);return{x:c.x-u.x,y:c.y-u.y}}function B1({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:s,onDragStop:a}){let u={x:null,y:null},c=0,h=new Map,p=!1,y={x:0,y:0},x=null,v=!1,g=null,_=!1,S=!1,N=null;function b({noDragClassName:I,handleSelector:w,domNode:j,isSelectable:A,nodeId:$,nodeClickDistance:F=0}){g=Ut(j);function Y({x:te,y:Q}){const{nodeLookup:C,nodeExtent:V,snapGrid:W,snapToGrid:U,nodeOrigin:M,onNodeDrag:D,onSelectionDrag:H,onError:R,updateNodePositions:z}=r();u={x:te,y:Q};let ne=!1;const oe=h.size>1,fe=oe&&V?pc(ys(h)):null,he=oe&&U?H1({dragItems:h,snapGrid:W,x:te,y:Q}):null;for(const[pe,Z]of h){if(!C.has(pe))continue;let se={x:te-Z.distance.x,y:Q-Z.distance.y};U&&(se=he?{x:Math.round(se.x+he.x),y:Math.round(se.y+he.y)}:vs(se,W));let me=null;if(oe&&V&&!Z.extent&&fe){const{positionAbsolute:ve}=Z.internals,Pe=ve.x-fe.x+V[0][0],ue=ve.x+Z.measured.width-fe.x2+V[1][0],je=ve.y-fe.y+V[0][1],Le=ve.y+Z.measured.height-fe.y2+V[1][1];me=[[Pe,je],[ue,Le]]}const{position:Ne,positionAbsolute:we}=gg({nodeId:pe,nextPosition:se,nodeLookup:C,nodeExtent:me||V,nodeOrigin:M,onError:R});ne=ne||Z.position.x!==Ne.x||Z.position.y!==Ne.y,Z.position=Ne,Z.internals.positionAbsolute=we}if(S=S||ne,!!ne&&(z(h,!0),N&&(s||D||!$&&H))){const[pe,Z]=Yu({nodeId:$,dragItems:h,nodeLookup:C});s==null||s(N,h,pe,Z),D==null||D(N,pe,Z),$||H==null||H(N,Z)}}async function q(){if(!x)return;const{transform:te,panBy:Q,autoPanSpeed:C,autoPanOnNodeDrag:V}=r();if(!V){p=!1,cancelAnimationFrame(c);return}const[W,U]=Mc(y,x,C);(W!==0||U!==0)&&(u.x=(u.x??0)-W/te[2],u.y=(u.y??0)-U/te[2],await Q({x:W,y:U})&&Y(u)),c=requestAnimationFrame(q)}function re(te){var oe;const{nodeLookup:Q,multiSelectionActive:C,nodesDraggable:V,transform:W,snapGrid:U,snapToGrid:M,selectNodesOnDrag:D,onNodeDragStart:H,onSelectionDragStart:R,unselectNodesAndEdges:z}=r();v=!0,(!D||!A)&&!C&&$&&((oe=Q.get($))!=null&&oe.selected||z()),A&&D&&$&&(t==null||t($));const ne=es(te.sourceEvent,{transform:W,snapGrid:U,snapToGrid:M,containerBounds:x});if(u=ne,h=F1(Q,V,ne,$),h.size>0&&(o||H||!$&&R)){const[fe,he]=Yu({nodeId:$,dragItems:h,nodeLookup:Q});o==null||o(te.sourceEvent,h,fe,he),H==null||H(te.sourceEvent,fe,he),$||R==null||R(te.sourceEvent,he)}}const J=Xp().clickDistance(F).on("start",te=>{const{domNode:Q,nodeDragThreshold:C,transform:V,snapGrid:W,snapToGrid:U}=r();x=(Q==null?void 0:Q.getBoundingClientRect())||null,_=!1,S=!1,N=te.sourceEvent,C===0&&re(te),u=es(te.sourceEvent,{transform:V,snapGrid:W,snapToGrid:U,containerBounds:x}),y=xn(te.sourceEvent,x)}).on("drag",te=>{const{autoPanOnNodeDrag:Q,transform:C,snapGrid:V,snapToGrid:W,nodeDragThreshold:U,nodeLookup:M}=r(),D=es(te.sourceEvent,{transform:C,snapGrid:V,snapToGrid:W,containerBounds:x});if(N=te.sourceEvent,(te.sourceEvent.type==="touchmove"&&te.sourceEvent.touches.length>1||$&&!M.has($))&&(_=!0),!_){if(!p&&Q&&v&&(p=!0,q()),!v){const H=xn(te.sourceEvent,x),R=H.x-y.x,z=H.y-y.y;Math.sqrt(R*R+z*z)>U&&re(te)}(u.x!==D.xSnapped||u.y!==D.ySnapped)&&h&&v&&(y=xn(te.sourceEvent,x),Y(D))}}).on("end",te=>{if(!v||_){_&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,v=!1,cancelAnimationFrame(c),h.size>0){const{nodeLookup:Q,updateNodePositions:C,onNodeDragStop:V,onSelectionDragStop:W}=r();if(S&&(C(h,!1),S=!1),a||V||!$&&W){const[U,M]=Yu({nodeId:$,dragItems:h,nodeLookup:Q,dragging:!1});a==null||a(te.sourceEvent,h,U,M),V==null||V(te.sourceEvent,U,M),$||W==null||W(te.sourceEvent,M)}}}).filter(te=>{const Q=te.target;return!te.button&&(!I||!Fh(Q,`.${I}`,j))&&(!w||Fh(Q,w,j))});g.call(J)}function E(){g==null||g.on(".drag",null)}return{update:b,destroy:E}}function V1(t,r,o){const s=[],a={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const u of r.values())Ga(a,cs(u))>0&&s.push(u);return s}const W1=250;function U1(t,r,o,s){var h,p;let a=[],u=1/0;const c=V1(t,o,r+W1);for(const y of c){const x=[...((h=y.internals.handleBounds)==null?void 0:h.source)??[],...((p=y.internals.handleBounds)==null?void 0:p.target)??[]];for(const v of x){if(s.nodeId===v.nodeId&&s.type===v.type&&s.id===v.id)continue;const{x:g,y:_}=mo(y,v,v.position,!0),S=Math.sqrt(Math.pow(g-t.x,2)+Math.pow(_-t.y,2));S>r||(S1){const y=s.type==="source"?"target":"source";return a.find(x=>x.type===y)??a[0]}return a[0]}function Tg(t,r,o,s,a,u=!1){var y,x,v;const c=s.get(t);if(!c)return null;const h=a==="strict"?(y=c.internals.handleBounds)==null?void 0:y[r]:[...((x=c.internals.handleBounds)==null?void 0:x.source)??[],...((v=c.internals.handleBounds)==null?void 0:v.target)??[]],p=(o?h==null?void 0:h.find(g=>g.id===o):h==null?void 0:h[0])??null;return p&&u?{...p,...mo(c,p,p.position,!0)}:p}function Lg(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function G1(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const Ag=()=>!0;function Y1(t,{connectionMode:r,connectionRadius:o,handleId:s,nodeId:a,edgeUpdaterType:u,isTarget:c,domNode:h,nodeLookup:p,lib:y,autoPanOnConnect:x,flowId:v,panBy:g,cancelConnection:_,onConnectStart:S,onConnect:N,onConnectEnd:b,isValidConnection:E=Ag,onReconnectEnd:I,updateConnection:w,getTransform:j,getFromHandle:A,autoPanSpeed:$,dragThreshold:F=1,handleDomNode:Y}){const q=Sg(t.target);let re=0,J;const{x:te,y:Q}=xn(t),C=Lg(u,Y),V=h==null?void 0:h.getBoundingClientRect();let W=!1;if(!V||!C)return;const U=Tg(a,C,s,p,r);if(!U)return;let M=xn(t,V),D=!1,H=null,R=!1,z=null;function ne(){if(!x||!V)return;const[Ne,we]=Mc(M,V,$);g({x:Ne,y:we}),re=requestAnimationFrame(ne)}const oe={...U,nodeId:a,type:C,position:U.position},fe=p.get(a);let pe={inProgress:!0,isValid:null,from:mo(fe,oe,ke.Left,!0),fromHandle:oe,fromPosition:oe.position,fromNode:fe,to:M,toHandle:null,toPosition:Ch[oe.position],toNode:null,pointer:M};function Z(){W=!0,w(pe),S==null||S(t,{nodeId:a,handleId:s,handleType:C})}F===0&&Z();function se(Ne){if(!W){const{x:Le,y:nt}=xn(Ne),lt=Le-te,ut=nt-Q;if(!(lt*lt+ut*ut>F*F))return;Z()}if(!A()||!oe){me(Ne);return}const we=j();M=xn(Ne,V),J=U1(xs(M,we,!1,[1,1]),o,p,oe),D||(ne(),D=!0);const ve=$g(Ne,{handle:J,connectionMode:r,fromNodeId:a,fromHandleId:s,fromType:c?"target":"source",isValidConnection:E,doc:q,lib:y,flowId:v,nodeLookup:p});z=ve.handleDomNode,H=ve.connection,R=G1(!!J,ve.isValid);const Pe=p.get(a),ue=Pe?mo(Pe,oe,ke.Left,!0):pe.from,je={...pe,from:ue,isValid:R,to:ve.toHandle&&R?ri({x:ve.toHandle.x,y:ve.toHandle.y},we):M,toHandle:ve.toHandle,toPosition:R&&ve.toHandle?ve.toHandle.position:Ch[oe.position],toNode:ve.toHandle?p.get(ve.toHandle.nodeId):null,pointer:M};w(je),pe=je}function me(Ne){if(!("touches"in Ne&&Ne.touches.length>0)){if(W){(J||z)&&H&&R&&(N==null||N(H));const{inProgress:we,...ve}=pe,Pe={...ve,toPosition:pe.toHandle?pe.toPosition:null};b==null||b(Ne,Pe),u&&(I==null||I(Ne,Pe))}_(),cancelAnimationFrame(re),D=!1,R=!1,H=null,z=null,q.removeEventListener("mousemove",se),q.removeEventListener("mouseup",me),q.removeEventListener("touchmove",se),q.removeEventListener("touchend",me)}}q.addEventListener("mousemove",se),q.addEventListener("mouseup",me),q.addEventListener("touchmove",se),q.addEventListener("touchend",me)}function $g(t,{handle:r,connectionMode:o,fromNodeId:s,fromHandleId:a,fromType:u,doc:c,lib:h,flowId:p,isValidConnection:y=Ag,nodeLookup:x}){const v=u==="target",g=r?c.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:_,y:S}=xn(t),N=c.elementFromPoint(_,S),b=N!=null&&N.classList.contains(`${h}-flow__handle`)?N:g,E={handleDomNode:b,isValid:!1,connection:null,toHandle:null};if(b){const I=Lg(void 0,b),w=b.getAttribute("data-nodeid"),j=b.getAttribute("data-handleid"),A=b.classList.contains("connectable"),$=b.classList.contains("connectableend");if(!w||!I)return E;const F={source:v?w:s,sourceHandle:v?j:a,target:v?s:w,targetHandle:v?a:j};E.connection=F;const q=A&&$&&(o===ti.Strict?v&&I==="source"||!v&&I==="target":w!==s||j!==a);E.isValid=q&&y(F),E.toHandle=Tg(w,I,j,x,o,!0)}return E}const yc={onPointerDown:Y1,isValid:$g};function X1({domNode:t,panZoom:r,getTransform:o,getViewScale:s}){const a=Ut(t);function u({translateExtent:h,width:p,height:y,zoomStep:x=1,pannable:v=!0,zoomable:g=!0,inversePan:_=!1}){const S=w=>{if(w.sourceEvent.type!=="wheel"||!r)return;const j=o(),A=w.sourceEvent.ctrlKey&&ds()?10:1,$=-w.sourceEvent.deltaY*(w.sourceEvent.deltaMode===1?.05:w.sourceEvent.deltaMode?1:.002)*x,F=j[2]*Math.pow(2,$*A);r.scaleTo(F)};let N=[0,0];const b=w=>{(w.sourceEvent.type==="mousedown"||w.sourceEvent.type==="touchstart")&&(N=[w.sourceEvent.clientX??w.sourceEvent.touches[0].clientX,w.sourceEvent.clientY??w.sourceEvent.touches[0].clientY])},E=w=>{const j=o();if(w.sourceEvent.type!=="mousemove"&&w.sourceEvent.type!=="touchmove"||!r)return;const A=[w.sourceEvent.clientX??w.sourceEvent.touches[0].clientX,w.sourceEvent.clientY??w.sourceEvent.touches[0].clientY],$=[A[0]-N[0],A[1]-N[1]];N=A;const F=s()*Math.max(j[2],Math.log(j[2]))*(_?-1:1),Y={x:j[0]-$[0]*F,y:j[1]-$[1]*F},q=[[0,0],[p,y]];r.setViewportConstrained({x:Y.x,y:Y.y,zoom:j[2]},q,h)},I=ug().on("start",b).on("zoom",v?E:null).on("zoom.wheel",g?S:null);a.call(I,{})}function c(){a.on("zoom",null)}return{update:u,destroy:c,pointer:mn}}const il=t=>({x:t.x,y:t.y,zoom:t.k}),Xu=({x:t,y:r,zoom:o})=>nl.translate(t,r).scale(o),Lr=(t,r)=>t.target.closest(`.${r}`),zg=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),q1=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,qu=(t,r=0,o=q1,s=()=>{})=>{const a=typeof r=="number"&&r>0;return a||s(),a?t.transition().duration(r).ease(o).on("end",s):t},Dg=t=>{const r=t.ctrlKey&&ds()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function K1({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:s,panOnScrollMode:a,panOnScrollSpeed:u,zoomOnPinch:c,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:y}){return x=>{if(Lr(x,r))return x.ctrlKey&&x.preventDefault(),!1;x.preventDefault(),x.stopImmediatePropagation();const v=o.property("__zoom").k||1;if(x.ctrlKey&&c){const b=mn(x),E=Dg(x),I=v*Math.pow(2,E);s.scaleTo(o,I,b,x);return}const g=x.deltaMode===1?20:1;let _=a===co.Vertical?0:x.deltaX*g,S=a===co.Horizontal?0:x.deltaY*g;!ds()&&x.shiftKey&&a!==co.Vertical&&(_=x.deltaY*g,S=0),s.translateBy(o,-(_/v)*u,-(S/v)*u,{internal:!0});const N=il(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?p==null||p(x,N):(t.isPanScrolling=!0,h==null||h(x,N)),t.panScrollTimeout=setTimeout(()=>{y==null||y(x,N),t.isPanScrolling=!1},150)}}function Q1({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(s,a){const u=s.type==="wheel",c=!r&&u&&!s.ctrlKey,h=Lr(s,t);if(s.ctrlKey&&u&&h&&s.preventDefault(),c||h)return null;s.preventDefault(),o.call(this,s,a)}}function Z1({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return s=>{var u,c,h;if((u=s.sourceEvent)!=null&&u.internal)return;const a=il(s.transform);t.mouseButton=((c=s.sourceEvent)==null?void 0:c.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=a,((h=s.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),o&&(o==null||o(s.sourceEvent,a))}}function J1({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:s,onPanZoom:a}){return u=>{var c,h;t.usedRightMouseButton=!!(o&&zg(r,t.mouseButton??0)),(c=u.sourceEvent)!=null&&c.sync||s([u.transform.x,u.transform.y,u.transform.k]),a&&!((h=u.sourceEvent)!=null&&h.internal)&&(a==null||a(u.sourceEvent,il(u.transform)))}}function e_({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:s,onPanZoomEnd:a,onPaneContextMenu:u}){return c=>{var h;if(!((h=c.sourceEvent)!=null&&h.internal)&&(t.isZoomingOrPanning=!1,u&&zg(r,t.mouseButton??0)&&!t.usedRightMouseButton&&c.sourceEvent&&u(c.sourceEvent),t.usedRightMouseButton=!1,s(!1),a)){const p=il(c.transform);t.prevViewport=p,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{a==null||a(c.sourceEvent,p)},o?150:0)}}}function t_({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:s,panOnDrag:a,panOnScroll:u,zoomOnDoubleClick:c,userSelectionActive:h,noWheelClassName:p,noPanClassName:y,lib:x,connectionInProgress:v}){return g=>{var E;const _=r||o,S=s&&g.ctrlKey,N=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Lr(g,`${x}-flow__node`)||Lr(g,`${x}-flow__edge`)||Lr(g,`${x}-flow__selection`)||Lr(g,`${x}-flow__nodesselection`)))return!0;if(!a&&!_&&!u&&!c&&!s||h||v&&!N||Lr(g,p)&&N||Lr(g,y)&&(!N||u&&N&&!r)||!s&&g.ctrlKey&&N)return!1;if(!s&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!_&&!u&&!S&&N||!a&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(a)&&!a.includes(g.button)&&g.type==="mousedown")return!1;const b=Array.isArray(a)&&a.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||N||t)&&b}}function n_({domNode:t,minZoom:r,maxZoom:o,translateExtent:s,viewport:a,onPanZoom:u,onPanZoomStart:c,onPanZoomEnd:h,onDraggingChange:p}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},x=t.getBoundingClientRect();let v=[[0,0],[x.width,x.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(Q=>{const C=Q[0];C&&(v=[[0,0],[C.contentRect.width,C.contentRect.height]])}):null;g==null||g.observe(t);const _=ug().extent(()=>v).scaleExtent([r,o]).translateExtent(s),S=Ut(t).call(_);j({x:a.x,y:a.y,zoom:ni(a.zoom,r,o)},[[0,0],[x.width,x.height]],s);const N=S.on("wheel.zoom"),b=S.on("dblclick.zoom");_.wheelDelta(Dg);async function E(Q,C){return S?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ji:La).transform(qu(S,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),Q)}):!1}function I({noWheelClassName:Q,noPanClassName:C,onPaneContextMenu:V,userSelectionActive:W,panOnScroll:U,panOnDrag:M,panOnScrollMode:D,panOnScrollSpeed:H,preventScrolling:R,zoomOnPinch:z,zoomOnScroll:ne,zoomOnDoubleClick:oe,panActivationKeyPressed:fe=!1,zoomActivationKeyPressed:he,lib:pe,onTransformChange:Z,connectionInProgress:se,paneClickDistance:me,selectionOnDrag:Ne}){W&&!y.isZoomingOrPanning&&w();const we=U&&!he&&!W;_.clickDistance(Ne?1/0:!vn(me)||me<0?0:me);const ve=we?K1({zoomPanValues:y,noWheelClassName:Q,d3Selection:S,d3Zoom:_,panOnScrollMode:D,panOnScrollSpeed:H,zoomOnPinch:z,onPanZoomStart:c,onPanZoom:u,onPanZoomEnd:h}):Q1({noWheelClassName:Q,preventScrolling:R,d3ZoomHandler:N});S.on("wheel.zoom",ve,{passive:!1});const Pe=Z1({zoomPanValues:y,onDraggingChange:p,onPanZoomStart:c});_.on("start",Pe);const ue=J1({zoomPanValues:y,panOnDrag:M,onPaneContextMenu:!!V,onPanZoom:u,onTransformChange:Z});_.on("zoom",ue);const je=e_({zoomPanValues:y,panOnDrag:M,panOnScroll:U,onPaneContextMenu:V,onPanZoomEnd:h,onDraggingChange:p});_.on("end",je);const Le=t_({panActivationKeyPressed:fe,zoomActivationKeyPressed:he,panOnDrag:M,zoomOnScroll:ne,panOnScroll:U,zoomOnDoubleClick:oe,zoomOnPinch:z,userSelectionActive:W,noPanClassName:C,noWheelClassName:Q,lib:pe,connectionInProgress:se});_.filter(Le),oe?S.on("dblclick.zoom",b):S.on("dblclick.zoom",null)}function w(){_.on("zoom",null)}async function j(Q,C,V){const W=Xu(Q),U=_==null?void 0:_.constrain()(W,C,V);return U&&await E(U),U}async function A(Q,C){const V=Xu(Q);return await E(V,C),V}function $(Q){if(S){const C=Xu(Q),V=S.property("__zoom");(V.k!==Q.zoom||V.x!==Q.x||V.y!==Q.y)&&(_==null||_.transform(S,C,null,{sync:!0}))}}function F(){const Q=S?lg(S.node()):{x:0,y:0,k:1};return{x:Q.x,y:Q.y,zoom:Q.k}}async function Y(Q,C){return S?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ji:La).scaleTo(qu(S,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),Q)}):!1}async function q(Q,C){return S?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ji:La).scaleBy(qu(S,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),Q)}):!1}function re(Q){_==null||_.scaleExtent(Q)}function J(Q){_==null||_.translateExtent(Q)}function te(Q){const C=!vn(Q)||Q<0?0:Q;_==null||_.clickDistance(C)}return{update:I,destroy:w,setViewport:A,setViewportConstrained:j,getViewport:F,scaleTo:Y,scaleBy:q,setScaleExtent:re,setTranslateExtent:J,syncViewport:$,setClickDistance:te}}var oi;(function(t){t.Line="line",t.Handle="handle"})(oi||(oi={}));function r_({width:t,prevWidth:r,height:o,prevHeight:s,affectsX:a,affectsY:u}){const c=t-r,h=o-s,p=[c>0?1:c<0?-1:0,h>0?1:h<0?-1:0];return c&&a&&(p[0]=p[0]*-1),h&&u&&(p[1]=p[1]*-1),p}function Hh(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),s=t.includes("left"),a=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:s,affectsY:a}}function Rr(t,r){return Math.max(0,r-t)}function Tr(t,r){return Math.max(0,t-r)}function Ca(t,r,o){return Math.max(0,r-t,t-o)}function Bh(t,r){return t?!r:r}function o_(t,r,o,s,a,u,c,h){let{affectsX:p,affectsY:y}=r;const{isHorizontal:x,isVertical:v}=r,g=x&&v,{xSnapped:_,ySnapped:S}=o,{minWidth:N,maxWidth:b,minHeight:E,maxHeight:I}=s,{x:w,y:j,width:A,height:$,aspectRatio:F}=t;let Y=Math.floor(x?_-t.pointerX:0),q=Math.floor(v?S-t.pointerY:0);const re=A+(p?-Y:Y),J=$+(y?-q:q),te=-u[0]*A,Q=-u[1]*$;let C=Ca(re,N,b),V=Ca(J,E,I);if(c){let M=0,D=0;p&&Y<0?M=Rr(w+Y+te,c[0][0]):!p&&Y>0&&(M=Tr(w+re+te,c[1][0])),y&&q<0?D=Rr(j+q+Q,c[0][1]):!y&&q>0&&(D=Tr(j+J+Q,c[1][1])),C=Math.max(C,M),V=Math.max(V,D)}if(h){let M=0,D=0;p&&Y>0?M=Tr(w+Y,h[0][0]):!p&&Y<0&&(M=Rr(w+re,h[1][0])),y&&q>0?D=Tr(j+q,h[0][1]):!y&&q<0&&(D=Rr(j+J,h[1][1])),C=Math.max(C,M),V=Math.max(V,D)}if(a){if(x){const M=Ca(re/F,E,I)*F;if(C=Math.max(C,M),c){let D=0;!p&&!y||p&&!y&&g?D=Tr(j+Q+re/F,c[1][1])*F:D=Rr(j+Q+(p?Y:-Y)/F,c[0][1])*F,C=Math.max(C,D)}if(h){let D=0;!p&&!y||p&&!y&&g?D=Rr(j+re/F,h[1][1])*F:D=Tr(j+(p?Y:-Y)/F,h[0][1])*F,C=Math.max(C,D)}}if(v){const M=Ca(J*F,N,b)/F;if(V=Math.max(V,M),c){let D=0;!p&&!y||y&&!p&&g?D=Tr(w+J*F+te,c[1][0])/F:D=Rr(w+(y?q:-q)*F+te,c[0][0])/F,V=Math.max(V,D)}if(h){let D=0;!p&&!y||y&&!p&&g?D=Rr(w+J*F,h[1][0])/F:D=Tr(w+(y?q:-q)*F,h[0][0])/F,V=Math.max(V,D)}}}q=q+(q<0?V:-V),Y=Y+(Y<0?C:-C),a&&(g?re>J*F?q=(Bh(p,y)?-Y:Y)/F:Y=(Bh(p,y)?-q:q)*F:x?(q=Y/F,y=p):(Y=q*F,p=y));const W=p?w+Y:w,U=y?j+q:j;return{width:A+(p?-Y:Y),height:$+(y?-q:q),x:u[0]*Y*(p?-1:1)+W,y:u[1]*q*(y?-1:1)+U}}const Og={width:0,height:0,x:0,y:0},i_={...Og,pointerX:0,pointerY:0,aspectRatio:1};function s_(t,r,o){const s=r.position.x+t.position.x,a=r.position.y+t.position.y,u=t.measured.width??0,c=t.measured.height??0,h=o[0]*u,p=o[1]*c;return[[s-h,a-p],[s+u-h,a+c-p]]}function a_({domNode:t,nodeId:r,getStoreItems:o,onChange:s,onEnd:a}){const u=Ut(t);let c={controlDirection:Hh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:y,boundaries:x,keepAspectRatio:v,resizeDirection:g,onResizeStart:_,onResize:S,onResizeEnd:N,shouldResize:b}){let E={...Og},I={...i_};c={boundaries:x,resizeDirection:g,keepAspectRatio:v,controlDirection:Hh(y)};let w,j=null,A=[],$,F,Y,q=!1;const re=Xp().on("start",J=>{const{nodeLookup:te,transform:Q,snapGrid:C,snapToGrid:V,nodeOrigin:W,paneDomNode:U}=o();if(w=te.get(r),!w)return;j=(U==null?void 0:U.getBoundingClientRect())??null;const{xSnapped:M,ySnapped:D}=es(J.sourceEvent,{transform:Q,snapGrid:C,snapToGrid:V,containerBounds:j});E={width:w.measured.width??0,height:w.measured.height??0,x:w.position.x??0,y:w.position.y??0},I={...E,pointerX:M,pointerY:D,aspectRatio:E.width/E.height},$=void 0,F=go(w.extent)?w.extent:void 0,w.parentId&&(w.extent==="parent"||w.expandParent)&&($=te.get(w.parentId)),$&&w.extent==="parent"&&(F=[[0,0],[$.measured.width,$.measured.height]]),A=[],Y=void 0;for(const[H,R]of te)if(R.parentId===r&&(A.push({id:H,position:{...R.position},extent:R.extent}),R.extent==="parent"||R.expandParent)){const z=s_(R,w,R.origin??W);Y?Y=[[Math.min(z[0][0],Y[0][0]),Math.min(z[0][1],Y[0][1])],[Math.max(z[1][0],Y[1][0]),Math.max(z[1][1],Y[1][1])]]:Y=z}_==null||_(J,{...E})}).on("drag",J=>{const{transform:te,snapGrid:Q,snapToGrid:C,nodeOrigin:V}=o(),W=es(J.sourceEvent,{transform:te,snapGrid:Q,snapToGrid:C,containerBounds:j}),U=[];if(!w)return;const{x:M,y:D,width:H,height:R}=E,z={},ne=w.origin??V,{width:oe,height:fe,x:he,y:pe}=o_(I,c.controlDirection,W,c.boundaries,c.keepAspectRatio,ne,F,Y),Z=oe!==H,se=fe!==R,me=he!==M&&Z,Ne=pe!==D&&se;if(!me&&!Ne&&!Z&&!se)return;if((me||Ne||ne[0]===1||ne[1]===1)&&(z.x=me?he:E.x,z.y=Ne?pe:E.y,E.x=z.x,E.y=z.y,A.length>0)){const ue=he-M,je=pe-D;for(const Le of A)Le.position={x:Le.position.x-ue+ne[0]*(oe-H),y:Le.position.y-je+ne[1]*(fe-R)},U.push(Le)}if((Z||se)&&(z.width=Z&&(!c.resizeDirection||c.resizeDirection==="horizontal")?oe:E.width,z.height=se&&(!c.resizeDirection||c.resizeDirection==="vertical")?fe:E.height,E.width=z.width,E.height=z.height),$&&w.expandParent){const ue=ne[0]*(z.width??0);z.x&&z.x{q&&(N==null||N(J,{...E}),a==null||a({...E}),q=!1)});u.call(re)}function p(){u.on(".drag",null)}return{update:h,destroy:p}}var Ku={exports:{}},Qu={},Zu={exports:{}},Ju={};/** + * @license React + * use-sync-external-store-shim.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Vh;function l_(){if(Vh)return Ju;Vh=1;var t=hs();function r(v,g){return v===g&&(v!==0||1/v===1/g)||v!==v&&g!==g}var o=typeof Object.is=="function"?Object.is:r,s=t.useState,a=t.useEffect,u=t.useLayoutEffect,c=t.useDebugValue;function h(v,g){var _=g(),S=s({inst:{value:_,getSnapshot:g}}),N=S[0].inst,b=S[1];return u(function(){N.value=_,N.getSnapshot=g,p(N)&&b({inst:N})},[v,_,g]),a(function(){return p(N)&&b({inst:N}),v(function(){p(N)&&b({inst:N})})},[v]),c(_),_}function p(v){var g=v.getSnapshot;v=v.value;try{var _=g();return!o(v,_)}catch{return!0}}function y(v,g){return g()}var x=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:h;return Ju.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:x,Ju}var Wh;function u_(){return Wh||(Wh=1,Zu.exports=l_()),Zu.exports}/** + * @license React + * use-sync-external-store-shim/with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Uh;function c_(){if(Uh)return Qu;Uh=1;var t=hs(),r=u_();function o(y,x){return y===x&&(y!==0||1/y===1/x)||y!==y&&x!==x}var s=typeof Object.is=="function"?Object.is:o,a=r.useSyncExternalStore,u=t.useRef,c=t.useEffect,h=t.useMemo,p=t.useDebugValue;return Qu.useSyncExternalStoreWithSelector=function(y,x,v,g,_){var S=u(null);if(S.current===null){var N={hasValue:!1,value:null};S.current=N}else N=S.current;S=h(function(){function E($){if(!I){if(I=!0,w=$,$=g($),_!==void 0&&N.hasValue){var F=N.value;if(_(F,$))return j=F}return j=$}if(F=j,s(w,$))return F;var Y=g($);return _!==void 0&&_(F,Y)?(w=$,F):(w=$,j=Y)}var I=!1,w,j,A=v===void 0?null:v;return[function(){return E(x())},A===null?void 0:function(){return E(A())}]},[x,v,g,_]);var b=a(y,S[0],S[1]);return c(function(){N.hasValue=!0,N.value=b},[b]),p(b),b},Qu}var Gh;function d_(){return Gh||(Gh=1,Ku.exports=c_()),Ku.exports}var f_=d_();const h_=Pp(f_),p_={},Yh=t=>{let r;const o=new Set,s=(x,v)=>{const g=typeof x=="function"?x(r):x;if(!Object.is(g,r)){const _=r;r=v??(typeof g!="object"||g===null)?g:Object.assign({},r,g),o.forEach(S=>S(r,_))}},a=()=>r,p={setState:s,getState:a,getInitialState:()=>y,subscribe:x=>(o.add(x),()=>o.delete(x)),destroy:()=>{(p_?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),o.clear()}},y=r=t(s,a,p);return p},g_=t=>t?Yh(t):Yh,{useDebugValue:m_}=d0,{useSyncExternalStoreWithSelector:y_}=h_,v_=t=>t;function Fg(t,r=v_,o){const s=y_(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return m_(s),s}const Xh=(t,r)=>{const o=g_(t),s=(a,u=r)=>Fg(o,a,u);return Object.assign(s,o),s},x_=(t,r)=>t?Xh(t,r):Xh;function Qe(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[s,a]of t)if(!Object.is(a,r.get(s)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const s of t)if(!r.has(s))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const s of o)if(!Object.prototype.hasOwnProperty.call(r,s)||!Object.is(t[s],r[s]))return!1;return!0}Ip();const sl=L.createContext(null),w_=sl.Provider,Hg=wn.error001("react");function De(t,r){const o=L.useContext(sl);if(o===null)throw new Error(Hg);return Fg(o,t,r)}function Ge(){const t=L.useContext(sl);if(t===null)throw new Error(Hg);return L.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const qh={display:"none"},__={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},Bg="react-flow__node-desc",Vg="react-flow__edge-desc",S_="react-flow__aria-live",k_=t=>t.ariaLiveMessage,N_=t=>t.ariaLabelConfig;function j_({rfId:t}){const r=De(k_);return d.jsx("div",{id:`${S_}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:__,children:r})}function b_({rfId:t,disableKeyboardA11y:r}){const o=De(N_);return d.jsxs(d.Fragment,{children:[d.jsx("div",{id:`${Bg}-${t}`,style:qh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),d.jsx("div",{id:`${Vg}-${t}`,style:qh,children:o["edge.a11yDescription.default"]}),!r&&d.jsx(j_,{rfId:t})]})}const al=L.forwardRef(({position:t="top-left",children:r,className:o,style:s,...a},u)=>{const c=`${t}`.split("-");return d.jsx("div",{className:ot(["react-flow__panel",o,...c]),style:s,ref:u,...a,children:r})});al.displayName="Panel";const Kh="https://reactflow.dev?utm_source=attribution";function E_({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:d.jsx(al,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Kh}`,children:d.jsx("a",{href:Kh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const C_=t=>{const r=[],o=[];for(const[,s]of t.nodeLookup)s.selected&&r.push(s.internals.userNode);for(const[,s]of t.edgeLookup)s.selected&&o.push(s);return{selectedNodes:r,selectedEdges:o}},Ma=t=>t.id;function M_(t,r){return Qe(t.selectedNodes.map(Ma),r.selectedNodes.map(Ma))&&Qe(t.selectedEdges.map(Ma),r.selectedEdges.map(Ma))}function P_({onSelectionChange:t}){const r=Ge(),{selectedNodes:o,selectedEdges:s}=De(C_,M_);return L.useEffect(()=>{const a={nodes:o,edges:s};t==null||t(a),r.getState().onSelectionChangeHandlers.forEach(u=>u(a))},[o,s,t]),null}const I_=t=>!!t.onSelectionChangeHandlers;function R_({onSelectionChange:t}){const r=De(I_);return t||r?d.jsx(P_,{onSelectionChange:t}):null}const Wg=[0,0],T_={x:0,y:0,zoom:1},L_=["nodes","edges","defaultNodes","defaultEdges","onConnect","onConnectStart","onConnectEnd","onClickConnectStart","onClickConnectEnd","nodesDraggable","autoPanOnNodeFocus","nodesConnectable","nodesFocusable","edgesFocusable","edgesReconnectable","elevateNodesOnSelect","elevateEdgesOnSelect","minZoom","maxZoom","nodeExtent","onNodesChange","onEdgesChange","elementsSelectable","connectionMode","snapGrid","snapToGrid","translateExtent","connectOnClick","defaultEdgeOptions","fitView","fitViewOptions","onNodesDelete","onEdgesDelete","onDelete","onNodeDrag","onNodeDragStart","onNodeDragStop","onSelectionDrag","onSelectionDragStart","onSelectionDragStop","onMoveStart","onMove","onMoveEnd","noPanClassName","nodeOrigin","autoPanOnConnect","autoPanOnNodeDrag","onError","connectionRadius","isValidConnection","selectNodesOnDrag","nodeDragThreshold","connectionDragThreshold","onBeforeDelete","debug","autoPanSpeed","ariaLabelConfig","zIndexMode"],Qh=[...L_,"rfId"],A_=t=>({setNodes:t.setNodes,setEdges:t.setEdges,setMinZoom:t.setMinZoom,setMaxZoom:t.setMaxZoom,setTranslateExtent:t.setTranslateExtent,setNodeExtent:t.setNodeExtent,reset:t.reset,setDefaultNodesAndEdges:t.setDefaultNodesAndEdges}),Zh={translateExtent:as,nodeOrigin:Wg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function $_(t){const{setNodes:r,setEdges:o,setMinZoom:s,setMaxZoom:a,setTranslateExtent:u,setNodeExtent:c,reset:h,setDefaultNodesAndEdges:p}=De(A_,Qe),y=Ge();L.useEffect(()=>(p(t.defaultNodes,t.defaultEdges),()=>{x.current=Zh,h()}),[]);const x=L.useRef(Zh);return L.useEffect(()=>{for(const v of Qh){const g=t[v],_=x.current[v];g!==_&&(typeof t[v]>"u"||(v==="nodes"?r(g):v==="edges"?o(g):v==="minZoom"?s(g):v==="maxZoom"?a(g):v==="translateExtent"?u(g):v==="nodeExtent"?c(g):v==="ariaLabelConfig"?y.setState({ariaLabelConfig:w1(g)}):v==="fitView"?y.setState({fitViewQueued:g}):v==="fitViewOptions"?y.setState({fitViewOptions:g}):y.setState({[v]:g})))}x.current=t},Qh.map(v=>t[v])),null}function Jh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function z_(t){var s;const[r,o]=L.useState(t==="system"?null:t);return L.useEffect(()=>{if(t!=="system"){o(t);return}const a=Jh(),u=()=>o(a!=null&&a.matches?"dark":"light");return u(),a==null||a.addEventListener("change",u),()=>{a==null||a.removeEventListener("change",u)}},[t]),r!==null?r:(s=Jh())!=null&&s.matches?"dark":"light"}const ep=typeof document<"u"?document:null;function fs(t=null,r={target:ep,actInsideInputWithModifier:!0}){const[o,s]=L.useState(!1),a=L.useRef(!1),u=L.useRef(new Set([])),[c,h]=L.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(v=>typeof v=="string").map(v=>v.replace(/\+/g,` +`).replace(` + +`,` ++`).split(` +`)),x=y.reduce((v,g)=>v.concat(...g),[]);return[y,x]}return[[],[]]},[t]);return L.useEffect(()=>{const p=(r==null?void 0:r.target)??ep,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const x=_=>{var b,E;if(a.current=_.ctrlKey||_.metaKey||_.shiftKey||_.altKey,(!a.current||a.current&&!y)&&kg(_))return!1;const N=np(_.code,h);if(u.current.add(_[N]),tp(c,u.current,!1)){const I=((E=(b=_.composedPath)==null?void 0:b.call(_))==null?void 0:E[0])||_.target,w=(I==null?void 0:I.nodeName)==="BUTTON"||(I==null?void 0:I.nodeName)==="A";r.preventDefault!==!1&&(a.current||!w)&&_.preventDefault(),s(!0)}},v=_=>{const S=np(_.code,h);tp(c,u.current,!0)?(s(!1),u.current.clear()):u.current.delete(_[S]),_.key==="Meta"&&u.current.clear(),a.current=!1},g=()=>{u.current.clear(),s(!1)};return p==null||p.addEventListener("keydown",x),p==null||p.addEventListener("keyup",v),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",x),p==null||p.removeEventListener("keyup",v),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[t,s]),o}function tp(t,r,o){return t.filter(s=>o||s.length===r.size).some(s=>s.every(a=>r.has(a)))}function np(t,r){return r.includes(t)?"code":"key"}const D_=()=>{const t=Ge();return L.useMemo(()=>({zoomIn:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1/1.2,r):!1},zoomTo:async(r,o)=>{const{panZoom:s}=t.getState();return s?s.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[s,a,u],panZoom:c}=t.getState();return c?(await c.setViewport({x:r.x??s,y:r.y??a,zoom:r.zoom??u},o),!0):!1},getViewport:()=>{const[r,o,s]=t.getState().transform;return{x:r,y:o,zoom:s}},setCenter:async(r,o,s)=>t.getState().setCenter(r,o,s),fitBounds:async(r,o)=>{const{width:s,height:a,minZoom:u,maxZoom:c,panZoom:h}=t.getState(),p=Pc(r,s,a,u,c,(o==null?void 0:o.padding)??.1);return h?(await h.setViewport(p,{duration:o==null?void 0:o.duration,ease:o==null?void 0:o.ease,interpolate:o==null?void 0:o.interpolate}),!0):!1},screenToFlowPosition:(r,o={})=>{const{transform:s,snapGrid:a,snapToGrid:u,domNode:c}=t.getState();if(!c)return r;const{x:h,y:p}=c.getBoundingClientRect(),y={x:r.x-h,y:r.y-p},x=o.snapGrid??a,v=o.snapToGrid??u;return xs(y,s,v,x)},flowToScreenPosition:r=>{const{transform:o,domNode:s}=t.getState();if(!s)return r;const{x:a,y:u}=s.getBoundingClientRect(),c=ri(r,o);return{x:c.x+a,y:c.y+u}}}),[])};function Ug(t,r){const o=[],s=new Map,a=[];for(const u of t)if(u.type==="add"){a.push(u);continue}else if(u.type==="remove"||u.type==="replace")s.set(u.id,[u]);else{const c=s.get(u.id);c?c.push(u):s.set(u.id,[u])}for(const u of r){const c=s.get(u.id);if(!c){o.push(u);continue}if(c[0].type==="remove")continue;if(c[0].type==="replace"){o.push({...c[0].item});continue}const h={...u};for(const p of c)O_(p,h);o.push(h)}return a.length&&a.forEach(u=>{u.index!==void 0?o.splice(u.index,0,{...u.item}):o.push({...u.item})}),o}function O_(t,r){switch(t.type){case"select":{r.selected=t.selected;break}case"position":{typeof t.position<"u"&&(r.position=t.position),typeof t.dragging<"u"&&(r.dragging=t.dragging);break}case"dimensions":{typeof t.dimensions<"u"&&(r.measured={...t.dimensions},t.setAttributes&&((t.setAttributes===!0||t.setAttributes==="width")&&(r.width=t.dimensions.width),(t.setAttributes===!0||t.setAttributes==="height")&&(r.height=t.dimensions.height))),typeof t.resizing=="boolean"&&(r.resizing=t.resizing);break}}}function F_(t,r){return Ug(t,r)}function H_(t,r){return Ug(t,r)}function ao(t,r){return{id:t,type:"select",selected:r}}function Ko(t,r=new Set,o=!1){const s=[];for(const[a,u]of t){const c=r.has(a);!(u.selected===void 0&&!c)&&u.selected!==c&&(o&&(u.selected=c),s.push(ao(u.id,c)))}return s}function rp({items:t=[],lookup:r}){var a;const o=[],s=new Map(t.map(u=>[u.id,u]));for(const[u,c]of t.entries()){const h=r.get(c.id),p=((a=h==null?void 0:h.internals)==null?void 0:a.userNode)??h;p!==void 0&&p!==c&&o.push({id:c.id,item:c,type:"replace"}),p===void 0&&o.push({item:c,type:"add",index:u})}for(const[u]of r)s.get(u)===void 0&&o.push({id:u,type:"remove"});return o}function op(t){return{id:t.id,type:"remove"}}const B_=xg();function V_(t,r,o={}){return b1(t,r,{...o,onError:o.onError??B_})}const ip=t=>d1(t),W_=t=>pg(t);function Gg(t){return L.forwardRef(t)}const Yg=typeof window<"u"?L.useLayoutEffect:L.useEffect;function sp(t){const[r,o]=L.useState(BigInt(0)),[s]=L.useState(()=>U_(()=>o(a=>a+BigInt(1))));return Yg(()=>{const a=s.get();a.length&&(t(a),s.reset())},[r]),s}function U_(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const Xg=L.createContext(null);function G_({children:t}){const r=Ge(),o=L.useCallback(h=>{const{nodes:p=[],setNodes:y,hasDefaultNodes:x,onNodesChange:v,nodeLookup:g,fitViewQueued:_,onNodesChangeMiddlewareMap:S}=r.getState();let N=p;for(const E of h)N=typeof E=="function"?E(N):E;let b=rp({items:N,lookup:g});for(const E of S.values())b=E(b);x&&y(N),b.length>0?v==null||v(b):_&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:I,setNodes:w}=r.getState();E&&w(I)})},[]),s=sp(o),a=L.useCallback(h=>{const{edges:p=[],setEdges:y,hasDefaultEdges:x,onEdgesChange:v,edgeLookup:g}=r.getState();let _=p;for(const S of h)_=typeof S=="function"?S(_):S;x?y(_):v&&v(rp({items:_,lookup:g}))},[]),u=sp(a),c=L.useMemo(()=>({nodeQueue:s,edgeQueue:u}),[]);return d.jsx(Xg.Provider,{value:c,children:t})}function Y_(){const t=L.useContext(Xg);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const X_=t=>!!t.panZoom;function ll(){const t=D_(),r=Ge(),o=Y_(),s=De(X_),a=L.useMemo(()=>{const u=v=>r.getState().nodeLookup.get(v),c=v=>{o.nodeQueue.push(v)},h=v=>{o.edgeQueue.push(v)},p=v=>{var E,I;const{nodeLookup:g,nodeOrigin:_}=r.getState(),S=ip(v)?v:g.get(v.id),N=S.parentId?_g(S.position,S.measured,S.parentId,g,_):S.position,b={...S,position:N,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((I=S.measured)==null?void 0:I.height)??S.height};return cs(b)},y=(v,g,_={replace:!1})=>{c(S=>S.map(N=>{if(N.id===v){const b=typeof g=="function"?g(N):g;return _.replace&&ip(b)?b:{...N,...b}}return N}))},x=(v,g,_={replace:!1})=>{h(S=>S.map(N=>{if(N.id===v){const b=typeof g=="function"?g(N):g;return _.replace&&W_(b)?b:{...N,...b}}return N}))};return{getNodes:()=>r.getState().nodes.map(v=>({...v})),getNode:v=>{var g;return(g=u(v))==null?void 0:g.internals.userNode},getInternalNode:u,getEdges:()=>{const{edges:v=[]}=r.getState();return v.map(g=>({...g}))},getEdge:v=>r.getState().edgeLookup.get(v),setNodes:c,setEdges:h,addNodes:v=>{const g=Array.isArray(v)?v:[v];o.nodeQueue.push(_=>[..._,...g])},addEdges:v=>{const g=Array.isArray(v)?v:[v];o.edgeQueue.push(_=>[..._,...g])},toObject:()=>{const{nodes:v=[],edges:g=[],transform:_}=r.getState(),[S,N,b]=_;return{nodes:v.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:N,zoom:b}}},deleteElements:async({nodes:v=[],edges:g=[]})=>{const{nodes:_,edges:S,onNodesDelete:N,onEdgesDelete:b,triggerNodeChanges:E,triggerEdgeChanges:I,onDelete:w,onBeforeDelete:j}=r.getState(),{nodes:A,edges:$}=await m1({nodesToRemove:v,edgesToRemove:g,nodes:_,edges:S,onBeforeDelete:j}),F=$.length>0,Y=A.length>0;if(F){const q=$.map(op);b==null||b($),I(q)}if(Y){const q=A.map(op);N==null||N(A),E(q)}return(Y||F)&&(w==null||w({nodes:A,edges:$})),{deletedNodes:A,deletedEdges:$}},getIntersectingNodes:(v,g=!0,_)=>{const S=Ph(v),N=S?v:p(v),b=_!==void 0;return N?(_||r.getState().nodes).filter(E=>{const I=r.getState().nodeLookup.get(E.id);if(I&&!S&&(E.id===v.id||!I.internals.positionAbsolute))return!1;const w=cs(b?E:I),j=Ga(w,N);return g&&j>0||j>=w.width*w.height||j>=N.width*N.height}):[]},isNodeIntersecting:(v,g,_=!0)=>{const N=Ph(v)?v:p(v);if(!N)return!1;const b=Ga(N,g);return _&&b>0||b>=g.width*g.height||b>=N.width*N.height},updateNode:y,updateNodeData:(v,g,_={replace:!1})=>{y(v,S=>{const N=typeof g=="function"?g(S):g;return _.replace?{...S,data:N}:{...S,data:{...S.data,...N}}},_)},updateEdge:x,updateEdgeData:(v,g,_={replace:!1})=>{x(v,S=>{const N=typeof g=="function"?g(S):g;return _.replace?{...S,data:N}:{...S,data:{...S.data,...N}}},_)},getNodesBounds:v=>{const{nodeLookup:g,nodeOrigin:_}=r.getState();return f1(v,{nodeLookup:g,nodeOrigin:_})},getHandleConnections:({type:v,id:g,nodeId:_})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${_}-${v}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:v,handleId:g,nodeId:_})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${_}${v?g?`-${v}-${g}`:`-${v}`:""}`))==null?void 0:S.values())??[])},fitView:async v=>{const g=r.getState().fitViewResolver??x1();return r.setState({fitViewQueued:!0,fitViewOptions:v,fitViewResolver:g}),o.nodeQueue.push(_=>[..._]),g.promise}}},[]);return L.useMemo(()=>({...a,...t,viewportInitialized:s}),[s])}const ap=t=>t.selected,q_=typeof window<"u"?window:void 0;function K_({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=Ge(),{deleteElements:s}=ll(),a=fs(t,{actInsideInputWithModifier:!1}),u=fs(r,{target:q_});L.useEffect(()=>{if(a){const{edges:c,nodes:h}=o.getState();s({nodes:h.filter(ap),edges:c.filter(ap)}),o.setState({nodesSelectionActive:!1})}},[a]),L.useEffect(()=>{o.setState({multiSelectionActive:u})},[u])}function Q_(t){const r=Ge();L.useEffect(()=>{const o=()=>{var a,u,c,h;if(!t.current||!(((u=(a=t.current).checkVisibility)==null?void 0:u.call(a))??!0))return!1;const s=Ic(t.current);(s.height===0||s.width===0)&&((h=(c=r.getState()).onError)==null||h.call(c,"004",wn.error004())),r.setState({width:s.width||500,height:s.height||500})};if(t.current){o(),window.addEventListener("resize",o);const s=new ResizeObserver(()=>o());return s.observe(t.current),()=>{window.removeEventListener("resize",o),s&&t.current&&s.unobserve(t.current)}}},[])}const ul={position:"absolute",width:"100%",height:"100%",top:0,left:0},Z_=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function J_({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:s=!1,panActivationKeyPressed:a,panOnScrollSpeed:u=.5,panOnScrollMode:c=co.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:y,translateExtent:x,minZoom:v,maxZoom:g,zoomActivationKeyCode:_,preventScrolling:S=!0,children:N,noWheelClassName:b,noPanClassName:E,onViewportChange:I,isControlledViewport:w,paneClickDistance:j,selectionOnDrag:A}){const $=Ge(),F=L.useRef(null),{userSelectionActive:Y,lib:q,connectionInProgress:re}=De(Z_,Qe),J=fs(_),te=L.useRef();Q_(F);const Q=L.useCallback(C=>{I==null||I({x:C[0],y:C[1],zoom:C[2]}),w||$.setState({transform:C})},[I,w]);return L.useEffect(()=>{if(F.current){te.current=n_({domNode:F.current,minZoom:v,maxZoom:g,translateExtent:x,viewport:y,onDraggingChange:U=>$.setState(M=>M.paneDragging===U?M:{paneDragging:U}),onPanZoomStart:(U,M)=>{const{onViewportChangeStart:D,onMoveStart:H}=$.getState();H==null||H(U,M),D==null||D(M)},onPanZoom:(U,M)=>{const{onViewportChange:D,onMove:H}=$.getState();H==null||H(U,M),D==null||D(M)},onPanZoomEnd:(U,M)=>{const{onViewportChangeEnd:D,onMoveEnd:H}=$.getState();H==null||H(U,M),D==null||D(M)}});const{x:C,y:V,zoom:W}=te.current.getViewport();return $.setState({panZoom:te.current,transform:[C,V,W],domNode:F.current.closest(".react-flow")}),()=>{var U;(U=te.current)==null||U.destroy()}}},[]),L.useEffect(()=>{var C;(C=te.current)==null||C.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:s,panActivationKeyPressed:a,panOnScrollSpeed:u,panOnScrollMode:c,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:J,preventScrolling:S,noPanClassName:E,userSelectionActive:Y,noWheelClassName:b,lib:q,onTransformChange:Q,connectionInProgress:re,selectionOnDrag:A,paneClickDistance:j})},[t,r,o,s,a,u,c,h,p,J,S,E,Y,b,q,Q,re,A,j]),d.jsx("div",{className:"react-flow__renderer",ref:F,style:ul,children:N})}const eS=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function tS(){const{userSelectionActive:t,userSelectionRect:r}=De(eS,Qe);return t&&r?d.jsx("div",{className:"react-flow__selection react-flow__container",style:{width:r.width,height:r.height,transform:`translate(${r.x}px, ${r.y}px)`}}):null}const ec=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},nS=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function rS({isSelecting:t,selectionKeyPressed:r,selectionMode:o=ls.Full,panOnDrag:s,autoPanOnSelection:a,paneClickDistance:u,selectionOnDrag:c,onSelectionStart:h,onSelectionEnd:p,onPaneClick:y,onPaneContextMenu:x,onPaneScroll:v,onPaneMouseEnter:g,onPaneMouseMove:_,onPaneMouseLeave:S,children:N}){const b=L.useRef(0),E=Ge(),{userSelectionActive:I,elementsSelectable:w,dragging:j,panBy:A,autoPanSpeed:$}=De(nS,Qe),F=w&&(t||I),Y=L.useRef(null),q=L.useRef(),re=L.useRef(new Set),J=L.useRef(new Set),te=L.useRef(!1),Q=L.useRef(!1),C=L.useRef({x:0,y:0}),V=L.useRef(!1),W=Z=>{if(Q.current||te.current||E.getState().connection.inProgress){Q.current=!1,te.current=!1;return}y==null||y(Z),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},U=Z=>{if(Array.isArray(s)&&(s!=null&&s.includes(2))){Z.preventDefault();return}x==null||x(Z)},M=v?Z=>v(Z):void 0,D=Z=>{Q.current&&(Z.stopPropagation(),Q.current=!1)},H=Z=>{var Le,nt;if(Z.pointerType==="touch"&&s!==!1&&!r)return;const{domNode:se,transform:me}=E.getState();if(q.current=se==null?void 0:se.getBoundingClientRect(),!q.current)return;const Ne=Z.target===Y.current;if(!Ne&&!!Z.target.closest(".nokey")||!t||!(c&&Ne||r)||Z.button!==0||!Z.isPrimary)return;(nt=(Le=Z.target)==null?void 0:Le.setPointerCapture)==null||nt.call(Le,Z.pointerId),Q.current=!1;const{x:Pe,y:ue}=xn(Z.nativeEvent,q.current),je=xs({x:Pe,y:ue},me);E.setState({userSelectionRect:{width:0,height:0,startX:je.x,startY:je.y,x:Pe,y:ue}}),Ne||(Z.stopPropagation(),Z.preventDefault())};function R(Z,se){const{userSelectionRect:me}=E.getState();if(!me)return;const{transform:Ne,nodeLookup:we,edgeLookup:ve,connectionLookup:Pe,triggerNodeChanges:ue,triggerEdgeChanges:je,defaultEdgeOptions:Le}=E.getState(),nt={x:me.startX,y:me.startY},{x:lt,y:ut}=ri(nt,Ne),Ye={startX:nt.x,startY:nt.y,x:Zmt.id)),J.current=new Set;const gt=(Le==null?void 0:Le.selectable)??!0;for(const mt of re.current){const Ct=Pe.get(mt);if(Ct)for(const{edgeId:ct}of Ct.values()){const et=ve.get(ct);et&&(et.selectable??gt)&&J.current.add(ct)}}if(!Ih(wt,re.current)){const mt=Ko(we,re.current,!0);ue(mt)}if(!Ih(Yt,J.current)){const mt=Ko(ve,J.current);je(mt)}E.setState({userSelectionRect:Ye,userSelectionActive:!0,nodesSelectionActive:!1})}function z(){if(!a||!q.current)return;const[Z,se]=Mc(C.current,q.current,$);A({x:Z,y:se}).then(me=>{if(!Q.current||!me){b.current=requestAnimationFrame(z);return}const{x:Ne,y:we}=C.current;R(Ne,we),b.current=requestAnimationFrame(z)})}const ne=()=>{cancelAnimationFrame(b.current),b.current=0,V.current=!1};L.useEffect(()=>()=>ne(),[]);const oe=Z=>{const{userSelectionRect:se,transform:me,resetSelectedElements:Ne}=E.getState();if(!q.current||!se)return;const{x:we,y:ve}=xn(Z.nativeEvent,q.current);C.current={x:we,y:ve};const Pe=ri({x:se.startX,y:se.startY},me);if(!Q.current){const ue=r?0:u;if(Math.hypot(we-Pe.x,ve-Pe.y)<=ue)return;Ne(),h==null||h(Z)}Q.current=!0,V.current||(z(),V.current=!0),R(we,ve)},fe=Z=>{var se,me;if(!F){Z.target===Y.current&&E.getState().connection.inProgress&&(te.current=!0);return}Z.button===0&&((me=(se=Z.target)==null?void 0:se.releasePointerCapture)==null||me.call(se,Z.pointerId),!I&&Z.target===Y.current&&E.getState().userSelectionRect&&(W==null||W(Z)),E.setState({userSelectionActive:!1,userSelectionRect:null}),Q.current&&(p==null||p(Z),E.setState({nodesSelectionActive:re.current.size>0})),ne())},he=Z=>{var se,me;(me=(se=Z.target)==null?void 0:se.releasePointerCapture)==null||me.call(se,Z.pointerId),ne()},pe=s===!0||Array.isArray(s)&&s.includes(0);return d.jsxs("div",{className:ot(["react-flow__pane",{draggable:pe,dragging:j,selection:t}]),onClick:F?void 0:ec(W,Y),onContextMenu:ec(U,Y),onWheel:ec(M,Y),onPointerEnter:F?void 0:g,onPointerMove:F?oe:_,onPointerUp:fe,onPointerCancel:F?he:void 0,onPointerDownCapture:F?H:void 0,onClickCapture:F?D:void 0,onPointerLeave:S,ref:Y,style:ul,children:[N,d.jsx(tS,{})]})}function vc({id:t,store:r,unselect:o=!1,nodeRef:s}){const{addSelectedNodes:a,unselectNodesAndEdges:u,multiSelectionActive:c,nodeLookup:h,onError:p}=r.getState(),y=h.get(t);if(!y){p==null||p("012",wn.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&c)&&(u({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var x;return(x=s==null?void 0:s.current)==null?void 0:x.blur()})):a([t])}function qg({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:s,nodeId:a,isSelectable:u,nodeClickDistance:c}){const h=Ge(),[p,y]=L.useState(!1),x=L.useRef();return L.useEffect(()=>{if(!r)return x.current=B1({getStoreItems:()=>h.getState(),onNodeMouseDown:v=>{vc({id:v,store:h,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var v;(v=x.current)==null||v.destroy(),x.current=void 0}},[r,h,t]),L.useEffect(()=>{r||!t.current||!x.current||x.current.update({noDragClassName:o,handleSelector:s,domNode:t.current,isSelectable:u,nodeId:a,nodeClickDistance:c})},[o,s,r,u,t,a,c]),p}const oS=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function Kg(){const t=Ge();return L.useCallback(o=>{const{nodeExtent:s,snapToGrid:a,snapGrid:u,nodesDraggable:c,onError:h,updateNodePositions:p,nodeLookup:y,nodeOrigin:x}=t.getState(),v=new Map,g=oS(c),_=a?u[0]:5,S=a?u[1]:5,N=o.direction.x*_*o.factor,b=o.direction.y*S*o.factor;for(const[,E]of y){if(!g(E))continue;let I={x:E.internals.positionAbsolute.x+N,y:E.internals.positionAbsolute.y+b};a&&(I=vs(I,u));const{position:w,positionAbsolute:j}=gg({nodeId:E.id,nextPosition:I,nodeLookup:y,nodeExtent:s,nodeOrigin:x,onError:h});E.position=w,E.internals.positionAbsolute=j,v.set(E.id,E)}p(v)},[])}const zc=L.createContext(null),iS=zc.Provider;zc.Consumer;const Qg=()=>L.useContext(zc),sS=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),Zg=L.createContext(null);function aS({children:t}){const r=De(sS,Qe);return d.jsx(Zg.Provider,{value:r,children:t})}function lS(){const t=L.useContext(Zg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const uS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},cS=(t,r,o)=>s=>{const{connectionClickStartHandle:a,connectionMode:u,connection:c}=s,{fromHandle:h,toHandle:p,isValid:y}=c;if(!h&&!a)return uS;const x=(p==null?void 0:p.nodeId)===t&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===o;return{connectingFrom:(h==null?void 0:h.nodeId)===t&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===o,connectingTo:x,clickConnecting:(a==null?void 0:a.nodeId)===t&&(a==null?void 0:a.id)===r&&(a==null?void 0:a.type)===o,isPossibleEndHandle:u===ti.Strict?(h==null?void 0:h.type)!==o:t!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!a,valid:x&&y}};function dS({type:t="source",position:r=ke.Top,isValidConnection:o,isConnectable:s=!0,isConnectableStart:a=!0,isConnectableEnd:u=!0,id:c,onConnect:h,children:p,className:y,onMouseDown:x,onTouchStart:v,...g},_){var V,W;const S=c||null,N=t==="target",b=Ge(),E=Qg(),{connectOnClick:I,noPanClassName:w,rfId:j}=lS(),{connectingFrom:A,connectingTo:$,clickConnecting:F,isPossibleEndHandle:Y,connectionInProcess:q,clickConnectionInProcess:re,valid:J}=De(cS(E,S,t),Qe);E||(W=(V=b.getState()).onError)==null||W.call(V,"010",wn.error010());const te=U=>{const{defaultEdgeOptions:M,onConnect:D,hasDefaultEdges:H}=b.getState(),R={...M,...U};if(H){const{edges:z,setEdges:ne,onError:oe}=b.getState();ne(V_(R,z,{onError:oe}))}D==null||D(R),h==null||h(R)},Q=U=>{if(!E)return;const M=Ng(U.nativeEvent);if(a&&(M&&U.button===0||!M)){const D=b.getState();yc.onPointerDown(U.nativeEvent,{handleDomNode:U.currentTarget,autoPanOnConnect:D.autoPanOnConnect,connectionMode:D.connectionMode,connectionRadius:D.connectionRadius,domNode:D.domNode,nodeLookup:D.nodeLookup,lib:D.lib,isTarget:N,handleId:S,nodeId:E,flowId:D.rfId,panBy:D.panBy,cancelConnection:D.cancelConnection,onConnectStart:D.onConnectStart,onConnectEnd:(...H)=>{var R,z;return(z=(R=b.getState()).onConnectEnd)==null?void 0:z.call(R,...H)},updateConnection:D.updateConnection,onConnect:te,isValidConnection:o||((...H)=>{var R,z;return((z=(R=b.getState()).isValidConnection)==null?void 0:z.call(R,...H))??!0}),getTransform:()=>b.getState().transform,getFromHandle:()=>b.getState().connection.fromHandle,autoPanSpeed:D.autoPanSpeed,dragThreshold:D.connectionDragThreshold})}M?x==null||x(U):v==null||v(U)},C=U=>{const{onClickConnectStart:M,onClickConnectEnd:D,connectionClickStartHandle:H,connectionMode:R,isValidConnection:z,lib:ne,rfId:oe,nodeLookup:fe,connection:he}=b.getState();if(!E||!H&&!a)return;if(!H){M==null||M(U.nativeEvent,{nodeId:E,handleId:S,handleType:t}),b.setState({connectionClickStartHandle:{nodeId:E,type:t,id:S}});return}const pe=Sg(U.target),Z=o||z,{connection:se,isValid:me}=yc.isValid(U.nativeEvent,{handle:{nodeId:E,id:S,type:t},connectionMode:R,fromNodeId:H.nodeId,fromHandleId:H.id||null,fromType:H.type,isValidConnection:Z,flowId:oe,doc:pe,lib:ne,nodeLookup:fe});me&&se&&te(se);const Ne=structuredClone(he);delete Ne.inProgress,Ne.toPosition=Ne.toHandle?Ne.toHandle.position:null,D==null||D(U,Ne),b.setState({connectionClickStartHandle:null})};return d.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${j}-${E}-${S}-${t}`,className:ot(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",w,y,{source:!N,target:N,connectable:s,connectablestart:a,connectableend:u,clickconnecting:F,connectingfrom:A,connectingto:$,valid:J,connectionindicator:s&&(!q||Y)&&(q||re?u:a)}]),onMouseDown:Q,onTouchStart:Q,onClick:I?C:void 0,ref:_,...g,children:p})}const ii=L.memo(Gg(dS));function fS({data:t,isConnectable:r,sourcePosition:o=ke.Bottom}){return d.jsxs(d.Fragment,{children:[t==null?void 0:t.label,d.jsx(ii,{type:"source",position:o,isConnectable:r})]})}function hS({data:t,isConnectable:r,targetPosition:o=ke.Top,sourcePosition:s=ke.Bottom}){return d.jsxs(d.Fragment,{children:[d.jsx(ii,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,d.jsx(ii,{type:"source",position:s,isConnectable:r})]})}function pS(){return null}function gS({data:t,isConnectable:r,targetPosition:o=ke.Top}){return d.jsxs(d.Fragment,{children:[d.jsx(ii,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const Xa={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},lp={input:fS,default:hS,output:gS,group:pS};function mS(t){var r,o,s,a;return t.internals.handleBounds===void 0?{width:t.width??t.initialWidth??((r=t.style)==null?void 0:r.width),height:t.height??t.initialHeight??((o=t.style)==null?void 0:o.height)}:{width:t.width??((s=t.style)==null?void 0:s.width),height:t.height??((a=t.style)==null?void 0:a.height)}}const yS=t=>{const{width:r,height:o,x:s,y:a}=ys(t.nodeLookup,{filter:u=>!!u.selected});return{width:vn(r)?r:null,height:vn(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${s}px,${a}px)`}};function vS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const s=Ge(),{width:a,height:u,transformString:c,userSelectionActive:h}=De(yS,Qe),p=Kg(),y=L.useRef(null);L.useEffect(()=>{var _;o||(_=y.current)==null||_.focus({preventScroll:!0})},[o]);const x=!h&&a!==null&&u!==null;if(qg({nodeRef:y,disabled:!x}),!x)return null;const v=t?_=>{const S=s.getState().nodes.filter(N=>N.selected);t(_,S)}:void 0,g=_=>{Object.prototype.hasOwnProperty.call(Xa,_.key)&&(_.preventDefault(),p({direction:Xa[_.key],factor:_.shiftKey?4:1}))};return d.jsx("div",{className:ot(["react-flow__nodesselection","react-flow__container",r]),style:{transform:c},children:d.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:v,tabIndex:o?void 0:-1,onKeyDown:o?void 0:g,style:{width:a,height:u}})})}const up=typeof window<"u"?window:void 0,xS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function Jg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:y,selectionOnDrag:x,selectionMode:v,onSelectionStart:g,onSelectionEnd:_,multiSelectionKeyCode:S,panActivationKeyCode:N,zoomActivationKeyCode:b,elementsSelectable:E,zoomOnScroll:I,zoomOnPinch:w,panOnScroll:j,panOnScrollSpeed:A,panOnScrollMode:$,zoomOnDoubleClick:F,panOnDrag:Y,autoPanOnSelection:q,defaultViewport:re,translateExtent:J,minZoom:te,maxZoom:Q,preventScrolling:C,onSelectionContextMenu:V,noWheelClassName:W,noPanClassName:U,disableKeyboardA11y:M,onViewportChange:D,isControlledViewport:H}){const{nodesSelectionActive:R,userSelectionActive:z}=De(xS,Qe),ne=fs(y,{target:up}),oe=fs(N,{target:up}),fe=oe||Y,he=oe||j,pe=x&&fe!==!0,Z=ne||z||pe;return K_({deleteKeyCode:p,multiSelectionKeyCode:S}),d.jsx(J_,{onPaneContextMenu:u,elementsSelectable:E,zoomOnScroll:I,zoomOnPinch:w,panOnScroll:he,panActivationKeyPressed:oe,panOnScrollSpeed:A,panOnScrollMode:$,zoomOnDoubleClick:F,panOnDrag:!ne&&fe,defaultViewport:re,translateExtent:J,minZoom:te,maxZoom:Q,zoomActivationKeyCode:b,preventScrolling:C,noWheelClassName:W,noPanClassName:U,onViewportChange:D,isControlledViewport:H,paneClickDistance:h,selectionOnDrag:pe,children:d.jsxs(rS,{onSelectionStart:g,onSelectionEnd:_,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,panOnDrag:fe,autoPanOnSelection:q,isSelecting:!!Z,selectionMode:v,selectionKeyPressed:ne,paneClickDistance:h,selectionOnDrag:pe,children:[t,R&&d.jsx(vS,{onSelectionContextMenu:V,noPanClassName:U,disableKeyboardA11y:M})]})})}Jg.displayName="FlowRenderer";const wS=L.memo(Jg),_S=t=>r=>t?Cc(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(o=>o.id):Array.from(r.nodeLookup.keys());function SS(t){return De(L.useCallback(_S(t),[t]),Qe)}const kS=t=>t.updateNodeInternals;function NS(){const t=De(kS),[r]=L.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const s=new Map;o.forEach(a=>{const u=a.target.getAttribute("data-id");s.set(u,{id:u,nodeElement:a.target,force:!0})}),t(s)}));return L.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function jS({node:t,nodeType:r,hasDimensions:o,resizeObserver:s}){const a=Ge(),u=L.useRef(null),c=L.useRef(null),h=L.useRef(t.sourcePosition),p=L.useRef(t.targetPosition),y=L.useRef(r),x=o&&!!t.internals.handleBounds;return L.useEffect(()=>{u.current&&!t.hidden&&(!x||c.current!==u.current)&&(c.current&&(s==null||s.unobserve(c.current)),s==null||s.observe(u.current),c.current=u.current)},[x,t.hidden]),L.useEffect(()=>()=>{c.current&&(s==null||s.unobserve(c.current),c.current=null)},[]),L.useEffect(()=>{if(u.current){const v=y.current!==r,g=h.current!==t.sourcePosition,_=p.current!==t.targetPosition;(v||g||_)&&(y.current=r,h.current=t.sourcePosition,p.current=t.targetPosition,a.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:u.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),u}function bS({id:t,onClick:r,onMouseEnter:o,onMouseMove:s,onMouseLeave:a,onContextMenu:u,onDoubleClick:c,nodesDraggable:h,elementsSelectable:p,nodesConnectable:y,nodesFocusable:x,resizeObserver:v,noDragClassName:g,noPanClassName:_,disableKeyboardA11y:S,rfId:N,nodeTypes:b,nodeClickDistance:E,onError:I}){const{node:w,internals:j,isParent:A}=De(Z=>{const se=Z.nodeLookup.get(t),me=Z.parentLookup.has(t);return{node:se,internals:se.internals,isParent:me}},Qe);let $=w.type||"default",F=(b==null?void 0:b[$])||lp[$];F===void 0&&(I==null||I("003",wn.error003($)),$="default",F=(b==null?void 0:b.default)||lp.default);const Y=!!(w.draggable||h&&typeof w.draggable>"u"),q=!!(w.selectable||p&&typeof w.selectable>"u"),re=!!(w.connectable||y&&typeof w.connectable>"u"),J=!!(w.focusable||x&&typeof w.focusable>"u"),te=Ge(),Q=wg(w),C=jS({node:w,nodeType:$,hasDimensions:Q,resizeObserver:v}),V=qg({nodeRef:C,disabled:w.hidden||!Y,noDragClassName:g,handleSelector:w.dragHandle,nodeId:t,isSelectable:q,nodeClickDistance:E}),W=Kg();if(w.hidden)return null;const U=Sn(w),M=mS(w),D=q||Y||r||o||s||a,H=o?Z=>o(Z,{...j.userNode}):void 0,R=s?Z=>s(Z,{...j.userNode}):void 0,z=a?Z=>a(Z,{...j.userNode}):void 0,ne=u?Z=>u(Z,{...j.userNode}):void 0,oe=c?Z=>c(Z,{...j.userNode}):void 0,fe=Z=>{const{selectNodesOnDrag:se,nodeDragThreshold:me}=te.getState();q&&(!se||!Y||me>0)&&vc({id:t,store:te,nodeRef:C}),r&&r(Z,{...j.userNode})},he=Z=>{if(!(kg(Z.nativeEvent)||S)){if(cg.includes(Z.key)&&q){const se=Z.key==="Escape";vc({id:t,store:te,unselect:se,nodeRef:C})}else if(Y&&w.selected&&Object.prototype.hasOwnProperty.call(Xa,Z.key)){Z.preventDefault();const{ariaLabelConfig:se}=te.getState();te.setState({ariaLiveMessage:se["node.a11yDescription.ariaLiveMessage"]({direction:Z.key.replace("Arrow","").toLowerCase(),x:~~j.positionAbsolute.x,y:~~j.positionAbsolute.y})}),W({direction:Xa[Z.key],factor:Z.shiftKey?4:1})}}},pe=()=>{var Pe;if(S||!((Pe=C.current)!=null&&Pe.matches(":focus-visible")))return;const{transform:Z,width:se,height:me,autoPanOnNodeFocus:Ne,setCenter:we}=te.getState();if(!Ne)return;Cc(new Map([[t,w]]),{x:0,y:0,width:se,height:me},Z,!0).length>0||we(w.position.x+U.width/2,w.position.y+U.height/2,{zoom:Z[2]})};return d.jsx("div",{className:ot(["react-flow__node",`react-flow__node-${$}`,{[_]:Y},w.className,{selected:w.selected,selectable:q,parent:A,draggable:Y,dragging:V}]),ref:C,style:{zIndex:j.z,transform:`translate(${j.positionAbsolute.x}px,${j.positionAbsolute.y}px)`,pointerEvents:D?"all":"none",visibility:Q?"visible":"hidden",...w.style,...M},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:H,onMouseMove:R,onMouseLeave:z,onContextMenu:ne,onClick:fe,onDoubleClick:oe,onKeyDown:J?he:void 0,tabIndex:J?0:void 0,onFocus:J?pe:void 0,role:w.ariaRole??(J?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${Bg}-${N}`,"aria-label":w.ariaLabel,...w.domAttributes,children:d.jsx(iS,{value:t,children:d.jsx(F,{id:t,data:w.data,type:$,positionAbsoluteX:j.positionAbsolute.x,positionAbsoluteY:j.positionAbsolute.y,selected:w.selected??!1,selectable:q,draggable:Y,deletable:w.deletable??!0,isConnectable:re,sourcePosition:w.sourcePosition,targetPosition:w.targetPosition,dragging:V,dragHandle:w.dragHandle,zIndex:j.z,parentId:w.parentId,...U})})})}var ES=L.memo(bS);const CS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function em(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,onError:a}=De(CS,Qe),u=SS(t.onlyRenderVisibleElements),c=NS();return d.jsx("div",{className:"react-flow__nodes",style:ul,children:u.map(h=>d.jsx(ES,{id:h,nodeTypes:t.nodeTypes,nodeExtent:t.nodeExtent,onClick:t.onNodeClick,onMouseEnter:t.onNodeMouseEnter,onMouseMove:t.onNodeMouseMove,onMouseLeave:t.onNodeMouseLeave,onContextMenu:t.onNodeContextMenu,onDoubleClick:t.onNodeDoubleClick,noDragClassName:t.noDragClassName,noPanClassName:t.noPanClassName,rfId:t.rfId,disableKeyboardA11y:t.disableKeyboardA11y,resizeObserver:c,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,nodeClickDistance:t.nodeClickDistance,onError:a},h))})}em.displayName="NodeRenderer";const MS=L.memo(em);function PS(t){return De(L.useCallback(o=>{if(!t)return o.edges.map(a=>a.id);const s=[];if(o.width&&o.height)for(const a of o.edges){const u=o.nodeLookup.get(a.source),c=o.nodeLookup.get(a.target);u&&c&&k1({sourceNode:u,targetNode:c,width:o.width,height:o.height,transform:o.transform})&&s.push(a.id)}return s},[t]),Qe)}const IS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return d.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},RS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return d.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},cp={[us.Arrow]:IS,[us.ArrowClosed]:RS};function TS(t){const r=Ge();return L.useMemo(()=>{var a,u;return Object.prototype.hasOwnProperty.call(cp,t)?cp[t]:((u=(a=r.getState()).onError)==null||u.call(a,"009",wn.error009(t)),null)},[t])}const LS=({id:t,type:r,color:o,width:s=12.5,height:a=12.5,markerUnits:u="strokeWidth",strokeWidth:c,orient:h="auto-start-reverse"})=>{const p=TS(r);return p?d.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${s}`,markerHeight:`${a}`,viewBox:"-10 -10 20 20",markerUnits:u,orient:h,refX:"0",refY:"0",children:d.jsx(p,{color:o,strokeWidth:c})}):null},tm=({defaultColor:t,rfId:r})=>{const o=De(u=>u.edges),s=De(u=>u.defaultEdgeOptions),a=L.useMemo(()=>I1(o,{id:r,defaultColor:t,defaultMarkerStart:s==null?void 0:s.markerStart,defaultMarkerEnd:s==null?void 0:s.markerEnd}),[o,s,r,t]);return a.length?d.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:d.jsx("defs",{children:a.map(u=>d.jsx(LS,{id:u.id,type:u.type,color:u.color,width:u.width,height:u.height,markerUnits:u.markerUnits,strokeWidth:u.strokeWidth,orient:u.orient},u.id))})}):null};tm.displayName="MarkerDefinitions";var AS=L.memo(tm);function nm({x:t,y:r,label:o,labelStyle:s,labelShowBg:a=!0,labelBgStyle:u,labelBgPadding:c=[2,4],labelBgBorderRadius:h=2,children:p,className:y,...x}){const[v,g]=L.useState({x:1,y:0,width:0,height:0}),_=ot(["react-flow__edge-textwrapper",y]),S=L.useRef(null);return L.useEffect(()=>{if(S.current){const N=S.current.getBBox();g({x:N.x,y:N.y,width:N.width,height:N.height})}},[o]),o?d.jsxs("g",{transform:`translate(${t-v.width/2} ${r-v.height/2})`,className:_,visibility:v.width?"visible":"hidden",...x,children:[a&&d.jsx("rect",{width:v.width+2*c[0],x:-c[0],y:-c[1],height:v.height+2*c[1],className:"react-flow__edge-textbg",style:u,rx:h,ry:h}),d.jsx("text",{className:"react-flow__edge-text",y:v.height/2,dy:"0.3em",ref:S,style:s,children:o}),p]}):null}nm.displayName="EdgeText";const $S=L.memo(nm);function ws({path:t,labelX:r,labelY:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:y=20,...x}){return d.jsxs(d.Fragment,{children:[d.jsx("path",{...x,d:t,fill:"none",className:ot(["react-flow__edge-path",x.className])}),y?d.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,s&&vn(r)&&vn(o)?d.jsx($S,{x:r,y:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function dp({pos:t,x1:r,y1:o,x2:s,y2:a}){return t===ke.Left||t===ke.Right?[.5*(r+s),o]:[r,.5*(o+a)]}function rm({sourceX:t,sourceY:r,sourcePosition:o=ke.Bottom,targetX:s,targetY:a,targetPosition:u=ke.Top}){const[c,h]=dp({pos:o,x1:t,y1:r,x2:s,y2:a}),[p,y]=dp({pos:u,x1:s,y1:a,x2:t,y2:r}),[x,v,g,_]=jg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:c,sourceControlY:h,targetControlX:p,targetControlY:y});return[`M${t},${r} C${c},${h} ${p},${y} ${s},${a}`,x,v,g,_]}function om(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c,targetPosition:h,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:_,style:S,markerEnd:N,markerStart:b,interactionWidth:E})=>{const[I,w,j]=rm({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:h}),A=t.isInternal?void 0:r;return d.jsx(ws,{id:A,path:I,labelX:w,labelY:j,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:_,style:S,markerEnd:N,markerStart:b,interactionWidth:E})})}const zS=om({isInternal:!1}),im=om({isInternal:!0});zS.displayName="SimpleBezierEdge";im.displayName="SimpleBezierEdgeInternal";function sm(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:g,sourcePosition:_=ke.Bottom,targetPosition:S=ke.Top,markerEnd:N,markerStart:b,pathOptions:E,interactionWidth:I})=>{const[w,j,A]=Ya({sourceX:o,sourceY:s,sourcePosition:_,targetX:a,targetY:u,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),$=t.isInternal?void 0:r;return d.jsx(ws,{id:$,path:w,labelX:j,labelY:A,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:g,markerEnd:N,markerStart:b,interactionWidth:I})})}const am=sm({isInternal:!1}),lm=sm({isInternal:!0});am.displayName="SmoothStepEdge";lm.displayName="SmoothStepEdgeInternal";function um(t){return L.memo(({id:r,...o})=>{var a;const s=t.isInternal?void 0:r;return d.jsx(am,{...o,id:s,pathOptions:L.useMemo(()=>{var u;return{borderRadius:0,offset:(u=o.pathOptions)==null?void 0:u.offset}},[(a=o.pathOptions)==null?void 0:a.offset])})})}const DS=um({isInternal:!1}),cm=um({isInternal:!0});DS.displayName="StepEdge";cm.displayName="StepEdgeInternal";function dm(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:g,markerEnd:_,markerStart:S,interactionWidth:N})=>{const[b,E,I]=Cg({sourceX:o,sourceY:s,targetX:a,targetY:u}),w=t.isInternal?void 0:r;return d.jsx(ws,{id:w,path:b,labelX:E,labelY:I,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:g,markerEnd:_,markerStart:S,interactionWidth:N})})}const OS=dm({isInternal:!1}),fm=dm({isInternal:!0});OS.displayName="StraightEdge";fm.displayName="StraightEdgeInternal";function hm(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c=ke.Bottom,targetPosition:h=ke.Top,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:_,style:S,markerEnd:N,markerStart:b,pathOptions:E,interactionWidth:I})=>{const[w,j,A]=bg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:h,curvature:E==null?void 0:E.curvature}),$=t.isInternal?void 0:r;return d.jsx(ws,{id:$,path:w,labelX:j,labelY:A,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:_,style:S,markerEnd:N,markerStart:b,interactionWidth:I})})}const FS=hm({isInternal:!1}),pm=hm({isInternal:!0});FS.displayName="BezierEdge";pm.displayName="BezierEdgeInternal";const fp={default:pm,straight:fm,step:cm,smoothstep:lm,simplebezier:im},hp={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},HS=(t,r,o)=>o===ke.Left?t-r:o===ke.Right?t+r:t,BS=(t,r,o)=>o===ke.Top?t-r:o===ke.Bottom?t+r:t,pp="react-flow__edgeupdater";function gp({position:t,centerX:r,centerY:o,radius:s=10,onMouseDown:a,onMouseEnter:u,onMouseOut:c,type:h}){return d.jsx("circle",{onMouseDown:a,onMouseEnter:u,onMouseOut:c,className:ot([pp,`${pp}-${h}`]),cx:HS(r,s,t),cy:BS(o,s,t),r:s,stroke:"transparent",fill:"transparent"})}function VS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:s,sourceY:a,targetX:u,targetY:c,sourcePosition:h,targetPosition:p,onReconnect:y,onReconnectStart:x,onReconnectEnd:v,setReconnecting:g,setUpdateHover:_}){const S=Ge(),N=(j,A)=>{if(j.button!==0)return;const{autoPanOnConnect:$,domNode:F,connectionMode:Y,connectionRadius:q,lib:re,onConnectStart:J,cancelConnection:te,nodeLookup:Q,rfId:C,panBy:V,updateConnection:W}=S.getState(),U=A.type==="target",M=(R,z)=>{g(!1),v==null||v(R,o,A.type,z)},D=R=>y==null?void 0:y(o,R),H=(R,z)=>{g(!0),x==null||x(j,o,A.type),J==null||J(R,z)};yc.onPointerDown(j.nativeEvent,{autoPanOnConnect:$,connectionMode:Y,connectionRadius:q,domNode:F,handleId:A.id,nodeId:A.nodeId,nodeLookup:Q,isTarget:U,edgeUpdaterType:A.type,lib:re,flowId:C,cancelConnection:te,panBy:V,isValidConnection:(...R)=>{var z,ne;return((ne=(z=S.getState()).isValidConnection)==null?void 0:ne.call(z,...R))??!0},onConnect:D,onConnectStart:H,onConnectEnd:(...R)=>{var z,ne;return(ne=(z=S.getState()).onConnectEnd)==null?void 0:ne.call(z,...R)},onReconnectEnd:M,updateConnection:W,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:j.currentTarget})},b=j=>N(j,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),E=j=>N(j,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),I=()=>_(!0),w=()=>_(!1);return d.jsxs(d.Fragment,{children:[(t===!0||t==="source")&&d.jsx(gp,{position:h,centerX:s,centerY:a,radius:r,onMouseDown:b,onMouseEnter:I,onMouseOut:w,type:"source"}),(t===!0||t==="target")&&d.jsx(gp,{position:p,centerX:u,centerY:c,radius:r,onMouseDown:E,onMouseEnter:I,onMouseOut:w,type:"target"})]})}function WS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:s,onClick:a,onDoubleClick:u,onContextMenu:c,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,reconnectRadius:x,onReconnect:v,onReconnectStart:g,onReconnectEnd:_,rfId:S,edgeTypes:N,noPanClassName:b,onError:E,disableKeyboardA11y:I}){let w=De(we=>we.edgeLookup.get(t));const j=De(we=>we.defaultEdgeOptions);w=j?{...j,...w}:w;let A=w.type||"default",$=(N==null?void 0:N[A])||fp[A];$===void 0&&(E==null||E("011",wn.error011(A)),A="default",$=(N==null?void 0:N.default)||fp.default);const F=!!(w.focusable||r&&typeof w.focusable>"u"),Y=typeof v<"u"&&(w.reconnectable||o&&typeof w.reconnectable>"u"),q=!!(w.selectable||s&&typeof w.selectable>"u"),re=L.useRef(null),[J,te]=L.useState(!1),[Q,C]=L.useState(!1),V=Ge(),{zIndex:W=w.zIndex,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:R,targetPosition:z}=De(L.useCallback(we=>{const ve=we.nodeLookup.get(w.source),Pe=we.nodeLookup.get(w.target);if(!ve||!Pe)return hp;const ue=P1({id:t,sourceNode:ve,targetNode:Pe,sourceHandle:w.sourceHandle||null,targetHandle:w.targetHandle||null,connectionMode:we.connectionMode,onError:E}),je=S1({selected:w.selected,zIndex:w.zIndex,sourceNode:ve,targetNode:Pe,elevateOnSelect:we.elevateEdgesOnSelect,zIndexMode:we.zIndexMode});return{...ue||hp,zIndex:je}},[w.source,w.target,w.sourceHandle,w.targetHandle,w.selected,w.zIndex,E]),Qe),ne=L.useMemo(()=>w.markerStart?`url('#${gc(w.markerStart,S)}')`:void 0,[w.markerStart,S]),oe=L.useMemo(()=>w.markerEnd?`url('#${gc(w.markerEnd,S)}')`:void 0,[w.markerEnd,S]);if(w.hidden||U===null||M===null||D===null||H===null)return null;const fe=we=>{var je;const{addSelectedEdges:ve,unselectNodesAndEdges:Pe,multiSelectionActive:ue}=V.getState();q&&(V.setState({nodesSelectionActive:!1}),w.selected&&ue?(Pe({nodes:[],edges:[w]}),(je=re.current)==null||je.blur()):ve([t])),a&&a(we,w)},he=u?we=>{u(we,{...w})}:void 0,pe=c?we=>{c(we,{...w})}:void 0,Z=h?we=>{h(we,{...w})}:void 0,se=p?we=>{p(we,{...w})}:void 0,me=y?we=>{y(we,{...w})}:void 0,Ne=we=>{var ve;if(!I&&cg.includes(we.key)&&q){const{unselectNodesAndEdges:Pe,addSelectedEdges:ue}=V.getState();we.key==="Escape"?((ve=re.current)==null||ve.blur(),Pe({edges:[w]})):ue([t])}};return d.jsx("svg",{style:{zIndex:W},children:d.jsxs("g",{className:ot(["react-flow__edge",`react-flow__edge-${A}`,w.className,b,{selected:w.selected,animated:w.animated,inactive:!q&&!a,updating:J,selectable:q}]),onClick:fe,onDoubleClick:he,onContextMenu:pe,onMouseEnter:Z,onMouseMove:se,onMouseLeave:me,onKeyDown:F?Ne:void 0,tabIndex:F?0:void 0,role:w.ariaRole??(F?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":w.ariaLabel===null?void 0:w.ariaLabel||`Edge from ${w.source} to ${w.target}`,"aria-describedby":F?`${Vg}-${S}`:void 0,ref:re,...w.domAttributes,children:[!Q&&d.jsx($,{id:t,source:w.source,target:w.target,type:w.type,selected:w.selected,animated:w.animated,selectable:q,deletable:w.deletable??!0,label:w.label,labelStyle:w.labelStyle,labelShowBg:w.labelShowBg,labelBgStyle:w.labelBgStyle,labelBgPadding:w.labelBgPadding,labelBgBorderRadius:w.labelBgBorderRadius,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:R,targetPosition:z,data:w.data,style:w.style,sourceHandleId:w.sourceHandle,targetHandleId:w.targetHandle,markerStart:ne,markerEnd:oe,pathOptions:"pathOptions"in w?w.pathOptions:void 0,interactionWidth:w.interactionWidth}),Y&&d.jsx(VS,{edge:w,isReconnectable:Y,reconnectRadius:x,onReconnect:v,onReconnectStart:g,onReconnectEnd:_,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:R,targetPosition:z,setUpdateHover:te,setReconnecting:C})]})})}var US=L.memo(WS);const GS=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function gm({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:s,noPanClassName:a,onReconnect:u,onEdgeContextMenu:c,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:y,onEdgeClick:x,reconnectRadius:v,onEdgeDoubleClick:g,onReconnectStart:_,onReconnectEnd:S,disableKeyboardA11y:N}){const{edgesFocusable:b,edgesReconnectable:E,elementsSelectable:I,onError:w}=De(GS,Qe),j=PS(r);return d.jsxs("div",{className:"react-flow__edges",children:[d.jsx(AS,{defaultColor:t,rfId:o}),j.map(A=>d.jsx(US,{id:A,edgesFocusable:b,edgesReconnectable:E,elementsSelectable:I,noPanClassName:a,onReconnect:u,onContextMenu:c,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,onClick:x,reconnectRadius:v,onDoubleClick:g,onReconnectStart:_,onReconnectEnd:S,rfId:o,onError:w,edgeTypes:s,disableKeyboardA11y:N},A))]})}gm.displayName="EdgeRenderer";const YS=L.memo(gm),mp=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function XS({children:t}){const r=Ge(),o=L.useRef(null),[s]=L.useState(()=>r.getState().transform);return Yg(()=>{let a=null;const u=()=>{const c=r.getState().transform;a&&c[0]===a[0]&&c[1]===a[1]&&c[2]===a[2]||(a=c,o.current&&(o.current.style.transform=mp(c)))};return u(),r.subscribe(u)},[r]),d.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:mp(s)},children:t})}function qS(t){const r=ll(),o=L.useRef(!1);L.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const KS=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function QS(t){const r=De(KS),o=Ge();return L.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function ZS(t){return t.connection.inProgress?{...t.connection,to:xs(t.connection.to,t.transform)}:{...t.connection}}function JS(t){return ZS}function ek(t){const r=JS();return De(r,Qe)}const tk=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function nk({containerStyle:t,style:r,type:o,component:s}){const{nodesConnectable:a,width:u,height:c,isValid:h,inProgress:p}=De(tk,Qe);return!(u&&a&&p)?null:d.jsx("svg",{style:t,width:u,height:c,className:"react-flow__connectionline react-flow__container",children:d.jsx("g",{className:ot(["react-flow__connection",hg(h)]),children:d.jsx(mm,{style:r,type:o,CustomComponent:s,isValid:h})})})}const mm=({style:t,type:r=$r.Bezier,CustomComponent:o,isValid:s})=>{const{inProgress:a,from:u,fromNode:c,fromHandle:h,fromPosition:p,to:y,toNode:x,toHandle:v,toPosition:g,pointer:_}=ek();if(!a)return;if(o)return d.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:c,fromHandle:h,fromX:u.x,fromY:u.y,toX:y.x,toY:y.y,fromPosition:p,toPosition:g,connectionStatus:hg(s),toNode:x,toHandle:v,pointer:_});let S="";const N={sourceX:u.x,sourceY:u.y,sourcePosition:p,targetX:y.x,targetY:y.y,targetPosition:g};switch(r){case $r.Bezier:[S]=bg(N);break;case $r.SimpleBezier:[S]=rm(N);break;case $r.Step:[S]=Ya({...N,borderRadius:0});break;case $r.SmoothStep:[S]=Ya(N);break;default:[S]=Cg(N)}return d.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:t})};mm.displayName="ConnectionLine";const rk={};function yp(t=rk){L.useRef(t),Ge(),L.useEffect(()=>{},[t])}function ok(){Ge(),L.useRef(!1),L.useEffect(()=>{},[])}function ym({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:s,onEdgeClick:a,onNodeDoubleClick:u,onEdgeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:x,onSelectionContextMenu:v,onSelectionStart:g,onSelectionEnd:_,connectionLineType:S,connectionLineStyle:N,connectionLineComponent:b,connectionLineContainerStyle:E,selectionKeyCode:I,selectionOnDrag:w,selectionMode:j,multiSelectionKeyCode:A,panActivationKeyCode:$,zoomActivationKeyCode:F,deleteKeyCode:Y,onlyRenderVisibleElements:q,elementsSelectable:re,defaultViewport:J,translateExtent:te,minZoom:Q,maxZoom:C,preventScrolling:V,defaultMarkerColor:W,zoomOnScroll:U,zoomOnPinch:M,panOnScroll:D,panOnScrollSpeed:H,panOnScrollMode:R,zoomOnDoubleClick:z,panOnDrag:ne,autoPanOnSelection:oe,onPaneClick:fe,onPaneMouseEnter:he,onPaneMouseMove:pe,onPaneMouseLeave:Z,onPaneScroll:se,onPaneContextMenu:me,paneClickDistance:Ne,nodeClickDistance:we,onEdgeContextMenu:ve,onEdgeMouseEnter:Pe,onEdgeMouseMove:ue,onEdgeMouseLeave:je,reconnectRadius:Le,onReconnect:nt,onReconnectStart:lt,onReconnectEnd:ut,noDragClassName:Ye,noWheelClassName:wt,noPanClassName:Yt,disableKeyboardA11y:gt,nodeExtent:mt,rfId:Ct,viewport:ct,onViewportChange:et,nodesDraggable:On}){return yp(t),yp(r),ok(),qS(o),QS(ct),d.jsx(wS,{onPaneClick:fe,onPaneMouseEnter:he,onPaneMouseMove:pe,onPaneMouseLeave:Z,onPaneContextMenu:me,onPaneScroll:se,paneClickDistance:Ne,deleteKeyCode:Y,selectionKeyCode:I,selectionOnDrag:w,selectionMode:j,onSelectionStart:g,onSelectionEnd:_,multiSelectionKeyCode:A,panActivationKeyCode:$,zoomActivationKeyCode:F,elementsSelectable:re,zoomOnScroll:U,zoomOnPinch:M,zoomOnDoubleClick:z,panOnScroll:D,panOnScrollSpeed:H,panOnScrollMode:R,panOnDrag:ne,autoPanOnSelection:oe,defaultViewport:J,translateExtent:te,minZoom:Q,maxZoom:C,onSelectionContextMenu:v,preventScrolling:V,noDragClassName:Ye,noWheelClassName:wt,noPanClassName:Yt,disableKeyboardA11y:gt,onViewportChange:et,isControlledViewport:!!ct,children:d.jsxs(XS,{children:[d.jsx(YS,{edgeTypes:r,onEdgeClick:a,onEdgeDoubleClick:c,onReconnect:nt,onReconnectStart:lt,onReconnectEnd:ut,onlyRenderVisibleElements:q,onEdgeContextMenu:ve,onEdgeMouseEnter:Pe,onEdgeMouseMove:ue,onEdgeMouseLeave:je,reconnectRadius:Le,defaultMarkerColor:W,noPanClassName:Yt,disableKeyboardA11y:gt,rfId:Ct}),d.jsx(nk,{style:N,type:S,component:b,containerStyle:E}),d.jsx("div",{className:"react-flow__edgelabel-renderer"}),d.jsx(MS,{nodeTypes:t,onNodeClick:s,onNodeDoubleClick:u,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:x,nodeClickDistance:we,onlyRenderVisibleElements:q,noPanClassName:Yt,noDragClassName:Ye,disableKeyboardA11y:gt,nodeExtent:mt,rfId:Ct,nodesDraggable:On}),d.jsx("div",{className:"react-flow__viewport-portal"})]})})}ym.displayName="GraphView";const ik=L.memo(ym),sk=xg(),vp=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p=.5,maxZoom:y=2,nodeOrigin:x,nodeExtent:v,zIndexMode:g="basic"}={})=>{const _=new Map,S=new Map,N=new Map,b=new Map,E=s??r??[],I=o??t??[],w=x??[0,0],j=v??as;Ig(N,b,E);const{nodesInitialized:A}=mc(I,_,S,{nodeOrigin:w,nodeExtent:j,zIndexMode:g});let $=[0,0,1];if(c&&a&&u){const F=ys(_,{filter:J=>!!((J.width||J.initialWidth)&&(J.height||J.initialHeight))}),{x:Y,y:q,zoom:re}=Pc(F,a,u,p,y,(h==null?void 0:h.padding)??.1);$=[Y,q,re]}return{rfId:"1",width:a??0,height:u??0,transform:$,nodes:I,nodesInitialized:A,nodeLookup:_,parentLookup:S,edges:E,edgeLookup:b,connectionLookup:N,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:s!==void 0,panZoom:null,minZoom:p,maxZoom:y,translateExtent:as,nodeExtent:j,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:ti.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:w,nodeDragThreshold:1,connectionDragThreshold:1,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesReconnectable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,elevateEdgesOnSelect:!0,selectNodesOnDrag:!0,multiSelectionActive:!1,fitViewQueued:c??!1,fitViewOptions:h,fitViewResolver:null,connection:{...fg},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:sk,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:dg,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},ak=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:x,nodeExtent:v,zIndexMode:g})=>x_((_,S)=>{async function N(){const{nodeLookup:b,panZoom:E,fitViewOptions:I,fitViewResolver:w,width:j,height:A,minZoom:$,maxZoom:F}=S();E&&(await g1({nodes:b,width:j,height:A,panZoom:E,minZoom:$,maxZoom:F},I),w==null||w.resolve(!0),_({fitViewResolver:null}))}return{...vp({nodes:t,edges:r,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:x,nodeExtent:v,defaultNodes:o,defaultEdges:s,zIndexMode:g}),setNodes:b=>{const{nodeLookup:E,parentLookup:I,nodeOrigin:w,nodeExtent:j,elevateNodesOnSelect:A,fitViewQueued:$,zIndexMode:F,nodesSelectionActive:Y}=S(),{nodesInitialized:q,hasSelectedNodes:re}=mc(b,E,I,{nodeOrigin:w,nodeExtent:j,elevateNodesOnSelect:A,checkEquality:!0,zIndexMode:F}),J=Y&&re;$&&q?(N(),_({nodes:b,nodesInitialized:q,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:J})):_({nodes:b,nodesInitialized:q,nodesSelectionActive:J})},setEdges:b=>{const{connectionLookup:E,edgeLookup:I}=S();Ig(E,I,b),_({edges:b})},setDefaultNodesAndEdges:(b,E)=>{if(b){const{setNodes:I}=S();I(b),_({hasDefaultNodes:!0})}if(E){const{setEdges:I}=S();I(E),_({hasDefaultEdges:!0})}},updateNodeInternals:b=>{const{triggerNodeChanges:E,nodeLookup:I,parentLookup:w,domNode:j,nodeOrigin:A,nodeExtent:$,debug:F,fitViewQueued:Y,zIndexMode:q}=S(),{changes:re,updatedInternals:J}=D1(b,I,w,j,A,$,q);J&&(L1(I,w,{nodeOrigin:A,nodeExtent:$,zIndexMode:q}),Y?(N(),_({fitViewQueued:!1,fitViewOptions:void 0})):_({}),(re==null?void 0:re.length)>0&&(F&&console.log("React Flow: trigger node changes",re),E==null||E(re)))},updateNodePositions:(b,E=!1)=>{const I=[];let w=[];const{nodeLookup:j,triggerNodeChanges:A,connection:$,updateConnection:F,onNodesChangeMiddlewareMap:Y}=S();for(const[q,re]of b){const J=j.get(q),te=!!(J!=null&&J.expandParent&&(J!=null&&J.parentId)&&(re!=null&&re.position)),Q={id:q,type:"position",position:te?{x:Math.max(0,re.position.x),y:Math.max(0,re.position.y)}:re.position,dragging:E};if(J&&$.inProgress&&$.fromNode.id===J.id){const C=mo(J,$.fromHandle,ke.Left,!0);F({...$,from:C})}te&&J.parentId&&I.push({id:q,parentId:J.parentId,rect:{...re.internals.positionAbsolute,width:re.measured.width??0,height:re.measured.height??0}}),w.push(Q)}if(I.length>0){const{parentLookup:q,nodeOrigin:re}=S(),J=$c(I,j,q,re);w.push(...J)}for(const q of Y.values())w=q(w);A(w)},triggerNodeChanges:b=>{const{onNodesChange:E,setNodes:I,nodes:w,hasDefaultNodes:j,debug:A}=S();if(b!=null&&b.length){if(j){const $=F_(b,w);I($)}A&&console.log("React Flow: trigger node changes",b),E==null||E(b)}},triggerEdgeChanges:b=>{const{onEdgesChange:E,setEdges:I,edges:w,hasDefaultEdges:j,debug:A}=S();if(b!=null&&b.length){if(j){const $=H_(b,w);I($)}A&&console.log("React Flow: trigger edge changes",b),E==null||E(b)}},addSelectedNodes:b=>{const{multiSelectionActive:E,edgeLookup:I,nodeLookup:w,triggerNodeChanges:j,triggerEdgeChanges:A}=S();if(E){const $=b.map(F=>ao(F,!0));j($);return}j(Ko(w,new Set([...b]),!0)),A(Ko(I))},addSelectedEdges:b=>{const{multiSelectionActive:E,edgeLookup:I,nodeLookup:w,triggerNodeChanges:j,triggerEdgeChanges:A}=S();if(E){const $=b.map(F=>ao(F,!0));A($);return}A(Ko(I,new Set([...b]))),j(Ko(w,new Set,!0))},unselectNodesAndEdges:({nodes:b,edges:E}={})=>{const{edges:I,nodes:w,nodeLookup:j,triggerNodeChanges:A,triggerEdgeChanges:$}=S(),F=b||w,Y=E||I,q=[];for(const J of F){if(!J.selected)continue;const te=j.get(J.id);te&&(te.selected=!1),q.push(ao(J.id,!1))}const re=[];for(const J of Y)J.selected&&re.push(ao(J.id,!1));A(q),$(re)},setMinZoom:b=>{const{panZoom:E,maxZoom:I}=S();E==null||E.setScaleExtent([b,I]),_({minZoom:b})},setMaxZoom:b=>{const{panZoom:E,minZoom:I}=S();E==null||E.setScaleExtent([I,b]),_({maxZoom:b})},setTranslateExtent:b=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(b),_({translateExtent:b})},resetSelectedElements:()=>{const{edges:b,nodes:E,triggerNodeChanges:I,triggerEdgeChanges:w,elementsSelectable:j}=S();if(!j)return;const A=E.reduce((F,Y)=>Y.selected?[...F,ao(Y.id,!1)]:F,[]),$=b.reduce((F,Y)=>Y.selected?[...F,ao(Y.id,!1)]:F,[]);I(A),w($)},setNodeExtent:b=>{const{nodes:E,nodeLookup:I,parentLookup:w,nodeOrigin:j,elevateNodesOnSelect:A,nodeExtent:$,zIndexMode:F}=S();b[0][0]===$[0][0]&&b[0][1]===$[0][1]&&b[1][0]===$[1][0]&&b[1][1]===$[1][1]||(mc(E,I,w,{nodeOrigin:j,nodeExtent:b,elevateNodesOnSelect:A,checkEquality:!1,zIndexMode:F}),_({nodeExtent:b}))},panBy:b=>{const{transform:E,width:I,height:w,panZoom:j,translateExtent:A}=S();return O1({delta:b,panZoom:j,transform:E,translateExtent:A,width:I,height:w})},setCenter:async(b,E,I)=>{const{width:w,height:j,maxZoom:A,panZoom:$}=S();if(!$)return!1;const F=typeof(I==null?void 0:I.zoom)<"u"?I.zoom:A;return await $.setViewport({x:w/2-b*F,y:j/2-E*F,zoom:F},{duration:I==null?void 0:I.duration,ease:I==null?void 0:I.ease,interpolate:I==null?void 0:I.interpolate}),!0},cancelConnection:()=>{_({connection:{...fg}})},updateConnection:b=>{_({connection:b})},reset:()=>_({...vp()})}},Object.is);function vm({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:s,initialWidth:a,initialHeight:u,initialMinZoom:c,initialMaxZoom:h,initialFitViewOptions:p,fitView:y,nodeOrigin:x,nodeExtent:v,zIndexMode:g,children:_}){const[S]=L.useState(()=>ak({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:y,minZoom:c,maxZoom:h,fitViewOptions:p,nodeOrigin:x,nodeExtent:v,zIndexMode:g}));return d.jsx(w_,{value:S,children:d.jsx(G_,{children:d.jsx(aS,{children:_})})})}function lk({children:t,nodes:r,edges:o,defaultNodes:s,defaultEdges:a,width:u,height:c,fitView:h,fitViewOptions:p,minZoom:y,maxZoom:x,nodeOrigin:v,nodeExtent:g,zIndexMode:_}){return L.useContext(sl)?d.jsx(d.Fragment,{children:t}):d.jsx(vm,{initialNodes:r,initialEdges:o,defaultNodes:s,defaultEdges:a,initialWidth:u,initialHeight:c,fitView:h,initialFitViewOptions:p,initialMinZoom:y,initialMaxZoom:x,nodeOrigin:v,nodeExtent:g,zIndexMode:_,children:t})}const uk={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function ck({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,className:a,nodeTypes:u,edgeTypes:c,onNodeClick:h,onEdgeClick:p,onInit:y,onMove:x,onMoveStart:v,onMoveEnd:g,onConnect:_,onConnectStart:S,onConnectEnd:N,onClickConnectStart:b,onClickConnectEnd:E,onNodeMouseEnter:I,onNodeMouseMove:w,onNodeMouseLeave:j,onNodeContextMenu:A,onNodeDoubleClick:$,onNodeDragStart:F,onNodeDrag:Y,onNodeDragStop:q,onNodesDelete:re,onEdgesDelete:J,onDelete:te,onSelectionChange:Q,onSelectionDragStart:C,onSelectionDrag:V,onSelectionDragStop:W,onSelectionContextMenu:U,onSelectionStart:M,onSelectionEnd:D,onBeforeDelete:H,connectionMode:R,connectionLineType:z=$r.Bezier,connectionLineStyle:ne,connectionLineComponent:oe,connectionLineContainerStyle:fe,deleteKeyCode:he="Backspace",selectionKeyCode:pe="Shift",selectionOnDrag:Z=!1,selectionMode:se=ls.Full,panActivationKeyCode:me="Space",multiSelectionKeyCode:Ne=ds()?"Meta":"Control",zoomActivationKeyCode:we=ds()?"Meta":"Control",snapToGrid:ve,snapGrid:Pe,onlyRenderVisibleElements:ue=!1,selectNodesOnDrag:je,nodesDraggable:Le,autoPanOnNodeFocus:nt,nodesConnectable:lt,nodesFocusable:ut,nodeOrigin:Ye=Wg,edgesFocusable:wt,edgesReconnectable:Yt,elementsSelectable:gt=!0,defaultViewport:mt=T_,minZoom:Ct=.5,maxZoom:ct=2,translateExtent:et=as,preventScrolling:On=!0,nodeExtent:Mt,defaultMarkerColor:kn="#b1b1b7",zoomOnScroll:ui=!0,zoomOnPinch:Fn=!0,panOnScroll:vo=!1,panOnScrollSpeed:lr=.5,panOnScrollMode:Or=co.Free,zoomOnDoubleClick:Hn=!0,panOnDrag:Fr=!0,onPaneClick:ur,onPaneMouseEnter:cr,onPaneMouseMove:Ft,onPaneMouseLeave:dt,onPaneScroll:Bn,onPaneContextMenu:Vn,paneClickDistance:Nn=1,nodeClickDistance:Wn=0,children:jn,onReconnect:it,onReconnectStart:dr,onReconnectEnd:bn,onEdgeContextMenu:Pt,onEdgeDoubleClick:nn,onEdgeMouseEnter:xo,onEdgeMouseMove:Ze,onEdgeMouseLeave:He,reconnectRadius:En=10,onNodesChange:Un,onEdgesChange:rn,noDragClassName:Hr="nodrag",noWheelClassName:on="nowheel",noPanClassName:It="nopan",fitView:Xt,fitViewOptions:Gn,connectOnClick:wo,attributionPosition:_o,proOptions:Rt,defaultEdgeOptions:Yn,elevateNodesOnSelect:Br=!0,elevateEdgesOnSelect:Xn=!1,disableKeyboardA11y:fr=!1,autoPanOnConnect:Ve,autoPanOnNodeDrag:ci,autoPanOnSelection:Vr=!0,autoPanSpeed:So,connectionRadius:hr,isValidConnection:di,onError:ko,style:Cn,id:_t,nodeDragThreshold:fi,connectionDragThreshold:yt,viewport:hi,onViewportChange:pi,width:Wr,height:Mn,colorMode:qn="light",debug:Pn,onScroll:qt,ariaLabelConfig:Ur,zIndexMode:Gr="basic",...pr},Yr){const sn=_t||"1",Kn=z_(qn),No=L.useCallback(gr=>{gr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),qt==null||qt(gr)},[qt]);return d.jsx("div",{"data-testid":"rf__wrapper",...pr,onScroll:No,style:{...Cn,...uk},ref:Yr,className:ot(["react-flow",a,Kn]),id:_t,role:"application",children:d.jsxs(lk,{nodes:t,edges:r,width:Wr,height:Mn,fitView:Xt,fitViewOptions:Gn,minZoom:Ct,maxZoom:ct,nodeOrigin:Ye,nodeExtent:Mt,zIndexMode:Gr,children:[d.jsx($_,{nodes:t,edges:r,defaultNodes:o,defaultEdges:s,onConnect:_,onConnectStart:S,onConnectEnd:N,onClickConnectStart:b,onClickConnectEnd:E,nodesDraggable:Le,autoPanOnNodeFocus:nt,nodesConnectable:lt,nodesFocusable:ut,edgesFocusable:wt,edgesReconnectable:Yt,elementsSelectable:gt,elevateNodesOnSelect:Br,elevateEdgesOnSelect:Xn,minZoom:Ct,maxZoom:ct,nodeExtent:Mt,onNodesChange:Un,onEdgesChange:rn,snapToGrid:ve,snapGrid:Pe,connectionMode:R,translateExtent:et,connectOnClick:wo,defaultEdgeOptions:Yn,fitView:Xt,fitViewOptions:Gn,onNodesDelete:re,onEdgesDelete:J,onDelete:te,onNodeDragStart:F,onNodeDrag:Y,onNodeDragStop:q,onSelectionDrag:V,onSelectionDragStart:C,onSelectionDragStop:W,onMove:x,onMoveStart:v,onMoveEnd:g,noPanClassName:It,nodeOrigin:Ye,rfId:sn,autoPanOnConnect:Ve,autoPanOnNodeDrag:ci,autoPanSpeed:So,onError:ko,connectionRadius:hr,isValidConnection:di,selectNodesOnDrag:je,nodeDragThreshold:fi,connectionDragThreshold:yt,onBeforeDelete:H,debug:Pn,ariaLabelConfig:Ur,zIndexMode:Gr}),d.jsx(ik,{onInit:y,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:I,onNodeMouseMove:w,onNodeMouseLeave:j,onNodeContextMenu:A,onNodeDoubleClick:$,nodeTypes:u,edgeTypes:c,connectionLineType:z,connectionLineStyle:ne,connectionLineComponent:oe,connectionLineContainerStyle:fe,selectionKeyCode:pe,selectionOnDrag:Z,selectionMode:se,deleteKeyCode:he,multiSelectionKeyCode:Ne,panActivationKeyCode:me,zoomActivationKeyCode:we,onlyRenderVisibleElements:ue,defaultViewport:mt,translateExtent:et,minZoom:Ct,maxZoom:ct,preventScrolling:On,zoomOnScroll:ui,zoomOnPinch:Fn,zoomOnDoubleClick:Hn,panOnScroll:vo,panOnScrollSpeed:lr,panOnScrollMode:Or,panOnDrag:Fr,autoPanOnSelection:Vr,onPaneClick:ur,onPaneMouseEnter:cr,onPaneMouseMove:Ft,onPaneMouseLeave:dt,onPaneScroll:Bn,onPaneContextMenu:Vn,paneClickDistance:Nn,nodeClickDistance:Wn,onSelectionContextMenu:U,onSelectionStart:M,onSelectionEnd:D,onReconnect:it,onReconnectStart:dr,onReconnectEnd:bn,onEdgeContextMenu:Pt,onEdgeDoubleClick:nn,onEdgeMouseEnter:xo,onEdgeMouseMove:Ze,onEdgeMouseLeave:He,reconnectRadius:En,defaultMarkerColor:kn,noDragClassName:Hr,noWheelClassName:on,noPanClassName:It,rfId:sn,disableKeyboardA11y:fr,nodeExtent:Mt,viewport:hi,onViewportChange:pi,nodesDraggable:Le}),d.jsx(R_,{onSelectionChange:Q}),jn,d.jsx(E_,{proOptions:Rt,position:_o}),d.jsx(b_,{rfId:sn,disableKeyboardA11y:fr})]})})}var dk=Gg(ck);function fk({dimensions:t,lineWidth:r,variant:o,className:s}){return d.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:ot(["react-flow__background-pattern",o,s])})}function hk({radius:t,className:r}){return d.jsx("circle",{cx:t,cy:t,r:t,className:ot(["react-flow__background-pattern","dots",r])})}var zr;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})(zr||(zr={}));const pk={[zr.Dots]:1,[zr.Lines]:1,[zr.Cross]:6},gk=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function xm({id:t,variant:r=zr.Dots,gap:o=20,size:s,lineWidth:a=1,offset:u=0,color:c,bgColor:h,style:p,className:y,patternClassName:x}){const v=L.useRef(null),{transform:g,patternId:_}=De(gk,Qe),S=s||pk[r],N=r===zr.Dots,b=r===zr.Cross,E=Array.isArray(o)?o:[o,o],I=[E[0]*g[2]||1,E[1]*g[2]||1],w=S*g[2],j=Array.isArray(u)?u:[u,u],A=b?[w,w]:I,$=[j[0]*g[2]+A[0]/2,j[1]*g[2]+A[1]/2],F=`${_}${t||""}`;return d.jsxs("svg",{className:ot(["react-flow__background",y]),style:{...p,...ul,"--xy-background-color-props":h,"--xy-background-pattern-color-props":c},ref:v,"data-testid":"rf__background",children:[d.jsx("pattern",{id:F,x:g[0]%I[0],y:g[1]%I[1],width:I[0],height:I[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${$[0]},-${$[1]})`,children:N?d.jsx(hk,{radius:w/2,className:x}):d.jsx(fk,{dimensions:A,lineWidth:a,variant:r,className:x})}),d.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${F})`})]})}xm.displayName="Background";const mk=L.memo(xm);function yk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:d.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function vk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:d.jsx("path",{d:"M0 0h32v4.2H0z"})})}function xk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:d.jsx("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"})})}function wk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:d.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"})})}function _k(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:d.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"})})}function Pa({children:t,className:r,...o}){return d.jsx("button",{type:"button",className:ot(["react-flow__controls-button",r]),...o,children:t})}const Sk=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function wm({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:s=!0,fitViewOptions:a,onZoomIn:u,onZoomOut:c,onFitView:h,onInteractiveChange:p,className:y,children:x,position:v="bottom-left",orientation:g="vertical","aria-label":_}){const S=Ge(),{isInteractive:N,minZoomReached:b,maxZoomReached:E,ariaLabelConfig:I}=De(Sk,Qe),{zoomIn:w,zoomOut:j,fitView:A}=ll(),$=()=>{w(),u==null||u()},F=()=>{j(),c==null||c()},Y=()=>{A(a),h==null||h()},q=()=>{S.setState({nodesDraggable:!N,nodesConnectable:!N,elementsSelectable:!N}),p==null||p(!N)},re=g==="horizontal"?"horizontal":"vertical";return d.jsxs(al,{className:ot(["react-flow__controls",re,y]),position:v,style:t,"data-testid":"rf__controls","aria-label":_??I["controls.ariaLabel"],children:[r&&d.jsxs(d.Fragment,{children:[d.jsx(Pa,{onClick:$,className:"react-flow__controls-zoomin",title:I["controls.zoomIn.ariaLabel"],"aria-label":I["controls.zoomIn.ariaLabel"],disabled:E,children:d.jsx(yk,{})}),d.jsx(Pa,{onClick:F,className:"react-flow__controls-zoomout",title:I["controls.zoomOut.ariaLabel"],"aria-label":I["controls.zoomOut.ariaLabel"],disabled:b,children:d.jsx(vk,{})})]}),o&&d.jsx(Pa,{className:"react-flow__controls-fitview",onClick:Y,title:I["controls.fitView.ariaLabel"],"aria-label":I["controls.fitView.ariaLabel"],children:d.jsx(xk,{})}),s&&d.jsx(Pa,{className:"react-flow__controls-interactive",onClick:q,title:I["controls.interactive.ariaLabel"],"aria-label":I["controls.interactive.ariaLabel"],children:N?d.jsx(_k,{}):d.jsx(wk,{})}),x]})}wm.displayName="Controls";const kk=L.memo(wm);function Nk({id:t,x:r,y:o,width:s,height:a,style:u,color:c,strokeColor:h,strokeWidth:p,className:y,borderRadius:x,shapeRendering:v,selected:g,onClick:_}){const{background:S,backgroundColor:N}=u||{},b=c||S||N;return d.jsx("rect",{className:ot(["react-flow__minimap-node",{selected:g},y]),x:r,y:o,rx:x,ry:x,width:s,height:a,style:{fill:b,stroke:h,strokeWidth:p},shapeRendering:v,onClick:_?E=>_(E,t):void 0})}const jk=L.memo(Nk),bk=t=>t.nodes.map(r=>r.id),tc=t=>t instanceof Function?t:()=>t;function Ek({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:s=5,nodeStrokeWidth:a,nodeComponent:u=jk,onClick:c}){const h=De(bk,Qe),p=tc(r),y=tc(t),x=tc(o),v=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return d.jsx(d.Fragment,{children:h.map(g=>d.jsx(Mk,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:y,nodeClassNameFunc:x,nodeBorderRadius:s,nodeStrokeWidth:a,NodeComponent:u,onClick:c,shapeRendering:v},g))})}function Ck({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:s,nodeBorderRadius:a,nodeStrokeWidth:u,shapeRendering:c,NodeComponent:h,onClick:p}){const{node:y,x,y:v,width:g,height:_}=De(S=>{const N=S.nodeLookup.get(t);if(!N)return{node:void 0,x:0,y:0,width:0,height:0};const b=N.internals.userNode,{x:E,y:I}=N.internals.positionAbsolute,{width:w,height:j}=Sn(b);return{node:b,x:E,y:I,width:w,height:j}},Qe);return!y||y.hidden||!wg(y)?null:d.jsx(h,{x,y:v,width:g,height:_,style:y.style,selected:!!y.selected,className:s(y),color:r(y),borderRadius:a,strokeColor:o(y),strokeWidth:u,shapeRendering:c,onClick:p,id:y.id})}const Mk=L.memo(Ck);var Pk=L.memo(Ek);const Ik=200,Rk=150,Tk=t=>!t.hidden,Lk=t=>{const r={x:-t.transform[0]/t.transform[2],y:-t.transform[1]/t.transform[2],width:t.width/t.transform[2],height:t.height/t.transform[2]};return{viewBB:r,boundingRect:t.nodeLookup.size>0?yg(ys(t.nodeLookup,{filter:Tk}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},xp=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,Ak=(t,r)=>xp(t.viewBB,r.viewBB)&&xp(t.boundingRect,r.boundingRect)&&t.rfId===r.rfId&&t.panZoom===r.panZoom&&t.translateExtent===r.translateExtent&&t.flowWidth===r.flowWidth&&t.flowHeight===r.flowHeight&&t.ariaLabelConfig===r.ariaLabelConfig,$k="react-flow__minimap-desc";function _m({style:t,className:r,nodeStrokeColor:o,nodeColor:s,nodeClassName:a="",nodeBorderRadius:u=5,nodeStrokeWidth:c,nodeComponent:h,bgColor:p,maskColor:y,maskStrokeColor:x,maskStrokeWidth:v,position:g="bottom-right",onClick:_,onNodeClick:S,pannable:N=!1,zoomable:b=!1,ariaLabel:E,inversePan:I,zoomStep:w=1,offsetScale:j=5}){const A=Ge(),$=L.useRef(null),{boundingRect:F,viewBB:Y,rfId:q,panZoom:re,translateExtent:J,flowWidth:te,flowHeight:Q,ariaLabelConfig:C}=De(Lk,Ak),V=(t==null?void 0:t.width)??Ik,W=(t==null?void 0:t.height)??Rk,U=F.width/V,M=F.height/W,D=Math.max(U,M),H=D*V,R=D*W,z=j*D,ne=F.x-(H-F.width)/2-z,oe=F.y-(R-F.height)/2-z,fe=H+z*2,he=R+z*2,pe=`${$k}-${q}`,Z=L.useRef(0),se=L.useRef();Z.current=D,L.useEffect(()=>{if($.current&&re)return se.current=X1({domNode:$.current,panZoom:re,getTransform:()=>A.getState().transform,getViewScale:()=>Z.current}),()=>{var ve;(ve=se.current)==null||ve.destroy()}},[re]),L.useEffect(()=>{var ve;(ve=se.current)==null||ve.update({translateExtent:J,width:te,height:Q,inversePan:I,pannable:N,zoomStep:w,zoomable:b})},[N,b,I,w,J,te,Q]);const me=_?ve=>{var je;const[Pe,ue]=((je=se.current)==null?void 0:je.pointer(ve))||[0,0];_(ve,{x:Pe,y:ue})}:void 0,Ne=S?L.useCallback((ve,Pe)=>{const ue=A.getState().nodeLookup.get(Pe).internals.userNode;S(ve,ue)},[]):void 0,we=E??C["minimap.ariaLabel"];return d.jsx(al,{position:g,style:{...t,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof x=="string"?x:void 0,"--xy-minimap-mask-stroke-width-props":typeof v=="number"?v*D:void 0,"--xy-minimap-node-background-color-props":typeof s=="string"?s:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof c=="number"?c:void 0},className:ot(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:d.jsxs("svg",{width:V,height:W,viewBox:`${ne} ${oe} ${fe} ${he}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":pe,ref:$,onClick:me,children:[we&&d.jsx("title",{id:pe,children:we}),d.jsx(Pk,{onClick:Ne,nodeColor:s,nodeStrokeColor:o,nodeBorderRadius:u,nodeClassName:a,nodeStrokeWidth:c,nodeComponent:h}),d.jsx("path",{className:"react-flow__minimap-mask",d:`M${ne-z},${oe-z}h${fe+z*2}v${he+z*2}h${-fe-z*2}z + M${Y.x},${Y.y}h${Y.width}v${Y.height}h${-Y.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}_m.displayName="MiniMap";const zk=L.memo(_m),Dk=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,Ok={[oi.Line]:"right",[oi.Handle]:"bottom-right"};function Fk({nodeId:t,position:r,variant:o=oi.Handle,className:s,style:a=void 0,children:u,color:c,minWidth:h=10,minHeight:p=10,maxWidth:y=Number.MAX_VALUE,maxHeight:x=Number.MAX_VALUE,keepAspectRatio:v=!1,resizeDirection:g,autoScale:_=!0,shouldResize:S,onResizeStart:N,onResize:b,onResizeEnd:E}){const I=Qg(),w=typeof t=="string"?t:I,j=Ge(),A=L.useRef(null),$=o===oi.Handle,F=De(L.useCallback(Dk($&&_),[$,_]),Qe),Y=L.useRef(null),q=r??Ok[o];L.useEffect(()=>{if(!(!A.current||!w))return Y.current||(Y.current=a_({domNode:A.current,nodeId:w,getStoreItems:()=>{const{nodeLookup:J,transform:te,snapGrid:Q,snapToGrid:C,nodeOrigin:V,domNode:W}=j.getState();return{nodeLookup:J,transform:te,snapGrid:Q,snapToGrid:C,nodeOrigin:V,paneDomNode:W}},onChange:(J,te)=>{const{triggerNodeChanges:Q,nodeLookup:C,parentLookup:V,nodeOrigin:W}=j.getState(),U=[],M={x:J.x,y:J.y},D=C.get(w);if(D&&D.expandParent&&D.parentId){const H=D.origin??W,R=J.width??D.measured.width??0,z=J.height??D.measured.height??0,ne={id:D.id,parentId:D.parentId,rect:{width:R,height:z,..._g({x:J.x??D.position.x,y:J.y??D.position.y},{width:R,height:z},D.parentId,C,H)}},oe=$c([ne],C,V,W);U.push(...oe),M.x=J.x?Math.max(H[0]*R,J.x):void 0,M.y=J.y?Math.max(H[1]*z,J.y):void 0}if(M.x!==void 0&&M.y!==void 0){const H={id:w,type:"position",position:{...M}};U.push(H)}if(J.width!==void 0&&J.height!==void 0){const R={id:w,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:J.width,height:J.height}};U.push(R)}for(const H of te){const R={...H,type:"position"};U.push(R)}Q(U)},onEnd:({width:J,height:te})=>{const Q={id:w,type:"dimensions",resizing:!1,dimensions:{width:J,height:te}};j.getState().triggerNodeChanges([Q])}})),Y.current.update({controlPosition:q,boundaries:{minWidth:h,minHeight:p,maxWidth:y,maxHeight:x},keepAspectRatio:v,resizeDirection:g,onResizeStart:N,onResize:b,onResizeEnd:E,shouldResize:S}),()=>{var J;(J=Y.current)==null||J.destroy()}},[q,h,p,y,x,v,N,b,E,S]);const re=q.split("-");return d.jsx("div",{className:ot(["react-flow__resize-control","nodrag",...re,o,s]),ref:A,style:{...a,scale:F,...c&&{[$?"backgroundColor":"borderColor"]:c}},children:u})}L.memo(Fk);const Hk={"arch.context":0,"django.app":0,"django.route":1,"django.websocket_route":1,"fastapi.route":1,"django.url_name":2,"django.view":3,"django.viewset_action":3,"django.permission":3,"django.throttle":3,"django.serializer":4,"django.form":4,"graphql.type":4,"fastapi.model":4,"django.serializer_field":5,"django.service":5,"graphql.field":5,"django.model":6,"django.field":7,"django.relation":7,"django.task":8,"django.receiver":8,"django.signal":8,"django.test":8,"django.migration_op":8,"django.admin":8,"django.management_command":8,"django.consumer":8,"django.cache_key":8,"django.feature_flag":8,"django.side_effect":8,"openapi.path":9,"graphql.operation":9,"react.api_client":10,"django.htmx":10,"react.query_key":11,"react.hook":11,"react.feature":11,"react.route":12,"react.page":12,"react.server_action":12,"django.template":12,"react.component":13,"react.context":13,"react.form_schema":14,"react.test":14};function si(t){return Hk[t]??8}const zn=208,Dr=64,ai=88,Dc=28,Bk=8;function Vk(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function Sm(t,r=[]){const o=new Map;if(!t.length)return o;const s=new Map;for(const w of t){const j=si(w.type),A=s.get(j)??[];A.push(w),s.set(j,A)}const u=[...s.keys()].sort((w,j)=>w-j).map(w=>[...s.get(w)??[]].sort((j,A)=>j.name.localeCompare(A.name)||j.id.localeCompare(A.id))),c=new Set(t.map(w=>w.id)),h=new Map,p=new Map;for(const w of t)h.set(w.id,[]),p.set(w.id,[]);for(const w of r)!c.has(w.src)||!c.has(w.dst)||w.src===w.dst||(p.get(w.src).push(w.dst),h.get(w.dst).push(w.src));const y=new Map;u.forEach((w,j)=>{for(const A of w)y.set(A.id,j)});const x=new Map,v=()=>{for(const w of u)w.forEach((j,A)=>x.set(j.id,A))};v();const g=(w,j)=>{const A=w.map(($,F)=>{const Y=j($.id).map(re=>x.get(re)).filter(re=>re!==void 0),q=Vk(Y);return{n:$,bary:Number.isNaN(q)?F:q,name:$.name,id:$.id}});return A.sort(($,F)=>$.bary-F.bary||$.name.localeCompare(F.name)||$.id.localeCompare(F.id)),A.map($=>$.n)},_=w=>j=>y.get(j)===w;for(let w=0;w(h.get(A)??[]).filter(_(j-1))),v();for(let j=u.length-2;j>=0;j--)u[j]=g(u[j],A=>(p.get(A)??[]).filter(_(j+1))),v()}const S=zn+ai,N=Dr+Dc,b=Math.max(...u.map(w=>w.length),1),E=[];let I=0;for(let w=0;wY.id)),A=new Set((u[w+1]??[]).map(Y=>Y.id));let $=0;if(A.size)for(const Y of r)j.has(Y.src)&&A.has(Y.dst)&&($+=1);const F=Math.min(120,Math.max(0,($-2)*12));I+=S+F}return u.forEach((w,j)=>{const A=(b-w.length)*N/2;w.forEach(($,F)=>{o.set($.id,{x:E[j]??0,y:A+F*N})})}),o}const xc=[{id:"layers",label:"Architecture layers"},{id:"flow",label:"Edge flow"},{id:"radial",label:"Radial"},{id:"grid",label:"Compact grid"}],Wk=new Set(xc.map(t=>t.id)),km="loadpath.graphLayout",Uk=8,Gk=new Set(["django.route","react.route","react.page","react.server_action","django.task","django.migration_op","django.permission","openapi.path","django.consumer","django.websocket_route","django.template","graphql.operation","fastapi.route"]),Nm=90,Yk=new Set(["django.field","django.serializer_field","django.relation","django.test","react.test","graphql.field","django.url_name","django.throttle"]),wp={"arch.context":"#edf2f4","django.app":"#8d99ae","django.route":"#4cc9f0","django.url_name":"#4cc9f0","django.view":"#4895ef","django.viewset_action":"#4361ee","django.permission":"#7b8cde","django.serializer":"#f4a261","django.form":"#e9c46a","django.serializer_field":"#e9c46a","django.service":"#90be6d","django.model":"#2a9d8f","django.field":"#8ac926","django.task":"#e76f51","django.receiver":"#e85d04","django.signal":"#f4a261","django.test":"#6c757d","django.admin":"#adb5bd","django.migration_op":"#9d4edd","django.consumer":"#e76f51","django.websocket_route":"#4cc9f0","django.template":"#c77dff","django.htmx":"#ff6b6b","django.cache_key":"#6c757d","django.feature_flag":"#f4a261","django.side_effect":"#e85d04","graphql.type":"#00bbf9","graphql.operation":"#00bbf9","fastapi.route":"#4cc9f0","fastapi.model":"#f4a261","openapi.path":"#00bbf9","react.api_client":"#ff6b6b","react.query_key":"#adb5bd","react.hook":"#7b2cbf","react.feature":"#9d4edd","react.route":"#c77dff","react.page":"#c77dff","react.server_action":"#e76f51","react.component":"#9d4edd","react.form_schema":"#ffd166","react.test":"#6c757d"},Xk=Math.PI*(3-Math.sqrt(5)),jm=220,qk=26,Kk={0:"context",1:"routes",2:"url names",3:"views",4:"serializers",5:"services",6:"models",7:"fields",8:"jobs / signals",9:"openapi",10:"api client",11:"hooks",12:"pages",13:"components",14:"forms / tests"};function bm(t){return t.startsWith("react.")?"react":t.startsWith("openapi.")||t.startsWith("graphql.")||t.startsWith("fastapi.")?"stitch":t.startsWith("arch.")?"arch":"django"}function aj(t){return wp[t]?wp[t]:t.startsWith("react.")?"#9d4edd":t.startsWith("openapi.")?"#00bbf9":"#4a5568"}function Qk(t){return t>=Nm?"3d":"2d"}function Zk(t){return t>=Nm?"overview":"full"}function Jk(t,r,o=1){const s=new Set([t]);let a=new Set([t]);for(let u=0;uo.families.has(bm(h.type)));o.detail==="overview"&&(s=s.filter(h=>!Yk.has(h.type)));const a=new Set(s.map(h=>h.id)),u=r.filter(h=>a.has(h.src)&&a.has(h.dst)),c=o.focusId?Jk(o.focusId,u,1):new Set;if(o.neighborhoodOnly&&o.focusId&&c.size){s=s.filter(p=>c.has(p.id));const h=new Set(s.map(p=>p.id));return{nodes:s,edges:u.filter(p=>h.has(p.src)&&h.has(p.dst)),neighborIds:c}}return{nodes:s,edges:u,neighborIds:c}}function tN(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>`${s.name} ${s.qualified_name} ${s.type} ${s.file_path||""} ${s.context||""}`.toLowerCase().includes(o)).slice(0,24):[]}function nN(t,r,o,s){const a=new Set(t.map(N=>N.id));if(!a.has(o))return{nodeIds:new Set,edgeIds:new Set};const u=new Map,c=new Map;for(const N of r){if(!a.has(N.src)||!a.has(N.dst))continue;const b=u.get(N.src)??[];b.push({dst:N.dst,id:N.id}),u.set(N.src,b);const E=c.get(N.dst)??[];E.push({src:N.src,id:N.id}),c.set(N.dst,E)}const h=new Set(t.filter(N=>Gk.has(N.type)).map(N=>N.id)),p=h.size?h:a,y=new Set,x=[o];for(;x.length;){const N=x.pop();if(!y.has(N)){y.add(N);for(const b of u.get(N)??[])y.has(b.dst)||x.push(b.dst)}}const v=new Set([o]),g=[...p].filter(N=>y.has(N)),_=new Set(g);for(;g.length;){const N=g.pop();v.add(N);for(const b of c.get(N)??[])y.has(b.src)&&!_.has(b.src)&&(_.add(b.src),g.push(b.src))}const S=new Set;for(const N of r)v.has(N.src)&&v.has(N.dst)&&S.add(N.id);return{nodeIds:v,edgeIds:S}}function lj(t){const r=new Map;for(const s of t){const a=si(s.type),u=r.get(a)??[];u.push(s),r.set(a,u)}const o=new Map;for(const[s,a]of r){a.sort((c,h)=>c.name.localeCompare(h.name));const u=s*jm;a.forEach((c,h)=>{if(a.length===1){o.set(c.id,{x:u,y:0,z:0});return}const p=qk*Math.sqrt(h+1),y=h*Xk;o.set(c.id,{x:u,y:p*Math.cos(y),z:p*Math.sin(y)})})}return o}function uj(t){const r=new Map;for(const o of t){const s=si(o.type);r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>o[0]-s[0]).map(([o,s])=>({layer:o,x:o*jm,count:s}))}function rN(){try{if(typeof localStorage>"u")return"layers";const t=localStorage.getItem(km);return t&&Wk.has(t)?t:"layers"}catch{return"layers"}}function oN(t){try{if(typeof localStorage>"u")return;localStorage.setItem(km,t)}catch{}}function iN(t){return t==="layers"||t==="flow"}function sN(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function ts(t,r){return t.name.localeCompare(r.name)||t.id.localeCompare(r.id)}function aN(t,r){const o=new Map;if(!t.length)return o;const s=new Set(t.flat().map(S=>S.id)),a=new Map,u=new Map;for(const S of t.flat())a.set(S.id,[]),u.set(S.id,[]);for(const S of r)!s.has(S.src)||!s.has(S.dst)||S.src===S.dst||(u.get(S.src).push(S.dst),a.get(S.dst).push(S.src));const c=new Map;t.forEach((S,N)=>{for(const b of S)c.set(b.id,N)});const h=new Map,p=()=>{for(const S of t)S.forEach((N,b)=>h.set(N.id,b))};p();const y=(S,N)=>{const b=S.map((E,I)=>{const w=N(E.id).map(A=>h.get(A)).filter(A=>A!==void 0),j=sN(w);return{n:E,bary:Number.isNaN(j)?I:j,name:E.name,id:E.id}});return b.sort((E,I)=>E.bary-I.bary||E.name.localeCompare(I.name)||E.id.localeCompare(I.id)),b.map(E=>E.n)},x=S=>N=>c.get(N)===S;for(let S=0;S(a.get(b)??[]).filter(x(N-1))),p();for(let N=t.length-2;N>=0;N--)t[N]=y(t[N],b=>(u.get(b)??[]).filter(x(N+1))),p()}const v=zn+ai,g=Dr+Dc,_=Math.max(...t.map(S=>S.length),1);return t.forEach((S,N)=>{const b=(_-S.length)*g/2;S.forEach((E,I)=>{o.set(E.id,{x:N*v,y:b+I*g})})}),o}function lN(t,r){const o=new Set(t.map(h=>h.id)),s=Math.max(t.length-1,0),a=new Map;for(const h of t)a.set(h.id,0);for(let h=0;h(a.get(y.dst)||0)&&(a.set(y.dst,x),p=!0)}if(!p)break}const u=new Map;for(const h of t){const p=a.get(h.id)||0,y=u.get(p)??[];y.push(h),u.set(p,y)}const c=[...u.keys()].sort((h,p)=>h-p).map(h=>(u.get(h)??[]).sort(ts));return aN(c,r)}function uN(t,r){const o=new Map;if(!t.length)return o;const s=new Set(t.map(g=>g.id)),a=new Map,u=new Map;for(const g of t)a.set(g.id,[]),u.set(g.id,0);for(const g of r)!s.has(g.src)||!s.has(g.dst)||g.src===g.dst||(a.get(g.src).push(g.dst),a.get(g.dst).push(g.src),u.set(g.src,(u.get(g.src)||0)+1),u.set(g.dst,(u.get(g.dst)||0)+1));const c=[...t].sort((g,_)=>(u.get(_.id)||0)-(u.get(g.id)||0)||ts(g,_))[0]??t[0],h=new Map,p=[[c]];h.set(c.id,0);const y=[c];for(;y.length;){const g=y.shift(),_=h.get(g.id)||0,S=(a.get(g.id)??[]).map(N=>t.find(b=>b.id===N)).filter(N=>!!N).sort(ts);for(const N of S){if(h.has(N.id))continue;h.set(N.id,_+1);const b=p[_+1]??[];b.push(N),p[_+1]=b,y.push(N)}}const x=t.filter(g=>!h.has(g.id)).sort(ts);x.length&&p.push(x);const v=zn+32;return p.forEach((g,_)=>{if(_===0&&g.length===1){o.set(g[0].id,{x:0,y:0});return}const S=Math.max(_*(zn+ai),g.length<=1?zn:g.length*v/(2*Math.PI));g.forEach((N,b)=>{const E=-Math.PI/2+2*Math.PI*b/g.length;o.set(N.id,{x:Math.cos(E)*S,y:Math.sin(E)*S})})}),o}function cN(t){const r=new Map,o=[...t].sort((c,h)=>si(c.type)-si(h.type)||ts(c,h)),s=Math.max(1,Math.ceil(Math.sqrt(o.length))),a=zn+ai,u=Dr+Dc;return o.forEach((c,h)=>{r.set(c.id,{x:h%s*a,y:Math.floor(h/s)*u})}),r}function dN(t,r=[],o="layers"){return o==="flow"?lN(t,r):o==="radial"?uN(t,r):o==="grid"?cN(t):Sm(t,r)}const Ia=16,fN=12,hN=new Set(["django.route","react.route","react.page","react.server_action","django.task","django.migration_op","django.permission","django.throttle","django.admin","django.management_command","openapi.path","django.consumer","django.websocket_route","django.template","django.cache_key","django.feature_flag","django.side_effect","graphql.operation","fastapi.route"]),pN=new Set(["django.serializer","django.serializer_field","django.form","openapi.path","react.form_schema","django.route","graphql.type","graphql.field","graphql.operation","fastapi.model","fastapi.route"]),_p={"arch.context":"Ownership boundary from loadpath.yml — the context this code belongs to.","django.app":"Django app package that owns models, views, and jobs.","django.route":"HTTP URL that publishes a view. A sink: this is where a change becomes a public request.","django.url_name":"Named URL used by reverse() / {% url %} lookups.","django.view":"Request handler (class-based view, function view, or ViewSet).","django.viewset_action":"One ViewSet action (list, create, retrieve, update, destroy).","django.permission":"Auth gate on a view — who is allowed to hit this path.","django.throttle":"Rate-limit class attached to a view.","django.serializer":"Request/response contract: which fields go in and come out.","django.form":"Django form or django-filter FilterSet — the typed input contract.","django.serializer_field":"One field on a serializer or form — the typed slot on the contract.","django.service":"Internal service or use-case. Work that is not itself an HTTP sink.","django.model":"ORM model. Schema and relations live here.","django.field":"Model column. Type, indexes, and relations are the contract of the table.","django.relation":"Model-to-model relation (FK / M2M / O2O).","django.task":"Celery or Dramatiq job. Once enqueued, this is a sink.","django.receiver":"Signal handler that runs after a model event.","django.signal":"Django signal that receivers subscribe to.","django.test":"Backend test that mentions symbols on this path.","django.admin":"Django admin class for a model.","django.migration_op":"Schema migration operation (CreateModel, AlterField, …).","django.management_command":"manage.py command — an operational sink.","django.consumer":"Django Channels WebSocket/HTTP consumer. A sink once a client connects.","django.websocket_route":"ASGI WebSocket URL. A sink: this is where a change becomes a live connection.","django.template":"Django template. HTML (and HTMX) the server renders.","django.htmx":"HTMX call from a template to a URL — another published seam.","django.cache_key":"Cache get/set key. Invalidation is part of the load path.","django.feature_flag":"Feature flag checked on this path. The change may be dark-launched.","django.side_effect":"transaction.on_commit (or similar) side effect that runs after the request commits.","graphql.type":"GraphQL object/input type — a published contract.","graphql.field":"One field on a GraphQL type.","graphql.operation":"GraphQL query, mutation, or subscription. A published contract and a sink.","fastapi.route":"FastAPI path operation sitting next to Django in this repo.","fastapi.model":"Pydantic response/request model — the FastAPI contract.","openapi.path":"Generated OpenAPI operation. The typed HTTP contract between stacks.","react.api_client":"Frontend fetch or generated client call to an API path.","react.query_key":"React Query cache key. Invalidation and reads share this name.","react.hook":"Data hook wrapping query or mutation calls.","react.feature":"Frontend feature module (folder).","react.route":"Client-side route. A sink: this is a URL the user can open.","react.page":"Page or screen component rendered by a route.","react.server_action":"Next.js Server Action. A sink: the mutation runs on the server.","react.component":"UI component.","react.form_schema":"Zod (or similar) schema — typed form inputs on the client.","react.test":"Frontend test covering a page, hook, or component.","react.context":"React context provider."},gN={field_type:"Type",fields:"Fields",form_fields:"Form fields",permissions:"Permissions",throttles:"Throttles",authentication:"Authentication",pagination:"Pagination",filterset:"Filterset",bases:"Extends",on_delete:"on_delete",related_name:"related_name",unique:"Unique",db_index:"Indexed",relation:"Relation field",looks_idempotent_on_pk:"Idempotent on pk",broker:"Broker",route:"Route",url_name:"URL name",view:"View",include:"Includes",mounted_at:"Mounted at",full_path:"Full path",method:"Method",path:"Path",operation_id:"Operation",raw:"URL",kind:"Schema",exclude:"Excludes",queryset_in_serializer:"Queryset in serializer",get_queryset:"Custom get_queryset",get_serializer_class:"Dynamic serializer",dynamic:"Dynamic",fbv:"Function view",next_app:"Next.js App Router",next_pages:"Next.js Pages Router",next_kind:"Next file",next_layout:"Layout",server_action:"Server Action",typed_client:"Typed client",endpoint:"Endpoint",procedure:"Procedure",e2e:"E2E",visits:"Visits",nested_serializer:"Nested serializer",nested_serializers:"Nested serializers",method_field:"SerializerMethodField",method_fields:"Method fields",from_to_representation:"to_representation",to_representation_fields:"to_representation fields",to_representation:"Custom to_representation",serializer_classes:"get_serializer_class returns",get_serializer_class_resolved:"Serializer resolved",ninja_schema:"Ninja Schema",pydantic:"Pydantic",django_form:"Django form",mutation:"Mutation",has_error_boundary:"Error boundary",invalidation:"Cache invalidation",inferred:"Inferred stitch",generated:"Generated",shared:"Shared module",element:"Renders",model_name:"Model",field_name:"Field",op:"Operation",app:"App",feature:"Feature",from_view:"From view",mentions:"Mentions",nodeid:"Test id",task:"Task",to:"Related to",doc:"Summary",template:"Template",signal:"Signal",sender:"Sender",decorators:"Decorators",nplusone:"N+1 risk",lookups:"Lookups",null:"NULL",blank:"Blank",default:"Default",max_length:"max_length",max_digits:"max_digits",decimal_places:"decimal_places",primary_key:"Primary key",help_text:"Help text",choices:"Choices",auto_now:"auto_now",auto_now_add:"auto_now_add",basename:"Router basename",args:"Args",beat:"Beat",schedule_name:"Schedule",websocket:"WebSocket",htmx:"HTMX",blocks:"Blocks",db_table:"db_table"},Sp=["doc","field_type","method","path","operation_id","raw","route","mounted_at","full_path","url_name","view","element","fields","form_fields","exclude","nested_serializer","nested_serializers","method_fields","to_representation_fields","serializer_classes","typed_client","endpoint","procedure","visits","kind","bases","permissions","authentication","throttles","pagination","filterset","on_delete","related_name","to","unique","db_index","null","blank","default","max_length","max_digits","decimal_places","primary_key","auto_now","auto_now_add","help_text","choices","relation","nplusone","lookups","template","signal","sender","decorators","basename","args","beat","schedule_name","websocket","htmx","blocks","db_table","looks_idempotent_on_pk","broker","task","model_name","field_name","op","app","feature","from_view","include","fbv","ninja","django_form","mutation","has_error_boundary","invalidation","inferred","generated","shared","queryset_in_serializer","get_queryset","get_serializer_class","dynamic","mentions","nodeid"],kp=new Set(["referenced","placeholder","booted","line","call","from","import","local","source","file","plain_handler","string_ref","pagination_sink","match","via","generated_client","django","react","superseded_by_generated","foreign_app","imported"]),mN=new Set(["looks_idempotent_on_pk","null","blank"]),yN=new Set(["inferred","generated","mutation","fbv","ninja","filterset","next_app","next_pages","server_action","e2e","ninja_schema","pydantic","method_field","trpc"]);function vN(t){return _p[t]?_p[t]:t.startsWith("react.")?"A React node on the load path.":t.startsWith("django.")?"A Django node on the load path.":t.startsWith("openapi.")?"A stitch node between Django and React.":"A node on the architecture graph."}function xN(t,r,o){const s=new Map(r.map(g=>[g.id,g])),a=[];hN.has(t.type)&&a.push("sink"),pN.has(t.type)&&a.push("contract");const u=t.extra??{};u.inferred&&a.push("inferred"),u.generated&&a.push("generated"),u.mutation&&a.push("mutation"),u.fbv&&a.push("function view"),u.ninja&&a.push("ninja"),u.ninja_schema&&a.push("ninja schema"),u.next_app&&a.push("app router"),u.typed_client&&a.push(String(u.typed_client)),u.e2e&&a.push("e2e"),u.filterset===!0&&a.push("filterset");const c=o.filter(g=>g.dst===t.id),h=o.filter(g=>g.src===t.id),p=c.slice(0,Ia).map(g=>Ra(g,s,g.src)),y=h.slice(0,Ia).map(g=>Ra(g,s,g.dst)),x=t.file_path?`${t.file_path}${t.start_line?`:${t.start_line}`:""}`:void 0,v={type:t.type,typeLabel:ns(li(t.type)),layer:Kk[si(t.type)]??"other",purpose:vN(t.type),name:t.name,qualifiedName:t.qualified_name,file:x,context:t.context,roles:a,facts:_N(u).filter(g=>!(g.key==="app"&&g.value===t.context)),inputs:p,outputs:y,extraInputs:Math.max(0,c.length-Ia),extraOutputs:Math.max(0,h.length-Ia),degreeIn:c.length,degreeOut:h.length,inputKinds:Np(c.map(g=>Ra(g,s,g.src))),outputKinds:Np(h.map(g=>Ra(g,s,g.dst))),pathSummary:""};return v.pathSummary=wN(v),v}function Np(t){const r=new Map;for(const o of t){const s=o.edgeLabel||o.edgeType.replaceAll("_"," ");r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])).map(([o,s])=>({label:o,count:s}))}function wN(t){const r=t.inputKinds.map(s=>`${s.label} ×${s.count}`).join(", "),o=t.outputKinds.map(s=>`${s.label} ×${s.count}`).join(", ");return r&&o?`${r} → this → ${o}`:o?`this → ${o}`:r?`${r} → this`:""}function Ra(t,r,o){const s=r.get(o),a=o.includes(":")?o.slice(o.indexOf(":")+1):o;return{id:o,name:(s==null?void 0:s.name)||a,type:(s==null?void 0:s.type)||"",typeLabel:s?ns(li(s.type)):"",edgeType:t.type,edgeLabel:ns(t.type),inferred:t.confidence<.8}}function _N(t){const r=[...Sp.filter(a=>a in t),...Object.keys(t).filter(a=>!Sp.includes(a)&&!kp.has(a))],o=[],s=new Set;for(const a of r){if(s.has(a)||kp.has(a)||yN.has(a))continue;s.add(a);const u=SN(a,t[a]);u!=null&&o.push({key:a,label:gN[a]??ns(a),value:u})}return o}function SN(t,r){if(r==null)return null;if(typeof r=="boolean")return!r&&!mN.has(t)?null:r?"yes":"no";if(typeof r=="number")return String(r);if(typeof r=="string")return r.trim()||null;if(Array.isArray(r)){if(r.some(u=>u&&typeof u=="object"))return kN(t,r);const o=r.map(u=>typeof u=="string"||typeof u=="number"?String(u):"").filter(Boolean);if(!o.length)return null;const s=o.slice(0,fN),a=o.length-s.length;return a>0?`${s.join(", ")} +${a} more`:s.join(", ")}return null}function kN(t,r){const o=r.slice(0,4).map(a=>{if(t==="nplusone"){const c=String(a.queryset||"queryset"),h=Array.isArray(a.accessed)?a.accessed.join("."):"",p=a.line?` L${a.line}`:"";return h?`${c} → ${h}${p}`:`${c}${p}`}if(t==="lookups"){const c=Array.isArray(a.fields)?a.fields.join(", "):"",h=String(a.kind||"filter");return c?`${h} ${c}`:h}return Object.entries(a).filter(([,c])=>c!=null&&(typeof c=="string"||typeof c=="number")).slice(0,3).map(([c,h])=>`${c}=${h}`).join(" ")});if(!o.some(Boolean))return null;const s=r.length-o.length;return s>0?`${o.join("; ")} +${s} more`:o.join("; ")}const jp=12,bp=.2,NN=.8,qa=20,jN=Dr;function bN(t,r,o){const s=o??Sm(t,r),a=[...new Set([...s.values()].map(p=>p.x))].sort((p,y)=>p-y),u=[];for(const p of r){const y=s.get(p.src),x=s.get(p.dst);if(!y||!x)continue;const v=y.y+Dr/2,g=x.y+Dr/2;if(Math.abs(v-g)S.y0-N.y0||S.y1-N.y1||S.id.localeCompare(N.id)),x=MN(y),v=Math.max(0,...x.values())+1,g=y[0].sourceX,_=EN(a,g);for(const S of y){const N=PN(x.get(S.id)??0,v),b=g+qa+Math.max(1,_-2*qa)*N;h.set(S.id,CN(S.sourceX,S.targetX,b))}}return h}function EN(t,r){const o=r-zn,s=t.find(a=>a>o+1);return s===void 0?ai:Math.max(ai,s-r)}function CN(t,r,o){const s=r-t-2*qa;return s<1?.5:Math.min(1,Math.max(0,(o-t-qa)/s))}function MN(t){const r=[],o=new Map;for(const s of t){let a=-1;for(let u=0;ur[u]+jN){a=u;break}a<0?(a=r.length,r.push(s.y1)):r[a]=Math.max(r[a],s.y1),o.set(s.id,a)}return o}function PN(t,r){return r<=1?.5:bp+(NN-bp)*t/(r-1)}const IN=new Set,RN=L.lazy(()=>I0(()=>import("./LayeredGraph3D-Ch8n5xd0.js"),[],import.meta.url).then(t=>({default:t.LayeredGraph3D}))),TN={cheap:"var(--edge-cheap)",expensive:"var(--edge-expensive)",critical:"var(--edge-critical)"},Ka={n:ke.Top,e:ke.Right,s:ke.Bottom,w:ke.Left};function LN(t,r){const o=r.x-t.x,s=r.y-t.y;return Math.abs(o)>=Math.abs(s)?o>=0?{source:"e",target:"w"}:{source:"w",target:"e"}:s>=0?{source:"s",target:"n"}:{source:"n",target:"s"}}function AN({data:t,selected:r}){const o=(t.roles||[]).map(s=>`role-${s}`).join(" ");return d.jsxs("div",{className:["lp-node",r?"selected":"",t.dim?"dim":"",o].filter(Boolean).join(" "),children:[["n","e","s","w"].map(s=>d.jsx(ii,{id:`tgt-${s}`,type:"target",position:Ka[s],isConnectable:!1},`tgt-${s}`)),d.jsx("div",{className:"t",children:li(t.type)}),d.jsx("div",{className:"n",title:t.name,children:Ar(t.name)}),["n","e","s","w"].map(s=>d.jsx(ii,{id:`src-${s}`,type:"source",position:Ka[s],isConnectable:!1},`src-${s}`))]})}const $N={load:AN},zN=new Set(["django","react","stitch","arch"]);function DN({id:t,sourceX:r,sourceY:o,targetX:s,targetY:a,sourcePosition:u,targetPosition:c,style:h,markerEnd:p,markerStart:y,label:x,labelStyle:v,labelShowBg:g,labelBgStyle:_,labelBgPadding:S,labelBgBorderRadius:N,data:b,interactionWidth:E}){const[I,w,j]=Ya({sourceX:r,sourceY:o,sourcePosition:u,targetX:s,targetY:a,targetPosition:c,borderRadius:8,stepPosition:(b==null?void 0:b.stepPosition)??.5});return d.jsx(ws,{id:t,path:I,labelX:w,labelY:j,label:x,labelStyle:v,labelShowBg:g,labelBgStyle:_,labelBgPadding:S,labelBgBorderRadius:N,style:h,markerEnd:p,markerStart:y,interactionWidth:E})}const ON={loadstep:DN};function FN({topologyKey:t}){const{fitView:r}=ll();return L.useEffect(()=>{let o=0;const s=requestAnimationFrame(()=>{o=requestAnimationFrame(()=>{r({padding:.2,maxZoom:1.15})})});return()=>{cancelAnimationFrame(s),cancelAnimationFrame(o)}},[r,t]),null}function HN(t,r,o=null,s={}){const a=new Map(t.map(v=>[v.id,v])),u=s.layout??"layers",c=iN(u),h=dN(t,r,u),p=bN(t,r,h),y=t.map(v=>{var S;const g=((S=s.roles)==null?void 0:S[v.id])||[],_=!!s.testOverlay&&!g.includes("tested")&&!g.includes("untested")&&!g.includes("test")&&!g.includes("seed");return{id:v.id,type:"load",position:h.get(v.id)??{x:0,y:0},data:{name:v.name,type:v.type,file:v.file_path,roles:g,dim:_},selected:o===v.id,sourcePosition:ke.Right,targetPosition:ke.Left,width:zn,height:Dr,style:{width:zn,height:Dr}}}),x=r.filter(v=>a.has(v.src)&&a.has(v.dst)).map(v=>{const g=TN[v.weight]||"var(--edge-cheap)",_=!!(o&&(v.src===o||v.dst===o)),S=h.get(v.src)??{x:0,y:0},N=h.get(v.dst)??{x:0,y:0},b=c?{source:"e",target:"w"}:LN(S,N);return{id:v.id,source:v.src,target:v.dst,sourceHandle:`src-${b.source}`,targetHandle:`tgt-${b.target}`,sourcePosition:Ka[b.source],targetPosition:Ka[b.target],type:c?"loadstep":"default",animated:v.weight==="critical",data:{stepPosition:p.get(v.id)??.5},style:{stroke:g,strokeWidth:v.weight==="critical"?2.4:1.2,strokeDasharray:v.confidence<.8?"6 4":void 0},markerEnd:{type:us.ArrowClosed,width:14,height:14,color:g},label:_?v.type.replaceAll("_"," "):void 0,labelStyle:_?{fill:"var(--ink)",fontSize:10,fontWeight:600}:void 0,labelBgStyle:_?{fill:"var(--graph-bg)",fillOpacity:.92}:void 0,labelBgPadding:_?[3,5]:void 0,labelBgBorderRadius:_?4:void 0}});return{rfNodes:y,rfEdges:x}}function BN({node:t,nodes:r,edges:o,onClose:s,onWhatIf:a,onSelect:u,onOpenFile:c,pinned:h,onPin:p,onIsolate:y}){const x=xN(t,r,o);return L.useEffect(()=>{const v=g=>{g.key==="Escape"&&s()};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[s]),d.jsxs("aside",{className:"inspector","data-testid":"graph-inspector",children:[d.jsxs("div",{className:"inspector-head",children:[d.jsx("div",{className:"t",children:x.typeLabel}),d.jsx("div",{className:"inspector-roles",children:x.roles.map(v=>d.jsx("span",{className:"inspector-chip",children:v},v))}),d.jsx("button",{type:"button",className:"inspector-close","data-testid":"graph-inspector-close","aria-label":"Close inspector",onClick:s,children:"×"})]}),d.jsx("div",{className:"n",children:Ar(x.name)}),d.jsx("p",{className:"inspector-purpose","data-testid":"graph-inspector-purpose",children:x.purpose}),x.context?d.jsx("div",{className:"muted",children:Ar(x.context)}):null,x.file?d.jsxs("div",{className:"file-row",children:[d.jsx("div",{className:"file",children:Ar(x.file)}),c&&t.file_path?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-open-editor",onClick:()=>c(t.file_path,t.start_line),children:"Open in editor"}):null]}):null,d.jsx("div",{className:"muted",children:Ar(x.qualifiedName)}),d.jsxs("div",{className:"muted inspector-layer",children:["layer · ",x.layer]}),d.jsxs("div",{className:"muted inspector-degree","data-testid":"graph-inspector-degree",children:[x.degreeIn," in · ",x.degreeOut," out"]}),x.pathSummary?d.jsx("p",{className:"inspector-path","data-testid":"graph-inspector-path",children:x.pathSummary}):null,x.facts.length?d.jsx("dl",{className:"inspector-facts","data-testid":"graph-inspector-facts",children:x.facts.map(v=>d.jsxs("div",{className:"inspector-fact",children:[d.jsx("dt",{children:v.label}),d.jsx("dd",{children:Ar(v.value)})]},v.key))}):null,d.jsx(Ep,{title:"Inputs",testId:"graph-inspector-inputs",links:x.inputs,extra:x.extraInputs,empty:"Nothing in this graph points here.",onSelect:u}),d.jsx(Ep,{title:"Outputs",testId:"graph-inspector-outputs",links:x.outputs,extra:x.extraOutputs,empty:"This node does not point at anything in this graph.",onSelect:u}),a?d.jsx("p",{className:"whatif-hint","data-testid":"whatif-hint",children:y?"Walks a new path from this node with no git range. Isolate (next) only hides the rest of this map.":"Walks a new path from this node with no git range — as if this changed, regardless of Base/Head."}):null,d.jsxs("div",{className:"btn-row",children:[a?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-whatif",title:"Start a hypothetical walk from this node. Does not use Base/Head.",onClick:()=>a(t.id),children:"What if this changes"}):null,y?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-isolate",title:"Hide nodes that are not on a path from here to a sink. Does not start a new walk.",onClick:()=>y(t.id),children:"Isolate path to sinks"}):null,p?d.jsx("button",{type:"button",className:h?"btn primary":"btn","data-testid":"btn-pin-node",onClick:()=>p(h?null:t.id),children:h?"Unpin":"Pin"}):null]})]})}function Ep({title:t,testId:r,links:o,extra:s,empty:a,onSelect:u}){return d.jsxs("section",{className:"inspector-section","data-testid":r,children:[d.jsxs("h3",{children:[t,d.jsx("span",{className:"count",children:o.length+s})]}),o.length?d.jsx("ul",{children:o.map((c,h)=>d.jsx("li",{children:u?d.jsxs("button",{type:"button",className:"inspector-link",onClick:()=>u(c.id),children:[d.jsx("span",{className:"inspector-link-name",title:c.name,children:Ar(c.name)}),d.jsxs("span",{className:"inspector-link-meta",children:[c.typeLabel?`${c.typeLabel} · `:"",c.edgeLabel,c.inferred?" · inferred":""]})]}):d.jsxs(d.Fragment,{children:[d.jsx("span",{className:"inspector-link-name",title:c.name,children:Ar(c.name)}),d.jsxs("span",{className:"inspector-link-meta",children:[c.typeLabel?`${c.typeLabel} · `:"",c.edgeLabel,c.inferred?" · inferred":""]})]})},`${c.edgeType}:${c.id}:${h}`))}):d.jsx("p",{className:"muted",children:a}),s?d.jsxs("p",{className:"muted",children:["+",s," more"]}):null]})}function nc({nodes:t,edges:r,onWhatIf:o,focusPath:s,selectedId:a,onSelect:u,nodeRoles:c,testOverlay:h=!1,isolateSource:p,onIsolate:y,repoPath:x,onOpenFile:v,pinnedId:g,onPin:_}){const[S,N]=L.useState(null),b=a!==void 0?a:S,E=ue=>{a===void 0&&N(ue),u==null||u(ue)},[I,w]=L.useState(null),[j,A]=L.useState(null),[$,F]=L.useState(()=>rN()),[Y,q]=L.useState(new Set(zN)),[re,J]=L.useState(!1),[te,Q]=L.useState(""),[C,V]=L.useState(!1),W=typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,U=I??Qk(t.length),M=j??Zk(t.length),D=re?b:null,H=L.useMemo(()=>p?nN(t,r,p):null,[t,r,p]),R=H?t.filter(ue=>H.nodeIds.has(ue.id)):t,z=H?r.filter(ue=>H.edgeIds.has(ue.id)):r,ne=L.useMemo(()=>eN(R,z,{detail:M,families:Y,focusId:D,neighborhoodOnly:!!D}),[R,z,M,Y,D]),oe=L.useMemo(()=>`${$}|${ne.nodes.map(ue=>ue.id).join("\0")}|${ne.edges.map(ue=>ue.id).join("\0")}`,[$,ne.nodes,ne.edges]),fe=b?t.find(ue=>ue.id===b)??null:null,{rfNodes:he,rfEdges:pe}=L.useMemo(()=>{const ue=HN(ne.nodes,ne.edges,b,{roles:c,testOverlay:h,layout:$});return W&&(ue.rfEdges=ue.rfEdges.map(je=>({...je,animated:!1}))),ue},[ne.nodes,ne.edges,b,W,c,h,$]);L.useEffect(()=>{if(!s)return;const ue=t.find(je=>je.file_path===s);ue&&E(ue.id)},[s,t]);const Z=L.useMemo(()=>tN(t,te),[t,te]),se=(ue,je)=>{E(je.id)},me=()=>{E(null),J(!1)},Ne=fe?d.jsx(BN,{node:fe,nodes:t,edges:r,onClose:me,onWhatIf:o,onSelect:E,onOpenFile:v,pinned:g===fe.id,onPin:_,onIsolate:y?ue=>{y(p===ue?null:ue)}:void 0}):null,we=ue=>{q(je=>{const Le=new Set(je);if(Le.has(ue)){if(Le.size===1)return je;Le.delete(ue)}else Le.add(ue);return Le})},ve=L.useMemo(()=>{const ue=new Set;for(const je of t)ue.add(bm(je.type));return ue},[t]),Pe=t.length-ne.nodes.length;return d.jsxs("div",{className:"impact-graph",style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[d.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[d.jsxs("div",{className:"seg","aria-label":"Graph projection",children:[d.jsx("button",{type:"button","data-testid":"graph-view-2d",className:U==="2d"?"active":"","aria-pressed":U==="2d",onClick:()=>w("2d"),children:"2D map"}),d.jsx("button",{type:"button","data-testid":"graph-view-3d",className:U==="3d"?"active":"","aria-pressed":U==="3d",onClick:()=>w("3d"),children:"3D layers"})]}),d.jsxs("div",{className:"seg","aria-label":"Graph detail",children:[d.jsx("button",{type:"button","data-testid":"graph-detail-overview",className:M==="overview"?"active":"","aria-pressed":M==="overview",onClick:()=>A("overview"),children:"Overview"}),d.jsx("button",{type:"button","data-testid":"graph-detail-full",className:M==="full"?"active":"","aria-pressed":M==="full",onClick:()=>A("full"),children:"Full"})]}),d.jsx("div",{className:"seg","aria-label":"Graph families",children:["django","stitch","react"].filter(ue=>ve.has(ue)).map(ue=>d.jsx("button",{type:"button","data-testid":`graph-family-${ue}`,className:Y.has(ue)?"active":"","aria-pressed":Y.has(ue),onClick:()=>we(ue),children:ue},ue))}),U==="2d"?d.jsxs("label",{className:"graph-layout",children:["Layout",d.jsx("select",{id:"graph-layout","data-testid":"graph-layout",value:$,"aria-label":"2D layout algorithm",onChange:ue=>{var Le;const je=(Le=xc.find(nt=>nt.id===ue.target.value))==null?void 0:Le.id;je&&(F(je),oN(je))},children:xc.map(ue=>d.jsx("option",{value:ue.id,children:ue.label},ue.id))})]}):null,d.jsx("button",{type:"button",className:re?"chip-btn active":"chip-btn","data-testid":"graph-neighborhood",disabled:!b,onClick:()=>J(ue=>!ue),children:re?"Neighborhood":"Focus neighbors"}),p?d.jsx("button",{type:"button",className:"chip-btn active","data-testid":"graph-isolate-clear",onClick:()=>y==null?void 0:y(null),children:"Path isolate"}):null,d.jsxs("label",{className:"graph-search",children:[d.jsx("span",{className:"sr-only",children:"Search nodes"}),d.jsx("input",{"data-testid":"graph-search",placeholder:"Find a node",value:te,onChange:ue=>{Q(ue.target.value),V(!0)},onFocus:()=>V(!0),onBlur:()=>window.setTimeout(()=>V(!1),150)}),C&&te.trim()&&Z.length?d.jsx("ul",{className:"graph-search-hits","data-testid":"graph-search-hits",children:Z.map(ue=>d.jsx("li",{children:d.jsxs("button",{type:"button",onMouseDown:je=>je.preventDefault(),onClick:()=>{E(ue.id),Q(""),V(!1)},children:[ue.name,d.jsx("span",{className:"muted",children:li(ue.type)})]})},ue.id))}):null]}),d.jsxs("span",{className:"muted graph-count",children:[ne.nodes.length," nodes · ",ne.edges.length," edges",Pe?` · ${Pe} hidden`:""]})]}),d.jsx("div",{className:"graph-stage",children:U==="3d"?d.jsxs("div",{className:"graph-3d","data-testid":"graph-3d",children:[d.jsx("p",{className:"graph-3d-hint",children:"Architecture layers are stacked in depth (Django → stitch → React). Drag to orbit, scroll to zoom, click a node to inspect it."}),d.jsx(L.Suspense,{fallback:d.jsx("p",{className:"muted graph-3d-hint",children:"Loading 3D layers…"}),children:d.jsx(RN,{nodes:ne.nodes,edges:ne.edges,selectedId:b,neighborIds:D?ne.neighborIds:IN,onSelect:ue=>{E(ue),ue||J(!1)}})}),Ne]}):d.jsxs(vm,{children:[d.jsxs(dk,{nodes:he,edges:pe,nodeTypes:$N,edgeTypes:ON,fitView:!1,minZoom:.25,nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,deleteKeyCode:null,onNodeClick:se,onPaneClick:me,proOptions:{hideAttribution:!1},"data-testid":"impact-graph",children:[d.jsx(FN,{topologyKey:oe}),d.jsx(mk,{}),d.jsx(zk,{pannable:!0,zoomable:!0,ariaLabel:"Impact graph overview",nodeColor:"var(--muted)",nodeStrokeColor:"transparent",nodeStrokeWidth:0,maskColor:"rgba(0, 0, 0, 0.45)",maskStrokeColor:"var(--accent)",maskStrokeWidth:1.4,bgColor:"var(--graph-bg)",style:{width:184,height:128}}),d.jsx(kk,{})]}),Ne]})})]})}function Em(){const t=localStorage.getItem("loadpath.editor")||"auto";return t==="cursor"||t==="vscode"||t==="system"?t:"auto"}function VN(t){localStorage.setItem("loadpath.editor",t)}async function WN(t,r,o,s=Em()){try{const a=await Te.openEditor(t,r,o??void 0,s);if(a.ok)return{ok:!0,message:`Opened ${r} in ${a.opened_with||"editor"}`};const u=a.urls||{},c=s==="vscode"?u.vscode:s==="cursor"?u.cursor:u.cursor||u.vscode;return c?(window.open(c,"_blank","noopener,noreferrer"),{ok:!0,message:`Opening ${r} via editor URL`}):{ok:!1,message:a.error||"Could not open editor"}}catch(a){return{ok:!1,message:a instanceof Error?a.message:String(a)}}}const Cp=[{value:"HEAD",label:"HEAD",group:"preset"},{value:"HEAD~1",label:"HEAD~1",group:"preset"}],UN=["preset","branch","tag","commit"];function GN(t){var a;if(!(t!=null&&t.git))return[...Cp];const r=((a=t.presets)!=null&&a.length?t.presets:Cp.map(u=>u.value)).map(u=>({value:u,label:u,group:"preset"})),o=new Set(r.map(u=>u.value)),s=[...r];for(const u of t.branches||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.current?`${u.name} (current)`:u.name,detail:u.subject,group:"branch"}));for(const u of t.tags||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.name,detail:u.subject,group:"tag"}));for(const u of t.commits||[])o.has(u.sha)||(o.add(u.sha),s.push({value:u.sha,label:u.short,detail:u.subject,group:"commit"}));return s}function YN(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.value.toLowerCase().includes(o)||s.label.toLowerCase().includes(o)||(s.detail||"").toLowerCase().includes(o)):t}function XN(t){return UN.map(r=>({group:r,items:t.filter(o=>o.group===r)})).filter(r=>r.items.length>0)}function qN(t){return t==="preset"?"Common":t==="branch"?"Branches":t==="tag"?"Tags":"Recent commits"}function Mp({value:t,onChange:r,placeholder:o,testId:s,menuTestId:a,refs:u,onNeedRefs:c}){const h=L.useId(),p=L.useRef(null),[y,x]=L.useState(!1),[v,g]=L.useState(null),[_,S]=L.useState(0),N=L.useMemo(()=>{const j=GN(u);return v===null?j:YN(j,v)},[u,v]),b=L.useMemo(()=>XN(N),[N]);L.useEffect(()=>{y&&c()},[y,c]),L.useEffect(()=>{S(0)},[v,y]);const E=()=>{x(!1),g(null)},I=j=>{r(j.value),E()},w=j=>{if(j.key==="ArrowDown"){if(j.preventDefault(),!y){x(!0);return}S(A=>Math.min(A+1,Math.max(N.length-1,0)))}else if(j.key==="ArrowUp"){if(j.preventDefault(),!y)return;S(A=>Math.max(A-1,0))}else if(j.key==="Enter"&&y){j.preventDefault();const A=N[_];A&&I(A)}else j.key==="Escape"&&y&&(j.preventDefault(),E())};return d.jsxs("div",{className:"combo",ref:p,onBlur:j=>{j.currentTarget.contains(j.relatedTarget)||E()},children:[d.jsxs("div",{className:"combo-row",children:[d.jsx("input",{"data-testid":s,value:t,placeholder:o,spellCheck:!1,role:"combobox","aria-expanded":y,"aria-controls":h,"aria-autocomplete":"list",onChange:j=>{r(j.target.value),y&&g(j.target.value)},onKeyDown:w}),d.jsx("button",{type:"button",className:"icon-btn combo-toggle","data-testid":`${s}-toggle`,"aria-label":"Show recent refs","aria-expanded":y,onMouseDown:j=>j.preventDefault(),onClick:()=>y?E():x(!0),children:d.jsx(C0,{})})]}),y?d.jsx("div",{className:"combo-menu",id:h,role:"listbox","data-testid":a,children:b.length===0?d.jsx("div",{className:"combo-empty muted",children:"No matching refs — the typed value is kept"}):b.map(j=>d.jsxs("div",{className:"combo-group",children:[d.jsx("div",{className:"combo-heading",children:qN(j.group)}),j.items.map(A=>{const $=N.indexOf(A);return d.jsxs("button",{type:"button",role:"option","aria-selected":$===_,className:$===_?"combo-option active":"combo-option","data-testid":`ref-option-${A.group}`,onMouseDown:F=>F.preventDefault(),onMouseEnter:()=>S($),onClick:()=>I(A),children:[d.jsx("span",{className:"combo-label",children:A.label}),A.detail?d.jsx("span",{className:"combo-detail",children:A.detail}):null]},`${A.group}:${A.value}`)})]},j.group))}):null]})}function KN({initialPath:t,onSelect:r,onClose:o}){const[s,a]=L.useState(null),[u,c]=L.useState(t),[h,p]=L.useState(null),[y,x]=L.useState(""),[v,g]=L.useState(!1),_=L.useRef(null),S=L.useRef(0),N=async w=>{const j=S.current+1;S.current=j,g(!0);try{const A=await Te.browse(w);if(S.current!==j)return;a(A),c(A.path),p(A.is_git?A.path:null),x("")}catch(A){if(S.current!==j)return;x(A instanceof Error?A.message:String(A))}finally{S.current===j&&g(!1)}};L.useEffect(()=>{var w,j;N(t),(w=_.current)==null||w.focus(),(j=_.current)==null||j.select()},[t]);const b=h||(s==null?void 0:s.path)||u,E=h&&h!==(s==null?void 0:s.path)?h.split(/[\\/]/).filter(Boolean).pop():s!=null&&s.is_git?"this repository":"this folder",I=w=>{w.key==="Escape"&&(w.preventDefault(),o())};return d.jsx("div",{className:"modal-backdrop","data-testid":"repo-explorer","data-overlay":"true",onClick:o,onKeyDown:I,children:d.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"explorer-title",onClick:w=>w.stopPropagation(),children:[d.jsxs("div",{className:"modal-head",children:[d.jsxs("div",{children:[d.jsx("h2",{id:"explorer-title",children:"Select repository"}),d.jsx("p",{className:"muted",children:"Browse to a git root, or paste the full path."})]}),d.jsx("button",{type:"button",className:"btn ghost","data-testid":"explorer-cancel",onClick:o,children:"Cancel"})]}),d.jsxs("form",{className:"explorer-path",onSubmit:w=>{w.preventDefault(),N(u)},children:[d.jsx("input",{ref:_,"data-testid":"explorer-path",value:u,onChange:w=>c(w.target.value),spellCheck:!1,"aria-label":"Directory path"}),d.jsx("button",{type:"button",className:"btn",disabled:!(s!=null&&s.parent),onClick:()=>(s==null?void 0:s.parent)&&void N(s.parent),children:"Up"}),d.jsx("button",{type:"button",className:"btn",onClick:()=>s&&void N(s.home),children:"Home"}),d.jsx("button",{type:"submit",className:"btn",children:"Go"})]}),y?d.jsx("div",{className:"error",role:"alert",children:y}):null,d.jsx("div",{className:"explorer-list",role:"listbox","aria-label":"Folders","aria-busy":v,children:s!=null&&s.entries.length?s.entries.map(w=>{const j=h===w.path;return d.jsxs("button",{type:"button",role:"option","aria-selected":j,className:j?"explorer-row active":"explorer-row","data-testid":"explorer-entry","data-path":w.path,onClick:()=>p(w.path),onDoubleClick:()=>void N(w.path),children:[d.jsx(Tp,{}),d.jsx("span",{className:"explorer-name",children:w.name}),w.is_git?d.jsx("span",{className:"chip git-badge",children:"git"}):null]},w.path)}):d.jsx("div",{className:"muted explorer-empty",children:v?"Loading…":"No folders here"})}),d.jsxs("div",{className:"modal-foot",children:[d.jsx("span",{className:"muted explorer-current",title:b,children:b}),d.jsxs("button",{type:"button",className:"btn primary","data-testid":"explorer-use",disabled:!b,onClick:()=>b&&r(b),children:["Use ",E]})]})]})})}const QN={scan:{start:0,end:20},extract:{start:20,end:88},boot:{start:88,end:94},stitch:{start:94,end:99},skipped:{start:100,end:100},done:{start:100,end:100}},ZN=new Set(["scan","extract","boot","stitch"]);function JN(t){const r=t.phase||"";if(!r||r==="idle")return null;const o=QN[r];if(!o)return null;if(o.start===o.end)return o.end;const s=t.total||0;if(s<=0)return o.start;const a=Math.min(1,Math.max(0,(t.done||0)/s));return Math.round(o.start+(o.end-o.start)*a)}function ej(t){return!t.phase||t.phase==="idle"?null:typeof t.percent=="number"&&Number.isFinite(t.percent)?Math.max(0,Math.min(100,Math.round(t.percent))):JN(t)}const Qa=[{id:"obsidian",label:"Obsidian",group:"dark"},{id:"nord",label:"Nord",group:"dark"},{id:"solarized-dark",label:"Solarized Dark",group:"dark"},{id:"forest",label:"Forest",group:"dark"},{id:"rose",label:"Rose Pine",group:"dark"},{id:"amber",label:"Midnight Amber",group:"dark"},{id:"volcano",label:"Volcano",group:"dark"},{id:"lavender",label:"Lavender",group:"dark"},{id:"neon-noir",label:"Neon Noir",group:"dark"},{id:"synthwave",label:"Synthwave",group:"dark"},{id:"phosphor",label:"Phosphor",group:"dark"},{id:"aurora",label:"Aurora",group:"dark"},{id:"biolume",label:"Biolume",group:"dark"},{id:"carbon",label:"Carbon",group:"dark"},{id:"paper",label:"Paper",group:"light"},{id:"solarized-light",label:"Solarized Light",group:"light"},{id:"seafoam",label:"Seafoam",group:"light"},{id:"high-contrast",label:"High Contrast",group:"light"},{id:"sakura",label:"Sakura",group:"light"},{id:"citrus",label:"Citrus",group:"light"},{id:"peach",label:"Peach Fuzz",group:"light"},{id:"candy",label:"Cotton Candy",group:"light"},{id:"sky",label:"Clear Sky",group:"light"},{id:"coral",label:"Coral Reef",group:"light"}],tj="obsidian",Cm="loadpath.theme";function nj(t){return Qa.some(r=>r.id===t)}function Mm(){try{const t=localStorage.getItem(Cm)||"";if(nj(t))return t}catch{}return tj}function rj(t){var r;return((r=Qa.find(o=>o.id===t))==null?void 0:r.group)==="light"?"light":"dark"}function Pm(t){document.documentElement.dataset.theme=t,document.documentElement.style.colorScheme=rj(t);try{localStorage.setItem(Cm,t)}catch{}}const rc=[{id:"review",label:"Review",testId:"tab-review",shortcut:"1",icon:k0},{id:"architecture",label:"Architecture",testId:"tab-architecture",shortcut:"2",icon:N0},{id:"graph",label:"Impact graph",testId:"tab-graph",shortcut:"3",icon:j0},{id:"prs",label:"Pull requests",testId:"tab-prs",shortcut:"4",icon:b0},{id:"settings",label:"Settings",testId:"tab-settings",shortcut:"5",icon:E0}];function oc(t,r,o){let s;try{s=new URL(t)}catch{return}if(s.protocol!=="https:"||s.username||s.password)return;const a=s.hostname.toLowerCase();a!==r&&!a.endsWith(`.${r}`)||s.pathname.startsWith(o)&&window.open(s.toString(),"_blank","noopener,noreferrer")}function oj(){var gi,jo,mi,yi,vi,bo,Xr,an,ln,un;const[t,r]=L.useState("review"),[o,s]=L.useState(localStorage.getItem("loadpath.repo")||""),[a,u]=L.useState(localStorage.getItem("loadpath.base")||"HEAD~1"),[c,h]=L.useState(localStorage.getItem("loadpath.head")||"HEAD"),[p,y]=L.useState(null),[x,v]=L.useState(null),[g,_]=L.useState(null),[S,N]=L.useState([]),[b,E]=L.useState("review"),[I,w]=L.useState(""),[j,A]=L.useState(""),[$,F]=L.useState(null),[Y,q]=L.useState(!1),[re,J]=L.useState(!1),[te,Q]=L.useState(""),[C,V]=L.useState({}),[W,U]=L.useState([]),[M,D]=L.useState([]),[H,R]=L.useState(localStorage.getItem("loadpath.scmRepo")||""),[z,ne]=L.useState(localStorage.getItem("loadpath.provider")||"github"),[oe,fe]=L.useState(localStorage.getItem("loadpath.prNumber")||""),[he,pe]=L.useState(localStorage.getItem("loadpath.dirty")==="1"),[Z,se]=L.useState(0),[me,Ne]=L.useState(""),[we,ve]=L.useState(Mm),[Pe,ue]=L.useState(!1),[je,Le]=L.useState(!1),[nt,lt]=L.useState(!1),[ut,Ye]=L.useState(null),[wt,Yt]=L.useState(null),[gt,mt]=L.useState(localStorage.getItem("loadpath.testOverlay")==="1"),[Ct,ct]=L.useState(null),[et,On]=L.useState(localStorage.getItem("loadpath.watch")==="1"),[Mt,kn]=L.useState([]),[ui,Fn]=L.useState(null),[vo,lr]=L.useState(null),[Or,Hn]=L.useState(null),[Fr,ur]=L.useState(()=>{try{return!!(localStorage.getItem("loadpath.lastReviewId")&&(localStorage.getItem("loadpath.repo")||"").trim())}catch{return!1}}),[cr,Ft]=L.useState(null),[dt,Bn]=L.useState(null),[Vn,Nn]=L.useState(!1),[Wn,jn]=L.useState(!1),it=L.useRef(o);it.current=o;const dr=L.useRef(he);dr.current=he;const bn=L.useRef(!1);bn.current=je;const Pt=L.useRef(""),nn=L.useRef(""),xo=P=>{ve(P),Pm(P)},Ze=L.useRef(""),He=P=>{Ze.current=P,A(P)},En=P=>{let G=0,ce=!1;F(0);const Ce=()=>{Te.indexProgress(P).then(Re=>{if(!Ze.current)return;if(Re.phase&&Re.phase!=="idle"&&Re.message&&He(Re.message),ZN.has(Re.phase))ce=!0;else if(!ce)return;const mr=ej(Re);mr!=null&&(Re.phase==="scan"&&!Re.done?G=mr:G=Math.max(G,mr),F(G))}).catch(()=>{})};Ce();const Ie=window.setInterval(Ce,250);return()=>{window.clearInterval(Ie),F(null)}};L.useEffect(()=>{Te.settings().then(V).catch(()=>{}).finally(()=>ue(!0)),Te.repos().then(P=>N(P.repos)).catch(()=>{})},[]);const Un=()=>o.trim()?!0:(w("Point at a local repository path first."),!1);L.useEffect(()=>{if(t!=="architecture"||!o.trim())return;const P=o;let G=!1;return nn.current!==P&&Yn(P),Te.config(P).then(ce=>{!G&&it.current===P&&lr(ce)}).catch(()=>{}),Te.architectureHealth(P).then(ce=>{!G&&it.current===P&&Hn(ce)}).catch(()=>{}),()=>{G=!0}},[t,o]);const rn=P=>{it.current=P,s(P),localStorage.setItem("loadpath.repo",P),P.trim()!==Pt.current&&(Pt.current="",Ft(null))},Hr=L.useCallback(P=>{const G=(P??it.current).trim();return!G||Pt.current===G?Promise.resolve():(Pt.current=G,Te.gitRefs(G).then(ce=>{it.current.trim()===G&&Ft(ce)}).catch(()=>{Pt.current===G&&(Pt.current="",Ft(null))}))},[]),on=(P,G)=>{u(P),h(G),localStorage.setItem("loadpath.base",P),localStorage.setItem("loadpath.head",G)},It=(P,G,ce)=>{ne(P),R(G),localStorage.setItem("loadpath.provider",P),localStorage.setItem("loadpath.scmRepo",G),ce!==void 0&&(fe(ce),localStorage.setItem("loadpath.prNumber",ce))},Xt=P=>{y(P),se(0),Ye(wt&&P.nodes.some(G=>G.id===wt)?wt:null),ct(null),Fn(null),P.what_if||(v(P),P.id&&localStorage.setItem("loadpath.lastReviewId",P.id))},Gn=async P=>{try{const G=await Te.reviews(P);kn(G.reviews)}catch{kn([])}},wo=async P=>{try{Hn(await Te.architectureHealth(P))}catch{Hn(null)}},_o=P=>P==="github"?!!C.github_token_set:P==="gitlab"?!!C.gitlab_token_set:!!C.bitbucket_token_set,Rt=L.useCallback(async(P=z)=>{var G;try{const ce=await Te.scmRepos(P);D(ce.repos),(G=ce.user)!=null&&G.login&&V(Ce=>({...Ce,...P==="github"?{github_user:ce.user.login}:P==="gitlab"?{gitlab_user:ce.user.login}:{bitbucket_user:ce.user.login}}))}catch{D([])}},[z]);L.useEffect(()=>{if(t!=="prs")return;let P=!1;return Rt(z).catch(()=>{P||D([])}),()=>{P=!0}},[t,z,Rt]),L.useEffect(()=>{if(!dt)return;let P=!1,G=0;const ce=async()=>{try{const Ce=await Te.githubOAuthPoll(dt.flow_id);if(P)return;if(Ce.status==="complete"){Bn(null);const Ie=await Te.settings();V(Ie),Q(Ce.user?`Signed in to GitHub as ${Ce.user}`:"Signed in to GitHub"),Rt("github");return}if(Ce.status==="pending"||Ce.status==="slow_down"){G=window.setTimeout(ce,Math.max(Ce.interval||dt.interval,5)*1e3);return}Bn(null),w(Ce.status==="denied"?"GitHub sign-in was denied.":"GitHub sign-in expired. Try again.")}catch(Ce){if(P)return;Bn(null),w(Ce instanceof Error?Ce.message:String(Ce))}};return G=window.setTimeout(ce,Math.max(dt.interval,5)*1e3),()=>{P=!0,window.clearTimeout(G)}},[dt,Rt]),L.useEffect(()=>{if(!Vn)return;let P=!1,G=0;const ce=Date.now(),Ce=async()=>{try{const Ie=await Te.oauthStatus();if(P)return;if(Ie.bitbucket.connected){Nn(!1);const Re=await Te.settings();V(Re),Q(Ie.bitbucket.user?`Signed in to Bitbucket as ${Ie.bitbucket.user}`:"Signed in to Bitbucket"),Rt("bitbucket");return}if(Date.now()-ce>18e4){Nn(!1),w("Bitbucket sign-in timed out. Finish in the browser, or try again.");return}G=window.setTimeout(Ce,1500)}catch(Ie){if(P)return;Nn(!1),w(Ie instanceof Error?Ie.message:String(Ie))}};return G=window.setTimeout(Ce,1500),()=>{P=!0,window.clearTimeout(G)}},[Vn,Rt]),L.useEffect(()=>{if(!Wn)return;let P=!1,G=0;const ce=Date.now(),Ce=async()=>{try{const Ie=await Te.oauthStatus();if(P)return;if(Ie.gitlab.connected){jn(!1);const Re=await Te.settings();V(Re),Q(Ie.gitlab.user?`Signed in to GitLab as ${Ie.gitlab.user}`:"Signed in to GitLab"),Rt("gitlab");return}if(Date.now()-ce>18e4){jn(!1),w("GitLab sign-in timed out. Finish in the browser, or try again.");return}G=window.setTimeout(Ce,1500)}catch(Ie){if(P)return;jn(!1),w(Ie instanceof Error?Ie.message:String(Ie))}};return G=window.setTimeout(Ce,1500),()=>{P=!0,window.clearTimeout(G)}},[Wn,Rt]);const Yn=async(P=o,G=!1)=>{if(!P.trim())return null;nn.current=P,J(!0);try{const ce=await Te.architecture(P,!1);it.current===P&&_(ce);const Ce=Te.architectureGraph(P).then(Ie=>{it.current===P&&_(Re=>Re&&{...Re,nodes:Ie.nodes,edges:Ie.edges,graph_pending:!1})});return Ce.catch(()=>{_(Ie=>Ie&&it.current===P?{...Ie,graph_pending:!1}:Ie)}).finally(()=>{nn.current===P&&J(!1)}),G&&await Ce,ce}catch(ce){throw it.current===P&&J(!1),ce}},Br=async P=>{const G=P.trim();if(!(!G||G===it.current)){if(Ze.current){w("Wait for the current job to finish before switching workspace.");return}w(""),Q(""),y(null),v(null),_(null),E("architecture"),rn(G),q(!0),He(`Loading ${S0(G)}…`);try{await Promise.all([Yn(G),Hr(G)])}catch(ce){it.current===G&&w(ce instanceof Error?ce.message:String(ce))}finally{it.current===G&&(He(""),q(!1))}}},Xn=async()=>{if(Ze.current||!Un())return;w(""),Q(""),He("Tracing load path…"),rn(o),on(a,c);const P=En(o);try{const G=await Te.review(o,a,c,!0,dr.current);Xt(G),E("review"),r("review"),await Te.repos().then(ce=>N(ce.repos)).catch(()=>{}),await Promise.all([Yn(o),Gn(o),wo(o)])}catch(G){w(G instanceof Error?G.message:String(G))}finally{P(),He("")}},fr=async(P=!0)=>{if(Ze.current||!Un())return;w(""),Q(""),He(P?"Indexing…":"Full reindex…"),rn(o);const G=En(o);try{await Te.index(o,P);const ce=await Yn(o);await Te.repos().then(Ce=>N(Ce.repos)).catch(()=>{}),ce!=null&&ce.indexed&&(E("architecture"),r("architecture"))}catch(ce){w(ce instanceof Error?ce.message:String(ce))}finally{G(),He("")}},Ve=async()=>{if(!Ze.current&&Un()){w(""),Q(""),He("Detecting layout…"),rn(o);try{const P=await Te.init(o);Q(P.message),await Te.repos().then(G=>N(G.repos)).catch(()=>{})}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},ci=async()=>{if(p!=null&&p.markdown)try{await navigator.clipboard.writeText(p.markdown),Q("Copied markdown brief")}catch(P){w(P instanceof Error?P.message:String(P))}},Vr=async()=>{if(!Ze.current){if(p!=null&&p.what_if){w("What-if walks are hypothetical — they are not posted to a pull request. Restore the git-range walk first.");return}if(!(p!=null&&p.markdown)||!H||!oe){w("Pick a pull request first (Pull requests tab), then post the brief.");return}He("Posting Loadpath brief…");try{const P=await Te.postComment(z,H,Number(oe),p.markdown);Q(P.updated?"Updated the Loadpath PR comment":"Posted the Loadpath PR comment")}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},So=async()=>{if(!Ze.current){w(""),He("Fetching pull requests…");try{const P=await Te.prs(z,H,"open",o.trim()||void 0);U(P.pull_requests);const G=M.find(ce=>ce.slug.toLowerCase()===H.trim().toLowerCase());G!=null&&G.local_path&&rn(G.local_path)}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},hr=async()=>{w("");try{const P=await Te.githubOAuthStart();Bn(P),oc(P.verification_uri_complete,"github.com","/login/device")}catch(P){w(P instanceof Error?P.message:String(P))}},di=async()=>{w("");try{const P=await Te.bitbucketOAuthStart();Nn(!0),oc(P.authorize_url,"bitbucket.org","/site/oauth2/authorize")}catch(P){Nn(!1),w(P instanceof Error?P.message:String(P))}},ko=async()=>{w("");try{const P=await Te.gitlabOAuthStart();jn(!0),oc(P.authorize_url,new URL(P.authorize_url).hostname,"/oauth/authorize")}catch(P){jn(!1),w(P instanceof Error?P.message:String(P))}},Cn=async P=>{if(!(Ze.current||!o.trim())){w(""),He("Walking what-if path…");try{const G=await Te.whatIf(o,P);Q(`${G.title} — ${G.confidence.level} · ${(G.sinks||[]).length} sinks`),Xt({...G,markdown:G.markdown||"",index:G.index||(p==null?void 0:p.index),workspace:G.workspace||(p==null?void 0:p.workspace)}),E("review"),r("review")}catch(G){w(G instanceof Error?G.message:String(G))}finally{He("")}}},_t=()=>{if(x){Xt(x),E("review"),r("review"),Q("Restored the last git-range walk");return}y(null),se(0),Ye(null),ct(null),Fn(null),E("architecture"),r("architecture"),Q("")},fi=async P=>{var Ie;if(Ze.current)return;It(P.provider,P.repo,String(P.number));const G=M.find(Re=>Re.slug.toLowerCase()===P.repo.toLowerCase());G!=null&&G.local_path&&rn(G.local_path),w(""),He(`Fetching ${P.provider} #${P.number}…`);const ce=(G==null?void 0:G.local_path)||o,Ce=ce?En(ce):()=>{};try{const Re=await Te.reviewPr(P.provider,P.repo,P.number,(G==null?void 0:G.local_path)||o||void 0);Xt(Re),Re.pull_request&&typeof Re.pull_request.repo_path=="string"&&rn(Re.pull_request.repo_path),on(String(Re.base||P.target_branch),String(Re.head||P.source_branch)),E("review"),r("review"),typeof((Ie=Re.pull_request)==null?void 0:Ie.repo_path)=="string"&&Gn(Re.pull_request.repo_path)}catch(Re){on(P.base_sha||P.target_branch,P.head_sha||P.source_branch),r("review"),w(Re instanceof Error?Re.message:String(Re))}finally{Ce(),He("")}},yt=async P=>{w("");try{V(await Te.oauthDisconnect(P)),z===P&&D([]),Q(`Disconnected ${P}`)}catch(G){w(G instanceof Error?G.message:String(G))}},hi=async P=>{P.preventDefault();const G=new FormData(P.currentTarget),ce={github_token:String(G.get("github_token")||""),github_oauth_client_id:String(G.get("github_oauth_client_id")||""),github_host:String(G.get("github_host")||""),gitlab_token:String(G.get("gitlab_token")||""),gitlab_host:String(G.get("gitlab_host")||""),gitlab_oauth_client_id:String(G.get("gitlab_oauth_client_id")||""),gitlab_oauth_client_secret:String(G.get("gitlab_oauth_client_secret")||""),bitbucket_token:String(G.get("bitbucket_token")||""),bitbucket_username:String(G.get("bitbucket_username")||""),bitbucket_oauth_client_id:String(G.get("bitbucket_oauth_client_id")||""),bitbucket_oauth_client_secret:String(G.get("bitbucket_oauth_client_secret")||""),ai_provider:String(G.get("ai_provider")||"none"),ai_api_key:String(G.get("ai_api_key")||""),ai_model:String(G.get("ai_model")||""),ai_base_url:String(G.get("ai_base_url")||"")},Ce=S.length?{...ce,workspaces:S.map(Ie=>({path:Ie.path,name:Ie.name}))}:ce;try{V(await Te.saveSettings(Ce)),Q("Settings saved on this machine")}catch(Ie){w(Ie instanceof Error?Ie.message:String(Ie))}},pi=async()=>{if(!(!p||Ze.current)){He("Residual analysis…");try{const P=await Te.residual(p);Ne(P.note)}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},Wr=L.useRef(Xn);Wr.current=Xn;const Mn=L.useRef(t);Mn.current=t;const qn=L.useRef(!1);qn.current=nt;const Pn=L.useRef(p);Pn.current=p;const qt=L.useRef(Z);qt.current=Z,L.useEffect(()=>{const P=localStorage.getItem("loadpath.lastReviewId"),G=(localStorage.getItem("loadpath.repo")||"").trim();if(!P||!G){ur(!1);return}let ce=!1;return Te.getReview(G,P).then(Ce=>{ce||(Xt(Ce),on(Ce.base||localStorage.getItem("loadpath.base")||"HEAD~1",Ce.head||localStorage.getItem("loadpath.head")||"HEAD"),Gn(G),wo(G))}).catch(()=>{}).finally(()=>{ce||ur(!1)}),()=>{ce=!0}},[]);const Ur=L.useRef("");L.useEffect(()=>{if(!et||!o.trim())return;let P=!1;const G=async()=>{try{const Ce=await Te.workspaceStatus(o);if(P)return;Ur.current&&Ce.fingerprint!==Ur.current&&!Ze.current&&(pe(!0),dr.current=!0,localStorage.setItem("loadpath.dirty","1"),Wr.current()),Ur.current=Ce.fingerprint}catch{}};G();const ce=window.setInterval(G,2e3);return()=>{P=!0,window.clearInterval(ce)}},[et,o]),L.useEffect(()=>{const P=G=>{var Ie;if((G.metaKey||G.ctrlKey)&&G.key.toLowerCase()==="k"){G.preventDefault(),lt(Re=>!Re);return}if(qn.current){G.key==="Escape"&&(G.preventDefault(),lt(!1));return}if(bn.current){G.key==="Escape"&&(G.preventDefault(),Le(!1));return}const ce=G.target;if(ce&&(ce.tagName==="INPUT"||ce.tagName==="TEXTAREA"||ce.tagName==="SELECT"||ce.isContentEditable)){G.key==="Escape"&&ce.blur();return}if(G.key==="Escape"){w(""),Q(""),Ye(wt),ct(null);return}if(G.key==="j"||G.key==="k"){const Re=((Ie=Pn.current)==null?void 0:Ie.read_order)||[];if(!Re.length)return;G.preventDefault();const xi=qt.current,mr=G.key==="j"?Math.min(Re.length-1,xi+1):Math.max(0,xi-1);se(mr);return}const Ce=rc.find(Re=>Re.shortcut===G.key);if(Ce&&!G.metaKey&&!G.ctrlKey&&!G.altKey&&r(Ce.id),(G.metaKey||G.ctrlKey)&&G.key==="Enter"){if(Mn.current==="settings"||Mn.current==="prs"||Ze.current)return;G.preventDefault(),Wr.current()}};return window.addEventListener("keydown",P),()=>window.removeEventListener("keydown",P)},[wt]);const Gr=async(P,G)=>{if(!o.trim())return;const ce=await WN(o,P,G);ce.ok?Q(ce.message):w(ce.message)},pr=async()=>{if(p)try{const P=await Te.exportHtml(p),G=URL.createObjectURL(P),ce=document.createElement("a");ce.href=G,ce.download=`loadpath-${(p.id||"review").slice(0,8)}.html`,ce.click(),URL.revokeObjectURL(G),Q("Saved HTML brief")}catch(P){w(P instanceof Error?P.message:String(P))}},Yr=async P=>{if(o.trim()){He("Loading stored review…");try{const G=await Te.getReview(o,P);Xt(G),on(G.base||a,G.head||c),E("review"),r("review");const ce=Mt.findIndex(Ie=>Ie.id===P),Ce=ce>=0?Mt[ce+1]:void 0;if(Ce)try{Fn(await Te.reviewDiff(o,P,Ce.id))}catch{Fn(null)}}catch(G){w(G instanceof Error?G.message:String(G))}finally{He("")}}},sn={selectedId:ut,onSelect:Ye,nodeRoles:p==null?void 0:p.node_roles,testOverlay:gt,isolateSource:Ct,onIsolate:ct,repoPath:o,onOpenFile:Gr,pinnedId:wt,onPin:Yt},Kn=[{id:"review",group:"Run",label:"Review this range",hint:"⌘/Ctrl+Enter",run:()=>void Xn()},...p!=null&&p.what_if?[{id:"exit-whatif",group:"Review",label:x?"Back to git-range walk":"Exit what-if walk",run:_t}]:[],{id:"index",group:"Run",label:"Index repository",run:()=>void fr(!0)},{id:"watch",group:"Run",label:et?"Stop watching working tree":"Watch working tree",run:()=>{const P=!et;On(P),localStorage.setItem("loadpath.watch",P?"1":"0")}},{id:"tests",group:"Graph",label:gt?"Hide test overlay":"Show test overlay",run:()=>{const P=!gt;mt(P),localStorage.setItem("loadpath.testOverlay",P?"1":"0")}},{id:"export",group:"Review",label:"Export HTML brief",run:()=>void pr()},...rc.map(P=>({id:`tab-${P.id}`,group:"Tabs",label:`Go to ${P.label}`,hint:P.shortcut,run:()=>r(P.id)})),...((p==null?void 0:p.nodes)||[]).slice(0,30).map(P=>({id:`node-${P.id}`,group:"Nodes",label:P.name,hint:li(P.type),run:()=>{Ye(P.id),r("graph")}})),...Mt.slice(0,12).map(P=>({id:`hist-${P.id}`,group:"History",label:P.title||P.id,hint:`${P.level||""} ${P.created_at||""}`.trim(),run:()=>void Yr(P.id)}))],No=L.useMemo(()=>b==="architecture"?(g==null?void 0:g.nodes)??[]:(p==null?void 0:p.nodes)??[],[b,g,p]),gr=L.useMemo(()=>b==="architecture"?(g==null?void 0:g.edges)??[]:(p==null?void 0:p.edges)??[],[b,g,p]),Fe=p!=null&&p.index?`${p.index.counts.nodes} nodes · ${p.index.counts.edges} edges`:g!=null&&g.indexed?`${g.counts.nodes} nodes · ${g.counts.edges} edges`:"Not indexed",_s=((p==null?void 0:p.findings)||[]).filter(P=>!P.waived);return d.jsxs("div",{className:"app",children:[d.jsx("a",{className:"skip",href:"#main",children:"Skip to content"}),d.jsxs("nav",{className:"rail","data-testid":"rail","aria-label":"Primary",children:[d.jsxs("div",{className:"brand",children:[d.jsx("div",{className:"brand-mark",children:"Loadpath"}),d.jsx("div",{className:"brand-sub",children:"Load-path review"})]}),rc.map(P=>{const G=P.icon,ce=t===P.id;return d.jsxs("button",{type:"button","data-testid":P.testId,className:ce?"nav-item active":"nav-item","aria-current":ce?"page":void 0,"aria-label":P.label,onClick:()=>r(P.id),children:[d.jsx(G,{}),d.jsx("span",{children:P.label})]},P.id)}),d.jsxs("div",{className:"theme-pick",children:[d.jsx("label",{htmlFor:"theme-select",children:"Theme"}),d.jsx("select",{id:"theme-select","data-testid":"theme-select",value:we,onChange:P=>xo(P.target.value),children:["dark","light"].map(P=>d.jsx("optgroup",{label:P==="dark"?"Dark":"Light",children:Qa.filter(G=>G.group===P).map(G=>d.jsx("option",{value:G.id,children:G.label},G.id))},P))})]}),d.jsxs("div",{className:"rail-foot",children:[d.jsx("div",{className:"muted",role:"status",children:j||Fe}),d.jsxs("div",{className:"kbd-hint",children:[d.jsx("kbd",{children:"1"}),"–",d.jsx("kbd",{children:"5"})," tabs · ",d.jsx("kbd",{children:"⌘"}),d.jsx("kbd",{children:"K"})," palette · ",d.jsx("kbd",{children:"j"}),"/",d.jsx("kbd",{children:"k"})," read order"]})]})]}),d.jsxs("div",{className:"main",id:"main",children:[j?d.jsxs("div",{className:$!=null?"progress determinate":"progress",role:$!=null?"progressbar":"status","aria-label":j,"aria-live":"polite","aria-busy":"true","aria-valuemin":$!=null?0:void 0,"aria-valuemax":$!=null?100:void 0,"aria-valuenow":$??void 0,"data-testid":"progress",children:[d.jsx("i",{style:$!=null?{width:`${$}%`}:void 0}),d.jsx("span",{className:"sr-only",children:j})]}):null,d.jsxs("header",{className:"topbar","data-testid":"topbar",children:[S.length>0?d.jsxs("label",{className:"field workspace",children:[d.jsx("span",{children:"Workspace"}),d.jsxs("select",{"data-testid":"workspace-select",value:S.some(P=>P.path===o)?o:"",disabled:!!j,"aria-busy":Y,onChange:P=>{P.target.value&&Br(P.target.value)},children:[d.jsx("option",{value:"",children:"Indexed repos…"}),S.map(P=>d.jsxs("option",{value:P.path,children:[P.name,P.indexed?` (${P.counts.nodes})`:""]},P.path))]})]}):null,d.jsxs("label",{className:"field path",children:[d.jsx("span",{children:"Repository"}),d.jsxs("div",{className:"path-row",children:[d.jsx("input",{"data-testid":"repo-path",placeholder:"Local monorepo path",value:o,onChange:P=>{const G=P.target.value;s(G),G.trim()!==Pt.current&&(Pt.current="",Ft(null))},spellCheck:!1}),d.jsx("button",{type:"button",className:"icon-btn","data-testid":"btn-browse-repo","aria-label":"Browse for a local repository",onClick:()=>Le(!0),children:d.jsx(Tp,{})})]})]}),d.jsxs("label",{className:"field ref",children:[d.jsx("span",{children:"Base"}),d.jsx(Mp,{testId:"base-ref",menuTestId:"base-ref-menu",value:a,onChange:P=>on(P,c),placeholder:"base",refs:cr,onNeedRefs:Hr})]}),d.jsxs("label",{className:"field ref",children:[d.jsx("span",{children:"Head"}),d.jsx(Mp,{testId:"head-ref",menuTestId:"head-ref-menu",value:c,onChange:P=>on(a,P),placeholder:"head",refs:cr,onNeedRefs:Hr})]}),d.jsxs("label",{className:"field dirty",children:[d.jsx("span",{children:"Working tree"}),d.jsx("button",{type:"button",className:he?"chip-btn active":"chip-btn","data-testid":"btn-dirty","aria-pressed":he,onClick:()=>{const P=!he;pe(P),localStorage.setItem("loadpath.dirty",P?"1":"0")},children:he?"Include uncommitted":"Committed range"})]}),d.jsxs("label",{className:"field dirty",children:[d.jsx("span",{children:"Watch"}),d.jsx("button",{type:"button",className:et?"chip-btn active":"chip-btn","data-testid":"btn-watch","aria-pressed":et,onClick:()=>{const P=!et;On(P),localStorage.setItem("loadpath.watch",P?"1":"0")},children:et?"Watching":"Paused"})]}),p?d.jsxs("div",{className:`merge-box compact ${p.confidence.level}`,"data-testid":"merge-box",children:[d.jsx("div",{className:`level ${p.confidence.level}`,children:p.confidence.level.toUpperCase()}),d.jsxs("div",{className:"muted",children:[p.what_if?"what-if · ":"",p.confidence.covered_sinks,"/",p.confidence.sinks," sinks"]})]}):null,d.jsxs("div",{className:"topbar-actions",children:[d.jsx("button",{type:"button","data-testid":"btn-init",disabled:!!j,onClick:Ve,children:"Draft config"}),d.jsx("button",{type:"button","data-testid":"btn-index",disabled:!!j,onClick:()=>fr(!0),children:"Index"}),d.jsx("button",{type:"button","data-testid":"btn-review",className:"btn primary",disabled:!!j,onClick:Xn,children:"Review"})]})]}),d.jsxs("div",{className:"alerts",children:[I?d.jsxs("div",{className:"error","data-testid":"error",role:"alert",children:[d.jsx("span",{children:I}),d.jsx("button",{type:"button",className:"dismiss",onClick:()=>w(""),"aria-label":"Dismiss error",children:"×"})]}):null,te?d.jsxs("div",{className:"banner","data-testid":"status-note",children:[d.jsx("span",{children:te}),d.jsx("button",{type:"button",className:"dismiss",onClick:()=>Q(""),"aria-label":"Dismiss",children:"×"})]}):null,((gi=p==null?void 0:p.index)!=null&&gi.stale||g!=null&&g.stale)&&(t==="review"||t==="architecture")?d.jsx("div",{className:"banner stale","data-testid":"index-stale",children:"Index is stale — files changed since the last extract. Index again before trusting this walk."}):null,((jo=p==null?void 0:p.index)==null?void 0:jo.django_boot)==="failed"||(g==null?void 0:g.django_boot)==="failed"?d.jsx("div",{className:"banner warn","data-testid":"django-boot-failed",children:((mi=p==null?void 0:p.index)==null?void 0:mi.django_boot_detail)||(g==null?void 0:g.django_boot_detail)||"django.setup() failed"}):null,(yi=p==null?void 0:p.workspace)!=null&&yi.dirty_overlaps_review&&t==="review"?d.jsxs("div",{className:"banner warn","data-testid":"dirty-tree",children:["Uncommitted files overlap this review: ",(p.workspace.dirty_overlap||[]).slice(0,6).join(", ")]}):null,p!=null&&p.what_if?d.jsxs("div",{className:"banner whatif","data-testid":"whatif-banner",children:[d.jsxs("span",{children:["Hypothetical walk from"," ",d.jsx("strong",{children:((vi=p.node)==null?void 0:vi.name)||"this node"}),". Loadpath ignored Base/Head and asked which sinks would feel this node change — not a filter of the current map."]}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-exit-whatif",onClick:_t,children:x?"Back to git range":"Back to architecture"})]}):null,Y?d.jsx("div",{className:"banner","data-testid":"workspace-loading",children:j||"Loading workspace…"}):null]}),d.jsxs("div",{className:"stage","aria-busy":Y||re,children:[t==="review"&&d.jsxs("div",{className:"content","data-testid":"review-layout",children:[d.jsx("aside",{className:"brief","data-testid":"brief",children:p?d.jsx(ij,{review:p,findings:_s,aiNote:me,busy:!!j,tourIndex:Z,onTour:se,onAskAi:pi,onCopy:ci,onPost:Vr,onSelect:Ye,onOpenFile:Gr,onExport:pr,history:Mt,diff:ui,onReopen:Yr,onWaiver:(P,G)=>{o.trim()&&Te.addWaiver(o,P,G||void 0,"from review").then(ce=>{lr(ce),Q(`Waived ${P} in loadpath.yml`)})}}):Fr?d.jsxs("div",{className:"empty","data-testid":"review-restoring",children:[d.jsx("h2",{children:"Restoring last review"}),d.jsx("p",{children:"Loading the walk this machine stored last time Loadpath was open."})]}):d.jsxs("div",{className:"empty","data-testid":"review-empty",children:[d.jsx("h2",{children:"Trace the force of this diff"}),d.jsx("p",{children:"The graph is the architecture. The brief is where this change travels — not a hunk list."}),d.jsxs("ol",{children:[d.jsx("li",{children:"Point at a Django + React monorepo, or pick an indexed workspace."}),d.jsxs("li",{children:["Index it. Missing ",d.jsx("code",{children:"loadpath.yml"})," is drafted from ",d.jsx("code",{children:"manage.py"})," and"," ",d.jsx("code",{children:"src/features"}),"."]}),d.jsx("li",{children:"Review a git range, or open a pull request so base/head become a three-dot merge-base."})]})]})}),d.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:p?d.jsx(nc,{nodes:p.nodes,edges:p.edges,onWhatIf:Cn,focusPath:(bo=p.read_order[Z])==null?void 0:bo.path,...sn}):null})]}),t==="architecture"&&d.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[d.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:g!=null&&g.indexed?d.jsx(sj,{architecture:g,busy:!!j,onReindex:()=>fr(!1),onReview:Xn,onSelect:Ye,config:vo,health:Or,onSaveConfig:P=>{Te.saveConfig(o,P).then(G=>{lr(G),Q("Wrote loadpath.yml")})},onWaiver:(P,G,ce)=>{Te.addWaiver(o,P,G,ce).then(Ce=>{lr(Ce),Q(`Waived ${P}`)})}}):Y?d.jsx("p",{className:"muted","data-testid":"architecture-loading",children:"Loading the index summary…"}):d.jsx("p",{className:"muted","data-testid":"architecture-empty",children:"Index this repo to build the architecture graph. Review then walks that same graph for a git range — it does not start from a hunk list."})}),d.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:(re||g!=null&&g.graph_pending)&&!((g==null?void 0:g.nodes)||[]).length?d.jsxs("div",{className:"empty graph-loading","data-testid":"graph-loading",children:[d.jsx("h2",{children:"Drawing the architecture map…"}),d.jsx("p",{children:(Xr=g==null?void 0:g.counts)!=null&&Xr.nodes?`${g.counts.nodes} indexed nodes. The brief is ready while the graph loads.`:"Fetching the indexed graph."})]}):g!=null&&g.indexed?d.jsx(nc,{nodes:g.nodes,edges:g.edges,onWhatIf:Cn,...sn,isolateSource:null,onIsolate:void 0}):null})]}),t==="graph"&&d.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%"},children:[d.jsxs("div",{className:"graph-modes",children:[d.jsxs("div",{className:"seg","aria-label":"Graph scope",children:[d.jsx("button",{type:"button","aria-pressed":b==="review","data-testid":"graph-mode-review",className:b==="review"?"active":"",onClick:()=>E("review"),children:"This review"}),d.jsx("button",{type:"button","aria-pressed":b==="architecture","data-testid":"graph-mode-architecture",className:b==="architecture"?"active":"",onClick:()=>E("architecture"),children:"Indexed architecture"})]}),d.jsxs("div",{className:"legend","aria-hidden":"true",children:[d.jsxs("span",{children:[d.jsx("i",{})," cheap"]}),d.jsxs("span",{children:[d.jsx("i",{className:"exp"})," expensive"]}),d.jsxs("span",{children:[d.jsx("i",{className:"crit"})," critical"]}),d.jsxs("span",{children:[d.jsx("i",{className:"dash"})," inferred"]}),d.jsxs("span",{children:[d.jsx("i",{className:"seed"})," changed"]}),d.jsxs("span",{children:[d.jsx("i",{className:"down"})," downstream"]})]}),d.jsx("button",{type:"button",className:gt?"chip-btn active":"chip-btn","data-testid":"graph-test-overlay","aria-pressed":gt,onClick:()=>{const P=!gt;mt(P),localStorage.setItem("loadpath.testOverlay",P?"1":"0")},children:"Tests"})]}),No.length?d.jsx(nc,{nodes:No,edges:gr,onWhatIf:Cn,...sn,...b==="architecture"?{isolateSource:null,onIsolate:void 0,nodeRoles:void 0,testOverlay:!1}:{}}):re||g!=null&&g.graph_pending?d.jsx("p",{className:"empty","data-testid":"graph-loading",children:"Drawing the architecture map…"}):d.jsx("p",{className:"empty","data-testid":"graph-empty",children:"Index the repo or run a review first. Click a node to inspect it."})]}),t==="prs"&&d.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[d.jsxs("div",{className:"pr-toolbar",children:[d.jsxs("label",{className:"field provider",children:[d.jsx("span",{children:"Provider"}),d.jsxs("select",{"data-testid":"pr-provider",value:z,onChange:P=>It(P.target.value,H,oe),children:[d.jsx("option",{value:"github",children:"GitHub"}),d.jsx("option",{value:"gitlab",children:"GitLab"}),d.jsx("option",{value:"bitbucket",children:"Bitbucket"})]})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Repository"}),d.jsx("input",{"data-testid":"pr-repo",placeholder:M.length?"Search your repos":"owner/repo",value:H,onChange:P=>It(z,P.target.value,oe),list:"scm-repos",spellCheck:!1}),d.jsx("datalist",{id:"scm-repos",children:M.map(P=>d.jsxs("option",{value:P.slug,children:[P.private?"private":"public",P.local_path?" · local":""]},P.slug))})]}),d.jsx("button",{type:"button","data-testid":"btn-refresh-repos",className:"btn",disabled:!!j||!_o(z),onClick:()=>{Rt(z)},children:"My repos"}),d.jsx("button",{type:"button","data-testid":"btn-list-prs",className:"btn",disabled:!!j,onClick:So,children:"List PRs"})]}),M.length>0?d.jsxs("p",{className:"muted scm-count","data-testid":"scm-repo-count",children:[M.length," ",z," repositor",M.length===1?"y":"ies",z==="github"&&C.github_user?` · @${String(C.github_user)}`:"",z==="gitlab"&&C.gitlab_user?` · @${String(C.gitlab_user)}`:"",z==="bitbucket"&&C.bitbucket_user?` · ${String(C.bitbucket_user)}`:""]}):null,W.length===0?d.jsxs("div",{className:"empty","data-testid":"pr-empty",children:[d.jsx("h2",{children:"No pull requests loaded"}),d.jsx("p",{children:"Sign in under Settings (or paste a token), load your repositories, then list open PRs. Reviewing a PR fills base and head from its SHAs."})]}):W.map(P=>{var G;return d.jsxs("article",{className:"pr","data-testid":`pr-${P.number}`,children:[d.jsxs("h3",{children:["#",P.number," ",P.title]}),d.jsxs("div",{className:"pr-meta muted",children:[d.jsx("span",{className:`chip ${P.draft?"":"open"}`,children:P.draft?"draft":P.state}),d.jsx("span",{children:P.author}),d.jsxs("span",{children:[P.source_branch," → ",P.target_branch]}),P.loadpath?d.jsxs("span",{className:`chip ${P.loadpath.level||""}`,"data-testid":`pr-loadpath-${P.number}`,children:[((G=P.loadpath.level)==null?void 0:G.toUpperCase())||"REVIEWED",P.loadpath.contract_break&&P.loadpath.contract_break!=="none"?` · ${P.loadpath.contract_break}`:""]}):d.jsx("span",{className:"muted",children:"no Loadpath walk yet"})]}),d.jsxs("div",{className:"pr-actions",children:[d.jsxs("a",{href:P.url,target:"_blank",rel:"noreferrer",children:["Open on ",P.provider]}),d.jsx("button",{type:"button",className:"btn primary","data-testid":`pr-review-${P.number}`,onClick:()=>void fi(P),children:"Review this PR"})]})]},`${P.provider}-${P.number}`)})]}),t==="settings"&&Pe&&d.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:hi,children:[d.jsxs("div",{children:[d.jsx("h1",{children:"Settings"}),d.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. AI runs only on residual uncertainty the graph could not close."})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Appearance"}),d.jsx("p",{className:"muted",children:"Local to this browser. High contrast is a first-class theme, not an afterthought."}),d.jsx("div",{className:"theme-grid","data-testid":"theme-grid",children:Qa.map(P=>d.jsxs("button",{type:"button","data-theme":P.id,className:we===P.id?"theme-swatch active":"theme-swatch","data-testid":`theme-${P.id}`,onClick:()=>xo(P.id),children:[d.jsx("div",{className:"swatch-bar","aria-hidden":"true"}),d.jsx("div",{className:"name",children:P.label}),d.jsx("div",{className:"group",children:P.group})]},P.id))})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Editor"}),d.jsx("p",{className:"muted",children:"Open files from the inspector and read-order in Cursor, VS Code, or the system handler."}),d.jsx("label",{htmlFor:"editor-pref",children:"Preferred editor"}),d.jsxs("select",{id:"editor-pref","data-testid":"editor-pref",defaultValue:Em(),onChange:P=>VN(P.target.value),children:[d.jsx("option",{value:"auto",children:"Auto (Cursor, then VS Code)"}),d.jsx("option",{value:"cursor",children:"Cursor"}),d.jsx("option",{value:"vscode",children:"VS Code"}),d.jsx("option",{value:"system",children:"System default"})]})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Source control"}),d.jsx("p",{className:"muted",children:"Sign in with OAuth to list every repository the account can access. Tokens stay in ~/.loadpath/settings.json. A classic PAT still works if you prefer not to register an OAuth app."}),d.jsxs("div",{className:"scm-login","data-testid":"scm-github",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"GitHub"}),d.jsx("p",{className:"muted",children:C.github_token_set?C.github_user?`Signed in as @${String(C.github_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.github_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-github-disconnect",onClick:()=>void yt("github"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-github-login",disabled:!!dt||!C.github_oauth_ready,onClick:()=>void hr(),children:dt?"Waiting for GitHub…":"Sign in with GitHub"})})]}),dt?d.jsxs("p",{className:"oauth-code","data-testid":"github-user-code",children:["Enter ",d.jsx("code",{children:dt.user_code})," at GitHub if the browser did not fill it in."]}):null,C.github_oauth_ready?null:d.jsx("p",{className:"muted",children:"Sign-in needs a GitHub OAuth App with Device Flow enabled. Set LOADPATH_GITHUB_CLIENT_ID or paste the client ID below."}),d.jsx("label",{htmlFor:"github_oauth_client_id",children:"GitHub OAuth client ID"}),d.jsx("input",{id:"github_oauth_client_id",name:"github_oauth_client_id","data-testid":"github-oauth-client-id",placeholder:"Ov23…",defaultValue:String(C.github_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"github_token",children:"GitHub token (optional PAT)"}),d.jsx("input",{id:"github_token",name:"github_token",type:"password",placeholder:"ghp_…",autoComplete:"off"}),d.jsx("label",{htmlFor:"github_host",children:"GitHub host (Enterprise)"}),d.jsx("input",{id:"github_host",name:"github_host","data-testid":"github-host",placeholder:"github.com",defaultValue:String(C.github_host||""),autoComplete:"off"}),d.jsxs("div",{className:"scm-login","data-testid":"scm-gitlab",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"GitLab"}),d.jsx("p",{className:"muted",children:C.gitlab_token_set?C.gitlab_user?`Signed in as @${String(C.gitlab_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.gitlab_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-gitlab-disconnect",onClick:()=>void yt("gitlab"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-gitlab-login",disabled:Wn||!C.gitlab_oauth_ready,onClick:()=>void ko(),children:Wn?"Waiting for GitLab…":"Sign in with GitLab"})})]}),d.jsx("label",{htmlFor:"gitlab_host",children:"GitLab host"}),d.jsx("input",{id:"gitlab_host",name:"gitlab_host","data-testid":"gitlab-host",placeholder:"gitlab.com",defaultValue:String(C.gitlab_host||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_oauth_client_id",children:"GitLab OAuth application ID"}),d.jsx("input",{id:"gitlab_oauth_client_id",name:"gitlab_oauth_client_id","data-testid":"gitlab-oauth-client-id",defaultValue:String(C.gitlab_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_oauth_client_secret",children:"GitLab OAuth secret"}),d.jsx("input",{id:"gitlab_oauth_client_secret",name:"gitlab_oauth_client_secret",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_token",children:"GitLab token (optional PAT)"}),d.jsx("input",{id:"gitlab_token",name:"gitlab_token",type:"password",placeholder:"glpat-…",autoComplete:"off"}),d.jsxs("div",{className:"scm-login","data-testid":"scm-bitbucket",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"Bitbucket"}),d.jsx("p",{className:"muted",children:C.bitbucket_token_set?C.bitbucket_user?`Signed in as ${String(C.bitbucket_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.bitbucket_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-bitbucket-disconnect",onClick:()=>void yt("bitbucket"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-bitbucket-login",disabled:Vn||!C.bitbucket_oauth_ready,onClick:()=>void di(),children:Vn?"Waiting for Bitbucket…":"Sign in with Bitbucket"})})]}),C.bitbucket_oauth_ready?null:d.jsxs("p",{className:"muted",children:["Sign-in needs a Bitbucket OAuth consumer (key + secret). Callback URL:"," ",d.jsx("code",{children:"/api/oauth/bitbucket/callback"})," on this app origin."]}),d.jsx("label",{htmlFor:"bitbucket_oauth_client_id",children:"Bitbucket OAuth key"}),d.jsx("input",{id:"bitbucket_oauth_client_id",name:"bitbucket_oauth_client_id","data-testid":"bitbucket-oauth-client-id",defaultValue:String(C.bitbucket_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_oauth_client_secret",children:"Bitbucket OAuth secret"}),d.jsx("input",{id:"bitbucket_oauth_client_secret",name:"bitbucket_oauth_client_secret",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_token",children:"Bitbucket token (optional app password)"}),d.jsx("input",{id:"bitbucket_token",name:"bitbucket_token",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_username",children:"Bitbucket username (app passwords)"}),d.jsx("input",{id:"bitbucket_username",name:"bitbucket_username",defaultValue:String(C.bitbucket_username||"")})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Residual AI"}),d.jsx("label",{htmlFor:"ai_provider",children:"Provider"}),d.jsxs("select",{id:"ai_provider",name:"ai_provider",defaultValue:String(((an=C.ai)==null?void 0:an.provider)||"none"),children:[d.jsx("option",{value:"none",children:"none (graph only)"}),d.jsx("option",{value:"anthropic",children:"Anthropic"}),d.jsx("option",{value:"openai",children:"OpenAI"}),d.jsx("option",{value:"grok",children:"Grok / xAI"}),d.jsx("option",{value:"deepseek",children:"DeepSeek"}),d.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),d.jsx("option",{value:"ollama",children:"Ollama local"})]}),d.jsx("label",{htmlFor:"ai_api_key",children:"API key"}),d.jsx("input",{id:"ai_api_key",name:"ai_api_key",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"ai_model",children:"Model"}),d.jsx("input",{id:"ai_model",name:"ai_model","data-testid":"ai-model",placeholder:"optional override",defaultValue:String(((ln=C.ai)==null?void 0:ln.model)||"")}),d.jsx("label",{htmlFor:"ai_base_url",children:"Base URL"}),d.jsx("input",{id:"ai_base_url",name:"ai_base_url","data-testid":"ai-base-url",placeholder:"optional, OpenAI-compatible",defaultValue:String(((un=C.ai)==null?void 0:un.base_url)||"")}),d.jsx("button",{className:"btn primary",type:"submit","data-testid":"btn-save-settings",children:"Save"})]})]})]})]}),d.jsx(x0,{open:nt,actions:Kn,onClose:()=>lt(!1)}),je?d.jsx(KN,{initialPath:o,onClose:()=>Le(!1),onSelect:P=>{if(Ze.current){w("Wait for the current job to finish before switching workspace.");return}Le(!1),Br(P)}}):null]})}function ij({review:t,findings:r,aiNote:o,busy:s,tourIndex:a,onTour:u,onAskAi:c,onCopy:h,onPost:p,onSelect:y,onOpenFile:x,onExport:v,history:g,diff:_,onReopen:S,onWaiver:N}){var E,I,w,j,A,$,F,Y,q,re,J,te,Q,C,V,W,U;const b=[...new Set(t.confidence.reasons||[])];return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:`merge-box ${t.confidence.level}`,children:[d.jsxs("div",{className:`level ${t.confidence.level}`,children:[t.confidence.level.toUpperCase()," — ",t.title]}),b.length?d.jsx("ul",{className:"reasons",children:b.map(M=>d.jsx("li",{children:M},M))}):null,t.what_if?d.jsx("span",{className:"chip whatif","data-testid":"whatif-chip",children:"what-if"}):null,t.low_risk?d.jsx("span",{className:"chip",children:"low-risk"}):null,t.change_kinds.map(M=>d.jsx("span",{className:"chip",children:ns(M)},M)),(E=t.contract_break)!=null&&E.kind&&t.contract_break.kind!=="none"?d.jsxs("span",{className:`chip ${t.contract_break.kind==="breaking"?"blocker":""}`,"data-testid":"contract-kind",children:["contract ",t.contract_break.kind]}):null]}),d.jsxs("div",{className:"metrics",children:[d.jsxs("div",{className:"metric",children:[d.jsxs("div",{className:"n",children:[t.confidence.covered_sinks,"/",t.confidence.sinks]}),d.jsx("div",{className:"l",children:"Sinks tested"})]}),d.jsxs("div",{className:"metric",children:[d.jsx("div",{className:"n",children:r.length}),d.jsx("div",{className:"l",children:"Findings"})]}),d.jsxs("div",{className:"metric",children:[d.jsx("div",{className:"n",children:t.residuals.length}),d.jsx("div",{className:"l",children:"Residuals"})]})]}),d.jsx("pre",{className:"headline",children:t.headline}),(t.checklist||[]).length?d.jsxs("details",{className:"section",open:!0,"data-testid":"merge-checklist",children:[d.jsxs("summary",{children:["Merge checklist"," ",d.jsx("span",{className:"count",children:(t.checklist||[]).filter(M=>M.status==="todo").length})]}),(t.checklist||[]).map(M=>d.jsxs("div",{className:`check-item ${M.status}`,children:[d.jsxs("button",{type:"button",className:"linkish",onClick:()=>M.node_id&&y(M.node_id),children:[d.jsx("span",{className:`chip ${M.status}`,children:M.status}),M.title]}),M.detail?d.jsx("div",{className:"why",children:M.detail}):null,M.body?d.jsx("button",{type:"button",className:"btn",onClick:()=>{navigator.clipboard.writeText(M.body||"")},children:"Copy test"}):null,M.kind==="finding"&&M.status==="todo"&&M.rule?d.jsx("button",{type:"button",className:"btn",onClick:()=>N(M.rule,M.node_id),children:"Waive in loadpath.yml"}):null]},M.id))]}):null,t.index?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Index ",d.jsx("span",{className:"count",children:t.index.counts.nodes})]}),d.jsxs("div",{className:"muted",children:["Walked ",t.index.counts.nodes," nodes / ",t.index.counts.edges," edges",t.index.reindex_skipped?" from an unchanged index":t.index.reindexed?" after an incremental refresh":" from the existing index",t.index.django_boot&&t.index.django_boot!=="off"?` · Django boot ${t.index.django_boot}`:"",(I=t.workspace)!=null&&I.three_dot?" · three-dot range":""]})]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Read this ",d.jsx("span",{className:"count",children:t.read_order.length})]}),t.read_order.map((M,D)=>d.jsxs("div",{className:D===a?"read-item tour-current":"read-item",children:[d.jsxs("button",{type:"button",className:"linkish file",onClick:()=>u(D),children:[D+1,". ",M.path]}),d.jsx("div",{className:"why",children:M.why}),d.jsx("button",{type:"button",className:"btn",onClick:()=>x(M.path),children:"Open"})]},M.path)),t.read_order.length>0?d.jsxs("div",{className:"btn-row tour-row",children:[d.jsx("button",{type:"button",className:"btn","data-testid":"btn-tour-prev",disabled:a<=0,onClick:()=>u(Math.max(0,a-1)),children:"Previous"}),d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-tour-next",disabled:a>=t.read_order.length-1,onClick:()=>u(Math.min(t.read_order.length-1,a+1)),children:"Next in read order"}),d.jsxs("span",{className:"muted",children:[a+1,"/",t.read_order.length]})]}):null]}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Clusters ",d.jsx("span",{className:"count",children:t.clusters.length})]}),t.clusters.map(M=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:M.title})," — ",M.files.join(", ")]},M.id))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Architecture ",d.jsx("span",{className:"count",children:r.length})]}),r.length===0?d.jsx("div",{className:"muted",children:t.architecture_note}):r.map(M=>d.jsx("div",{className:"finding",children:d.jsxs("button",{type:"button",className:"linkish",onClick:()=>M.node_id&&y(M.node_id),children:[d.jsx("span",{className:`chip ${M.severity}`,children:M.severity}),M.message]})},M.rule+M.message))]}),d.jsx(Im,{cards:t.deepening}),(j=(w=t.contract_break)==null?void 0:w.reasons)!=null&&j.length?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Contract ",d.jsx("span",{className:"count",children:t.contract_break.kind})]}),t.contract_break.reasons.map(M=>d.jsx("div",{className:"muted",children:M},M)),($=(A=t.contract_break.sides)==null?void 0:A.rows)!=null&&$.length?d.jsxs("table",{className:"type-table","data-testid":"contract-sides",children:[d.jsx("thead",{children:d.jsxs("tr",{children:[d.jsx("th",{children:"Field"}),d.jsx("th",{children:"Serializer"}),d.jsx("th",{children:"Zod"}),d.jsx("th",{children:"GraphQL"})]})}),d.jsx("tbody",{children:t.contract_break.sides.rows.map(M=>d.jsxs("tr",{className:M.status,children:[d.jsx("td",{children:M.field}),d.jsx("td",{children:M.serializer?"yes":"—"}),d.jsx("td",{children:M.zod?"yes":"—"}),d.jsx("td",{children:M.graphql?"yes":"—"})]},M.field))})]}):null]}):null,(F=t.auth)!=null&&F.note?d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Auth"}),d.jsx("div",{className:"muted",children:t.auth.note}),(t.auth.missing_permissions||[]).map(M=>d.jsxs("div",{className:"finding",children:[d.jsx("span",{className:"chip warning",children:"missing"}),M.name]},M.id))]}):null,(t.suggested_tests||[]).length?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Suggested tests ",d.jsx("span",{className:"count",children:(Y=t.suggested_tests)==null?void 0:Y.length})]}),(t.suggested_tests||[]).map(M=>d.jsxs("div",{className:"residual",children:[d.jsx("strong",{children:M.title}),d.jsx("pre",{className:"headline",children:M.body}),d.jsx("button",{type:"button",className:"btn",onClick:()=>{navigator.clipboard.writeText(M.body)},children:"Copy sketch"})]},M.title))]}):null,(q=t.trend)!=null&&q.note?d.jsxs("details",{className:"section",children:[d.jsx("summary",{children:"Confidence trend"}),d.jsx("div",{className:"muted",children:t.trend.note}),(t.trend.points||[]).slice(0,6).map(M=>d.jsxs("div",{className:"muted",children:[M.level," · ",ic(M.created_at),M.sinks!=null?` · ${M.sinks} sinks`:""]},M.id))]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Residual ",d.jsx("span",{className:"count",children:t.residuals.length})]}),d.jsx("p",{className:"muted",children:"AI is only used here, on what the graph could not close."}),t.residuals.map(M=>d.jsx("div",{className:"residual muted",children:M},M))]}),g.length?d.jsxs("details",{className:"section","data-testid":"review-history",children:[d.jsxs("summary",{children:["History ",d.jsx("span",{className:"count",children:g.length})]}),_?d.jsx("div",{className:"muted",children:_.note}):null,g.slice(0,12).map(M=>d.jsxs("button",{type:"button",className:M.id===t.id?"history-item current":"history-item",onClick:()=>S(M.id),children:[d.jsx("span",{className:`chip ${M.level||""}`,children:M.level||"walk"}),M.title||M.id.slice(0,8),d.jsx("span",{className:"muted",children:M.created_at?ic(M.created_at):""})]},M.id))]}):null,(J=(re=t.evolution)==null?void 0:re.notes)!=null&&J.length||(Q=(te=t.evolution)==null?void 0:te.hotspots)!=null&&Q.some(M=>M.commits)?d.jsxs("details",{className:"section",children:[d.jsx("summary",{children:"Churn & coupling"}),(((C=t.evolution)==null?void 0:C.notes)||[]).map(M=>d.jsx("div",{className:"muted",children:M},M)),(((V=t.evolution)==null?void 0:V.hotspots)||[]).filter(M=>M.commits).slice(0,6).map(M=>d.jsxs("div",{className:"muted",children:[d.jsx("span",{className:"file",children:M.path})," — ",M.commits," commits, bus factor ",M.bus_factor]},M.path))]}):null,d.jsxs("div",{className:"btn-row",children:[d.jsx("button",{type:"button",className:"btn",disabled:s,onClick:c,children:"Ask configured model"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-copy-markdown",onClick:h,children:"Copy markdown"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-export-html",onClick:v,children:"Save HTML"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-post-comment",disabled:s||!!t.what_if,title:t.what_if?"Hypothetical walks are not posted to a pull request":void 0,onClick:p,children:"Post to PR"})]}),o?d.jsx("pre",{className:"headline",children:o}):null,d.jsx("div",{className:"kicker",children:"Reviewers"}),d.jsx("div",{className:"muted",children:t.suggested_reviewers.join(", ")||"—"}),(W=t.codeowners_reviewers)!=null&&W.length?d.jsxs("div",{className:"muted",children:["CODEOWNERS: ",t.codeowners_reviewers.join(", ")]}):null,(U=t.knowledge_owners)!=null&&U.length?d.jsxs("div",{className:"muted",children:["Knowledge: ",t.knowledge_owners.join(", ")]}):null]})}function sj({architecture:t,busy:r,onReindex:o,onReview:s,onSelect:a,config:u,health:c,onSaveConfig:h,onWaiver:p}){var x;const y=t.findings.filter(v=>!v.waived);return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:"merge-box high",children:[d.jsxs("div",{className:"level high",children:["INDEXED — ",t.counts.nodes," nodes"]}),d.jsxs("div",{className:"muted",style:{marginTop:8},children:[t.indexed_at?`Last index ${ic(t.indexed_at)}`:"Indexed",t.incremental?" · incremental":" · full",t.stale?" · stale":"",t.django_boot&&t.django_boot!=="off"?` · Django boot ${t.django_boot}`:""]}),d.jsxs("span",{className:"chip",children:[t.counts.edges," edges"]}),t.has_config?d.jsx("span",{className:"chip",children:"loadpath.yml"}):null]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Bounded contexts"}),Object.values(t.contexts).map(v=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:v.name})," — ",(v.django_apps||[]).join(", ")||"no apps"," ·"," ",(v.owners||[]).join(", ")||"unowned"]},v.name))]}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Rules ",d.jsx("span",{className:"count",children:(t.rules||[]).length})]}),(t.rules||[]).map(v=>d.jsx("div",{className:"muted",children:v},v))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Findings ",d.jsx("span",{className:"count",children:y.length})]}),y.length===0?d.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):y.map(v=>d.jsx("div",{className:"finding",children:d.jsxs("button",{type:"button",className:"linkish",onClick:()=>v.node_id&&a(v.node_id),children:[d.jsx("span",{className:`chip ${v.severity}`,children:v.severity}),v.message]})},v.rule+v.message))]}),d.jsx(Im,{cards:t.deepening}),(x=c==null?void 0:c.points)!=null&&x.length?d.jsxs("details",{className:"section",open:!0,"data-testid":"architecture-health",children:[d.jsxs("summary",{children:["Health over time ",d.jsx("span",{className:"count",children:c.points.length})]}),d.jsx("div",{className:"sparkline","aria-hidden":"true",children:c.points.map(v=>d.jsx("i",{className:v.level||"",title:`${v.level} · ${v.findings} findings`,style:{height:`${8+Math.min(24,(v.findings||0)*4)}px`}},v.id||v.created_at))}),Object.entries(c.contexts).map(([v,g])=>{var _;return d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:v})," — last ",((_=g[g.length-1])==null?void 0:_.findings)??0," findings"]},v)})]}):null,u?d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"loadpath.yml"}),d.jsx(w0,{config:u,busy:r,onSave:h,onWaiver:p})]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Types"}),d.jsx("table",{className:"type-table",children:d.jsx("tbody",{children:Object.entries(t.type_counts||{}).sort((v,g)=>g[1]-v[1]).slice(0,12).map(([v,g])=>d.jsxs("tr",{children:[d.jsx("td",{children:li(v)}),d.jsx("td",{children:g})]},v))})})]}),d.jsxs("div",{className:"btn-row",children:[d.jsx("button",{type:"button",className:"btn",disabled:r,onClick:o,"data-testid":"btn-full-reindex",children:"Full reindex"}),d.jsx("button",{type:"button",className:"btn primary",disabled:r,onClick:s,children:"Review against this index"})]})]})}function Im({cards:t}){const r=t||[];return r.length?d.jsxs("details",{className:"section",open:!0,"data-testid":"deepening-list",children:[d.jsxs("summary",{children:["Depth ",d.jsx("span",{className:"count",children:r.length})]}),d.jsx("p",{className:"muted",children:"Deepening opportunities: more behaviour behind a smaller interface, at a real seam."}),r.map(o=>d.jsxs("div",{className:"finding","data-testid":"deepening-card",children:[d.jsx("span",{className:`chip ${o.strength}`,children:_0(o.strength)}),o.top?d.jsx("span",{className:"chip",children:"top"}):null,d.jsx("strong",{children:o.title}),d.jsx("div",{className:"why",children:o.message}),o.deletion_test?d.jsxs("div",{className:"muted",children:["Deletion test: ",o.deletion_test]}):null,o.before&&o.after?d.jsxs("div",{className:"muted",children:[o.before," → ",o.after]}):null]},o.rule+o.title))]}):null}Pm(Mm());m0.createRoot(document.getElementById("root")).render(d.jsx(L.StrictMode,{children:d.jsx(oj,{})}));export{Kk as L,uj as a,aj as c,d as j,lj as l,L as r,li as t}; diff --git a/src/loadpath/static/assets/index-DCcHASmi.css b/src/loadpath/static/assets/index-CdW5Vb1S.css similarity index 68% rename from src/loadpath/static/assets/index-DCcHASmi.css rename to src/loadpath/static/assets/index-CdW5Vb1S.css index 0bba5ec..e233d8e 100644 --- a/src/loadpath/static/assets/index-DCcHASmi.css +++ b/src/loadpath/static/assets/index-CdW5Vb1S.css @@ -1 +1 @@ -.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #555;--xy-background-pattern-lines-color-default: #333;--xy-background-pattern-cross-color-default: #333;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}:root,[data-theme=obsidian]{--bg: #070b10;--bg-2: #0d141c;--surface: #121a24;--line: #1e2c3c;--ink: #e7eef6;--muted: #8b9bb0;--high: #2a9d8f;--medium: #e9c46a;--low: #e76f51;--critical: #e85d04;--accent: #4cc9f0;--rail-from: #0b1219;--rail-to: #070b10;--rail-active: #15202c;--btn: #173044;--btn-line: #24506c;--btn-primary: #134e4a;--btn-primary-line: #2a9d8f;--node-bg: #101822;--node-line: #2a3d52;--graph-bg: #070b10;--graph-grid: rgba(42, 80, 120, .09);--edge-cheap: #4a5568;--edge-expensive: #f4a261;--edge-critical: #e85d04;--shadow: rgba(76, 201, 240, .08)}[data-theme=nord]{--bg: #2e3440;--bg-2: #3b4252;--surface: #434c5e;--line: #4c566a;--ink: #eceff4;--muted: #d8dee9;--high: #a3be8c;--medium: #ebcb8b;--low: #bf616a;--critical: #d08770;--accent: #88c0d0;--rail-from: #3b4252;--rail-to: #2e3440;--rail-active: #4c566a;--btn: #434c5e;--btn-line: #81a1c1;--btn-primary: #5e81ac;--btn-primary-line: #88c0d0;--node-bg: #3b4252;--node-line: #81a1c1;--graph-bg: #2e3440;--graph-grid: rgba(136, 192, 208, .12);--edge-cheap: #4c566a;--edge-expensive: #d08770;--edge-critical: #bf616a;--shadow: rgba(136, 192, 208, .12)}[data-theme=solarized-dark]{--bg: #002b36;--bg-2: #073642;--surface: #0a3944;--line: #16444f;--ink: #eee8d5;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #2aa198;--rail-from: #073642;--rail-to: #002b36;--rail-active: #16444f;--btn: #073642;--btn-line: #268bd2;--btn-primary: #0a4a42;--btn-primary-line: #2aa198;--node-bg: #073642;--node-line: #268bd2;--graph-bg: #002b36;--graph-grid: rgba(42, 161, 152, .12);--edge-cheap: #586e75;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(42, 161, 152, .12)}[data-theme=forest]{--bg: #0e1510;--bg-2: #152019;--surface: #1b2a20;--line: #2c4334;--ink: #e4f0e6;--muted: #8eaa96;--high: #6ab04c;--medium: #c8a951;--low: #e17055;--critical: #d35400;--accent: #7bed9f;--rail-from: #152019;--rail-to: #0e1510;--rail-active: #1f3326;--btn: #1f3326;--btn-line: #3d6b4f;--btn-primary: #1e4d32;--btn-primary-line: #6ab04c;--node-bg: #16241b;--node-line: #3d6b4f;--graph-bg: #0e1510;--graph-grid: rgba(123, 237, 159, .1);--edge-cheap: #3d6b4f;--edge-expensive: #c8a951;--edge-critical: #d35400;--shadow: rgba(123, 237, 159, .1)}[data-theme=rose]{--bg: #191724;--bg-2: #1f1d2e;--surface: #26233a;--line: #403d52;--ink: #e0def4;--muted: #908caa;--high: #9ccfd8;--medium: #f6c177;--low: #eb6f92;--critical: #eb6f92;--accent: #c4a7e7;--rail-from: #1f1d2e;--rail-to: #191724;--rail-active: #26233a;--btn: #26233a;--btn-line: #c4a7e7;--btn-primary: #3a2f4d;--btn-primary-line: #c4a7e7;--node-bg: #1f1d2e;--node-line: #524f67;--graph-bg: #191724;--graph-grid: rgba(196, 167, 231, .12);--edge-cheap: #524f67;--edge-expensive: #f6c177;--edge-critical: #eb6f92;--shadow: rgba(196, 167, 231, .12)}[data-theme=amber]{--bg: #120e0a;--bg-2: #1c1610;--surface: #261e16;--line: #3d2f22;--ink: #f4e6d0;--muted: #b59a78;--high: #c4d6a0;--medium: #e9b44c;--low: #d8572a;--critical: #c0392b;--accent: #f0a05a;--rail-from: #1c1610;--rail-to: #120e0a;--rail-active: #2b2218;--btn: #2b2218;--btn-line: #8a5a2b;--btn-primary: #4a3418;--btn-primary-line: #f0a05a;--node-bg: #1c1610;--node-line: #8a5a2b;--graph-bg: #120e0a;--graph-grid: rgba(240, 160, 90, .12);--edge-cheap: #5c4a38;--edge-expensive: #e9b44c;--edge-critical: #d8572a;--shadow: rgba(240, 160, 90, .12)}[data-theme=volcano]{--bg: #14090a;--bg-2: #1e0e10;--surface: #2a1416;--line: #4a2226;--ink: #fde8e4;--muted: #c48b86;--high: #7bed9f;--medium: #f6c90e;--low: #ff6b6b;--critical: #ff3b3b;--accent: #ff7b54;--rail-from: #1e0e10;--rail-to: #14090a;--rail-active: #32181b;--btn: #32181b;--btn-line: #ff7b54;--btn-primary: #5a1f18;--btn-primary-line: #ff7b54;--node-bg: #1e0e10;--node-line: #7a3330;--graph-bg: #14090a;--graph-grid: rgba(255, 123, 84, .12);--edge-cheap: #5a3330;--edge-expensive: #ff7b54;--edge-critical: #ff3b3b;--shadow: rgba(255, 123, 84, .14)}[data-theme=lavender]{--bg: #12101c;--bg-2: #1a1730;--surface: #221e3c;--line: #3b3560;--ink: #efeaff;--muted: #b3a7d6;--high: #80ffdb;--medium: #ffd166;--low: #ff6b9d;--critical: #ff4d6d;--accent: #c77dff;--rail-from: #1a1730;--rail-to: #12101c;--rail-active: #2a2550;--btn: #2a2550;--btn-line: #c77dff;--btn-primary: #3d2a66;--btn-primary-line: #c77dff;--node-bg: #1a1730;--node-line: #5a4d8a;--graph-bg: #12101c;--graph-grid: rgba(199, 125, 255, .12);--edge-cheap: #5a4d8a;--edge-expensive: #ffd166;--edge-critical: #ff4d6d;--shadow: rgba(199, 125, 255, .14)}[data-theme=neon-noir]{--bg: #05060a;--bg-2: #0a0c14;--surface: #10131c;--line: #1e2436;--ink: #f0f4ff;--muted: #8b93b0;--high: #39ff88;--medium: #ffe66d;--low: #ff2d95;--critical: #ff3d5a;--accent: #00f0ff;--rail-from: #0a0c14;--rail-to: #05060a;--rail-active: #151a2a;--btn: #151a2a;--btn-line: #00f0ff;--btn-primary: #063a40;--btn-primary-line: #00f0ff;--node-bg: #0a0c14;--node-line: #2a3550;--graph-bg: #05060a;--graph-grid: rgba(0, 240, 255, .12);--edge-cheap: #3a4560;--edge-expensive: #ff2d95;--edge-critical: #ff3d5a;--shadow: rgba(0, 240, 255, .22)}[data-theme=synthwave]{--bg: #1a0a2e;--bg-2: #240b3d;--surface: #2d1250;--line: #4a1d7a;--ink: #ffe6fb;--muted: #c49ad8;--high: #00f5d4;--medium: #ffd60a;--low: #ff6b9d;--critical: #ff006e;--accent: #ff2bd6;--rail-from: #240b3d;--rail-to: #1a0a2e;--rail-active: #3a1570;--btn: #3a1570;--btn-line: #ff2bd6;--btn-primary: #5a0a4a;--btn-primary-line: #ff2bd6;--node-bg: #240b3d;--node-line: #7b2cbf;--graph-bg: #1a0a2e;--graph-grid: rgba(255, 43, 214, .16);--edge-cheap: #5a3a80;--edge-expensive: #ff9e00;--edge-critical: #ff006e;--shadow: rgba(255, 43, 214, .24)}[data-theme=phosphor]{--bg: #020804;--bg-2: #061208;--surface: #0a1a0e;--line: #163c1e;--ink: #c8ffc8;--muted: #5aaa5a;--high: #39ff14;--medium: #c8f542;--low: #ffb000;--critical: #ff5e00;--accent: #00ff66;--rail-from: #061208;--rail-to: #020804;--rail-active: #0e2414;--btn: #0e2414;--btn-line: #00ff66;--btn-primary: #0a3a18;--btn-primary-line: #00ff66;--node-bg: #061208;--node-line: #1e6a32;--graph-bg: #020804;--graph-grid: rgba(0, 255, 102, .12);--edge-cheap: #1e5a2a;--edge-expensive: #c8f542;--edge-critical: #ff5e00;--shadow: rgba(0, 255, 102, .2)}[data-theme=aurora]{--bg: #071018;--bg-2: #0c1c28;--surface: #122636;--line: #1e3d52;--ink: #e8fff6;--muted: #7eb8a8;--high: #5fffcf;--medium: #ffe566;--low: #ff7eb6;--critical: #ff4d6d;--accent: #7cffb2;--rail-from: #0c1c28;--rail-to: #071018;--rail-active: #163044;--btn: #163044;--btn-line: #7cffb2;--btn-primary: #0e3d3a;--btn-primary-line: #7cffb2;--node-bg: #0c1c28;--node-line: #2a6a78;--graph-bg: #071018;--graph-grid: rgba(124, 255, 178, .12);--edge-cheap: #2a5a68;--edge-expensive: #c9a0ff;--edge-critical: #ff4d6d;--shadow: rgba(124, 255, 178, .18)}[data-theme=biolume]{--bg: #02141c;--bg-2: #042430;--surface: #073040;--line: #0a4a5c;--ink: #e6fffb;--muted: #6eb8b0;--high: #5dffb0;--medium: #ffe066;--low: #ff79c6;--critical: #ff4d6d;--accent: #18e7d4;--rail-from: #042430;--rail-to: #02141c;--rail-active: #0a3848;--btn: #0a3848;--btn-line: #18e7d4;--btn-primary: #0a4a48;--btn-primary-line: #18e7d4;--node-bg: #042430;--node-line: #1a7080;--graph-bg: #02141c;--graph-grid: rgba(24, 231, 212, .12);--edge-cheap: #1a5a68;--edge-expensive: #ff79c6;--edge-critical: #ff4d6d;--shadow: rgba(24, 231, 212, .2)}[data-theme=carbon]{--bg: #0d0d0f;--bg-2: #16161a;--surface: #1e1e24;--line: #33333c;--ink: #f2f2f4;--muted: #9a9aa8;--high: #3dd68c;--medium: #f0c040;--low: #ff5a5a;--critical: #ff2a2a;--accent: #ff2a2a;--rail-from: #16161a;--rail-to: #0d0d0f;--rail-active: #24242c;--btn: #24242c;--btn-line: #ff2a2a;--btn-primary: #4a1212;--btn-primary-line: #ff2a2a;--node-bg: #16161a;--node-line: #4a4a55;--graph-bg: #0d0d0f;--graph-grid: rgba(255, 42, 42, .1);--edge-cheap: #4a4a55;--edge-expensive: #ff8a3d;--edge-critical: #ff2a2a;--shadow: rgba(255, 42, 42, .18)}[data-theme=paper]{--bg: #f6f1e8;--bg-2: #efe6d6;--surface: #fffaf2;--line: #d9cbb6;--ink: #2b241c;--muted: #6f6456;--high: #2a7a4b;--medium: #b5811a;--low: #c0392b;--critical: #a93226;--accent: #1d6a7a;--rail-from: #efe6d6;--rail-to: #e7dcc8;--rail-active: #e2d3bb;--btn: #fffaf2;--btn-line: #c9b79a;--btn-primary: #d7eee0;--btn-primary-line: #2a7a4b;--node-bg: #fffaf2;--node-line: #c9b79a;--graph-bg: #f6f1e8;--graph-grid: rgba(29, 106, 122, .1);--edge-cheap: #b7a48c;--edge-expensive: #c0392b;--edge-critical: #a93226;--shadow: rgba(43, 36, 28, .08)}[data-theme=solarized-light]{--bg: #fdf6e3;--bg-2: #eee8d5;--surface: #f5efdc;--line: #d6cba9;--ink: #657b83;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #268bd2;--rail-from: #eee8d5;--rail-to: #e6dfc8;--rail-active: #e0d9c0;--btn: #fdf6e3;--btn-line: #93a1a1;--btn-primary: #e8efc8;--btn-primary-line: #859900;--node-bg: #fdf6e3;--node-line: #93a1a1;--graph-bg: #fdf6e3;--graph-grid: rgba(38, 139, 210, .12);--edge-cheap: #93a1a1;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(101, 123, 131, .1)}[data-theme=seafoam]{--bg: #eef7f4;--bg-2: #dff0ea;--surface: #ffffff;--line: #b7d5cc;--ink: #17332c;--muted: #4d7268;--high: #1b8a5a;--medium: #c48a14;--low: #c44536;--critical: #9b2d22;--accent: #1d9a8a;--rail-from: #dff0ea;--rail-to: #cfe6de;--rail-active: #c4ddd4;--btn: #ffffff;--btn-line: #8fbfb2;--btn-primary: #d4f0e4;--btn-primary-line: #1b8a5a;--node-bg: #ffffff;--node-line: #8fbfb2;--graph-bg: #eef7f4;--graph-grid: rgba(29, 154, 138, .12);--edge-cheap: #8fbfb2;--edge-expensive: #c48a14;--edge-critical: #c44536;--shadow: rgba(23, 51, 44, .08)}[data-theme=high-contrast]{--bg: #ffffff;--bg-2: #f2f2f2;--surface: #ffffff;--line: #111111;--ink: #000000;--muted: #222222;--high: #007a33;--medium: #8a5a00;--low: #b00000;--critical: #9b0000;--accent: #0033cc;--rail-from: #f2f2f2;--rail-to: #e6e6e6;--rail-active: #d9d9d9;--btn: #ffffff;--btn-line: #000000;--btn-primary: #d9f2e3;--btn-primary-line: #007a33;--node-bg: #ffffff;--node-line: #000000;--graph-bg: #ffffff;--graph-grid: rgba(0, 0, 0, .12);--edge-cheap: #444444;--edge-expensive: #8a5a00;--edge-critical: #b00000;--shadow: rgba(0, 0, 0, .12)}[data-theme=sakura]{--bg: #fff0f5;--bg-2: #ffe4ee;--surface: #fff7fa;--line: #f5b8cc;--ink: #4a1830;--muted: #a05a78;--high: #1a8a5c;--medium: #c48a14;--low: #d63d6e;--critical: #b01040;--accent: #e84a8a;--rail-from: #ffe4ee;--rail-to: #f8d4e0;--rail-active: #f5c8d8;--btn: #fff7fa;--btn-line: #e89ab0;--btn-primary: #ffd6e6;--btn-primary-line: #e84a8a;--node-bg: #fff7fa;--node-line: #e89ab0;--graph-bg: #fff0f5;--graph-grid: rgba(232, 74, 138, .12);--edge-cheap: #d4a0b0;--edge-expensive: #d63d6e;--edge-critical: #b01040;--shadow: rgba(74, 24, 48, .1)}[data-theme=citrus]{--bg: #fffce8;--bg-2: #fff3b0;--surface: #fffef5;--line: #e8d44a;--ink: #2a2a08;--muted: #6a6a20;--high: #2a8a20;--medium: #d4a000;--low: #e85d04;--critical: #c0392b;--accent: #5aad14;--rail-from: #fff3b0;--rail-to: #ffe98a;--rail-active: #ffe066;--btn: #fffef5;--btn-line: #d4c030;--btn-primary: #e8f5b8;--btn-primary-line: #5aad14;--node-bg: #fffef5;--node-line: #d4c030;--graph-bg: #fffce8;--graph-grid: rgba(90, 173, 20, .14);--edge-cheap: #c4b040;--edge-expensive: #e85d04;--edge-critical: #c0392b;--shadow: rgba(42, 42, 8, .1)}[data-theme=peach]{--bg: #fff3eb;--bg-2: #ffe0cc;--surface: #fffaf6;--line: #f0c4a8;--ink: #3a2218;--muted: #8a5a48;--high: #2a8a5c;--medium: #d48a14;--low: #e85d3a;--critical: #c0392b;--accent: #ff6b35;--rail-from: #ffe0cc;--rail-to: #ffd4b8;--rail-active: #ffc8a8;--btn: #fffaf6;--btn-line: #e8a888;--btn-primary: #ffe0cc;--btn-primary-line: #ff6b35;--node-bg: #fffaf6;--node-line: #e8a888;--graph-bg: #fff3eb;--graph-grid: rgba(255, 107, 53, .12);--edge-cheap: #d4a088;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(58, 34, 24, .1)}[data-theme=candy]{--bg: #f4f0ff;--bg-2: #e8dcff;--surface: #fbf8ff;--line: #d4c0f0;--ink: #2a1848;--muted: #6a5890;--high: #1a8a6a;--medium: #c48a14;--low: #e84a8a;--critical: #c01060;--accent: #ff5eb1;--rail-from: #e8dcff;--rail-to: #ddd0ff;--rail-active: #d4c4ff;--btn: #fbf8ff;--btn-line: #c4a8e8;--btn-primary: #ffd6ec;--btn-primary-line: #ff5eb1;--node-bg: #fbf8ff;--node-line: #c4a8e8;--graph-bg: #f4f0ff;--graph-grid: rgba(255, 94, 177, .14);--edge-cheap: #b0a0d0;--edge-expensive: #e84a8a;--edge-critical: #c01060;--shadow: rgba(42, 24, 72, .1)}[data-theme=sky]{--bg: #e8f4ff;--bg-2: #cfe8ff;--surface: #f5faff;--line: #90c8f0;--ink: #0a2848;--muted: #3a6080;--high: #0a8a4a;--medium: #c48a14;--low: #e85d3a;--critical: #c0392b;--accent: #0077ff;--rail-from: #cfe8ff;--rail-to: #b8dcff;--rail-active: #a8d4ff;--btn: #f5faff;--btn-line: #70b0e0;--btn-primary: #cfe8ff;--btn-primary-line: #0077ff;--node-bg: #f5faff;--node-line: #70b0e0;--graph-bg: #e8f4ff;--graph-grid: rgba(0, 119, 255, .12);--edge-cheap: #80b0d0;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(10, 40, 72, .1)}[data-theme=coral]{--bg: #fff1ee;--bg-2: #ffddd6;--surface: #fff8f6;--line: #f0b0a4;--ink: #3a1814;--muted: #8a5048;--high: #0d9488;--medium: #d48a14;--low: #e85d4a;--critical: #c0392b;--accent: #0d9488;--rail-from: #ffddd6;--rail-to: #ffd0c6;--rail-active: #ffc4b8;--btn: #fff8f6;--btn-line: #e89888;--btn-primary: #d4f4ee;--btn-primary-line: #0d9488;--node-bg: #fff8f6;--node-line: #e89888;--graph-bg: #fff1ee;--graph-grid: rgba(13, 148, 136, .14);--edge-cheap: #d4a098;--edge-expensive: #e85d4a;--edge-critical: #c0392b;--shadow: rgba(58, 24, 20, .1)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}:root{--radius: 6px;--radius-lg: 10px;--control-h: 32px;--font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);--space: 8px}body{background:var(--bg);color:var(--ink);font-family:var(--font);font-size:13px;line-height:1.45;-webkit-font-smoothing:antialiased}button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,a:focus-visible,summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip{position:absolute;left:12px;top:-40px;z-index:50;background:var(--surface);color:var(--ink);border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px}.skip:focus{top:12px}.app{display:grid;grid-template-columns:232px 1fr;height:100%}.rail{border-right:1px solid var(--line);background:linear-gradient(180deg,var(--rail-from),var(--rail-to));padding:16px 12px;display:flex;flex-direction:column;gap:2px;min-width:0}.brand{display:flex;flex-direction:column;gap:2px;padding:4px 8px 16px}.brand-mark{font-family:var(--mono);letter-spacing:.16em;font-size:11px;text-transform:uppercase;color:var(--accent);font-weight:600}.brand-sub{font-size:11px;color:var(--muted)}.nav-item{display:flex;align-items:center;gap:10px;background:transparent;border:0;text-align:left;padding:8px 10px;border-radius:var(--radius);color:var(--muted);cursor:pointer;width:100%}.nav-item:hover{background:color-mix(in srgb,var(--rail-active) 70%,transparent);color:var(--ink)}.nav-item.active{background:var(--rail-active);color:var(--ink);font-weight:500}.nav-item svg{flex-shrink:0}.theme-pick{margin-top:14px;display:grid;gap:4px;padding:0 2px}.theme-pick label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:500}.theme-pick select,.field select,.field input,.topbar input,.topbar select,.settings input,.settings select,.explorer-path input{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:0 10px;height:var(--control-h);width:100%}.rail-foot{margin-top:auto;padding:12px 8px 4px;border-top:1px solid var(--line);display:grid;gap:6px}.kbd-hint{font-size:11px;color:var(--muted)}kbd{font-family:var(--mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:0 4px;background:var(--surface)}.main{display:flex;flex-direction:column;min-width:0;min-height:0;position:relative;background:var(--bg)}.progress{position:absolute;top:0;left:0;right:0;height:2px;overflow:hidden;z-index:30;background:color-mix(in srgb,var(--accent) 20%,transparent)}.progress i{display:block;height:100%;width:32%;background:var(--accent);animation:indeterminate 1.1s ease-in-out infinite}.progress.determinate i{width:0;animation:none;transform:none;transition:width .2s ease-out}@keyframes indeterminate{0%{transform:translate(-120%)}to{transform:translate(400%)}}.topbar{display:flex;gap:10px;align-items:flex-end;padding:10px 16px;border-bottom:1px solid var(--line);background:var(--bg-2);flex-wrap:wrap}.field{display:grid;gap:4px;min-width:0}.field>span{font-size:11px;color:var(--muted);font-weight:500}.field.path{flex:1;min-width:180px}.field.ref{width:188px;flex:0 0 188px}.field.workspace{width:180px;flex:0 0 180px}.path-row,.combo-row{display:flex;min-width:0}.path-row input,.combo-row input{flex:1;min-width:0}.combo{position:relative;min-width:0}.combo-row input{border-top-right-radius:0;border-bottom-right-radius:0}.topbar .icon-btn{width:var(--control-h);padding:0;flex:0 0 var(--control-h)}.combo-toggle{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.combo-menu{position:absolute;top:calc(100% + 4px);right:0;left:auto;min-width:340px;max-width:min(480px,70vw);max-height:360px;overflow:auto;z-index:40;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 12px 32px var(--shadow);padding:6px 0}.combo-heading{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;padding:8px 12px 4px}.combo-menu .combo-option{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:transparent;border:0;border-radius:0;height:auto;padding:6px 12px;color:var(--ink);cursor:pointer}.combo-menu .combo-option:hover,.combo-menu .combo-option.active{background:var(--rail-active)}.combo-label{font-family:var(--mono);font-size:12px}.combo-detail{color:var(--muted);font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.combo-empty{padding:10px 12px}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:color-mix(in srgb,var(--bg) 72%,transparent);display:grid;place-items:center;padding:24px}.modal{width:min(720px,100%);max-height:min(640px,90vh);background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:0 16px 48px var(--shadow);display:flex;flex-direction:column;overflow:hidden}.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:14px 16px 10px;border-bottom:1px solid var(--line)}.modal-head h2{font-size:15px}.modal-head .muted{margin:4px 0 0}.explorer-path{display:flex;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line)}.explorer-path input{flex:1;min-width:0}.explorer-list{flex:1;overflow:auto;padding:8px;min-height:220px}.explorer-row{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:0;border-radius:var(--radius);padding:8px 10px;color:var(--ink);cursor:pointer;height:auto}.explorer-row:hover,.explorer-row.active{background:var(--rail-active)}.explorer-name{min-width:0;overflow:hidden;text-overflow:ellipsis}.git-badge{margin-left:auto;margin-bottom:0}.explorer-empty{padding:18px 10px}.modal-foot{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line)}.explorer-current{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:12px}.topbar input,.topbar select{min-width:0}.topbar-actions{display:flex;gap:8px;margin-left:auto;align-items:center;padding-bottom:0}.btn,.topbar button{background:var(--btn);border:1px solid var(--btn-line);border-radius:var(--radius);height:var(--control-h);padding:0 12px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}.btn:hover,.topbar button:hover{filter:brightness(1.08)}.btn:disabled,.topbar button:disabled{opacity:.55;cursor:not-allowed;filter:none}.btn.primary{background:var(--btn-primary);border-color:var(--btn-primary-line)}.btn.ghost{background:transparent}.alerts{display:grid;gap:8px;padding:10px 16px 0}.alerts:empty{display:none;padding:0}.stage{flex:1;min-height:0;display:flex;flex-direction:column}.content{flex:1;min-height:0;display:grid;grid-template-columns:minmax(340px,420px) 1fr}.brief{overflow:auto;border-right:1px solid var(--line);padding:16px 18px 24px;background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--accent) 8%,transparent),transparent 42%),var(--bg)}.graph-wrap{position:relative;min-height:0;display:flex;flex-direction:column}.impact-graph{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.graph-count{margin-left:auto;font-size:11px}.chip-btn{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.chip-btn:hover{color:var(--ink)}.chip-btn.active{background:var(--rail-active);color:var(--ink)}.chip-btn:disabled{opacity:.45;cursor:not-allowed}.graph-stage{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-stage .react-flow,.graph-3d,.graph-3d-host,.graph-3d-canvas-host{flex:1;width:100%;height:100%;min-height:280px}.graph-3d{position:relative;background:var(--graph-bg);display:flex;flex-direction:column}.graph-3d-host{position:relative;min-height:0;display:flex;flex-direction:column}.graph-3d-canvas-host{position:relative;min-height:0;background:var(--graph-bg)}.graph-3d canvas{display:block;width:100%;height:100%}.graph-3d-tip{position:absolute;pointer-events:none;z-index:2;max-width:320px;padding:6px 8px;border-radius:var(--radius);background:var(--surface);border:1px solid var(--line);color:var(--ink);font-size:11px;line-height:1.35;box-shadow:0 8px 24px var(--shadow)}.graph-3d-tip .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.graph-3d-tip .n{font-weight:600}.graph-3d-hint{position:absolute;left:10px;bottom:10px;z-index:2;margin:0;font-size:11px;color:var(--muted);max-width:min(420px,calc(100% - 24px));pointer-events:none}.graph-wrap .react-flow{background-color:var(--graph-bg);background-image:linear-gradient(var(--graph-grid) 1px,transparent 1px),linear-gradient(90deg,var(--graph-grid) 1px,transparent 1px);background-size:24px 24px}.react-flow__minimap{background:var(--graph-bg)!important;border:1px solid var(--line)!important;border-radius:var(--radius);overflow:hidden;box-shadow:0 8px 24px var(--shadow)}.react-flow__minimap-node{fill:var(--muted);stroke:none}.react-flow__minimap-node.selected{fill:var(--accent)}.react-flow__minimap-mask{fill:#00000073!important;stroke:var(--accent)!important}.react-flow__controls{box-shadow:none!important}.react-flow__controls-button{background:var(--surface)!important;border-bottom:1px solid var(--line)!important;fill:var(--ink)!important}h1{font-size:18px;margin:0 0 6px;font-weight:600}h2{font-size:13px;margin:0;font-weight:600}.merge-box{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:12px 14px;margin-bottom:12px}.merge-box.high{border-color:color-mix(in srgb,var(--high) 55%,var(--line))}.merge-box.medium{border-color:color-mix(in srgb,var(--medium) 55%,var(--line))}.merge-box.low{border-color:color-mix(in srgb,var(--low) 55%,var(--line))}.level{font-family:var(--mono);font-weight:600;font-size:14px}.level.high{color:var(--high)}.level.medium{color:var(--medium)}.level.low{color:var(--low)}.merge-title{margin-top:4px;font-size:13px;color:var(--ink)}.reasons{margin:10px 0 0;padding:0 0 0 18px;color:var(--muted)}.reasons li{margin:0 0 4px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 0 14px}.metric{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:8px 10px}.metric .n{font-family:var(--mono);font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}.metric .l{font-size:11px;color:var(--muted);margin-top:2px}.section{border-top:1px solid var(--line);padding:8px 0 4px}.section>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600;padding:6px 0}.section>summary::-webkit-details-marker{display:none}.section>summary .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.kicker{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}.chip{display:inline-flex;align-items:center;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);margin:0 6px 6px 0;color:var(--muted);background:var(--surface)}.chip.blocker{color:var(--low);border-color:var(--low)}.chip.warning{color:var(--medium);border-color:var(--medium)}.chip.strong{color:var(--low);border-color:var(--low)}.chip.worth_exploring{color:var(--medium);border-color:var(--medium)}.chip.speculative{color:var(--muted);border-color:var(--line)}.chip.open{color:var(--high);border-color:color-mix(in srgb,var(--high) 50%,var(--line))}.file{font-family:var(--mono);font-size:12px;color:var(--accent)}.read-item,.finding,.residual{padding:8px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.read-item:last-child,.finding:last-child{border-bottom:0}.read-item.tour-current{background:color-mix(in srgb,var(--accent) 12%,var(--surface));border-color:var(--accent)}.tour-row{margin-top:8px;align-items:center}.field.dirty .chip-btn{height:32px}.muted{color:var(--muted);font-size:13px;line-height:1.45}.error{color:var(--low);padding:8px 12px;border:1px solid var(--low);background:color-mix(in srgb,var(--low) 10%,var(--surface));border-radius:var(--radius);display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner{padding:8px 12px;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);font-size:13px;line-height:1.45;display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner.warn{border-color:var(--medium);color:var(--medium)}.banner.stale{border-color:var(--low);color:var(--low)}.banner.whatif{border-color:var(--accent);align-items:center}.banner.whatif .btn{flex:0 0 auto;white-space:nowrap}.chip.whatif{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 55%,var(--line))}.whatif-hint{margin:10px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.banner .dismiss{background:transparent;border:0;color:inherit;cursor:pointer;height:auto;padding:0 2px;opacity:.7}.empty{padding:24px 8px;color:var(--muted);font-size:13px;line-height:1.55}.workspace-loading{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:220px;padding:48px 16px}.empty h2{font-size:16px;color:var(--ink);margin-bottom:8px}.empty ol{margin:12px 0 0 18px;padding:0}.empty code,code{font-family:var(--mono);font-size:12px;color:var(--accent)}.btn-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.pr-list{padding:16px;overflow:auto}.pr-toolbar{display:flex;gap:8px;align-items:flex-end;margin-bottom:14px}.pr-toolbar .field{flex:1}.pr-toolbar .field.provider{flex:0 0 140px}.scm-count{margin:0 0 12px;font-size:12px}.scm-login{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:10px 0;border-top:1px solid var(--line)}.scm-login:first-of-type{border-top:0;padding-top:0}.scm-login .btn-row{margin-top:0}.scm-login p{margin:2px 0 0}.oauth-code{font-size:13px;margin:0}.oauth-code code{font-size:14px;letter-spacing:.08em}.pr{border:1px solid var(--line);background:var(--surface);padding:12px 14px;border-radius:var(--radius-lg);margin-bottom:10px}.pr h3{margin:0 0 4px;font-size:14px;font-weight:600}.pr-meta{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;margin:6px 0 10px}.pr-actions{display:flex;gap:8px;align-items:center}.settings{padding:24px;max-width:760px;overflow:auto;display:grid;gap:16px}.settings-card{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:16px;display:grid;gap:8px}.settings-card h2{font-size:14px;margin-bottom:2px}.settings label{font-size:12px;color:var(--muted);font-weight:500}.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}.theme-swatch{border:1px solid var(--line);background:var(--bg);color:var(--ink);border-radius:var(--radius);padding:10px;text-align:left;cursor:pointer;height:auto;box-shadow:0 1px 8px var(--shadow)}.theme-swatch.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 1px 8px var(--shadow)}.theme-swatch .swatch-bar{height:6px;border-radius:3px;margin-bottom:8px;background:linear-gradient(90deg,var(--accent),var(--high),var(--medium),var(--low))}.theme-swatch .name{font-size:13px;font-weight:600}.theme-swatch .group{font-size:11px;color:var(--muted)}.headline{white-space:pre-wrap;font-family:var(--mono);font-size:12px;color:var(--muted);margin:8px 0 0}.graph-modes{display:flex;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:2px;background:var(--surface)}.seg button,.graph-modes button{background:transparent;border:0;border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.seg button.active,.graph-modes button.active{background:var(--rail-active);color:var(--ink)}.legend{margin-left:auto;display:flex;gap:12px;color:var(--muted);font-size:11px}.legend i{display:inline-block;width:14px;height:2px;margin-right:6px;vertical-align:middle;background:var(--edge-cheap)}.legend i.exp{background:var(--edge-expensive)}.legend i.crit{background:var(--edge-critical);height:3px}.legend i.dash{border-top:2px dashed var(--muted);background:none;height:0}.legend i.seed{height:10px;width:10px;border-radius:2px;background:color-mix(in srgb,var(--medium) 70%,var(--node-bg))}.legend i.down{height:10px;width:10px;border-radius:2px;border:1px solid color-mix(in srgb,var(--accent) 45%,var(--node-line));background:var(--node-bg)}.inspector{position:absolute;top:12px;right:12px;z-index:5;width:300px;max-width:calc(100% - 24px);max-height:calc(100% - 24px);overflow-x:hidden;overflow-y:auto;overflow-wrap:break-word;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:10px 12px;box-shadow:0 8px 24px var(--shadow);font-size:12px}.inspector .t{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.inspector .n,.inspector .file,.inspector .muted{overflow-wrap:break-word}.inspector .n{font-weight:600;margin:4px 0}.inspector-head{display:flex;align-items:flex-start;gap:8px}.inspector-roles{display:flex;flex-wrap:wrap;justify-content:flex-end;flex:1;gap:4px}.inspector-chip{font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:1px 6px;border-radius:999px;border:1px solid var(--line);color:var(--muted);white-space:nowrap}.inspector-close{flex:0 0 auto;width:24px;height:24px;padding:0;border:1px solid var(--line);border-radius:var(--radius);background:transparent;color:var(--muted);font-size:16px;line-height:1;cursor:pointer}.inspector-close:hover{color:var(--ink)}.inspector-purpose{margin:6px 0 8px;color:var(--ink);font-size:12px;line-height:1.4}.inspector-layer{margin-top:4px;font-size:11px}.inspector-degree{font-size:11px}.inspector-path{margin:6px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.inspector-facts{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--line)}.inspector-fact{display:grid;grid-template-columns:minmax(64px,92px) minmax(0,1fr);gap:8px;padding:3px 0;align-items:start}.inspector-fact dt{color:var(--muted);font-size:11px;margin:0}.inspector-fact dd{margin:0;overflow-wrap:break-word}.inspector-section{margin-top:10px;padding-top:8px;border-top:1px solid var(--line)}.inspector-section h3{margin:0 0 6px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600}.inspector-section .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.inspector-section ul{list-style:none;margin:0;padding:0}.inspector-section li{padding:4px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.inspector-section li:last-child{border-bottom:0}.inspector-link-name{display:block;font-weight:600;overflow-wrap:break-word}.inspector-link-meta{display:block;color:var(--muted);font-size:11px}.lp-node{padding:8px 10px;border-radius:var(--radius);border:1px solid var(--node-line);background:var(--node-bg);width:208px;max-width:100%;height:64px;box-sizing:border-box;box-shadow:0 0 0 1px var(--shadow);overflow:visible;position:relative}.lp-node .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.lp-node .n{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}.lp-node.selected{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.lp-node.role-seed{border-color:var(--medium);background:color-mix(in srgb,var(--medium) 14%,var(--node-bg))}.lp-node.role-downstream{border-color:color-mix(in srgb,var(--accent) 45%,var(--node-line))}.lp-node.role-untested{box-shadow:inset 3px 0 0 var(--low)}.lp-node.role-tested{box-shadow:inset 3px 0 0 var(--high)}.lp-node.role-contract{outline:1px dashed color-mix(in srgb,var(--accent) 50%,transparent)}.lp-node.dim{opacity:.38}.merge-box.compact{padding:6px 10px;min-width:92px;margin:0}.merge-box.compact .level{font-size:12px}.palette-scrim{position:fixed;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--bg) 55%,transparent);z-index:40;display:grid;place-items:start center;padding-top:12vh}.palette{width:min(640px,calc(100vw - 32px));background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:0 18px 60px var(--shadow);overflow:hidden}.palette input{width:100%;border:0;border-bottom:1px solid var(--line);background:transparent;color:var(--ink);padding:14px 16px;font:inherit}.palette ul{list-style:none;margin:0;padding:6px;max-height:360px;overflow:auto}.palette li button{width:100%;display:flex;justify-content:space-between;gap:12px;text-align:left;background:transparent;border:0;color:var(--ink);padding:8px 10px;border-radius:8px;cursor:pointer}.palette li button.active,.palette li button:hover{background:var(--rail-active)}.palette-foot{padding:8px 12px 10px}.graph-search{position:relative;min-width:140px}.graph-search input{width:100%;background:var(--bg-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:6px 8px;font:inherit}.graph-search-hits{position:absolute;z-index:5;left:0;right:0;top:calc(100% + 4px);background:var(--surface);border:1px solid var(--line);border-radius:8px;list-style:none;margin:0;padding:4px;max-height:240px;overflow:auto}.graph-search-hits button{width:100%;display:flex;justify-content:space-between;gap:8px;background:transparent;border:0;color:var(--ink);text-align:left;padding:6px 8px;cursor:pointer}.graph-search-hits button:hover{background:var(--rail-active)}.inspector-link{display:flex;flex-direction:column;width:100%;background:transparent;border:0;color:inherit;text-align:left;cursor:pointer;padding:0}.file-row{display:flex;flex-direction:column;gap:6px}.linkish{background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer;padding:0}.history-item,.check-item{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;width:100%;background:transparent;border:0;color:inherit;font:inherit;text-align:left;padding:6px 0;cursor:pointer}.history-item.current{color:var(--accent)}.check-row{display:flex;gap:8px;align-items:center;margin:4px 0}.sparkline{display:flex;align-items:flex-end;gap:3px;height:36px;margin:8px 0}.sparkline i{flex:1;background:var(--muted);border-radius:2px 2px 0 0;min-width:4px}.sparkline i.high{background:var(--high)}.sparkline i.medium{background:var(--medium)}.sparkline i.low{background:var(--low)}.config-editor .field{display:flex;flex-direction:column;gap:4px;margin:8px 0}.config-editor input,.config-editor select{background:var(--bg-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:6px 8px}.react-flow__node-load .react-flow__handle{width:8px;height:8px;border:none;background:transparent;opacity:0}.type-table{width:100%;border-collapse:collapse;font-size:12px}.type-table td{padding:3px 0}.type-table td:last-child{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--muted)}@media(prefers-reduced-motion:reduce){.progress i{animation:none;width:100%}.progress.determinate i{width:var(--progress, 100%)}*{scroll-behavior:auto!important}}@media(max-width:960px){.app{grid-template-columns:56px 1fr}.brand-sub,.nav-item span,.theme-pick,.kbd-hint,.rail-foot .muted{display:none}.nav-item{justify-content:center;padding:10px}.content{grid-template-columns:1fr}.brief{border-right:0;border-bottom:1px solid var(--line);max-height:42vh}} +.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #555;--xy-background-pattern-lines-color-default: #333;--xy-background-pattern-cross-color-default: #333;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}:root,[data-theme=obsidian]{--bg: #070b10;--bg-2: #0d141c;--surface: #121a24;--line: #1e2c3c;--ink: #e7eef6;--muted: #8b9bb0;--high: #2a9d8f;--medium: #e9c46a;--low: #e76f51;--critical: #e85d04;--accent: #4cc9f0;--rail-from: #0b1219;--rail-to: #070b10;--rail-active: #15202c;--btn: #173044;--btn-line: #24506c;--btn-primary: #134e4a;--btn-primary-line: #2a9d8f;--node-bg: #101822;--node-line: #2a3d52;--graph-bg: #070b10;--graph-grid: rgba(42, 80, 120, .09);--edge-cheap: #4a5568;--edge-expensive: #f4a261;--edge-critical: #e85d04;--shadow: rgba(76, 201, 240, .08)}[data-theme=nord]{--bg: #2e3440;--bg-2: #3b4252;--surface: #434c5e;--line: #4c566a;--ink: #eceff4;--muted: #d8dee9;--high: #a3be8c;--medium: #ebcb8b;--low: #bf616a;--critical: #d08770;--accent: #88c0d0;--rail-from: #3b4252;--rail-to: #2e3440;--rail-active: #4c566a;--btn: #434c5e;--btn-line: #81a1c1;--btn-primary: #5e81ac;--btn-primary-line: #88c0d0;--node-bg: #3b4252;--node-line: #81a1c1;--graph-bg: #2e3440;--graph-grid: rgba(136, 192, 208, .12);--edge-cheap: #4c566a;--edge-expensive: #d08770;--edge-critical: #bf616a;--shadow: rgba(136, 192, 208, .12)}[data-theme=solarized-dark]{--bg: #002b36;--bg-2: #073642;--surface: #0a3944;--line: #16444f;--ink: #eee8d5;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #2aa198;--rail-from: #073642;--rail-to: #002b36;--rail-active: #16444f;--btn: #073642;--btn-line: #268bd2;--btn-primary: #0a4a42;--btn-primary-line: #2aa198;--node-bg: #073642;--node-line: #268bd2;--graph-bg: #002b36;--graph-grid: rgba(42, 161, 152, .12);--edge-cheap: #586e75;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(42, 161, 152, .12)}[data-theme=forest]{--bg: #0e1510;--bg-2: #152019;--surface: #1b2a20;--line: #2c4334;--ink: #e4f0e6;--muted: #8eaa96;--high: #6ab04c;--medium: #c8a951;--low: #e17055;--critical: #d35400;--accent: #7bed9f;--rail-from: #152019;--rail-to: #0e1510;--rail-active: #1f3326;--btn: #1f3326;--btn-line: #3d6b4f;--btn-primary: #1e4d32;--btn-primary-line: #6ab04c;--node-bg: #16241b;--node-line: #3d6b4f;--graph-bg: #0e1510;--graph-grid: rgba(123, 237, 159, .1);--edge-cheap: #3d6b4f;--edge-expensive: #c8a951;--edge-critical: #d35400;--shadow: rgba(123, 237, 159, .1)}[data-theme=rose]{--bg: #191724;--bg-2: #1f1d2e;--surface: #26233a;--line: #403d52;--ink: #e0def4;--muted: #908caa;--high: #9ccfd8;--medium: #f6c177;--low: #eb6f92;--critical: #eb6f92;--accent: #c4a7e7;--rail-from: #1f1d2e;--rail-to: #191724;--rail-active: #26233a;--btn: #26233a;--btn-line: #c4a7e7;--btn-primary: #3a2f4d;--btn-primary-line: #c4a7e7;--node-bg: #1f1d2e;--node-line: #524f67;--graph-bg: #191724;--graph-grid: rgba(196, 167, 231, .12);--edge-cheap: #524f67;--edge-expensive: #f6c177;--edge-critical: #eb6f92;--shadow: rgba(196, 167, 231, .12)}[data-theme=amber]{--bg: #120e0a;--bg-2: #1c1610;--surface: #261e16;--line: #3d2f22;--ink: #f4e6d0;--muted: #b59a78;--high: #c4d6a0;--medium: #e9b44c;--low: #d8572a;--critical: #c0392b;--accent: #f0a05a;--rail-from: #1c1610;--rail-to: #120e0a;--rail-active: #2b2218;--btn: #2b2218;--btn-line: #8a5a2b;--btn-primary: #4a3418;--btn-primary-line: #f0a05a;--node-bg: #1c1610;--node-line: #8a5a2b;--graph-bg: #120e0a;--graph-grid: rgba(240, 160, 90, .12);--edge-cheap: #5c4a38;--edge-expensive: #e9b44c;--edge-critical: #d8572a;--shadow: rgba(240, 160, 90, .12)}[data-theme=volcano]{--bg: #14090a;--bg-2: #1e0e10;--surface: #2a1416;--line: #4a2226;--ink: #fde8e4;--muted: #c48b86;--high: #7bed9f;--medium: #f6c90e;--low: #ff6b6b;--critical: #ff3b3b;--accent: #ff7b54;--rail-from: #1e0e10;--rail-to: #14090a;--rail-active: #32181b;--btn: #32181b;--btn-line: #ff7b54;--btn-primary: #5a1f18;--btn-primary-line: #ff7b54;--node-bg: #1e0e10;--node-line: #7a3330;--graph-bg: #14090a;--graph-grid: rgba(255, 123, 84, .12);--edge-cheap: #5a3330;--edge-expensive: #ff7b54;--edge-critical: #ff3b3b;--shadow: rgba(255, 123, 84, .14)}[data-theme=lavender]{--bg: #12101c;--bg-2: #1a1730;--surface: #221e3c;--line: #3b3560;--ink: #efeaff;--muted: #b3a7d6;--high: #80ffdb;--medium: #ffd166;--low: #ff6b9d;--critical: #ff4d6d;--accent: #c77dff;--rail-from: #1a1730;--rail-to: #12101c;--rail-active: #2a2550;--btn: #2a2550;--btn-line: #c77dff;--btn-primary: #3d2a66;--btn-primary-line: #c77dff;--node-bg: #1a1730;--node-line: #5a4d8a;--graph-bg: #12101c;--graph-grid: rgba(199, 125, 255, .12);--edge-cheap: #5a4d8a;--edge-expensive: #ffd166;--edge-critical: #ff4d6d;--shadow: rgba(199, 125, 255, .14)}[data-theme=neon-noir]{--bg: #05060a;--bg-2: #0a0c14;--surface: #10131c;--line: #1e2436;--ink: #f0f4ff;--muted: #8b93b0;--high: #39ff88;--medium: #ffe66d;--low: #ff2d95;--critical: #ff3d5a;--accent: #00f0ff;--rail-from: #0a0c14;--rail-to: #05060a;--rail-active: #151a2a;--btn: #151a2a;--btn-line: #00f0ff;--btn-primary: #063a40;--btn-primary-line: #00f0ff;--node-bg: #0a0c14;--node-line: #2a3550;--graph-bg: #05060a;--graph-grid: rgba(0, 240, 255, .12);--edge-cheap: #3a4560;--edge-expensive: #ff2d95;--edge-critical: #ff3d5a;--shadow: rgba(0, 240, 255, .22)}[data-theme=synthwave]{--bg: #1a0a2e;--bg-2: #240b3d;--surface: #2d1250;--line: #4a1d7a;--ink: #ffe6fb;--muted: #c49ad8;--high: #00f5d4;--medium: #ffd60a;--low: #ff6b9d;--critical: #ff006e;--accent: #ff2bd6;--rail-from: #240b3d;--rail-to: #1a0a2e;--rail-active: #3a1570;--btn: #3a1570;--btn-line: #ff2bd6;--btn-primary: #5a0a4a;--btn-primary-line: #ff2bd6;--node-bg: #240b3d;--node-line: #7b2cbf;--graph-bg: #1a0a2e;--graph-grid: rgba(255, 43, 214, .16);--edge-cheap: #5a3a80;--edge-expensive: #ff9e00;--edge-critical: #ff006e;--shadow: rgba(255, 43, 214, .24)}[data-theme=phosphor]{--bg: #020804;--bg-2: #061208;--surface: #0a1a0e;--line: #163c1e;--ink: #c8ffc8;--muted: #5aaa5a;--high: #39ff14;--medium: #c8f542;--low: #ffb000;--critical: #ff5e00;--accent: #00ff66;--rail-from: #061208;--rail-to: #020804;--rail-active: #0e2414;--btn: #0e2414;--btn-line: #00ff66;--btn-primary: #0a3a18;--btn-primary-line: #00ff66;--node-bg: #061208;--node-line: #1e6a32;--graph-bg: #020804;--graph-grid: rgba(0, 255, 102, .12);--edge-cheap: #1e5a2a;--edge-expensive: #c8f542;--edge-critical: #ff5e00;--shadow: rgba(0, 255, 102, .2)}[data-theme=aurora]{--bg: #071018;--bg-2: #0c1c28;--surface: #122636;--line: #1e3d52;--ink: #e8fff6;--muted: #7eb8a8;--high: #5fffcf;--medium: #ffe566;--low: #ff7eb6;--critical: #ff4d6d;--accent: #7cffb2;--rail-from: #0c1c28;--rail-to: #071018;--rail-active: #163044;--btn: #163044;--btn-line: #7cffb2;--btn-primary: #0e3d3a;--btn-primary-line: #7cffb2;--node-bg: #0c1c28;--node-line: #2a6a78;--graph-bg: #071018;--graph-grid: rgba(124, 255, 178, .12);--edge-cheap: #2a5a68;--edge-expensive: #c9a0ff;--edge-critical: #ff4d6d;--shadow: rgba(124, 255, 178, .18)}[data-theme=biolume]{--bg: #02141c;--bg-2: #042430;--surface: #073040;--line: #0a4a5c;--ink: #e6fffb;--muted: #6eb8b0;--high: #5dffb0;--medium: #ffe066;--low: #ff79c6;--critical: #ff4d6d;--accent: #18e7d4;--rail-from: #042430;--rail-to: #02141c;--rail-active: #0a3848;--btn: #0a3848;--btn-line: #18e7d4;--btn-primary: #0a4a48;--btn-primary-line: #18e7d4;--node-bg: #042430;--node-line: #1a7080;--graph-bg: #02141c;--graph-grid: rgba(24, 231, 212, .12);--edge-cheap: #1a5a68;--edge-expensive: #ff79c6;--edge-critical: #ff4d6d;--shadow: rgba(24, 231, 212, .2)}[data-theme=carbon]{--bg: #0d0d0f;--bg-2: #16161a;--surface: #1e1e24;--line: #33333c;--ink: #f2f2f4;--muted: #9a9aa8;--high: #3dd68c;--medium: #f0c040;--low: #ff5a5a;--critical: #ff2a2a;--accent: #ff2a2a;--rail-from: #16161a;--rail-to: #0d0d0f;--rail-active: #24242c;--btn: #24242c;--btn-line: #ff2a2a;--btn-primary: #4a1212;--btn-primary-line: #ff2a2a;--node-bg: #16161a;--node-line: #4a4a55;--graph-bg: #0d0d0f;--graph-grid: rgba(255, 42, 42, .1);--edge-cheap: #4a4a55;--edge-expensive: #ff8a3d;--edge-critical: #ff2a2a;--shadow: rgba(255, 42, 42, .18)}[data-theme=paper]{--bg: #f6f1e8;--bg-2: #efe6d6;--surface: #fffaf2;--line: #d9cbb6;--ink: #2b241c;--muted: #6f6456;--high: #2a7a4b;--medium: #b5811a;--low: #c0392b;--critical: #a93226;--accent: #1d6a7a;--rail-from: #efe6d6;--rail-to: #e7dcc8;--rail-active: #e2d3bb;--btn: #fffaf2;--btn-line: #c9b79a;--btn-primary: #d7eee0;--btn-primary-line: #2a7a4b;--node-bg: #fffaf2;--node-line: #c9b79a;--graph-bg: #f6f1e8;--graph-grid: rgba(29, 106, 122, .1);--edge-cheap: #b7a48c;--edge-expensive: #c0392b;--edge-critical: #a93226;--shadow: rgba(43, 36, 28, .08)}[data-theme=solarized-light]{--bg: #fdf6e3;--bg-2: #eee8d5;--surface: #f5efdc;--line: #d6cba9;--ink: #657b83;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #268bd2;--rail-from: #eee8d5;--rail-to: #e6dfc8;--rail-active: #e0d9c0;--btn: #fdf6e3;--btn-line: #93a1a1;--btn-primary: #e8efc8;--btn-primary-line: #859900;--node-bg: #fdf6e3;--node-line: #93a1a1;--graph-bg: #fdf6e3;--graph-grid: rgba(38, 139, 210, .12);--edge-cheap: #93a1a1;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(101, 123, 131, .1)}[data-theme=seafoam]{--bg: #eef7f4;--bg-2: #dff0ea;--surface: #ffffff;--line: #b7d5cc;--ink: #17332c;--muted: #4d7268;--high: #1b8a5a;--medium: #c48a14;--low: #c44536;--critical: #9b2d22;--accent: #1d9a8a;--rail-from: #dff0ea;--rail-to: #cfe6de;--rail-active: #c4ddd4;--btn: #ffffff;--btn-line: #8fbfb2;--btn-primary: #d4f0e4;--btn-primary-line: #1b8a5a;--node-bg: #ffffff;--node-line: #8fbfb2;--graph-bg: #eef7f4;--graph-grid: rgba(29, 154, 138, .12);--edge-cheap: #8fbfb2;--edge-expensive: #c48a14;--edge-critical: #c44536;--shadow: rgba(23, 51, 44, .08)}[data-theme=high-contrast]{--bg: #ffffff;--bg-2: #f2f2f2;--surface: #ffffff;--line: #111111;--ink: #000000;--muted: #222222;--high: #007a33;--medium: #8a5a00;--low: #b00000;--critical: #9b0000;--accent: #0033cc;--rail-from: #f2f2f2;--rail-to: #e6e6e6;--rail-active: #d9d9d9;--btn: #ffffff;--btn-line: #000000;--btn-primary: #d9f2e3;--btn-primary-line: #007a33;--node-bg: #ffffff;--node-line: #000000;--graph-bg: #ffffff;--graph-grid: rgba(0, 0, 0, .12);--edge-cheap: #444444;--edge-expensive: #8a5a00;--edge-critical: #b00000;--shadow: rgba(0, 0, 0, .12)}[data-theme=sakura]{--bg: #fff0f5;--bg-2: #ffe4ee;--surface: #fff7fa;--line: #f5b8cc;--ink: #4a1830;--muted: #a05a78;--high: #1a8a5c;--medium: #c48a14;--low: #d63d6e;--critical: #b01040;--accent: #e84a8a;--rail-from: #ffe4ee;--rail-to: #f8d4e0;--rail-active: #f5c8d8;--btn: #fff7fa;--btn-line: #e89ab0;--btn-primary: #ffd6e6;--btn-primary-line: #e84a8a;--node-bg: #fff7fa;--node-line: #e89ab0;--graph-bg: #fff0f5;--graph-grid: rgba(232, 74, 138, .12);--edge-cheap: #d4a0b0;--edge-expensive: #d63d6e;--edge-critical: #b01040;--shadow: rgba(74, 24, 48, .1)}[data-theme=citrus]{--bg: #fffce8;--bg-2: #fff3b0;--surface: #fffef5;--line: #e8d44a;--ink: #2a2a08;--muted: #6a6a20;--high: #2a8a20;--medium: #d4a000;--low: #e85d04;--critical: #c0392b;--accent: #5aad14;--rail-from: #fff3b0;--rail-to: #ffe98a;--rail-active: #ffe066;--btn: #fffef5;--btn-line: #d4c030;--btn-primary: #e8f5b8;--btn-primary-line: #5aad14;--node-bg: #fffef5;--node-line: #d4c030;--graph-bg: #fffce8;--graph-grid: rgba(90, 173, 20, .14);--edge-cheap: #c4b040;--edge-expensive: #e85d04;--edge-critical: #c0392b;--shadow: rgba(42, 42, 8, .1)}[data-theme=peach]{--bg: #fff3eb;--bg-2: #ffe0cc;--surface: #fffaf6;--line: #f0c4a8;--ink: #3a2218;--muted: #8a5a48;--high: #2a8a5c;--medium: #d48a14;--low: #e85d3a;--critical: #c0392b;--accent: #ff6b35;--rail-from: #ffe0cc;--rail-to: #ffd4b8;--rail-active: #ffc8a8;--btn: #fffaf6;--btn-line: #e8a888;--btn-primary: #ffe0cc;--btn-primary-line: #ff6b35;--node-bg: #fffaf6;--node-line: #e8a888;--graph-bg: #fff3eb;--graph-grid: rgba(255, 107, 53, .12);--edge-cheap: #d4a088;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(58, 34, 24, .1)}[data-theme=candy]{--bg: #f4f0ff;--bg-2: #e8dcff;--surface: #fbf8ff;--line: #d4c0f0;--ink: #2a1848;--muted: #6a5890;--high: #1a8a6a;--medium: #c48a14;--low: #e84a8a;--critical: #c01060;--accent: #ff5eb1;--rail-from: #e8dcff;--rail-to: #ddd0ff;--rail-active: #d4c4ff;--btn: #fbf8ff;--btn-line: #c4a8e8;--btn-primary: #ffd6ec;--btn-primary-line: #ff5eb1;--node-bg: #fbf8ff;--node-line: #c4a8e8;--graph-bg: #f4f0ff;--graph-grid: rgba(255, 94, 177, .14);--edge-cheap: #b0a0d0;--edge-expensive: #e84a8a;--edge-critical: #c01060;--shadow: rgba(42, 24, 72, .1)}[data-theme=sky]{--bg: #e8f4ff;--bg-2: #cfe8ff;--surface: #f5faff;--line: #90c8f0;--ink: #0a2848;--muted: #3a6080;--high: #0a8a4a;--medium: #c48a14;--low: #e85d3a;--critical: #c0392b;--accent: #0077ff;--rail-from: #cfe8ff;--rail-to: #b8dcff;--rail-active: #a8d4ff;--btn: #f5faff;--btn-line: #70b0e0;--btn-primary: #cfe8ff;--btn-primary-line: #0077ff;--node-bg: #f5faff;--node-line: #70b0e0;--graph-bg: #e8f4ff;--graph-grid: rgba(0, 119, 255, .12);--edge-cheap: #80b0d0;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(10, 40, 72, .1)}[data-theme=coral]{--bg: #fff1ee;--bg-2: #ffddd6;--surface: #fff8f6;--line: #f0b0a4;--ink: #3a1814;--muted: #8a5048;--high: #0d9488;--medium: #d48a14;--low: #e85d4a;--critical: #c0392b;--accent: #0d9488;--rail-from: #ffddd6;--rail-to: #ffd0c6;--rail-active: #ffc4b8;--btn: #fff8f6;--btn-line: #e89888;--btn-primary: #d4f4ee;--btn-primary-line: #0d9488;--node-bg: #fff8f6;--node-line: #e89888;--graph-bg: #fff1ee;--graph-grid: rgba(13, 148, 136, .14);--edge-cheap: #d4a098;--edge-expensive: #e85d4a;--edge-critical: #c0392b;--shadow: rgba(58, 24, 20, .1)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}:root{--radius: 6px;--radius-lg: 10px;--control-h: 32px;--font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);--space: 8px}body{background:var(--bg);color:var(--ink);font-family:var(--font);font-size:13px;line-height:1.45;-webkit-font-smoothing:antialiased}button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,a:focus-visible,summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip{position:absolute;left:12px;top:-40px;z-index:50;background:var(--surface);color:var(--ink);border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px}.skip:focus{top:12px}.app{display:grid;grid-template-columns:232px 1fr;height:100%}.rail{border-right:1px solid var(--line);background:linear-gradient(180deg,var(--rail-from),var(--rail-to));padding:16px 12px;display:flex;flex-direction:column;gap:2px;min-width:0}.brand{display:flex;flex-direction:column;gap:2px;padding:4px 8px 16px}.brand-mark{font-family:var(--mono);letter-spacing:.16em;font-size:11px;text-transform:uppercase;color:var(--accent);font-weight:600}.brand-sub{font-size:11px;color:var(--muted)}.nav-item{display:flex;align-items:center;gap:10px;background:transparent;border:0;text-align:left;padding:8px 10px;border-radius:var(--radius);color:var(--muted);cursor:pointer;width:100%}.nav-item:hover{background:color-mix(in srgb,var(--rail-active) 70%,transparent);color:var(--ink)}.nav-item.active{background:var(--rail-active);color:var(--ink);font-weight:500}.nav-item svg{flex-shrink:0}.theme-pick{margin-top:14px;display:grid;gap:4px;padding:0 2px}.theme-pick label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:500}.theme-pick select,.field select,.field input,.topbar input,.topbar select,.settings input,.settings select,.explorer-path input{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:0 10px;height:var(--control-h);width:100%}.rail-foot{margin-top:auto;padding:12px 8px 4px;border-top:1px solid var(--line);display:grid;gap:6px}.kbd-hint{font-size:11px;color:var(--muted)}kbd{font-family:var(--mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:0 4px;background:var(--surface)}.main{display:flex;flex-direction:column;min-width:0;min-height:0;position:relative;background:var(--bg)}.progress{position:absolute;top:0;left:0;right:0;height:2px;overflow:hidden;z-index:30;background:color-mix(in srgb,var(--accent) 20%,transparent)}.progress i{display:block;height:100%;width:32%;background:var(--accent);animation:indeterminate 1.1s ease-in-out infinite}.progress.determinate i{width:0;animation:none;transform:none;transition:width .2s ease-out}@keyframes indeterminate{0%{transform:translate(-120%)}to{transform:translate(400%)}}.topbar{display:flex;gap:10px;align-items:flex-end;padding:10px 16px;border-bottom:1px solid var(--line);background:var(--bg-2);flex-wrap:wrap}.field{display:grid;gap:4px;min-width:0}.field>span{font-size:11px;color:var(--muted);font-weight:500}.field.path{flex:1;min-width:180px}.field.ref{width:188px;flex:0 0 188px}.field.workspace{width:180px;flex:0 0 180px}.path-row,.combo-row{display:flex;min-width:0}.path-row input,.combo-row input{flex:1;min-width:0}.combo{position:relative;min-width:0}.combo-row input{border-top-right-radius:0;border-bottom-right-radius:0}.topbar .icon-btn{width:var(--control-h);padding:0;flex:0 0 var(--control-h)}.combo-toggle{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.combo-menu{position:absolute;top:calc(100% + 4px);right:0;left:auto;min-width:340px;max-width:min(480px,70vw);max-height:360px;overflow:auto;z-index:40;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 12px 32px var(--shadow);padding:6px 0}.combo-heading{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;padding:8px 12px 4px}.combo-menu .combo-option{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:transparent;border:0;border-radius:0;height:auto;padding:6px 12px;color:var(--ink);cursor:pointer}.combo-menu .combo-option:hover,.combo-menu .combo-option.active{background:var(--rail-active)}.combo-label{font-family:var(--mono);font-size:12px}.combo-detail{color:var(--muted);font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.combo-empty{padding:10px 12px}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:color-mix(in srgb,var(--bg) 72%,transparent);display:grid;place-items:center;padding:24px}.modal{width:min(720px,100%);max-height:min(640px,90vh);background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:0 16px 48px var(--shadow);display:flex;flex-direction:column;overflow:hidden}.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:14px 16px 10px;border-bottom:1px solid var(--line)}.modal-head h2{font-size:15px}.modal-head .muted{margin:4px 0 0}.explorer-path{display:flex;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line)}.explorer-path input{flex:1;min-width:0}.explorer-list{flex:1;overflow:auto;padding:8px;min-height:220px}.explorer-row{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:0;border-radius:var(--radius);padding:8px 10px;color:var(--ink);cursor:pointer;height:auto}.explorer-row:hover,.explorer-row.active{background:var(--rail-active)}.explorer-name{min-width:0;overflow:hidden;text-overflow:ellipsis}.git-badge{margin-left:auto;margin-bottom:0}.explorer-empty{padding:18px 10px}.modal-foot{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line)}.explorer-current{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:12px}.topbar input,.topbar select{min-width:0}.topbar-actions{display:flex;gap:8px;margin-left:auto;align-items:center;padding-bottom:0}.btn,.topbar button{background:var(--btn);border:1px solid var(--btn-line);border-radius:var(--radius);height:var(--control-h);padding:0 12px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}.btn:hover,.topbar button:hover{filter:brightness(1.08)}.btn:disabled,.topbar button:disabled{opacity:.55;cursor:not-allowed;filter:none}.btn.primary{background:var(--btn-primary);border-color:var(--btn-primary-line)}.btn.ghost{background:transparent}.alerts{display:grid;gap:8px;padding:10px 16px 0}.alerts:empty{display:none;padding:0}.stage{flex:1;min-height:0;display:flex;flex-direction:column}.content{flex:1;min-height:0;display:grid;grid-template-columns:minmax(340px,420px) 1fr}.brief{overflow:auto;border-right:1px solid var(--line);padding:16px 18px 24px;background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--accent) 8%,transparent),transparent 42%),var(--bg)}.graph-wrap{position:relative;min-height:0;display:flex;flex-direction:column}.impact-graph{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.graph-count{margin-left:auto;font-size:11px}.graph-layout{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);letter-spacing:.04em}.graph-layout select{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:0 10px;height:26px;color:var(--ink);font:inherit;font-size:12px;letter-spacing:0;cursor:pointer}.chip-btn{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.chip-btn:hover{color:var(--ink)}.chip-btn.active{background:var(--rail-active);color:var(--ink)}.chip-btn:disabled{opacity:.45;cursor:not-allowed}.graph-stage{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-stage .react-flow,.graph-3d,.graph-3d-host,.graph-3d-canvas-host{flex:1;width:100%;height:100%;min-height:280px}.graph-3d{position:relative;background:var(--graph-bg);display:flex;flex-direction:column}.graph-3d-host{position:relative;min-height:0;display:flex;flex-direction:column}.graph-3d-canvas-host{position:relative;min-height:0;background:var(--graph-bg)}.graph-3d canvas{display:block;width:100%;height:100%}.graph-3d-tip{position:absolute;pointer-events:none;z-index:2;max-width:320px;padding:6px 8px;border-radius:var(--radius);background:var(--surface);border:1px solid var(--line);color:var(--ink);font-size:11px;line-height:1.35;box-shadow:0 8px 24px var(--shadow)}.graph-3d-tip .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.graph-3d-tip .n{font-weight:600}.graph-3d-hint{position:absolute;left:10px;bottom:10px;z-index:2;margin:0;font-size:11px;color:var(--muted);max-width:min(420px,calc(100% - 24px));pointer-events:none}.graph-wrap .react-flow{background-color:var(--graph-bg);background-image:linear-gradient(var(--graph-grid) 1px,transparent 1px),linear-gradient(90deg,var(--graph-grid) 1px,transparent 1px);background-size:24px 24px}.react-flow__minimap{background:var(--graph-bg)!important;border:1px solid var(--line)!important;border-radius:var(--radius);overflow:hidden;box-shadow:0 8px 24px var(--shadow)}.react-flow__minimap-node{fill:var(--muted);stroke:none}.react-flow__minimap-node.selected{fill:var(--accent)}.react-flow__minimap-mask{fill:#00000073!important;stroke:var(--accent)!important}.react-flow__controls{box-shadow:none!important}.react-flow__controls-button{background:var(--surface)!important;border-bottom:1px solid var(--line)!important;fill:var(--ink)!important}h1{font-size:18px;margin:0 0 6px;font-weight:600}h2{font-size:13px;margin:0;font-weight:600}.merge-box{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:12px 14px;margin-bottom:12px}.merge-box.high{border-color:color-mix(in srgb,var(--high) 55%,var(--line))}.merge-box.medium{border-color:color-mix(in srgb,var(--medium) 55%,var(--line))}.merge-box.low{border-color:color-mix(in srgb,var(--low) 55%,var(--line))}.level{font-family:var(--mono);font-weight:600;font-size:14px}.level.high{color:var(--high)}.level.medium{color:var(--medium)}.level.low{color:var(--low)}.merge-title{margin-top:4px;font-size:13px;color:var(--ink)}.reasons{margin:10px 0 0;padding:0 0 0 18px;color:var(--muted)}.reasons li{margin:0 0 4px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 0 14px}.metric{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:8px 10px}.metric .n{font-family:var(--mono);font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}.metric .l{font-size:11px;color:var(--muted);margin-top:2px}.section{border-top:1px solid var(--line);padding:8px 0 4px}.section>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600;padding:6px 0}.section>summary::-webkit-details-marker{display:none}.section>summary .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.kicker{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}.chip{display:inline-flex;align-items:center;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);margin:0 6px 6px 0;color:var(--muted);background:var(--surface)}.chip.blocker{color:var(--low);border-color:var(--low)}.chip.warning{color:var(--medium);border-color:var(--medium)}.chip.strong{color:var(--low);border-color:var(--low)}.chip.worth_exploring{color:var(--medium);border-color:var(--medium)}.chip.speculative{color:var(--muted);border-color:var(--line)}.chip.open{color:var(--high);border-color:color-mix(in srgb,var(--high) 50%,var(--line))}.file{font-family:var(--mono);font-size:12px;color:var(--accent)}.read-item,.finding,.residual{padding:8px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.read-item:last-child,.finding:last-child{border-bottom:0}.read-item.tour-current{background:color-mix(in srgb,var(--accent) 12%,var(--surface));border-color:var(--accent)}.tour-row{margin-top:8px;align-items:center}.field.dirty .chip-btn{height:32px}.muted{color:var(--muted);font-size:13px;line-height:1.45}.error{color:var(--low);padding:8px 12px;border:1px solid var(--low);background:color-mix(in srgb,var(--low) 10%,var(--surface));border-radius:var(--radius);display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner{padding:8px 12px;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);font-size:13px;line-height:1.45;display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner.warn{border-color:var(--medium);color:var(--medium)}.banner.stale{border-color:var(--low);color:var(--low)}.banner.whatif{border-color:var(--accent);align-items:center}.banner.whatif .btn{flex:0 0 auto;white-space:nowrap}.chip.whatif{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 55%,var(--line))}.whatif-hint{margin:10px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.banner .dismiss{background:transparent;border:0;color:inherit;cursor:pointer;height:auto;padding:0 2px;opacity:.7}.empty{padding:24px 8px;color:var(--muted);font-size:13px;line-height:1.55}.workspace-loading{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:220px;padding:48px 16px}.empty h2{font-size:16px;color:var(--ink);margin-bottom:8px}.empty ol{margin:12px 0 0 18px;padding:0}.empty code,code{font-family:var(--mono);font-size:12px;color:var(--accent)}.btn-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.pr-list{padding:16px;overflow:auto}.pr-toolbar{display:flex;gap:8px;align-items:flex-end;margin-bottom:14px}.pr-toolbar .field{flex:1}.pr-toolbar .field.provider{flex:0 0 140px}.scm-count{margin:0 0 12px;font-size:12px}.scm-login{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:10px 0;border-top:1px solid var(--line)}.scm-login:first-of-type{border-top:0;padding-top:0}.scm-login .btn-row{margin-top:0}.scm-login p{margin:2px 0 0}.oauth-code{font-size:13px;margin:0}.oauth-code code{font-size:14px;letter-spacing:.08em}.pr{border:1px solid var(--line);background:var(--surface);padding:12px 14px;border-radius:var(--radius-lg);margin-bottom:10px}.pr h3{margin:0 0 4px;font-size:14px;font-weight:600}.pr-meta{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;margin:6px 0 10px}.pr-actions{display:flex;gap:8px;align-items:center}.settings{padding:24px;max-width:760px;overflow:auto;display:grid;gap:16px}.settings-card{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:16px;display:grid;gap:8px}.settings-card h2{font-size:14px;margin-bottom:2px}.settings label{font-size:12px;color:var(--muted);font-weight:500}.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}.theme-swatch{border:1px solid var(--line);background:var(--bg);color:var(--ink);border-radius:var(--radius);padding:10px;text-align:left;cursor:pointer;height:auto;box-shadow:0 1px 8px var(--shadow)}.theme-swatch.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 1px 8px var(--shadow)}.theme-swatch .swatch-bar{height:6px;border-radius:3px;margin-bottom:8px;background:linear-gradient(90deg,var(--accent),var(--high),var(--medium),var(--low))}.theme-swatch .name{font-size:13px;font-weight:600}.theme-swatch .group{font-size:11px;color:var(--muted)}.headline{white-space:pre-wrap;font-family:var(--mono);font-size:12px;color:var(--muted);margin:8px 0 0}.graph-modes{display:flex;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:2px;background:var(--surface)}.seg button,.graph-modes button{background:transparent;border:0;border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.seg button.active,.graph-modes button.active{background:var(--rail-active);color:var(--ink)}.legend{margin-left:auto;display:flex;gap:12px;color:var(--muted);font-size:11px}.legend i{display:inline-block;width:14px;height:2px;margin-right:6px;vertical-align:middle;background:var(--edge-cheap)}.legend i.exp{background:var(--edge-expensive)}.legend i.crit{background:var(--edge-critical);height:3px}.legend i.dash{border-top:2px dashed var(--muted);background:none;height:0}.legend i.seed{height:10px;width:10px;border-radius:2px;background:color-mix(in srgb,var(--medium) 70%,var(--node-bg))}.legend i.down{height:10px;width:10px;border-radius:2px;border:1px solid color-mix(in srgb,var(--accent) 45%,var(--node-line));background:var(--node-bg)}.inspector{position:absolute;top:12px;right:12px;z-index:5;width:300px;max-width:calc(100% - 24px);max-height:calc(100% - 24px);overflow-x:hidden;overflow-y:auto;overflow-wrap:break-word;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:10px 12px;box-shadow:0 8px 24px var(--shadow);font-size:12px}.inspector .t{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.inspector .n,.inspector .file,.inspector .muted{overflow-wrap:break-word}.inspector .n{font-weight:600;margin:4px 0}.inspector-head{display:flex;align-items:flex-start;gap:8px}.inspector-roles{display:flex;flex-wrap:wrap;justify-content:flex-end;flex:1;gap:4px}.inspector-chip{font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:1px 6px;border-radius:999px;border:1px solid var(--line);color:var(--muted);white-space:nowrap}.inspector-close{flex:0 0 auto;width:24px;height:24px;padding:0;border:1px solid var(--line);border-radius:var(--radius);background:transparent;color:var(--muted);font-size:16px;line-height:1;cursor:pointer}.inspector-close:hover{color:var(--ink)}.inspector-purpose{margin:6px 0 8px;color:var(--ink);font-size:12px;line-height:1.4}.inspector-layer{margin-top:4px;font-size:11px}.inspector-degree{font-size:11px}.inspector-path{margin:6px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.inspector-facts{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--line)}.inspector-fact{display:grid;grid-template-columns:minmax(64px,92px) minmax(0,1fr);gap:8px;padding:3px 0;align-items:start}.inspector-fact dt{color:var(--muted);font-size:11px;margin:0}.inspector-fact dd{margin:0;overflow-wrap:break-word}.inspector-section{margin-top:10px;padding-top:8px;border-top:1px solid var(--line)}.inspector-section h3{margin:0 0 6px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600}.inspector-section .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.inspector-section ul{list-style:none;margin:0;padding:0}.inspector-section li{padding:4px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.inspector-section li:last-child{border-bottom:0}.inspector-link-name{display:block;font-weight:600;overflow-wrap:break-word}.inspector-link-meta{display:block;color:var(--muted);font-size:11px}.lp-node{padding:8px 10px;border-radius:var(--radius);border:1px solid var(--node-line);background:var(--node-bg);width:208px;max-width:100%;height:64px;box-sizing:border-box;box-shadow:0 0 0 1px var(--shadow);overflow:visible;position:relative}.lp-node .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.lp-node .n{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}.lp-node.selected{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.lp-node.role-seed{border-color:var(--medium);background:color-mix(in srgb,var(--medium) 14%,var(--node-bg))}.lp-node.role-downstream{border-color:color-mix(in srgb,var(--accent) 45%,var(--node-line))}.lp-node.role-untested{box-shadow:inset 3px 0 0 var(--low)}.lp-node.role-tested{box-shadow:inset 3px 0 0 var(--high)}.lp-node.role-contract{outline:1px dashed color-mix(in srgb,var(--accent) 50%,transparent)}.lp-node.dim{opacity:.38}.merge-box.compact{padding:6px 10px;min-width:92px;margin:0}.merge-box.compact .level{font-size:12px}.palette-scrim{position:fixed;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--bg) 55%,transparent);z-index:40;display:grid;place-items:start center;padding-top:12vh}.palette{width:min(640px,calc(100vw - 32px));background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:0 18px 60px var(--shadow);overflow:hidden}.palette input{width:100%;border:0;border-bottom:1px solid var(--line);background:transparent;color:var(--ink);padding:14px 16px;font:inherit}.palette ul{list-style:none;margin:0;padding:6px;max-height:360px;overflow:auto}.palette li button{width:100%;display:flex;justify-content:space-between;gap:12px;text-align:left;background:transparent;border:0;color:var(--ink);padding:8px 10px;border-radius:8px;cursor:pointer}.palette li button.active,.palette li button:hover{background:var(--rail-active)}.palette-foot{padding:8px 12px 10px}.graph-search{position:relative;min-width:140px}.graph-search input{width:100%;background:var(--bg-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:6px 8px;font:inherit}.graph-search-hits{position:absolute;z-index:5;left:0;right:0;top:calc(100% + 4px);background:var(--surface);border:1px solid var(--line);border-radius:8px;list-style:none;margin:0;padding:4px;max-height:240px;overflow:auto}.graph-search-hits button{width:100%;display:flex;justify-content:space-between;gap:8px;background:transparent;border:0;color:var(--ink);text-align:left;padding:6px 8px;cursor:pointer}.graph-search-hits button:hover{background:var(--rail-active)}.inspector-link{display:flex;flex-direction:column;width:100%;background:transparent;border:0;color:inherit;text-align:left;cursor:pointer;padding:0}.file-row{display:flex;flex-direction:column;gap:6px}.linkish{background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer;padding:0}.history-item,.check-item{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;width:100%;background:transparent;border:0;color:inherit;font:inherit;text-align:left;padding:6px 0;cursor:pointer}.history-item.current{color:var(--accent)}.check-row{display:flex;gap:8px;align-items:center;margin:4px 0}.sparkline{display:flex;align-items:flex-end;gap:3px;height:36px;margin:8px 0}.sparkline i{flex:1;background:var(--muted);border-radius:2px 2px 0 0;min-width:4px}.sparkline i.high{background:var(--high)}.sparkline i.medium{background:var(--medium)}.sparkline i.low{background:var(--low)}.config-editor .field{display:flex;flex-direction:column;gap:4px;margin:8px 0}.config-editor input,.config-editor select{background:var(--bg-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:6px 8px}.react-flow__node-load .react-flow__handle{width:8px;height:8px;border:none;background:transparent;opacity:0}.type-table{width:100%;border-collapse:collapse;font-size:12px}.type-table td{padding:3px 0}.type-table td:last-child{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--muted)}@media(prefers-reduced-motion:reduce){.progress i{animation:none;width:100%}.progress.determinate i{width:var(--progress, 100%)}*{scroll-behavior:auto!important}}@media(max-width:960px){.app{grid-template-columns:56px 1fr}.brand-sub,.nav-item span,.theme-pick,.kbd-hint,.rail-foot .muted{display:none}.nav-item{justify-content:center;padding:10px}.content{grid-template-columns:1fr}.brief{border-right:0;border-bottom:1px solid var(--line);max-height:42vh}} diff --git a/src/loadpath/static/assets/index-cvBsmXkd.js b/src/loadpath/static/assets/index-cvBsmXkd.js deleted file mode 100644 index fa22bbf..0000000 --- a/src/loadpath/static/assets/index-cvBsmXkd.js +++ /dev/null @@ -1,62 +0,0 @@ -(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const u of a)if(u.type==="childList")for(const c of u.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function o(a){const u={};return a.integrity&&(u.integrity=a.integrity),a.referrerPolicy&&(u.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?u.credentials="include":a.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(a){if(a.ep)return;a.ep=!0;const u=o(a);fetch(a.href,u)}})();function bp(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Au={exports:{}},Uo={},$u={exports:{}},Te={};/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Qf;function r0(){if(Qf)return Te;Qf=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),c=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),v=Symbol.iterator;function m(I){return I===null||typeof I!="object"?null:(I=v&&I[v]||I["@@iterator"],typeof I=="function"?I:null)}var _={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},k=Object.assign,j={};function b(I,z,ie){this.props=I,this.context=z,this.refs=j,this.updater=ie||_}b.prototype.isReactComponent={},b.prototype.setState=function(I,z){if(typeof I!="object"&&typeof I!="function"&&I!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,I,z,"setState")},b.prototype.forceUpdate=function(I){this.updater.enqueueForceUpdate(this,I,"forceUpdate")};function E(){}E.prototype=b.prototype;function R(I,z,ie){this.props=I,this.context=z,this.refs=j,this.updater=ie||_}var w=R.prototype=new E;w.constructor=R,k(w,b.prototype),w.isPureReactComponent=!0;var N=Array.isArray,A=Object.prototype.hasOwnProperty,$={current:null},F={key:!0,ref:!0,__self:!0,__source:!0};function G(I,z,ie){var oe,fe={},he=null,pe=null;if(z!=null)for(oe in z.ref!==void 0&&(pe=z.ref),z.key!==void 0&&(he=""+z.key),z)A.call(z,oe)&&!F.hasOwnProperty(oe)&&(fe[oe]=z[oe]);var Z=arguments.length-2;if(Z===1)fe.children=ie;else if(1>>1,z=M[I];if(0>>1;Ia(fe,H))hea(pe,fe)?(M[I]=pe,M[he]=H,I=he):(M[I]=fe,M[oe]=H,I=oe);else if(hea(pe,H))M[I]=pe,M[he]=H,I=he;else break e}}return D}function a(M,D){var H=M.sortIndex-D.sortIndex;return H!==0?H:M.id-D.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;t.unstable_now=function(){return u.now()}}else{var c=Date,h=c.now();t.unstable_now=function(){return c.now()-h}}var p=[],y=[],x=1,v=null,m=3,_=!1,k=!1,j=!1,b=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,R=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function w(M){for(var D=o(y);D!==null;){if(D.callback===null)s(y);else if(D.startTime<=M)s(y),D.sortIndex=D.expirationTime,r(p,D);else break;D=o(y)}}function N(M){if(j=!1,w(M),!k)if(o(p)!==null)k=!0,W(A);else{var D=o(y);D!==null&&U(N,D.startTime-M)}}function A(M,D){k=!1,j&&(j=!1,E(G),G=-1),_=!0;var H=m;try{for(w(D),v=o(p);v!==null&&(!(v.expirationTime>D)||M&&!ee());){var I=v.callback;if(typeof I=="function"){v.callback=null,m=v.priorityLevel;var z=I(v.expirationTime<=D);D=t.unstable_now(),typeof z=="function"?v.callback=z:v===o(p)&&s(p),w(D)}else s(p);v=o(p)}if(v!==null)var ie=!0;else{var oe=o(y);oe!==null&&U(N,oe.startTime-D),ie=!1}return ie}finally{v=null,m=H,_=!1}}var $=!1,F=null,G=-1,q=5,te=-1;function ee(){return!(t.unstable_now()-teM||125I?(M.sortIndex=H,r(y,M),o(p)===null&&M===o(y)&&(j?(E(G),G=-1):j=!0,U(N,H-I))):(M.sortIndex=z,r(p,M),k||_||(k=!0,W(A))),M},t.unstable_shouldYield=ee,t.unstable_wrapCallback=function(M){var D=m;return function(){var H=m;m=D;try{return M.apply(this,arguments)}finally{m=H}}}})(Ou)),Ou}var nh;function a0(){return nh||(nh=1,Du.exports=l0()),Du.exports}/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var rh;function u0(){if(rh)return Dt;rh=1;var t=cs(),r=a0();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,i=1;i"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,y=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,x={},v={};function m(e){return p.call(v,e)?!0:p.call(x,e)?!1:y.test(e)?v[e]=!0:(x[e]=!0,!1)}function _(e,n,i,l){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return l?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function k(e,n,i,l){if(n===null||typeof n>"u"||_(e,n,i,l))return!0;if(l)return!1;if(i!==null)switch(i.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function j(e,n,i,l,f,g,S){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=l,this.attributeNamespace=f,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=g,this.removeEmptyString=S}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){b[e]=new j(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];b[n]=new j(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){b[e]=new j(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){b[e]=new j(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){b[e]=new j(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){b[e]=new j(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){b[e]=new j(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){b[e]=new j(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){b[e]=new j(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function R(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(E,R);b[n]=new j(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(E,R);b[n]=new j(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(E,R);b[n]=new j(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){b[e]=new j(e,1,!1,e.toLowerCase(),null,!1,!1)}),b.xlinkHref=new j("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){b[e]=new j(e,1,!1,e.toLowerCase(),null,!0,!0)});function w(e,n,i,l){var f=b.hasOwnProperty(n)?b[n]:null;(f!==null?f.type!==0:l||!(2T||f[S]!==g[T]){var O=` -`+f[S].replace(" at new "," at ");return e.displayName&&O.includes("")&&(O=O.replace("",e.displayName)),O}while(1<=S&&0<=T);break}}}finally{ie=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?z(e):""}function fe(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("SuspenseList");case 0:case 2:case 15:return e=oe(e.type,!1),e;case 11:return e=oe(e.type.render,!1),e;case 1:return e=oe(e.type,!0),e;default:return""}}function he(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case F:return"Fragment";case $:return"Portal";case q:return"Profiler";case G:return"StrictMode";case K:return"Suspense";case C:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case ee:return(e.displayName||"Context")+".Consumer";case te:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case V:return n=e.displayName||null,n!==null?n:he(e.type)||"Memo";case W:n=e._payload,e=e._init;try{return he(e(n))}catch{}}return null}function pe(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return he(n);case 8:return n===G?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Z(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function se(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function me(e){var n=se(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),l=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var f=i.get,g=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return f.call(this)},set:function(S){l=""+S,g.call(this,S)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return l},setValue:function(S){l=""+S},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function ke(e){e._valueTracker||(e._valueTracker=me(e))}function ve(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),l="";return e&&(l=se(e)?e.checked?"true":"false":e.value),e=l,e!==i?(n.setValue(e),!0):!1}function re(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ne(e,n){var i=n.checked;return H({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Ie(e,n){var i=n.defaultValue==null?"":n.defaultValue,l=n.checked!=null?n.checked:n.defaultChecked;i=Z(n.value!=null?n.value:i),e._wrapperState={initialChecked:l,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Le(e,n){n=n.checked,n!=null&&w(e,"checked",n,!1)}function $e(e,n){Le(e,n);var i=Z(n.value),l=n.type;if(i!=null)l==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(l==="submit"||l==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?at(e,n.type,i):n.hasOwnProperty("defaultValue")&&at(e,n.type,Z(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function lt(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var l=n.type;if(!(l!=="submit"&&l!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,i||n===e.value||(e.value=n),e.defaultValue=n}i=e.name,i!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,i!==""&&(e.name=i)}function at(e,n,i){(n!=="number"||re(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var ut=Array.isArray;function Ge(e,n,i,l){if(e=e.options,n){n={};for(var f=0;f"+n.valueOf().toString()+"",n=et.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function Mt(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var kn={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},oo=["Webkit","ms","Moz","O"];Object.keys(kn).forEach(function(e){oo.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),kn[n]=kn[e]})});function On(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||kn.hasOwnProperty(e)&&kn[e]?(""+n).trim():n+"px"}function gi(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var l=i.indexOf("--")===0,f=On(i,n[i],l);i==="float"&&(i="cssFloat"),l?e.setProperty(i,f):e[i]=f}}var lr=H({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function zr(e,n){if(n){if(lr[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(o(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(o(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(o(61))}if(n.style!=null&&typeof n.style!="object")throw Error(o(62))}}function Fn(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Dr=null;function ar(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var ur=null,Ft=null,dt=null;function Hn(e){if(e=Po(e)){if(typeof ur!="function")throw Error(o(280));var n=e.stateNode;n&&(n=Ts(n),ur(e.stateNode,e.type,n))}}function Bn(e){Ft?dt?dt.push(e):dt=[e]:Ft=e}function Nn(){if(Ft){var e=Ft,n=dt;if(dt=Ft=null,Hn(e),n)for(e=0;e>>=0,e===0?32:31-(uo(e)/co|0)|0}var Mn=64,Xn=4194304;function Pn(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function qt(e,n){var i=e.pendingLanes;if(i===0)return 0;var l=0,f=e.suspendedLanes,g=e.pingedLanes,S=i&268435455;if(S!==0){var T=S&~f;T!==0?l=Pn(T):(g&=S,g!==0&&(l=Pn(g)))}else S=i&~f,S!==0?l=Pn(S):g!==0&&(l=Pn(g));if(l===0)return 0;if(n!==0&&n!==l&&(n&f)===0&&(f=l&-l,g=n&-n,f>=g||f===16&&(g&4194240)!==0))return n;if((l&4)!==0&&(l|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=l;0i;i++)n.push(e);return n}function qn(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-yt(n),e[n]=i}function _i(e,n){var i=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var l=e.eventTimes;for(e=e.expirationTimes;0=_o),Vc=" ",Wc=!1;function Uc(e,n){switch(e){case"keyup":return Zm.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Yc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var bi=!1;function ey(e,n){switch(e){case"compositionend":return Yc(n);case"keypress":return n.which!==32?null:(Wc=!0,Vc);case"textInput":return e=n.data,e===Vc&&Wc?null:e;default:return null}}function ty(e,n){if(bi)return e==="compositionend"||!ga&&Uc(e,n)?(e=zc(),Ss=ua=mr=null,bi=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:i,offset:n-e};e=l}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=Jc(i)}}function td(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?td(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function nd(){for(var e=window,n=re();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=re(e.document)}return n}function va(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function cy(e){var n=nd(),i=e.focusedElem,l=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&td(i.ownerDocument.documentElement,i)){if(l!==null&&va(i)){if(n=l.start,e=l.end,e===void 0&&(e=n),"selectionStart"in i)i.selectionStart=n,i.selectionEnd=Math.min(e,i.value.length);else if(e=(n=i.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var f=i.textContent.length,g=Math.min(l.start,f);l=l.end===void 0?g:Math.min(l.end,f),!e.extend&&g>l&&(f=l,l=g,g=f),f=ed(i,g);var S=ed(i,l);f&&S&&(e.rangeCount!==1||e.anchorNode!==f.node||e.anchorOffset!==f.offset||e.focusNode!==S.node||e.focusOffset!==S.offset)&&(n=n.createRange(),n.setStart(f.node,f.offset),e.removeAllRanges(),g>l?(e.addRange(n),e.extend(S.node,S.offset)):(n.setEnd(S.node,S.offset),e.addRange(n)))}}for(n=[],e=i;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof i.focus=="function"&&i.focus(),i=0;i=document.documentMode,Ei=null,xa=null,jo=null,wa=!1;function rd(e,n,i){var l=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;wa||Ei==null||Ei!==re(l)||(l=Ei,"selectionStart"in l&&va(l)?l={start:l.selectionStart,end:l.selectionEnd}:(l=(l.ownerDocument&&l.ownerDocument.defaultView||window).getSelection(),l={anchorNode:l.anchorNode,anchorOffset:l.anchorOffset,focusNode:l.focusNode,focusOffset:l.focusOffset}),jo&&No(jo,l)||(jo=l,l=Ps(xa,"onSelect"),0Ri||(e.current=Ra[Ri],Ra[Ri]=null,Ri--)}function Be(e,n){Ri++,Ra[Ri]=e.current,e.current=n}var wr={},St=xr(wr),Tt=xr(!1),Xr=wr;function Ti(e,n){var i=e.type.contextTypes;if(!i)return wr;var l=e.stateNode;if(l&&l.__reactInternalMemoizedUnmaskedChildContext===n)return l.__reactInternalMemoizedMaskedChildContext;var f={},g;for(g in i)f[g]=n[g];return l&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=f),f}function Lt(e){return e=e.childContextTypes,e!=null}function Ls(){Ue(Tt),Ue(St)}function vd(e,n,i){if(St.current!==wr)throw Error(o(168));Be(St,n),Be(Tt,i)}function xd(e,n,i){var l=e.stateNode;if(n=n.childContextTypes,typeof l.getChildContext!="function")return i;l=l.getChildContext();for(var f in l)if(!(f in n))throw Error(o(108,pe(e)||"Unknown",f));return H({},i,l)}function As(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||wr,Xr=St.current,Be(St,e),Be(Tt,Tt.current),!0}function wd(e,n,i){var l=e.stateNode;if(!l)throw Error(o(169));i?(e=xd(e,n,Xr),l.__reactInternalMemoizedMergedChildContext=e,Ue(Tt),Ue(St),Be(St,e)):Ue(Tt),Be(Tt,i)}var Qn=null,$s=!1,Ta=!1;function _d(e){Qn===null?Qn=[e]:Qn.push(e)}function Sy(e){$s=!0,_d(e)}function _r(){if(!Ta&&Qn!==null){Ta=!0;var e=0,n=Fe;try{var i=Qn;for(Fe=1;e>=S,f-=S,Zn=1<<32-yt(n)+f|i<Ce?(pt=be,be=null):pt=be.sibling;var Oe=le(X,be,Q[Ce],de);if(Oe===null){be===null&&(be=pt);break}e&&be&&Oe.alternate===null&&n(X,be),B=g(Oe,B,Ce),je===null?_e=Oe:je.sibling=Oe,je=Oe,be=pt}if(Ce===Q.length)return i(X,be),Xe&&Kr(X,Ce),_e;if(be===null){for(;CeCe?(pt=be,be=null):pt=be.sibling;var Pr=le(X,be,Oe.value,de);if(Pr===null){be===null&&(be=pt);break}e&&be&&Pr.alternate===null&&n(X,be),B=g(Pr,B,Ce),je===null?_e=Pr:je.sibling=Pr,je=Pr,be=pt}if(Oe.done)return i(X,be),Xe&&Kr(X,Ce),_e;if(be===null){for(;!Oe.done;Ce++,Oe=Q.next())Oe=ue(X,Oe.value,de),Oe!==null&&(B=g(Oe,B,Ce),je===null?_e=Oe:je.sibling=Oe,je=Oe);return Xe&&Kr(X,Ce),_e}for(be=l(X,be);!Oe.done;Ce++,Oe=Q.next())Oe=ge(be,X,Ce,Oe.value,de),Oe!==null&&(e&&Oe.alternate!==null&&be.delete(Oe.key===null?Ce:Oe.key),B=g(Oe,B,Ce),je===null?_e=Oe:je.sibling=Oe,je=Oe);return e&&be.forEach(function(n0){return n(X,n0)}),Xe&&Kr(X,Ce),_e}function tt(X,B,Q,de){if(typeof Q=="object"&&Q!==null&&Q.type===F&&Q.key===null&&(Q=Q.props.children),typeof Q=="object"&&Q!==null){switch(Q.$$typeof){case A:e:{for(var _e=Q.key,je=B;je!==null;){if(je.key===_e){if(_e=Q.type,_e===F){if(je.tag===7){i(X,je.sibling),B=f(je,Q.props.children),B.return=X,X=B;break e}}else if(je.elementType===_e||typeof _e=="object"&&_e!==null&&_e.$$typeof===W&&Ed(_e)===je.type){i(X,je.sibling),B=f(je,Q.props),B.ref=Io(X,je,Q),B.return=X,X=B;break e}i(X,je);break}else n(X,je);je=je.sibling}Q.type===F?(B=ii(Q.props.children,X.mode,de,Q.key),B.return=X,X=B):(de=cl(Q.type,Q.key,Q.props,null,X.mode,de),de.ref=Io(X,B,Q),de.return=X,X=de)}return S(X);case $:e:{for(je=Q.key;B!==null;){if(B.key===je)if(B.tag===4&&B.stateNode.containerInfo===Q.containerInfo&&B.stateNode.implementation===Q.implementation){i(X,B.sibling),B=f(B,Q.children||[]),B.return=X,X=B;break e}else{i(X,B);break}else n(X,B);B=B.sibling}B=Pu(Q,X.mode,de),B.return=X,X=B}return S(X);case W:return je=Q._init,tt(X,B,je(Q._payload),de)}if(ut(Q))return xe(X,B,Q,de);if(D(Q))return we(X,B,Q,de);Fs(X,Q)}return typeof Q=="string"&&Q!==""||typeof Q=="number"?(Q=""+Q,B!==null&&B.tag===6?(i(X,B.sibling),B=f(B,Q),B.return=X,X=B):(i(X,B),B=Mu(Q,X.mode,de),B.return=X,X=B),S(X)):i(X,B)}return tt}var zi=Cd(!0),Md=Cd(!1),Hs=xr(null),Bs=null,Di=null,Oa=null;function Fa(){Oa=Di=Bs=null}function Ha(e){var n=Hs.current;Ue(Hs),e._currentValue=n}function Ba(e,n,i){for(;e!==null;){var l=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,l!==null&&(l.childLanes|=n)):l!==null&&(l.childLanes&n)!==n&&(l.childLanes|=n),e===i)break;e=e.return}}function Oi(e,n){Bs=e,Oa=Di=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(At=!0),e.firstContext=null)}function Zt(e){var n=e._currentValue;if(Oa!==e)if(e={context:e,memoizedValue:n,next:null},Di===null){if(Bs===null)throw Error(o(308));Di=e,Bs.dependencies={lanes:0,firstContext:e}}else Di=Di.next=e;return n}var Qr=null;function Va(e){Qr===null?Qr=[e]:Qr.push(e)}function Pd(e,n,i,l){var f=n.interleaved;return f===null?(i.next=i,Va(n)):(i.next=f.next,f.next=i),n.interleaved=i,er(e,l)}function er(e,n){e.lanes|=n;var i=e.alternate;for(i!==null&&(i.lanes|=n),i=e,e=e.return;e!==null;)e.childLanes|=n,i=e.alternate,i!==null&&(i.childLanes|=n),i=e,e=e.return;return i.tag===3?i.stateNode:null}var Sr=!1;function Wa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Id(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function tr(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function kr(e,n,i){var l=e.updateQueue;if(l===null)return null;if(l=l.shared,(ze&2)!==0){var f=l.pending;return f===null?n.next=n:(n.next=f.next,f.next=n),l.pending=n,er(e,i)}return f=l.interleaved,f===null?(n.next=n,Va(l)):(n.next=f.next,f.next=n),l.interleaved=n,er(e,i)}function Vs(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,pr(e,i)}}function Rd(e,n){var i=e.updateQueue,l=e.alternate;if(l!==null&&(l=l.updateQueue,i===l)){var f=null,g=null;if(i=i.firstBaseUpdate,i!==null){do{var S={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};g===null?f=g=S:g=g.next=S,i=i.next}while(i!==null);g===null?f=g=n:g=g.next=n}else f=g=n;i={baseState:l.baseState,firstBaseUpdate:f,lastBaseUpdate:g,shared:l.shared,effects:l.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function Ws(e,n,i,l){var f=e.updateQueue;Sr=!1;var g=f.firstBaseUpdate,S=f.lastBaseUpdate,T=f.shared.pending;if(T!==null){f.shared.pending=null;var O=T,J=O.next;O.next=null,S===null?g=J:S.next=J,S=O;var ae=e.alternate;ae!==null&&(ae=ae.updateQueue,T=ae.lastBaseUpdate,T!==S&&(T===null?ae.firstBaseUpdate=J:T.next=J,ae.lastBaseUpdate=O))}if(g!==null){var ue=f.baseState;S=0,ae=J=O=null,T=g;do{var le=T.lane,ge=T.eventTime;if((l&le)===le){ae!==null&&(ae=ae.next={eventTime:ge,lane:0,tag:T.tag,payload:T.payload,callback:T.callback,next:null});e:{var xe=e,we=T;switch(le=n,ge=i,we.tag){case 1:if(xe=we.payload,typeof xe=="function"){ue=xe.call(ge,ue,le);break e}ue=xe;break e;case 3:xe.flags=xe.flags&-65537|128;case 0:if(xe=we.payload,le=typeof xe=="function"?xe.call(ge,ue,le):xe,le==null)break e;ue=H({},ue,le);break e;case 2:Sr=!0}}T.callback!==null&&T.lane!==0&&(e.flags|=64,le=f.effects,le===null?f.effects=[T]:le.push(T))}else ge={eventTime:ge,lane:le,tag:T.tag,payload:T.payload,callback:T.callback,next:null},ae===null?(J=ae=ge,O=ue):ae=ae.next=ge,S|=le;if(T=T.next,T===null){if(T=f.shared.pending,T===null)break;le=T,T=le.next,le.next=null,f.lastBaseUpdate=le,f.shared.pending=null}}while(!0);if(ae===null&&(O=ue),f.baseState=O,f.firstBaseUpdate=J,f.lastBaseUpdate=ae,n=f.shared.interleaved,n!==null){f=n;do S|=f.lane,f=f.next;while(f!==n)}else g===null&&(f.shared.lanes=0);ei|=S,e.lanes=S,e.memoizedState=ue}}function Td(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var l=qa.transition;qa.transition={};try{e(!1),n()}finally{Fe=i,qa.transition=l}}function Zd(){return Jt().memoizedState}function by(e,n,i){var l=Er(e);if(i={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null},Jd(e))ef(n,i);else if(i=Pd(e,n,i,l),i!==null){var f=Et();gn(i,e,l,f),tf(i,n,l)}}function Ey(e,n,i){var l=Er(e),f={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null};if(Jd(e))ef(n,f);else{var g=e.alternate;if(e.lanes===0&&(g===null||g.lanes===0)&&(g=n.lastRenderedReducer,g!==null))try{var S=n.lastRenderedState,T=g(S,i);if(f.hasEagerState=!0,f.eagerState=T,cn(T,S)){var O=n.interleaved;O===null?(f.next=f,Va(n)):(f.next=O.next,O.next=f),n.interleaved=f;return}}catch{}finally{}i=Pd(e,n,f,l),i!==null&&(f=Et(),gn(i,e,l,f),tf(i,n,l))}}function Jd(e){var n=e.alternate;return e===Ke||n!==null&&n===Ke}function ef(e,n){Ao=Gs=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function tf(e,n,i){if((i&4194240)!==0){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,pr(e,i)}}var Ks={readContext:Zt,useCallback:kt,useContext:kt,useEffect:kt,useImperativeHandle:kt,useInsertionEffect:kt,useLayoutEffect:kt,useMemo:kt,useReducer:kt,useRef:kt,useState:kt,useDebugValue:kt,useDeferredValue:kt,useTransition:kt,useMutableSource:kt,useSyncExternalStore:kt,useId:kt,unstable_isNewReconciler:!1},Cy={readContext:Zt,useCallback:function(e,n){return Tn().memoizedState=[e,n===void 0?null:n],e},useContext:Zt,useEffect:Wd,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,Xs(4194308,4,Gd.bind(null,n,e),i)},useLayoutEffect:function(e,n){return Xs(4194308,4,e,n)},useInsertionEffect:function(e,n){return Xs(4,2,e,n)},useMemo:function(e,n){var i=Tn();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var l=Tn();return n=i!==void 0?i(n):n,l.memoizedState=l.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},l.queue=e,e=e.dispatch=by.bind(null,Ke,e),[l.memoizedState,e]},useRef:function(e){var n=Tn();return e={current:e},n.memoizedState=e},useState:Bd,useDebugValue:nu,useDeferredValue:function(e){return Tn().memoizedState=e},useTransition:function(){var e=Bd(!1),n=e[0];return e=jy.bind(null,e[1]),Tn().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var l=Ke,f=Tn();if(Xe){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),ht===null)throw Error(o(349));(Jr&30)!==0||zd(l,n,i)}f.memoizedState=i;var g={value:i,getSnapshot:n};return f.queue=g,Wd(Od.bind(null,l,g,e),[e]),l.flags|=2048,Do(9,Dd.bind(null,l,g,i,n),void 0,null),i},useId:function(){var e=Tn(),n=ht.identifierPrefix;if(Xe){var i=Jn,l=Zn;i=(l&~(1<<32-yt(l)-1)).toString(32)+i,n=":"+n+"R"+i,i=$o++,0<\/script>",e=e.removeChild(e.firstChild)):typeof l.is=="string"?e=S.createElement(i,{is:l.is}):(e=S.createElement(i),i==="select"&&(S=e,l.multiple?S.multiple=!0:l.size&&(S.size=l.size))):e=S.createElementNS(e,i),e[In]=n,e[Mo]=l,Sf(e,n,!1,!1),n.stateNode=e;e:{switch(S=Fn(i,l),i){case"dialog":We("cancel",e),We("close",e),f=l;break;case"iframe":case"object":case"embed":We("load",e),f=l;break;case"video":case"audio":for(f=0;fWi&&(n.flags|=128,l=!0,Oo(g,!1),n.lanes=4194304)}else{if(!l)if(e=Us(S),e!==null){if(n.flags|=128,l=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),Oo(g,!0),g.tail===null&&g.tailMode==="hidden"&&!S.alternate&&!Xe)return Nt(n),null}else 2*Ve()-g.renderingStartTime>Wi&&i!==1073741824&&(n.flags|=128,l=!0,Oo(g,!1),n.lanes=4194304);g.isBackwards?(S.sibling=n.child,n.child=S):(i=g.last,i!==null?i.sibling=S:n.child=S,g.last=S)}return g.tail!==null?(n=g.tail,g.rendering=n,g.tail=n.sibling,g.renderingStartTime=Ve(),n.sibling=null,i=qe.current,Be(qe,l?i&1|2:i&1),n):(Nt(n),null);case 22:case 23:return bu(),l=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==l&&(n.flags|=8192),l&&(n.mode&1)!==0?(Wt&1073741824)!==0&&(Nt(n),n.subtreeFlags&6&&(n.flags|=8192)):Nt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function $y(e,n){switch(Aa(n),n.tag){case 1:return Lt(n.type)&&Ls(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Fi(),Ue(Tt),Ue(St),Xa(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return Ya(n),null;case 13:if(Ue(qe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));$i()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return Ue(qe),null;case 4:return Fi(),null;case 10:return Ha(n.type._context),null;case 22:case 23:return bu(),null;case 24:return null;default:return null}}var el=!1,jt=!1,zy=typeof WeakSet=="function"?WeakSet:Set,ye=null;function Bi(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(l){Je(e,n,l)}else i.current=null}function pu(e,n,i){try{i()}catch(l){Je(e,n,l)}}var jf=!1;function Dy(e,n){if(ba=ws,e=nd(),va(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var l=i.getSelection&&i.getSelection();if(l&&l.rangeCount!==0){i=l.anchorNode;var f=l.anchorOffset,g=l.focusNode;l=l.focusOffset;try{i.nodeType,g.nodeType}catch{i=null;break e}var S=0,T=-1,O=-1,J=0,ae=0,ue=e,le=null;t:for(;;){for(var ge;ue!==i||f!==0&&ue.nodeType!==3||(T=S+f),ue!==g||l!==0&&ue.nodeType!==3||(O=S+l),ue.nodeType===3&&(S+=ue.nodeValue.length),(ge=ue.firstChild)!==null;)le=ue,ue=ge;for(;;){if(ue===e)break t;if(le===i&&++J===f&&(T=S),le===g&&++ae===l&&(O=S),(ge=ue.nextSibling)!==null)break;ue=le,le=ue.parentNode}ue=ge}i=T===-1||O===-1?null:{start:T,end:O}}else i=null}i=i||{start:0,end:0}}else i=null;for(Ea={focusedElem:e,selectionRange:i},ws=!1,ye=n;ye!==null;)if(n=ye,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,ye=e;else for(;ye!==null;){n=ye;try{var xe=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(xe!==null){var we=xe.memoizedProps,tt=xe.memoizedState,X=n.stateNode,B=X.getSnapshotBeforeUpdate(n.elementType===n.type?we:fn(n.type,we),tt);X.__reactInternalSnapshotBeforeUpdate=B}break;case 3:var Q=n.stateNode.containerInfo;Q.nodeType===1?Q.textContent="":Q.nodeType===9&&Q.documentElement&&Q.removeChild(Q.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(de){Je(n,n.return,de)}if(e=n.sibling,e!==null){e.return=n.return,ye=e;break}ye=n.return}return xe=jf,jf=!1,xe}function Fo(e,n,i){var l=n.updateQueue;if(l=l!==null?l.lastEffect:null,l!==null){var f=l=l.next;do{if((f.tag&e)===e){var g=f.destroy;f.destroy=void 0,g!==void 0&&pu(n,i,g)}f=f.next}while(f!==l)}}function tl(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var l=i.create;i.destroy=l()}i=i.next}while(i!==n)}}function gu(e){var n=e.ref;if(n!==null){var i=e.stateNode;switch(e.tag){case 5:e=i;break;default:e=i}typeof n=="function"?n(e):n.current=e}}function bf(e){var n=e.alternate;n!==null&&(e.alternate=null,bf(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[In],delete n[Mo],delete n[Ia],delete n[wy],delete n[_y])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Ef(e){return e.tag===5||e.tag===3||e.tag===4}function Cf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Ef(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function mu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.nodeType===8?i.parentNode.insertBefore(e,n):i.insertBefore(e,n):(i.nodeType===8?(n=i.parentNode,n.insertBefore(e,i)):(n=i,n.appendChild(e)),i=i._reactRootContainer,i!=null||n.onclick!==null||(n.onclick=Rs));else if(l!==4&&(e=e.child,e!==null))for(mu(e,n,i),e=e.sibling;e!==null;)mu(e,n,i),e=e.sibling}function yu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(l!==4&&(e=e.child,e!==null))for(yu(e,n,i),e=e.sibling;e!==null;)yu(e,n,i),e=e.sibling}var vt=null,hn=!1;function Nr(e,n,i){for(i=i.child;i!==null;)Mf(e,n,i),i=i.sibling}function Mf(e,n,i){if(_t&&typeof _t.onCommitFiberUnmount=="function")try{_t.onCommitFiberUnmount(Cn,i)}catch{}switch(i.tag){case 5:jt||Bi(i,n);case 6:var l=vt,f=hn;vt=null,Nr(e,n,i),vt=l,hn=f,vt!==null&&(hn?(e=vt,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):vt.removeChild(i.stateNode));break;case 18:vt!==null&&(hn?(e=vt,i=i.stateNode,e.nodeType===8?Pa(e.parentNode,i):e.nodeType===1&&Pa(e,i),vo(e)):Pa(vt,i.stateNode));break;case 4:l=vt,f=hn,vt=i.stateNode.containerInfo,hn=!0,Nr(e,n,i),vt=l,hn=f;break;case 0:case 11:case 14:case 15:if(!jt&&(l=i.updateQueue,l!==null&&(l=l.lastEffect,l!==null))){f=l=l.next;do{var g=f,S=g.destroy;g=g.tag,S!==void 0&&((g&2)!==0||(g&4)!==0)&&pu(i,n,S),f=f.next}while(f!==l)}Nr(e,n,i);break;case 1:if(!jt&&(Bi(i,n),l=i.stateNode,typeof l.componentWillUnmount=="function"))try{l.props=i.memoizedProps,l.state=i.memoizedState,l.componentWillUnmount()}catch(T){Je(i,n,T)}Nr(e,n,i);break;case 21:Nr(e,n,i);break;case 22:i.mode&1?(jt=(l=jt)||i.memoizedState!==null,Nr(e,n,i),jt=l):Nr(e,n,i);break;default:Nr(e,n,i)}}function Pf(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new zy),n.forEach(function(l){var f=Gy.bind(null,e,l);i.has(l)||(i.add(l),l.then(f,f))})}}function pn(e,n){var i=n.deletions;if(i!==null)for(var l=0;lf&&(f=S),l&=~g}if(l=f,l=Ve()-l,l=(120>l?120:480>l?480:1080>l?1080:1920>l?1920:3e3>l?3e3:4320>l?4320:1960*Fy(l/1960))-l,10e?16:e,br===null)var l=!1;else{if(e=br,br=null,sl=0,(ze&6)!==0)throw Error(o(331));var f=ze;for(ze|=4,ye=e.current;ye!==null;){var g=ye,S=g.child;if((ye.flags&16)!==0){var T=g.deletions;if(T!==null){for(var O=0;OVe()-wu?ni(e,0):xu|=i),zt(e,n)}function Vf(e,n){n===0&&((e.mode&1)===0?n=1:(n=Xn,Xn<<=1,(Xn&130023424)===0&&(Xn=4194304)));var i=Et();e=er(e,n),e!==null&&(qn(e,n,i),zt(e,i))}function Yy(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Vf(e,i)}function Gy(e,n){var i=0;switch(e.tag){case 13:var l=e.stateNode,f=e.memoizedState;f!==null&&(i=f.retryLane);break;case 19:l=e.stateNode;break;default:throw Error(o(314))}l!==null&&l.delete(n),Vf(e,i)}var Wf;Wf=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||Tt.current)At=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return At=!1,Ly(e,n,i);At=(e.flags&131072)!==0}else At=!1,Xe&&(n.flags&1048576)!==0&&Sd(n,Ds,n.index);switch(n.lanes=0,n.tag){case 2:var l=n.type;Js(e,n),e=n.pendingProps;var f=Ti(n,St.current);Oi(n,i),f=Qa(null,n,l,e,f,i);var g=Za();return n.flags|=1,typeof f=="object"&&f!==null&&typeof f.render=="function"&&f.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,Lt(l)?(g=!0,As(n)):g=!1,n.memoizedState=f.state!==null&&f.state!==void 0?f.state:null,Wa(n),f.updater=Qs,n.stateNode=f,f._reactInternals=n,iu(n,l,e,i),n=au(null,n,l,!0,g,i)):(n.tag=0,Xe&&g&&La(n),bt(null,n,f,i),n=n.child),n;case 16:l=n.elementType;e:{switch(Js(e,n),e=n.pendingProps,f=l._init,l=f(l._payload),n.type=l,f=n.tag=qy(l),e=fn(l,e),f){case 0:n=lu(null,n,l,e,i);break e;case 1:n=mf(null,n,l,e,i);break e;case 11:n=df(null,n,l,e,i);break e;case 14:n=ff(null,n,l,fn(l.type,e),i);break e}throw Error(o(306,l,""))}return n;case 0:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),lu(e,n,l,f,i);case 1:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),mf(e,n,l,f,i);case 3:e:{if(yf(n),e===null)throw Error(o(387));l=n.pendingProps,g=n.memoizedState,f=g.element,Id(e,n),Ws(n,l,null,i);var S=n.memoizedState;if(l=S.element,g.isDehydrated)if(g={element:l,isDehydrated:!1,cache:S.cache,pendingSuspenseBoundaries:S.pendingSuspenseBoundaries,transitions:S.transitions},n.updateQueue.baseState=g,n.memoizedState=g,n.flags&256){f=Hi(Error(o(423)),n),n=vf(e,n,l,i,f);break e}else if(l!==f){f=Hi(Error(o(424)),n),n=vf(e,n,l,i,f);break e}else for(Vt=vr(n.stateNode.containerInfo.firstChild),Bt=n,Xe=!0,dn=null,i=Md(n,null,l,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if($i(),l===f){n=nr(e,n,i);break e}bt(e,n,l,i)}n=n.child}return n;case 5:return Ld(n),e===null&&za(n),l=n.type,f=n.pendingProps,g=e!==null?e.memoizedProps:null,S=f.children,Ca(l,f)?S=null:g!==null&&Ca(l,g)&&(n.flags|=32),gf(e,n),bt(e,n,S,i),n.child;case 6:return e===null&&za(n),null;case 13:return xf(e,n,i);case 4:return Ua(n,n.stateNode.containerInfo),l=n.pendingProps,e===null?n.child=zi(n,null,l,i):bt(e,n,l,i),n.child;case 11:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),df(e,n,l,f,i);case 7:return bt(e,n,n.pendingProps,i),n.child;case 8:return bt(e,n,n.pendingProps.children,i),n.child;case 12:return bt(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(l=n.type._context,f=n.pendingProps,g=n.memoizedProps,S=f.value,Be(Hs,l._currentValue),l._currentValue=S,g!==null)if(cn(g.value,S)){if(g.children===f.children&&!Tt.current){n=nr(e,n,i);break e}}else for(g=n.child,g!==null&&(g.return=n);g!==null;){var T=g.dependencies;if(T!==null){S=g.child;for(var O=T.firstContext;O!==null;){if(O.context===l){if(g.tag===1){O=tr(-1,i&-i),O.tag=2;var J=g.updateQueue;if(J!==null){J=J.shared;var ae=J.pending;ae===null?O.next=O:(O.next=ae.next,ae.next=O),J.pending=O}}g.lanes|=i,O=g.alternate,O!==null&&(O.lanes|=i),Ba(g.return,i,n),T.lanes|=i;break}O=O.next}}else if(g.tag===10)S=g.type===n.type?null:g.child;else if(g.tag===18){if(S=g.return,S===null)throw Error(o(341));S.lanes|=i,T=S.alternate,T!==null&&(T.lanes|=i),Ba(S,i,n),S=g.sibling}else S=g.child;if(S!==null)S.return=g;else for(S=g;S!==null;){if(S===n){S=null;break}if(g=S.sibling,g!==null){g.return=S.return,S=g;break}S=S.return}g=S}bt(e,n,f.children,i),n=n.child}return n;case 9:return f=n.type,l=n.pendingProps.children,Oi(n,i),f=Zt(f),l=l(f),n.flags|=1,bt(e,n,l,i),n.child;case 14:return l=n.type,f=fn(l,n.pendingProps),f=fn(l.type,f),ff(e,n,l,f,i);case 15:return hf(e,n,n.type,n.pendingProps,i);case 17:return l=n.type,f=n.pendingProps,f=n.elementType===l?f:fn(l,f),Js(e,n),n.tag=1,Lt(l)?(e=!0,As(n)):e=!1,Oi(n,i),rf(n,l,f),iu(n,l,f,i),au(null,n,l,!0,e,i);case 19:return _f(e,n,i);case 22:return pf(e,n,i)}throw Error(o(156,n.tag))};function Uf(e,n){return Yn(e,n)}function Xy(e,n,i,l){this.tag=e,this.key=i,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=l,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function tn(e,n,i,l){return new Xy(e,n,i,l)}function Cu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function qy(e){if(typeof e=="function")return Cu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ne)return 11;if(e===V)return 14}return 2}function Mr(e,n){var i=e.alternate;return i===null?(i=tn(e.tag,n,e.key,e.mode),i.elementType=e.elementType,i.type=e.type,i.stateNode=e.stateNode,i.alternate=e,e.alternate=i):(i.pendingProps=n,i.type=e.type,i.flags=0,i.subtreeFlags=0,i.deletions=null),i.flags=e.flags&14680064,i.childLanes=e.childLanes,i.lanes=e.lanes,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,n=e.dependencies,i.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},i.sibling=e.sibling,i.index=e.index,i.ref=e.ref,i}function cl(e,n,i,l,f,g){var S=2;if(l=e,typeof e=="function")Cu(e)&&(S=1);else if(typeof e=="string")S=5;else e:switch(e){case F:return ii(i.children,f,g,n);case G:S=8,f|=8;break;case q:return e=tn(12,i,n,f|2),e.elementType=q,e.lanes=g,e;case K:return e=tn(13,i,n,f),e.elementType=K,e.lanes=g,e;case C:return e=tn(19,i,n,f),e.elementType=C,e.lanes=g,e;case U:return dl(i,f,g,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case te:S=10;break e;case ee:S=9;break e;case ne:S=11;break e;case V:S=14;break e;case W:S=16,l=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=tn(S,i,n,f),n.elementType=e,n.type=l,n.lanes=g,n}function ii(e,n,i,l){return e=tn(7,e,l,n),e.lanes=i,e}function dl(e,n,i,l){return e=tn(22,e,l,n),e.elementType=U,e.lanes=i,e.stateNode={isHidden:!1},e}function Mu(e,n,i){return e=tn(6,e,null,n),e.lanes=i,e}function Pu(e,n,i){return n=tn(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function Ky(e,n,i,l,f){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=sn(0),this.expirationTimes=sn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=sn(0),this.identifierPrefix=l,this.onRecoverableError=f,this.mutableSourceEagerHydrationData=null}function Iu(e,n,i,l,f,g,S,T,O){return e=new Ky(e,n,i,T,O),n===1?(n=1,g===!0&&(n|=8)):n=0,g=tn(3,null,null,n),e.current=g,g.stateNode=e,g.memoizedState={element:l,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},Wa(g),e}function Qy(e,n,i){var l=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),zu.exports=u0(),zu.exports}var oh;function c0(){if(oh)return vl;oh=1;var t=Ep();return vl.createRoot=t.createRoot,vl.hydrateRoot=t.hydrateRoot,vl}var d0=c0();function Cp(t,r="Request failed"){const o=(t||"").trim();if(!o)return r;try{const a=JSON.parse(o).detail;if(typeof a=="string"&&a.trim())return a;if(Array.isArray(a)){const u=a.map(c=>typeof c=="string"?c:c&&typeof c=="object"&&"msg"in c?String(c.msg):"").filter(Boolean);if(u.length)return u.join("; ")}}catch{}return o}async function Ae(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const s=await o.text();throw new Error(Cp(s,o.statusText||"Request failed"))}return o.json()}const f0=["github_token","gitlab_token","gitlab_oauth_client_secret","bitbucket_token","bitbucket_oauth_client_secret","ai_api_key","ai_model","ai_base_url"],Re={health:()=>Ae("/api/health"),settings:()=>Ae("/api/settings"),saveSettings:t=>{const r={...t};for(const o of f0)r[o]===""&&delete r[o];return Ae("/api/settings",{method:"PUT",body:JSON.stringify(r)})},repos:()=>Ae("/api/repos"),browse:t=>Ae(`/api/fs${t?`?path=${encodeURIComponent(t)}`:""}`),gitRefs:(t,r=50)=>Ae(`/api/git/refs?repo_path=${encodeURIComponent(t)}&limit=${r}`),index:(t,r=!0)=>Ae("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>Ae(`/api/index?repo_path=${encodeURIComponent(t)}`),indexProgress:t=>Ae(`/api/index/progress?repo_path=${encodeURIComponent(t)}`),architecture:(t,r=!0)=>Ae(`/api/architecture?repo_path=${encodeURIComponent(t)}&graph=${r?"1":"0"}`),architectureGraph:t=>Ae(`/api/architecture/graph?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,s=!0,a=!1)=>Ae("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:s,incremental:!0,three_dot:!0,dirty:a})}),whatIf:(t,r)=>Ae("/api/whatif",{method:"POST",body:JSON.stringify({repo_path:t,node_id:r})}),reviewPr:(t,r,o,s)=>Ae("/api/prs/review",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,repo_path:s||null})}),init:(t,r=!1)=>Ae("/api/init",{method:"POST",body:JSON.stringify({repo_path:t,overwrite:r})}),postComment:(t,r,o,s)=>Ae("/api/prs/comment",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,markdown:s})}),graph:(t,r="full")=>Ae(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open",s)=>Ae("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o,repo_path:s||null})}),scmRepos:t=>Ae(`/api/scm/repos?provider=${encodeURIComponent(t)}`),oauthStatus:()=>Ae("/api/oauth/status"),githubOAuthStart:()=>Ae("/api/oauth/github/start",{method:"POST",body:"{}"}),githubOAuthPoll:t=>Ae("/api/oauth/github/poll",{method:"POST",body:JSON.stringify({flow_id:t})}),bitbucketOAuthStart:()=>Ae("/api/oauth/bitbucket/start"),gitlabOAuthStart:()=>Ae("/api/oauth/gitlab/start"),oauthDisconnect:t=>Ae("/api/oauth/disconnect",{method:"POST",body:JSON.stringify({provider:t})}),residual:t=>Ae("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})}),reviews:t=>Ae(`/api/reviews?repo_path=${encodeURIComponent(t)}`),getReview:(t,r)=>Ae(`/api/reviews/${encodeURIComponent(r)}?repo_path=${encodeURIComponent(t)}`),reviewDiff:(t,r,o)=>Ae(`/api/reviews/${encodeURIComponent(r)}/diff?repo_path=${encodeURIComponent(t)}&other=${encodeURIComponent(o)}`),config:t=>Ae(`/api/config?repo_path=${encodeURIComponent(t)}`),saveConfig:(t,r)=>Ae("/api/config",{method:"PUT",body:JSON.stringify({repo_path:t,...r})}),addWaiver:(t,r,o,s)=>Ae("/api/config/waiver",{method:"POST",body:JSON.stringify({repo_path:t,rule:r,node:o||null,reason:s||""})}),marks:(t,r)=>Ae(`/api/marks?repo_path=${encodeURIComponent(t)}${r?`&review_id=${encodeURIComponent(r)}`:""}`),architectureHealth:t=>Ae(`/api/architecture/health?repo_path=${encodeURIComponent(t)}`),workspaceStatus:t=>Ae(`/api/workspace/status?repo_path=${encodeURIComponent(t)}`),openEditor:(t,r,o,s)=>Ae("/api/open",{method:"POST",body:JSON.stringify({repo_path:t,path:r,line:o||null,editor:s||null})}),exportHtml:t=>fetch("/api/export/html",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({review:t})}).then(async r=>{if(!r.ok){const o=await r.text();throw new Error(Cp(o,r.statusText||"Request failed"))}return r.blob()}),isolate:(t,r,o,s)=>Ae("/api/graph/isolate",{method:"POST",body:JSON.stringify({nodes:t,edges:r,source_id:o,target_id:s||null})})};function h0(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.label.toLowerCase().includes(o)||(s.hint||"").toLowerCase().includes(o)||(s.group||"").toLowerCase().includes(o)):t}function p0({open:t,actions:r,onClose:o}){const[s,a]=L.useState(""),[u,c]=L.useState(0),h=L.useRef(null),p=L.useMemo(()=>h0(r,s),[r,s]);if(L.useEffect(()=>{if(!t)return;a(""),c(0);const m=window.setTimeout(()=>{var _;return(_=h.current)==null?void 0:_.focus()},0);return()=>window.clearTimeout(m)},[t]),L.useEffect(()=>{c(0)},[s]),!t)return null;const y=p.slice(0,40),x=y[Math.min(u,Math.max(y.length-1,0))],v=m=>{m&&(o(),m.run())};return d.jsx("div",{className:"palette-scrim","data-testid":"command-palette",onClick:m=>{m.target===m.currentTarget&&o()},children:d.jsxs("div",{className:"palette",role:"dialog","aria-label":"Command palette",children:[d.jsx("input",{ref:h,"data-testid":"command-palette-input",placeholder:"Jump to a node, run a review, toggle overlays…",value:s,onChange:m=>a(m.target.value),onKeyDown:m=>{m.key==="Escape"?(m.preventDefault(),o()):m.key==="ArrowDown"?(m.preventDefault(),c(_=>Math.min(Math.max(y.length-1,0),_+1))):m.key==="ArrowUp"?(m.preventDefault(),c(_=>Math.max(0,_-1))):m.key==="Enter"&&(m.preventDefault(),v(x))}}),d.jsxs("ul",{children:[y.length===0?d.jsx("li",{className:"muted",children:"No matches"}):null,y.map((m,_)=>d.jsx("li",{children:d.jsxs("button",{type:"button",className:_===u?"active":"",onMouseEnter:()=>c(_),onClick:()=>v(m),children:[d.jsx("span",{children:m.label}),m.hint?d.jsx("span",{className:"muted",children:m.hint}):null]})},m.id))]}),d.jsxs("div",{className:"palette-foot muted",children:[d.jsx("kbd",{children:"↑"}),d.jsx("kbd",{children:"↓"})," move · ",d.jsx("kbd",{children:"Enter"})," run · ",d.jsx("kbd",{children:"Esc"})," close"]})]})})}function g0({config:t,busy:r,onSave:o,onWaiver:s}){const[a,u]=L.useState(t),[c,h]=L.useState(t.available_rules[0]||""),[p,y]=L.useState(""),[x,v]=L.useState("");L.useEffect(()=>{u(t)},[t]);const m=Object.entries(a.contexts||{}),_=(R,w,N)=>{const A=a.contexts[R];if(!A)return;const $=F=>F.split(",").map(G=>G.trim()).filter(Boolean);u({...a,contexts:{...a.contexts,[R]:{...A,[w]:w==="name"?N:$(N)}}})},k=(R,w)=>{const N=w.trim();if(!N||N===R)return;const{[R]:A,...$}=a.contexts;A&&u({...a,contexts:{...$,[N]:{...A,name:N}}})},j=()=>{let R=1;for(;a.contexts[`context-${R}`];)R+=1;const w=`context-${R}`;u({...a,contexts:{...a.contexts,[w]:{name:w,django_apps:[],react:[],public_api:[],owners:[]}}})},b=R=>{const{[R]:w,...N}=a.contexts;u({...a,contexts:N})},E=R=>{const w=a.rules.includes(R);u({...a,rules:w?a.rules.filter(N=>N!==R):[...a.rules,R]})};return d.jsxs("div",{className:"config-editor","data-testid":"config-editor",children:[d.jsx("p",{className:"muted",children:a.exists?a.path:"No loadpath.yml yet — saving writes one at the repo root."}),m.map(([R,w])=>d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Context ",d.jsx("span",{className:"count",children:R})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Name"}),d.jsx("input",{defaultValue:R,"data-testid":`config-context-name-${R}`,onBlur:N=>k(R,N.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Django apps"}),d.jsx("input",{value:(w.django_apps||[]).join(", "),onChange:N=>_(R,"django_apps",N.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"React folders"}),d.jsx("input",{value:(w.react||[]).join(", "),onChange:N=>_(R,"react",N.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Public API"}),d.jsx("input",{value:(w.public_api||[]).join(", "),onChange:N=>_(R,"public_api",N.target.value)})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Owners"}),d.jsx("input",{value:(w.owners||[]).join(", "),onChange:N=>_(R,"owners",N.target.value)})]}),d.jsx("button",{type:"button",className:"btn",onClick:()=>b(R),children:"Remove context"})]},R)),d.jsx("div",{className:"btn-row",children:d.jsx("button",{type:"button",className:"btn","data-testid":"config-add-context",onClick:j,children:"Add context"})}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Rules ",d.jsx("span",{className:"count",children:a.rules.length})]}),(a.available_rules.length?a.available_rules:a.rules).map(R=>d.jsxs("label",{className:"check-row",children:[d.jsx("input",{type:"checkbox",checked:a.rules.includes(R),onChange:()=>E(R)}),R]},R))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Waivers ",d.jsx("span",{className:"count",children:(a.waivers||[]).length})]}),(a.waivers||[]).map((R,w)=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:R.rule}),R.node?` · ${R.node}`:"",R.reason?` — ${R.reason}`:""]},`${R.rule}:${R.node}:${w}`)),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Rule"}),d.jsx("select",{value:c,onChange:R=>h(R.target.value),children:(a.available_rules.length?a.available_rules:a.rules).map(R=>d.jsx("option",{value:R,children:R},R))})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Node id (optional)"}),d.jsx("input",{value:p,onChange:R=>y(R.target.value),placeholder:"django.view:…"})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Reason"}),d.jsx("input",{value:x,onChange:R=>v(R.target.value)})]}),d.jsx("button",{type:"button",className:"btn","data-testid":"config-add-waiver",disabled:r||!c,onClick:()=>s==null?void 0:s(c,p,x),children:"Add waiver"})]}),d.jsx("div",{className:"btn-row",children:d.jsx("button",{type:"button",className:"btn primary","data-testid":"config-save",disabled:r,onClick:()=>o(a),children:"Save loadpath.yml"})})]})}function Zo(t){return t.replaceAll("_"," ")}function m0(t){return t.replaceAll("_"," ")}function io(t){return t.split(".").pop()||t}function nc(t){if(!t)return"";const r=new Date(t);return Number.isNaN(r.getTime())?t:r.toLocaleString()}function y0(t){return t.split(/[\\/]/).filter(Boolean).pop()||t}function Lr(t){return t.replace(/([/\\._:@-])/g,"$1​")}function pi({className:t,children:r}){return d.jsx("svg",{className:t,width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r})}function v0({className:t}){return d.jsxs(pi,{className:t,children:[d.jsx("path",{d:"M3 3.5h6.5L13 7v5.5H3z"}),d.jsx("path",{d:"M9.5 3.5V7H13"}),d.jsx("path",{d:"M5.5 9.5h5M5.5 11.5h3.5"})]})}function x0({className:t}){return d.jsxs(pi,{className:t,children:[d.jsx("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"0.8"}),d.jsx("rect",{x:"9",y:"9",width:"4.5",height:"4.5",rx:"0.8"})]})}function w0({className:t}){return d.jsxs(pi,{className:t,children:[d.jsx("circle",{cx:"4",cy:"8",r:"1.6"}),d.jsx("circle",{cx:"12",cy:"4",r:"1.6"}),d.jsx("circle",{cx:"12",cy:"12",r:"1.6"}),d.jsx("path",{d:"M5.5 7.2 10.4 4.8M5.5 8.8 10.4 11.2"})]})}function _0({className:t}){return d.jsxs(pi,{className:t,children:[d.jsx("circle",{cx:"4.5",cy:"4",r:"1.4"}),d.jsx("circle",{cx:"4.5",cy:"12",r:"1.4"}),d.jsx("circle",{cx:"11.5",cy:"12",r:"1.4"}),d.jsx("path",{d:"M4.5 5.5v5M4.5 8h4.2a3 3 0 0 1 3 3"})]})}function S0({className:t}){return d.jsxs(pi,{className:t,children:[d.jsx("circle",{cx:"8",cy:"8",r:"2.1"}),d.jsx("path",{d:"M8 2.5v1.6M8 11.9v1.6M2.5 8h1.6M11.9 8h1.6M4.1 4.1l1.1 1.1M10.8 10.8l1.1 1.1M11.9 4.1l-1.1 1.1M5.2 10.8l-1.1 1.1"})]})}function Mp({className:t}){return d.jsx(pi,{className:t,children:d.jsx("path",{d:"M2.5 4.5h4L8 6h5.5v6.5h-11z"})})}function k0({className:t}){return d.jsx(pi,{className:t,children:d.jsx("path",{d:"M4 6.5 8 10.5 12 6.5"})})}const N0="modulepreload",j0=function(t,r){return new URL(t,r).href},sh={},b0=function(r,o,s){let a=Promise.resolve();if(o&&o.length>0){let c=function(x){return Promise.all(x.map(v=>Promise.resolve(v).then(m=>({status:"fulfilled",value:m}),m=>({status:"rejected",reason:m}))))};const h=document.getElementsByTagName("link"),p=document.querySelector("meta[property=csp-nonce]"),y=(p==null?void 0:p.nonce)||(p==null?void 0:p.getAttribute("nonce"));a=c(o.map(x=>{if(x=j0(x,s),x in sh)return;sh[x]=!0;const v=x.endsWith(".css"),m=v?'[rel="stylesheet"]':"";if(!!s)for(let j=h.length-1;j>=0;j--){const b=h[j];if(b.href===x&&(!v||b.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${x}"]${m}`))return;const k=document.createElement("link");if(k.rel=v?"stylesheet":N0,v||(k.as="script"),k.crossOrigin="",k.href=x,y&&k.setAttribute("nonce",y),document.head.appendChild(k),v)return new Promise((j,b)=>{k.addEventListener("load",j),k.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${x}`)))})}))}function u(c){const h=new Event("vite:preloadError",{cancelable:!0});if(h.payload=c,window.dispatchEvent(h),!h.defaultPrevented)throw c}return a.then(c=>{for(const h of c||[])h.status==="rejected"&&u(h.reason);return r().catch(u)})};function rt(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,s;o{}};function Xl(){for(var t=0,r=arguments.length,o={},s;t=0&&(s=o.slice(a+1),o=o.slice(0,a)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:s}})}Pl.prototype=Xl.prototype={constructor:Pl,on:function(t,r){var o=this._,s=C0(t+"",o),a,u=-1,c=s.length;if(arguments.length<2){for(;++u0)for(var o=new Array(a),s=0,a,u;s=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),ah.hasOwnProperty(r)?{space:ah[r],local:t}:t}function P0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===rc&&r.documentElement.namespaceURI===rc?r.createElement(t):r.createElementNS(o,t)}}function I0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Pp(t){var r=ql(t);return(r.local?I0:P0)(r)}function R0(){}function yc(t){return t==null?R0:function(){return this.querySelector(t)}}function T0(t){typeof t!="function"&&(t=yc(t));for(var r=this._groups,o=r.length,s=new Array(o),a=0;a=w&&(w=R+1);!(A=b[w])&&++w=0;)(c=s[a])&&(u&&c.compareDocumentPosition(u)^4&&u.parentNode.insertBefore(c,u),u=c);return this}function iv(t){t||(t=ov);function r(v,m){return v&&m?t(v.__data__,m.__data__):!v-!m}for(var o=this._groups,s=o.length,a=new Array(s),u=0;ur?1:t>=r?0:NaN}function sv(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function lv(){return Array.from(this)}function av(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?xv:typeof r=="function"?_v:wv)(t,r,o??"")):Ki(this.node(),t)}function Ki(t,r){return t.style.getPropertyValue(r)||Ap(t).getComputedStyle(t,null).getPropertyValue(r)}function kv(t){return function(){delete this[t]}}function Nv(t,r){return function(){this[t]=r}}function jv(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function bv(t,r){return arguments.length>1?this.each((r==null?kv:typeof r=="function"?jv:Nv)(t,r)):this.node()[t]}function $p(t){return t.trim().split(/^|\s+/)}function vc(t){return t.classList||new zp(t)}function zp(t){this._node=t,this._names=$p(t.getAttribute("class")||"")}zp.prototype={add:function(t){var r=this._names.indexOf(t);r<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var r=this._names.indexOf(t);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function Dp(t,r){for(var o=vc(t),s=-1,a=r.length;++s=0&&(o=r.slice(s+1),r=r.slice(0,s)),{type:r,name:o}})}function ex(t){return function(){var r=this.__on;if(r){for(var o=0,s=-1,a=r.length,u;o()=>t;function ic(t,{sourceEvent:r,subject:o,target:s,identifier:a,active:u,x:c,y:h,dx:p,dy:y,dispatch:x}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:o,enumerable:!0,configurable:!0},target:{value:s,enumerable:!0,configurable:!0},identifier:{value:a,enumerable:!0,configurable:!0},active:{value:u,enumerable:!0,configurable:!0},x:{value:c,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:x}})}ic.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function cx(t){return!t.ctrlKey&&!t.button}function dx(){return this.parentNode}function fx(t,r){return r??{x:t.x,y:t.y}}function hx(){return navigator.maxTouchPoints||"ontouchstart"in this}function Wp(){var t=cx,r=dx,o=fx,s=hx,a={},u=Xl("start","drag","end"),c=0,h,p,y,x,v=0;function m(N){N.on("mousedown.drag",_).filter(s).on("touchstart.drag",b).on("touchmove.drag",E,ux).on("touchend.drag touchcancel.drag",R).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function _(N,A){if(!(x||!t.call(this,N,A))){var $=w(this,r.call(this,N,A),N,A,"mouse");$&&(Ut(N.view).on("mousemove.drag",k,Jo).on("mouseup.drag",j,Jo),Bp(N.view),Fu(N),y=!1,h=N.clientX,p=N.clientY,$("start",N))}}function k(N){if(Xi(N),!y){var A=N.clientX-h,$=N.clientY-p;y=A*A+$*$>v}a.mouse("drag",N)}function j(N){Ut(N.view).on("mousemove.drag mouseup.drag",null),Vp(N.view,y),Xi(N),a.mouse("end",N)}function b(N,A){if(t.call(this,N,A)){var $=N.changedTouches,F=r.call(this,N,A),G=$.length,q,te;for(q=0;q>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?wl(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?wl(r>>12&15|r>>8&240,r>>8&15|r>>4&240,r>>4&15|r&240,((r&15)<<4|r&15)/255):null):(r=gx.exec(t))?new Ot(r[1],r[2],r[3],1):(r=mx.exec(t))?new Ot(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=yx.exec(t))?wl(r[1],r[2],r[3],r[4]):(r=vx.exec(t))?wl(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=xx.exec(t))?gh(r[1],r[2]/100,r[3]/100,1):(r=wx.exec(t))?gh(r[1],r[2]/100,r[3]/100,r[4]):uh.hasOwnProperty(t)?fh(uh[t]):t==="transparent"?new Ot(NaN,NaN,NaN,0):null}function fh(t){return new Ot(t>>16&255,t>>8&255,t&255,1)}function wl(t,r,o,s){return s<=0&&(t=r=o=NaN),new Ot(t,r,o,s)}function kx(t){return t instanceof fs||(t=ui(t)),t?(t=t.rgb(),new Ot(t.r,t.g,t.b,t.opacity)):new Ot}function oc(t,r,o,s){return arguments.length===1?kx(t):new Ot(t,r,o,s??1)}function Ot(t,r,o,s){this.r=+t,this.g=+r,this.b=+o,this.opacity=+s}xc(Ot,oc,Up(fs,{brighter(t){return t=t==null?$l:Math.pow($l,t),new Ot(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?es:Math.pow(es,t),new Ot(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ot(li(this.r),li(this.g),li(this.b),zl(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:hh,formatHex:hh,formatHex8:Nx,formatRgb:ph,toString:ph}));function hh(){return`#${si(this.r)}${si(this.g)}${si(this.b)}`}function Nx(){return`#${si(this.r)}${si(this.g)}${si(this.b)}${si((isNaN(this.opacity)?1:this.opacity)*255)}`}function ph(){const t=zl(this.opacity);return`${t===1?"rgb(":"rgba("}${li(this.r)}, ${li(this.g)}, ${li(this.b)}${t===1?")":`, ${t})`}`}function zl(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function li(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function si(t){return t=li(t),(t<16?"0":"")+t.toString(16)}function gh(t,r,o,s){return s<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new yn(t,r,o,s)}function Yp(t){if(t instanceof yn)return new yn(t.h,t.s,t.l,t.opacity);if(t instanceof fs||(t=ui(t)),!t)return new yn;if(t instanceof yn)return t;t=t.rgb();var r=t.r/255,o=t.g/255,s=t.b/255,a=Math.min(r,o,s),u=Math.max(r,o,s),c=NaN,h=u-a,p=(u+a)/2;return h?(r===u?c=(o-s)/h+(o0&&p<1?0:c,new yn(c,h,p,t.opacity)}function jx(t,r,o,s){return arguments.length===1?Yp(t):new yn(t,r,o,s??1)}function yn(t,r,o,s){this.h=+t,this.s=+r,this.l=+o,this.opacity=+s}xc(yn,jx,Up(fs,{brighter(t){return t=t==null?$l:Math.pow($l,t),new yn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?es:Math.pow(es,t),new yn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,r=isNaN(t)||isNaN(this.s)?0:this.s,o=this.l,s=o+(o<.5?o:1-o)*r,a=2*o-s;return new Ot(Hu(t>=240?t-240:t+120,a,s),Hu(t,a,s),Hu(t<120?t+240:t-120,a,s),this.opacity)},clamp(){return new yn(mh(this.h),_l(this.s),_l(this.l),zl(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=zl(this.opacity);return`${t===1?"hsl(":"hsla("}${mh(this.h)}, ${_l(this.s)*100}%, ${_l(this.l)*100}%${t===1?")":`, ${t})`}`}}));function mh(t){return t=(t||0)%360,t<0?t+360:t}function _l(t){return Math.max(0,Math.min(1,t||0))}function Hu(t,r,o){return(t<60?r+(o-r)*t/60:t<180?o:t<240?r+(o-r)*(240-t)/60:r)*255}const wc=t=>()=>t;function bx(t,r){return function(o){return t+o*r}}function Ex(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(s){return Math.pow(t+s*r,o)}}function Cx(t){return(t=+t)==1?Gp:function(r,o){return o-r?Ex(r,o,t):wc(isNaN(r)?o:r)}}function Gp(t,r){var o=r-t;return o?bx(t,o):wc(isNaN(t)?r:t)}const Dl=(function t(r){var o=Cx(r);function s(a,u){var c=o((a=oc(a)).r,(u=oc(u)).r),h=o(a.g,u.g),p=o(a.b,u.b),y=Gp(a.opacity,u.opacity);return function(x){return a.r=c(x),a.g=h(x),a.b=p(x),a.opacity=y(x),a+""}}return s.gamma=t,s})(1);function Mx(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,s=r.slice(),a;return function(u){for(a=0;ao&&(u=r.slice(o,u),h[c]?h[c]+=u:h[++c]=u),(s=s[0])===(a=a[0])?h[c]?h[c]+=a:h[++c]=a:(h[++c]=null,p.push({i:c,x:An(s,a)})),o=Bu.lastIndex;return o180?x+=360:x-y>180&&(y+=360),m.push({i:v.push(a(v)+"rotate(",null,s)-2,x:An(y,x)})):x&&v.push(a(v)+"rotate("+x+s)}function h(y,x,v,m){y!==x?m.push({i:v.push(a(v)+"skewX(",null,s)-2,x:An(y,x)}):x&&v.push(a(v)+"skewX("+x+s)}function p(y,x,v,m,_,k){if(y!==v||x!==m){var j=_.push(a(_)+"scale(",null,",",null,")");k.push({i:j-4,x:An(y,v)},{i:j-2,x:An(x,m)})}else(v!==1||m!==1)&&_.push(a(_)+"scale("+v+","+m+")")}return function(y,x){var v=[],m=[];return y=t(y),x=t(x),u(y.translateX,y.translateY,x.translateX,x.translateY,v,m),c(y.rotate,x.rotate,v,m),h(y.skewX,x.skewX,v,m),p(y.scaleX,y.scaleY,x.scaleX,x.scaleY,v,m),y=x=null,function(_){for(var k=-1,j=m.length,b;++k=0&&t._call.call(void 0,r),t=t._next;--Qi}function xh(){ci=(Fl=ns.now())+Kl,Qi=Xo=0;try{Wx()}finally{Qi=0,Yx(),ci=0}}function Ux(){var t=ns.now(),r=t-Fl;r>Qp&&(Kl-=r,Fl=t)}function Yx(){for(var t,r=Ol,o,s=1/0;r;)r._call?(s>r._time&&(s=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:Ol=o);qo=t,ac(s)}function ac(t){if(!Qi){Xo&&(Xo=clearTimeout(Xo));var r=t-ci;r>24?(t<1/0&&(Xo=setTimeout(xh,t-ns.now()-Kl)),Yo&&(Yo=clearInterval(Yo))):(Yo||(Fl=ns.now(),Yo=setInterval(Ux,Qp)),Qi=1,Zp(xh))}}function wh(t,r,o){var s=new Hl;return r=r==null?0:+r,s.restart(a=>{s.stop(),t(a+r)},r,o),s}var Gx=Xl("start","end","cancel","interrupt"),Xx=[],eg=0,_h=1,uc=2,Rl=3,Sh=4,cc=5,Tl=6;function Ql(t,r,o,s,a,u){var c=t.__transition;if(!c)t.__transition={};else if(o in c)return;qx(t,o,{name:r,index:s,group:a,on:Gx,tween:Xx,time:u.time,delay:u.delay,duration:u.duration,ease:u.ease,timer:null,state:eg})}function Sc(t,r){var o=_n(t,r);if(o.state>eg)throw new Error("too late; already scheduled");return o}function zn(t,r){var o=_n(t,r);if(o.state>Rl)throw new Error("too late; already running");return o}function _n(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function qx(t,r,o){var s=t.__transition,a;s[r]=o,o.timer=Jp(u,0,o.time);function u(y){o.state=_h,o.timer.restart(c,o.delay,o.time),o.delay<=y&&c(y-o.delay)}function c(y){var x,v,m,_;if(o.state!==_h)return p();for(x in s)if(_=s[x],_.name===o.name){if(_.state===Rl)return wh(c);_.state===Sh?(_.state=Tl,_.timer.stop(),_.on.call("interrupt",t,t.__data__,_.index,_.group),delete s[x]):+xuc&&s.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function jw(t,r,o){var s,a,u=Nw(r)?Sc:zn;return function(){var c=u(this,t),h=c.on;h!==s&&(a=(s=h).copy()).on(r,o),c.on=a}}function bw(t,r){var o=this._id;return arguments.length<2?_n(this.node(),o).on.on(t):this.each(jw(o,t,r))}function Ew(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function Cw(){return this.on("end.remove",Ew(this._id))}function Mw(t){var r=this._name,o=this._id;typeof t!="function"&&(t=yc(t));for(var s=this._groups,a=s.length,u=new Array(a),c=0;c()=>t;function e1(t,{sourceEvent:r,target:o,transform:s,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:o,enumerable:!0,configurable:!0},transform:{value:s,enumerable:!0,configurable:!0},_:{value:a}})}function or(t,r,o){this.k=t,this.x=r,this.y=o}or.prototype={constructor:or,scale:function(t){return t===1?this:new or(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new or(this.k,this.x+this.k*t,this.y+this.k*r)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Zl=new or(1,0,0);ig.prototype=or.prototype;function ig(t){for(;!t.__zoom;)if(!(t=t.parentNode))return Zl;return t.__zoom}function Vu(t){t.stopImmediatePropagation()}function Go(t){t.preventDefault(),t.stopImmediatePropagation()}function t1(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function n1(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function kh(){return this.__zoom||Zl}function r1(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function i1(){return navigator.maxTouchPoints||"ontouchstart"in this}function o1(t,r,o){var s=t.invertX(r[0][0])-o[0][0],a=t.invertX(r[1][0])-o[1][0],u=t.invertY(r[0][1])-o[0][1],c=t.invertY(r[1][1])-o[1][1];return t.translate(a>s?(s+a)/2:Math.min(0,s)||Math.max(0,a),c>u?(u+c)/2:Math.min(0,u)||Math.max(0,c))}function og(){var t=t1,r=n1,o=o1,s=r1,a=i1,u=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],h=250,p=Il,y=Xl("start","zoom","end"),x,v,m,_=500,k=150,j=0,b=10;function E(C){C.property("__zoom",kh).on("wheel.zoom",G,{passive:!1}).on("mousedown.zoom",q).on("dblclick.zoom",te).filter(a).on("touchstart.zoom",ee).on("touchmove.zoom",ne).on("touchend.zoom touchcancel.zoom",K).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(C,V,W,U){var M=C.selection?C.selection():C;M.property("__zoom",kh),C!==M?A(C,V,W,U):M.interrupt().each(function(){$(this,arguments).event(U).start().zoom(null,typeof V=="function"?V.apply(this,arguments):V).end()})},E.scaleBy=function(C,V,W,U){E.scaleTo(C,function(){var M=this.__zoom.k,D=typeof V=="function"?V.apply(this,arguments):V;return M*D},W,U)},E.scaleTo=function(C,V,W,U){E.transform(C,function(){var M=r.apply(this,arguments),D=this.__zoom,H=W==null?N(M):typeof W=="function"?W.apply(this,arguments):W,I=D.invert(H),z=typeof V=="function"?V.apply(this,arguments):V;return o(w(R(D,z),H,I),M,c)},W,U)},E.translateBy=function(C,V,W,U){E.transform(C,function(){return o(this.__zoom.translate(typeof V=="function"?V.apply(this,arguments):V,typeof W=="function"?W.apply(this,arguments):W),r.apply(this,arguments),c)},null,U)},E.translateTo=function(C,V,W,U,M){E.transform(C,function(){var D=r.apply(this,arguments),H=this.__zoom,I=U==null?N(D):typeof U=="function"?U.apply(this,arguments):U;return o(Zl.translate(I[0],I[1]).scale(H.k).translate(typeof V=="function"?-V.apply(this,arguments):-V,typeof W=="function"?-W.apply(this,arguments):-W),D,c)},U,M)};function R(C,V){return V=Math.max(u[0],Math.min(u[1],V)),V===C.k?C:new or(V,C.x,C.y)}function w(C,V,W){var U=V[0]-W[0]*C.k,M=V[1]-W[1]*C.k;return U===C.x&&M===C.y?C:new or(C.k,U,M)}function N(C){return[(+C[0][0]+ +C[1][0])/2,(+C[0][1]+ +C[1][1])/2]}function A(C,V,W,U){C.on("start.zoom",function(){$(this,arguments).event(U).start()}).on("interrupt.zoom end.zoom",function(){$(this,arguments).event(U).end()}).tween("zoom",function(){var M=this,D=arguments,H=$(M,D).event(U),I=r.apply(M,D),z=W==null?N(I):typeof W=="function"?W.apply(M,D):W,ie=Math.max(I[1][0]-I[0][0],I[1][1]-I[0][1]),oe=M.__zoom,fe=typeof V=="function"?V.apply(M,D):V,he=p(oe.invert(z).concat(ie/oe.k),fe.invert(z).concat(ie/fe.k));return function(pe){if(pe===1)pe=fe;else{var Z=he(pe),se=ie/Z[2];pe=new or(se,z[0]-Z[0]*se,z[1]-Z[1]*se)}H.zoom(null,pe)}})}function $(C,V,W){return!W&&C.__zooming||new F(C,V)}function F(C,V){this.that=C,this.args=V,this.active=0,this.sourceEvent=null,this.extent=r.apply(C,V),this.taps=0}F.prototype={event:function(C){return C&&(this.sourceEvent=C),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(C,V){return this.mouse&&C!=="mouse"&&(this.mouse[1]=V.invert(this.mouse[0])),this.touch0&&C!=="touch"&&(this.touch0[1]=V.invert(this.touch0[0])),this.touch1&&C!=="touch"&&(this.touch1[1]=V.invert(this.touch1[0])),this.that.__zoom=V,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(C){var V=Ut(this.that).datum();y.call(C,this.that,new e1(C,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:y}),V)}};function G(C,...V){if(!t.apply(this,arguments))return;var W=$(this,V).event(C),U=this.__zoom,M=Math.max(u[0],Math.min(u[1],U.k*Math.pow(2,s.apply(this,arguments)))),D=mn(C);if(W.wheel)(W.mouse[0][0]!==D[0]||W.mouse[0][1]!==D[1])&&(W.mouse[1]=U.invert(W.mouse[0]=D)),clearTimeout(W.wheel);else{if(U.k===M)return;W.mouse=[D,U.invert(D)],Ll(this),W.start()}Go(C),W.wheel=setTimeout(H,k),W.zoom("mouse",o(w(R(U,M),W.mouse[0],W.mouse[1]),W.extent,c));function H(){W.wheel=null,W.end()}}function q(C,...V){if(m||!t.apply(this,arguments))return;var W=C.currentTarget,U=$(this,V,!0).event(C),M=Ut(C.view).on("mousemove.zoom",z,!0).on("mouseup.zoom",ie,!0),D=mn(C,W),H=C.clientX,I=C.clientY;Bp(C.view),Vu(C),U.mouse=[D,this.__zoom.invert(D)],Ll(this),U.start();function z(oe){if(Go(oe),!U.moved){var fe=oe.clientX-H,he=oe.clientY-I;U.moved=fe*fe+he*he>j}U.event(oe).zoom("mouse",o(w(U.that.__zoom,U.mouse[0]=mn(oe,W),U.mouse[1]),U.extent,c))}function ie(oe){M.on("mousemove.zoom mouseup.zoom",null),Vp(oe.view,U.moved),Go(oe),U.event(oe).end()}}function te(C,...V){if(t.apply(this,arguments)){var W=this.__zoom,U=mn(C.changedTouches?C.changedTouches[0]:C,this),M=W.invert(U),D=W.k*(C.shiftKey?.5:2),H=o(w(R(W,D),U,M),r.apply(this,V),c);Go(C),h>0?Ut(this).transition().duration(h).call(A,H,U,C):Ut(this).call(E.transform,H,U,C)}}function ee(C,...V){if(t.apply(this,arguments)){var W=C.touches,U=W.length,M=$(this,V,C.changedTouches.length===U).event(C),D,H,I,z;for(Vu(C),H=0;H`Seems like you have not used ${t==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${t}flow.dev/error#001`,error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:t=>`Node type "${t}" not found. Using fallback type "default".`,error004:()=>"The parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:t=>`The old edge with id=${t} does not exist.`,error009:t=>`Marker type "${t}" doesn't exist.`,error008:(t,{id:r,sourceHandle:o,targetHandle:s})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:s}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:t=>`Edge type "${t}" not found. Using fallback type "default".`,error012:t=>`Node with id "${t}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(t="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${t}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.",error016:t=>`Edge with id "${t}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},rs=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],sg=["Enter"," ","Escape"],lg={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:t,x:r,y:o})=>`Moved selected node ${t}. New position, x: ${r}, y: ${o}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var Zi;(function(t){t.Strict="strict",t.Loose="loose"})(Zi||(Zi={}));var ai;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(ai||(ai={}));var is;(function(t){t.Partial="partial",t.Full="full"})(is||(is={}));const ag={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Ar;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})(Ar||(Ar={}));var os;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(os||(os={}));var Se;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(Se||(Se={}));const Nh={[Se.Left]:Se.Right,[Se.Right]:Se.Left,[Se.Top]:Se.Bottom,[Se.Bottom]:Se.Top};function ug(t){return t===null?null:t?"valid":"invalid"}const cg=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,s1=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),Nc=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),hs=(t,r=[0,0])=>{const{width:o,height:s}=Sn(t),a=t.origin??r,u=o*a[0],c=s*a[1];return{x:t.position.x-u,y:t.position.y-c}},l1=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const s=t.reduce((a,u)=>{const c=typeof u=="string";let h=!r.nodeLookup&&!c?u:void 0;return r.nodeLookup&&(h=c?r.nodeLookup.get(u):Nc(u)?u:r.nodeLookup.get(u.id)),h?(o=!0,Jl(a,Bl(h,r.nodeOrigin))):a},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?ea(s):{x:0,y:0,width:0,height:0}},ps=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},s=!1;return t.forEach(a=>{(r.filter===void 0||r.filter(a))&&(o=Jl(o,Bl(a)),s=!0)}),s?ea(o):{x:0,y:0,width:0,height:0}},jc=(t,r,[o,s,a]=[0,0,1],u=!1,c=!1)=>{const h=(r.x-o)/a,p=(r.y-s)/a,y=r.width/a,x=r.height/a,v=[];for(const m of t.values()){const{measured:_,selectable:k=!0,hidden:j=!1}=m;if(c&&!k||j)continue;const b=_.width??m.width??m.initialWidth??0,E=_.height??m.height??m.initialHeight??0,{x:R,y:w}=m.internals.positionAbsolute,N=pg(h,p,y,x,R,w,b,E),A=b*E,$=u&&N>0;(!m.internals.handleBounds||$||N>=A||m.dragging)&&v.push(m)}return v},a1=(t,r)=>{const o=new Set;return t.forEach(s=>{o.add(s.id)}),r.filter(s=>o.has(s.source)||o.has(s.target))};function u1(t,r){const o=new Map,s=r!=null&&r.nodes?new Set(r.nodes.map(a=>a.id)):null;return t.forEach(a=>{let u;if(r!=null&&r.includeHiddenNodes){const{width:c,height:h}=Sn(a);u=c>0&&h>0}else u=!!(a.measured.width&&a.measured.height&&!a.hidden);u&&(!s||s.has(a.id))&&o.set(a.id,a)}),o}async function c1({nodes:t,width:r,height:o,panZoom:s,minZoom:a,maxZoom:u},c){if(t.size===0)return!0;const h=u1(t,c),p=ps(h),y=Ec(p,r,o,(c==null?void 0:c.minZoom)??a,(c==null?void 0:c.maxZoom)??u,(c==null?void 0:c.padding)??.1);return await s.setViewport(y,{duration:c==null?void 0:c.duration,ease:c==null?void 0:c.ease,interpolate:c==null?void 0:c.interpolate}),!0}function dg({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:s=[0,0],nodeExtent:a,onError:u}){const c=o.get(t),h=c.parentId?o.get(c.parentId):void 0,{x:p,y}=h?h.internals.positionAbsolute:{x:0,y:0},x=c.origin??s;let v=c.extent||a;if(c.extent==="parent"&&!c.expandParent)if(!h)u==null||u("005",wn.error005());else{const{width:_,height:k}=Sn(h);_&&k&&(v=[[p,y],[p+_,y+k]])}else h&&fi(c.extent)&&(v=[[c.extent[0][0]+p,c.extent[0][1]+y],[c.extent[1][0]+p,c.extent[1][1]+y]]);const m=fi(v)?di(r,v,c.measured):r;return(c.measured.width===void 0||c.measured.height===void 0)&&(u==null||u("015",wn.error015())),{position:{x:m.x-p+(c.measured.width??0)*x[0],y:m.y-y+(c.measured.height??0)*x[1]},positionAbsolute:m}}async function d1({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:s,onBeforeDelete:a}){const u=new Set(t.map(m=>m.id)),c=[];for(const m of o){if(m.deletable===!1)continue;const _=u.has(m.id),k=!_&&m.parentId&&c.find(j=>j.id===m.parentId);(_||k)&&c.push(m)}const h=new Set(r.map(m=>m.id)),p=s.filter(m=>m.deletable!==!1),x=a1(c,p);for(const m of p)h.has(m.id)&&!x.find(k=>k.id===m.id)&&x.push(m);if(!a)return{edges:x,nodes:c};const v=await a({nodes:c,edges:x});return typeof v=="boolean"?v?{edges:x,nodes:c}:{edges:[],nodes:[]}:v}const Ji=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),di=(t={x:0,y:0},r,o)=>({x:Ji(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:Ji(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function fg(t,r,o){const{width:s,height:a}=Sn(o),{x:u,y:c}=o.internals.positionAbsolute;return di(t,[[u,c],[u+s,c+a]],r)}const jh=(t,r,o)=>to?-Ji(Math.abs(t-o),1,r)/r:0,bc=(t,r,o=15,s=40)=>{const a=jh(t.x,s,r.width-s)*o,u=jh(t.y,s,r.height-s)*o;return[a,u]},Jl=(t,r)=>({x:Math.min(t.x,r.x),y:Math.min(t.y,r.y),x2:Math.max(t.x2,r.x2),y2:Math.max(t.y2,r.y2)}),dc=({x:t,y:r,width:o,height:s})=>({x:t,y:r,x2:t+o,y2:r+s}),ea=({x:t,y:r,x2:o,y2:s})=>({x:t,y:r,width:o-t,height:s-r}),ss=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=Nc(t)?t.internals.positionAbsolute:hs(t,r);return{x:o,y:s,width:((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0,height:((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0}},Bl=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=Nc(t)?t.internals.positionAbsolute:hs(t,r);return{x:o,y:s,x2:o+(((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0),y2:s+(((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0)}},hg=(t,r)=>ea(Jl(dc(t),dc(r))),pg=(t,r,o,s,a,u,c,h)=>{const p=Math.max(0,Math.min(t+o,a+c)-Math.max(t,a)),y=Math.max(0,Math.min(r+s,u+h)-Math.max(r,u));return Math.ceil(p*y)},Vl=(t,r)=>pg(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),bh=t=>vn(t.width)&&vn(t.height)&&vn(t.x)&&vn(t.y),vn=t=>!isNaN(t)&&isFinite(t),gg=(t,r)=>(o,s)=>{},gs=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),ms=({x:t,y:r},[o,s,a],u=!1,c=[1,1])=>{const h={x:(t-o)/a,y:(r-s)/a};return u?gs(h,c):h},eo=({x:t,y:r},[o,s,a])=>({x:t*a+o,y:r*a+s});function Yi(t,r){if(typeof t=="number")return Math.floor((r-r/(1+t))*.5);if(typeof t=="string"&&t.endsWith("px")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(o)}if(typeof t=="string"&&t.endsWith("%")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(r*o*.01)}return console.error(`The padding value "${t}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function f1(t,r,o){if(typeof t=="string"||typeof t=="number"){const s=Yi(t,o),a=Yi(t,r);return{top:s,right:a,bottom:s,left:a,x:a*2,y:s*2}}if(typeof t=="object"){const s=Yi(t.top??t.y??0,o),a=Yi(t.bottom??t.y??0,o),u=Yi(t.left??t.x??0,r),c=Yi(t.right??t.x??0,r);return{top:s,right:c,bottom:a,left:u,x:u+c,y:s+a}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function h1(t,r,o,s,a,u){const{x:c,y:h}=eo(t,[r,o,s]),{x:p,y}=eo({x:t.x+t.width,y:t.y+t.height},[r,o,s]),x=a-p,v=u-y;return{left:Math.floor(c),top:Math.floor(h),right:Math.floor(x),bottom:Math.floor(v)}}const Ec=(t,r,o,s,a,u)=>{const c=f1(u,r,o),h=(r-c.x)/t.width,p=(o-c.y)/t.height,y=Math.min(h,p),x=Ji(y,s,a),v=t.x+t.width/2,m=t.y+t.height/2,_=r/2-v*x,k=o/2-m*x,j=h1(t,_,k,x,r,o),b={left:Math.min(j.left-c.left,0),top:Math.min(j.top-c.top,0),right:Math.min(j.right-c.right,0),bottom:Math.min(j.bottom-c.bottom,0)};return{x:_-b.left+b.right,y:k-b.top+b.bottom,zoom:x}},ls=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function fi(t){return t!=null&&t!=="parent"}function Sn(t){var r,o;return{width:((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth??0,height:((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight??0}}function mg(t){var r,o;return(((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth)!==void 0&&(((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight)!==void 0}function yg(t,r={width:0,height:0},o,s,a){const u={...t},c=s.get(o);if(c){const h=c.origin||a;u.x+=c.internals.positionAbsolute.x-(r.width??0)*h[0],u.y+=c.internals.positionAbsolute.y-(r.height??0)*h[1]}return u}function Eh(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function p1(){let t,r;return{promise:new Promise((s,a)=>{t=s,r=a}),resolve:t,reject:r}}function g1(t){return{...lg,...t||{}}}function Qo(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:s,containerBounds:a}){const{x:u,y:c}=xn(t),h=ms({x:u-((a==null?void 0:a.left)??0),y:c-((a==null?void 0:a.top)??0)},s),{x:p,y}=o?gs(h,r):h;return{xSnapped:p,ySnapped:y,...h}}const Cc=t=>({width:t.offsetWidth,height:t.offsetHeight}),vg=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},m1=["INPUT","SELECT","TEXTAREA"];function xg(t){var s,a;const r=((a=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:a[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:m1.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const wg=t=>"clientX"in t,xn=(t,r)=>{var u,c;const o=wg(t),s=o?t.clientX:(u=t.touches)==null?void 0:u[0].clientX,a=o?t.clientY:(c=t.touches)==null?void 0:c[0].clientY;return{x:s-((r==null?void 0:r.left)??0),y:a-((r==null?void 0:r.top)??0)}},Ch=(t,r,o,s,a)=>{const u=r.querySelectorAll(`.${t}`);return!u||!u.length?null:Array.from(u).map(c=>{const h=c.getBoundingClientRect();return{id:c.getAttribute("data-handleid"),type:t,nodeId:a,position:c.getAttribute("data-handlepos"),x:(h.left-o.left)/s,y:(h.top-o.top)/s,...Cc(c)}})};function _g({sourceX:t,sourceY:r,targetX:o,targetY:s,sourceControlX:a,sourceControlY:u,targetControlX:c,targetControlY:h}){const p=t*.125+a*.375+c*.375+o*.125,y=r*.125+u*.375+h*.375+s*.125,x=Math.abs(p-t),v=Math.abs(y-r);return[p,y,x,v]}function Nl(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function Mh({pos:t,x1:r,y1:o,x2:s,y2:a,c:u}){switch(t){case Se.Left:return[r-Nl(r-s,u),o];case Se.Right:return[r+Nl(s-r,u),o];case Se.Top:return[r,o-Nl(o-a,u)];case Se.Bottom:return[r,o+Nl(a-o,u)]}}function Sg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top,curvature:c=.25}){const[h,p]=Mh({pos:o,x1:t,y1:r,x2:s,y2:a,c}),[y,x]=Mh({pos:u,x1:s,y1:a,x2:t,y2:r,c}),[v,m,_,k]=_g({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:h,sourceControlY:p,targetControlX:y,targetControlY:x});return[`M${t},${r} C${h},${p} ${y},${x} ${s},${a}`,v,m,_,k]}function kg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const a=Math.abs(o-t)/2,u=o0}const x1=({source:t,sourceHandle:r,target:o,targetHandle:s})=>`xy-edge__${t}${r||""}-${o}${s||""}`,w1=(t,r)=>r.some(o=>o.source===t.source&&o.target===t.target&&(o.sourceHandle===t.sourceHandle||!o.sourceHandle&&!t.sourceHandle)&&(o.targetHandle===t.targetHandle||!o.targetHandle&&!t.targetHandle)),_1=(t,r,o={})=>{var u;if(!t.source||!t.target)return(u=o.onError)==null||u.call(o,"006",wn.error006()),r;const s=o.getEdgeId||x1;let a;return cg(t)?a={...t}:a={...t,id:s(t)},w1(a,r)?r:(a.sourceHandle===null&&delete a.sourceHandle,a.targetHandle===null&&delete a.targetHandle,r.concat(a))};function Ng({sourceX:t,sourceY:r,targetX:o,targetY:s}){const[a,u,c,h]=kg({sourceX:t,sourceY:r,targetX:o,targetY:s});return[`M ${t},${r}L ${o},${s}`,a,u,c,h]}const Ph={[Se.Left]:{x:-1,y:0},[Se.Right]:{x:1,y:0},[Se.Top]:{x:0,y:-1},[Se.Bottom]:{x:0,y:1}},S1=({source:t,sourcePosition:r=Se.Bottom,target:o})=>r===Se.Left||r===Se.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function k1({source:t,sourcePosition:r=Se.Bottom,target:o,targetPosition:s=Se.Top,center:a,offset:u,stepPosition:c}){const h=Ph[r],p=Ph[s],y={x:t.x+h.x*u,y:t.y+h.y*u},x={x:o.x+p.x*u,y:o.y+p.y*u},v=S1({source:y,sourcePosition:r,target:x}),m=v.x!==0?"x":"y",_=v[m];let k=[],j,b;const E={x:0,y:0},R={x:0,y:0},[,,w,N]=kg({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(h[m]*p[m]===-1){m==="x"?(j=a.x??y.x+(x.x-y.x)*c,b=a.y??(y.y+x.y)/2):(j=a.x??(y.x+x.x)/2,b=a.y??y.y+(x.y-y.y)*c);const G=[{x:j,y:y.y},{x:j,y:x.y}],q=[{x:y.x,y:b},{x:x.x,y:b}];h[m]===_?k=m==="x"?G:q:k=m==="x"?q:G}else{const G=[{x:y.x,y:x.y}],q=[{x:x.x,y:y.y}];if(m==="x"?k=h.x===_?q:G:k=h.y===_?G:q,r===s){const C=Math.abs(t[m]-o[m]);if(C<=u){const V=Math.min(u-1,u-C);h[m]===_?E[m]=(y[m]>t[m]?-1:1)*V:R[m]=(x[m]>o[m]?-1:1)*V}}if(r!==s){const C=m==="x"?"y":"x",V=h[m]===p[C],W=y[C]>x[C],U=y[C]=K?(j=(te.x+ee.x)/2,b=k[0].y):(j=k[0].x,b=(te.y+ee.y)/2)}const A={x:y.x+E.x,y:y.y+E.y},$={x:x.x+R.x,y:x.y+R.y};return[[t,...A.x!==k[0].x||A.y!==k[0].y?[A]:[],...k,...$.x!==k[k.length-1].x||$.y!==k[k.length-1].y?[$]:[],o],j,b,w,N]}function N1(t,r,o,s){const a=Math.min(Ih(t,r)/2,Ih(r,o)/2,s),{x:u,y:c}=r;if(t.x===u&&u===o.x||t.y===c&&c===o.y)return`L${u} ${c}`;if(t.y===c){const y=t.xo.id===r):t[0])||null}function fc(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(s=>`${s}=${t[s]}`).join("&")}`:""}function b1(t,{id:r,defaultColor:o,defaultMarkerStart:s,defaultMarkerEnd:a}){const u=new Set;return t.reduce((c,h)=>([h.markerStart||s,h.markerEnd||a].forEach(p=>{if(p&&typeof p=="object"){const y=fc(p,r);u.has(y)||(c.push({id:y,color:p.color||o,...p}),u.add(y))}}),c),[]).sort((c,h)=>c.id.localeCompare(h.id))}const jg=1e3,E1=10,Mc={nodeOrigin:[0,0],nodeExtent:rs,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},C1={...Mc,checkEquality:!0};function Pc(t,r){const o={...t};for(const s in r)r[s]!==void 0&&(o[s]=r[s]);return o}function M1(t,r,o){const s=Pc(Mc,o);for(const a of t.values())if(a.parentId)Rc(a,t,r,s);else{const u=hs(a,s.nodeOrigin),c=fi(a.extent)?a.extent:s.nodeExtent,h=di(u,c,Sn(a));a.internals.positionAbsolute=h}}function P1(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],s=[];for(const a of t.handles){const u={id:a.id,width:a.width??1,height:a.height??1,nodeId:t.id,x:a.x,y:a.y,position:a.position,type:a.type};a.type==="source"?o.push(u):a.type==="target"&&s.push(u)}return{source:o,target:s}}function Ic(t){return t==="manual"}function hc(t,r,o,s={}){var x,v;const a=Pc(C1,s),u={i:0},c=new Map(r),h=a!=null&&a.elevateNodesOnSelect&&!Ic(a.zIndexMode)?jg:0;let p=t.length>0,y=!1;r.clear(),o.clear();for(const m of t){let _=c.get(m.id);if(a.checkEquality&&m===(_==null?void 0:_.internals.userNode))r.set(m.id,_);else{const k=hs(m,a.nodeOrigin),j=fi(m.extent)?m.extent:a.nodeExtent,b=di(k,j,Sn(m));_={...a.defaults,...m,measured:{width:(x=m.measured)==null?void 0:x.width,height:(v=m.measured)==null?void 0:v.height},internals:{positionAbsolute:b,handleBounds:P1(m,_),z:bg(m,h,a.zIndexMode),userNode:m}},r.set(m.id,_)}(_.measured===void 0||_.measured.width===void 0||_.measured.height===void 0)&&!_.hidden&&(p=!1),m.parentId&&Rc(_,r,o,s,u),y||(y=m.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:y}}function I1(t,r){if(!t.parentId)return;const o=r.get(t.parentId);o?o.set(t.id,t):r.set(t.parentId,new Map([[t.id,t]]))}function Rc(t,r,o,s,a){const{elevateNodesOnSelect:u,nodeOrigin:c,nodeExtent:h,zIndexMode:p}=Pc(Mc,s),y=t.parentId,x=r.get(y);if(!x){console.warn(`Parent node ${y} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}I1(t,o),a&&!x.parentId&&x.internals.rootParentIndex===void 0&&p==="auto"&&(x.internals.rootParentIndex=++a.i,x.internals.z=x.internals.z+a.i*E1),a&&x.internals.rootParentIndex!==void 0&&(a.i=x.internals.rootParentIndex);const v=u&&!Ic(p)?jg:0,{x:m,y:_,z:k}=R1(t,x,c,h,v,p),{positionAbsolute:j}=t.internals,b=m!==j.x||_!==j.y;(b||k!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:b?{x:m,y:_}:j,z:k}})}function bg(t,r,o){const s=vn(t.zIndex)?t.zIndex:0;return Ic(o)?s:s+(t.selected?r:0)}function R1(t,r,o,s,a,u){const{x:c,y:h}=r.internals.positionAbsolute,p=Sn(t),y=hs(t,o),x=fi(t.extent)?di(y,t.extent,p):y;let v=di({x:c+x.x,y:h+x.y},s,p);t.extent==="parent"&&(v=fg(v,p,r));const m=bg(t,a,u),_=r.internals.z??0;return{x:v.x,y:v.y,z:_>=m?_+1:m}}function Tc(t,r,o,s=[0,0]){var c;const a=[],u=new Map;for(const h of t){const p=r.get(h.parentId);if(!p)continue;const y=((c=u.get(h.parentId))==null?void 0:c.expandedRect)??ss(p),x=hg(y,h.rect);u.set(h.parentId,{expandedRect:x,parent:p})}return u.size>0&&u.forEach(({expandedRect:h,parent:p},y)=>{var w;const x=p.internals.positionAbsolute,v=Sn(p),m=p.origin??s,_=h.x0||k>0||E||R)&&(a.push({id:y,type:"position",position:{x:p.position.x-_+E,y:p.position.y-k+R}}),(w=o.get(y))==null||w.forEach(N=>{t.some(A=>A.id===N.id)||a.push({id:N.id,type:"position",position:{x:N.position.x+_,y:N.position.y+k}})})),(v.width0){const _=Tc(m,r,o,a);y.push(..._)}return{changes:y,updatedInternals:p}}async function L1({delta:t,panZoom:r,transform:o,translateExtent:s,width:a,height:u}){if(!r||!t.x&&!t.y)return!1;const c=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[a,u]],s);return!!c&&(c.x!==o[0]||c.y!==o[1]||c.k!==o[2])}function Ah(t,r,o,s,a,u){let c=a;const h=s.get(c)||new Map;s.set(c,h.set(o,r)),c=`${a}-${t}`;const p=s.get(c)||new Map;if(s.set(c,p.set(o,r)),u){c=`${a}-${t}-${u}`;const y=s.get(c)||new Map;s.set(c,y.set(o,r))}}function Eg(t,r,o){t.clear(),r.clear();for(const s of o){const{source:a,target:u,sourceHandle:c=null,targetHandle:h=null}=s,p={edgeId:s.id,source:a,target:u,sourceHandle:c,targetHandle:h},y=`${a}-${c}--${u}-${h}`,x=`${u}-${h}--${a}-${c}`;Ah("source",p,x,t,a,c),Ah("target",p,y,t,u,h),r.set(s.id,s)}}function Cg(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:Cg(o,r):!1}function $h(t,r,o){var a;let s=t;do{if((a=s==null?void 0:s.matches)!=null&&a.call(s,r))return!0;if(s===o)return!1;s=s==null?void 0:s.parentElement}while(s);return!1}function A1(t,r,o,s){const a=new Map;for(const[u,c]of t)if((c.selected||c.id===s)&&(!c.parentId||!Cg(c,t))&&(c.draggable||r&&typeof c.draggable>"u")){const h=t.get(u);h&&a.set(u,{id:u,position:h.position||{x:0,y:0},distance:{x:o.x-h.internals.positionAbsolute.x,y:o.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return a}function Wu({nodeId:t,dragItems:r,nodeLookup:o,dragging:s=!0}){var c,h,p;const a=[];for(const[y,x]of r){const v=(c=o.get(y))==null?void 0:c.internals.userNode;v&&a.push({...v,position:x.position,dragging:s})}if(!t)return[a[0],a];const u=(h=o.get(t))==null?void 0:h.internals.userNode;return[u?{...u,position:((p=r.get(t))==null?void 0:p.position)||u.position,dragging:s}:a[0],a]}function $1({dragItems:t,snapGrid:r,x:o,y:s}){const a=t.values().next().value;if(!a)return null;const u={x:o-a.distance.x,y:s-a.distance.y},c=gs(u,r);return{x:c.x-u.x,y:c.y-u.y}}function z1({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:s,onDragStop:a}){let u={x:null,y:null},c=0,h=new Map,p=!1,y={x:0,y:0},x=null,v=!1,m=null,_=!1,k=!1,j=null;function b({noDragClassName:R,handleSelector:w,domNode:N,isSelectable:A,nodeId:$,nodeClickDistance:F=0}){m=Ut(N);function G({x:ne,y:K}){const{nodeLookup:C,nodeExtent:V,snapGrid:W,snapToGrid:U,nodeOrigin:M,onNodeDrag:D,onSelectionDrag:H,onError:I,updateNodePositions:z}=r();u={x:ne,y:K};let ie=!1;const oe=h.size>1,fe=oe&&V?dc(ps(h)):null,he=oe&&U?$1({dragItems:h,snapGrid:W,x:ne,y:K}):null;for(const[pe,Z]of h){if(!C.has(pe))continue;let se={x:ne-Z.distance.x,y:K-Z.distance.y};U&&(se=he?{x:Math.round(se.x+he.x),y:Math.round(se.y+he.y)}:gs(se,W));let me=null;if(oe&&V&&!Z.extent&&fe){const{positionAbsolute:re}=Z.internals,Ne=re.x-fe.x+V[0][0],Ie=re.x+Z.measured.width-fe.x2+V[1][0],Le=re.y-fe.y+V[0][1],$e=re.y+Z.measured.height-fe.y2+V[1][1];me=[[Ne,Le],[Ie,$e]]}const{position:ke,positionAbsolute:ve}=dg({nodeId:pe,nextPosition:se,nodeLookup:C,nodeExtent:me||V,nodeOrigin:M,onError:I});ie=ie||Z.position.x!==ke.x||Z.position.y!==ke.y,Z.position=ke,Z.internals.positionAbsolute=ve}if(k=k||ie,!!ie&&(z(h,!0),j&&(s||D||!$&&H))){const[pe,Z]=Wu({nodeId:$,dragItems:h,nodeLookup:C});s==null||s(j,h,pe,Z),D==null||D(j,pe,Z),$||H==null||H(j,Z)}}async function q(){if(!x)return;const{transform:ne,panBy:K,autoPanSpeed:C,autoPanOnNodeDrag:V}=r();if(!V){p=!1,cancelAnimationFrame(c);return}const[W,U]=bc(y,x,C);(W!==0||U!==0)&&(u.x=(u.x??0)-W/ne[2],u.y=(u.y??0)-U/ne[2],await K({x:W,y:U})&&G(u)),c=requestAnimationFrame(q)}function te(ne){var oe;const{nodeLookup:K,multiSelectionActive:C,nodesDraggable:V,transform:W,snapGrid:U,snapToGrid:M,selectNodesOnDrag:D,onNodeDragStart:H,onSelectionDragStart:I,unselectNodesAndEdges:z}=r();v=!0,(!D||!A)&&!C&&$&&((oe=K.get($))!=null&&oe.selected||z()),A&&D&&$&&(t==null||t($));const ie=Qo(ne.sourceEvent,{transform:W,snapGrid:U,snapToGrid:M,containerBounds:x});if(u=ie,h=A1(K,V,ie,$),h.size>0&&(o||H||!$&&I)){const[fe,he]=Wu({nodeId:$,dragItems:h,nodeLookup:K});o==null||o(ne.sourceEvent,h,fe,he),H==null||H(ne.sourceEvent,fe,he),$||I==null||I(ne.sourceEvent,he)}}const ee=Wp().clickDistance(F).on("start",ne=>{const{domNode:K,nodeDragThreshold:C,transform:V,snapGrid:W,snapToGrid:U}=r();x=(K==null?void 0:K.getBoundingClientRect())||null,_=!1,k=!1,j=ne.sourceEvent,C===0&&te(ne),u=Qo(ne.sourceEvent,{transform:V,snapGrid:W,snapToGrid:U,containerBounds:x}),y=xn(ne.sourceEvent,x)}).on("drag",ne=>{const{autoPanOnNodeDrag:K,transform:C,snapGrid:V,snapToGrid:W,nodeDragThreshold:U,nodeLookup:M}=r(),D=Qo(ne.sourceEvent,{transform:C,snapGrid:V,snapToGrid:W,containerBounds:x});if(j=ne.sourceEvent,(ne.sourceEvent.type==="touchmove"&&ne.sourceEvent.touches.length>1||$&&!M.has($))&&(_=!0),!_){if(!p&&K&&v&&(p=!0,q()),!v){const H=xn(ne.sourceEvent,x),I=H.x-y.x,z=H.y-y.y;Math.sqrt(I*I+z*z)>U&&te(ne)}(u.x!==D.xSnapped||u.y!==D.ySnapped)&&h&&v&&(y=xn(ne.sourceEvent,x),G(D))}}).on("end",ne=>{if(!v||_){_&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,v=!1,cancelAnimationFrame(c),h.size>0){const{nodeLookup:K,updateNodePositions:C,onNodeDragStop:V,onSelectionDragStop:W}=r();if(k&&(C(h,!1),k=!1),a||V||!$&&W){const[U,M]=Wu({nodeId:$,dragItems:h,nodeLookup:K,dragging:!1});a==null||a(ne.sourceEvent,h,U,M),V==null||V(ne.sourceEvent,U,M),$||W==null||W(ne.sourceEvent,M)}}}).filter(ne=>{const K=ne.target;return!ne.button&&(!R||!$h(K,`.${R}`,N))&&(!w||$h(K,w,N))});m.call(ee)}function E(){m==null||m.on(".drag",null)}return{update:b,destroy:E}}function D1(t,r,o){const s=[],a={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const u of r.values())Vl(a,ss(u))>0&&s.push(u);return s}const O1=250;function F1(t,r,o,s){var h,p;let a=[],u=1/0;const c=D1(t,o,r+O1);for(const y of c){const x=[...((h=y.internals.handleBounds)==null?void 0:h.source)??[],...((p=y.internals.handleBounds)==null?void 0:p.target)??[]];for(const v of x){if(s.nodeId===v.nodeId&&s.type===v.type&&s.id===v.id)continue;const{x:m,y:_}=hi(y,v,v.position,!0),k=Math.sqrt(Math.pow(m-t.x,2)+Math.pow(_-t.y,2));k>r||(k1){const y=s.type==="source"?"target":"source";return a.find(x=>x.type===y)??a[0]}return a[0]}function Mg(t,r,o,s,a,u=!1){var y,x,v;const c=s.get(t);if(!c)return null;const h=a==="strict"?(y=c.internals.handleBounds)==null?void 0:y[r]:[...((x=c.internals.handleBounds)==null?void 0:x.source)??[],...((v=c.internals.handleBounds)==null?void 0:v.target)??[]],p=(o?h==null?void 0:h.find(m=>m.id===o):h==null?void 0:h[0])??null;return p&&u?{...p,...hi(c,p,p.position,!0)}:p}function Pg(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function H1(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const Ig=()=>!0;function B1(t,{connectionMode:r,connectionRadius:o,handleId:s,nodeId:a,edgeUpdaterType:u,isTarget:c,domNode:h,nodeLookup:p,lib:y,autoPanOnConnect:x,flowId:v,panBy:m,cancelConnection:_,onConnectStart:k,onConnect:j,onConnectEnd:b,isValidConnection:E=Ig,onReconnectEnd:R,updateConnection:w,getTransform:N,getFromHandle:A,autoPanSpeed:$,dragThreshold:F=1,handleDomNode:G}){const q=vg(t.target);let te=0,ee;const{x:ne,y:K}=xn(t),C=Pg(u,G),V=h==null?void 0:h.getBoundingClientRect();let W=!1;if(!V||!C)return;const U=Mg(a,C,s,p,r);if(!U)return;let M=xn(t,V),D=!1,H=null,I=!1,z=null;function ie(){if(!x||!V)return;const[ke,ve]=bc(M,V,$);m({x:ke,y:ve}),te=requestAnimationFrame(ie)}const oe={...U,nodeId:a,type:C,position:U.position},fe=p.get(a);let pe={inProgress:!0,isValid:null,from:hi(fe,oe,Se.Left,!0),fromHandle:oe,fromPosition:oe.position,fromNode:fe,to:M,toHandle:null,toPosition:Nh[oe.position],toNode:null,pointer:M};function Z(){W=!0,w(pe),k==null||k(t,{nodeId:a,handleId:s,handleType:C})}F===0&&Z();function se(ke){if(!W){const{x:$e,y:lt}=xn(ke),at=$e-ne,ut=lt-K;if(!(at*at+ut*ut>F*F))return;Z()}if(!A()||!oe){me(ke);return}const ve=N();M=xn(ke,V),ee=F1(ms(M,ve,!1,[1,1]),o,p,oe),D||(ie(),D=!0);const re=Rg(ke,{handle:ee,connectionMode:r,fromNodeId:a,fromHandleId:s,fromType:c?"target":"source",isValidConnection:E,doc:q,lib:y,flowId:v,nodeLookup:p});z=re.handleDomNode,H=re.connection,I=H1(!!ee,re.isValid);const Ne=p.get(a),Ie=Ne?hi(Ne,oe,Se.Left,!0):pe.from,Le={...pe,from:Ie,isValid:I,to:re.toHandle&&I?eo({x:re.toHandle.x,y:re.toHandle.y},ve):M,toHandle:re.toHandle,toPosition:I&&re.toHandle?re.toHandle.position:Nh[oe.position],toNode:re.toHandle?p.get(re.toHandle.nodeId):null,pointer:M};w(Le),pe=Le}function me(ke){if(!("touches"in ke&&ke.touches.length>0)){if(W){(ee||z)&&H&&I&&(j==null||j(H));const{inProgress:ve,...re}=pe,Ne={...re,toPosition:pe.toHandle?pe.toPosition:null};b==null||b(ke,Ne),u&&(R==null||R(ke,Ne))}_(),cancelAnimationFrame(te),D=!1,I=!1,H=null,z=null,q.removeEventListener("mousemove",se),q.removeEventListener("mouseup",me),q.removeEventListener("touchmove",se),q.removeEventListener("touchend",me)}}q.addEventListener("mousemove",se),q.addEventListener("mouseup",me),q.addEventListener("touchmove",se),q.addEventListener("touchend",me)}function Rg(t,{handle:r,connectionMode:o,fromNodeId:s,fromHandleId:a,fromType:u,doc:c,lib:h,flowId:p,isValidConnection:y=Ig,nodeLookup:x}){const v=u==="target",m=r?c.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:_,y:k}=xn(t),j=c.elementFromPoint(_,k),b=j!=null&&j.classList.contains(`${h}-flow__handle`)?j:m,E={handleDomNode:b,isValid:!1,connection:null,toHandle:null};if(b){const R=Pg(void 0,b),w=b.getAttribute("data-nodeid"),N=b.getAttribute("data-handleid"),A=b.classList.contains("connectable"),$=b.classList.contains("connectableend");if(!w||!R)return E;const F={source:v?w:s,sourceHandle:v?N:a,target:v?s:w,targetHandle:v?a:N};E.connection=F;const q=A&&$&&(o===Zi.Strict?v&&R==="source"||!v&&R==="target":w!==s||N!==a);E.isValid=q&&y(F),E.toHandle=Mg(w,R,N,x,o,!0)}return E}const pc={onPointerDown:B1,isValid:Rg};function V1({domNode:t,panZoom:r,getTransform:o,getViewScale:s}){const a=Ut(t);function u({translateExtent:h,width:p,height:y,zoomStep:x=1,pannable:v=!0,zoomable:m=!0,inversePan:_=!1}){const k=w=>{if(w.sourceEvent.type!=="wheel"||!r)return;const N=o(),A=w.sourceEvent.ctrlKey&&ls()?10:1,$=-w.sourceEvent.deltaY*(w.sourceEvent.deltaMode===1?.05:w.sourceEvent.deltaMode?1:.002)*x,F=N[2]*Math.pow(2,$*A);r.scaleTo(F)};let j=[0,0];const b=w=>{(w.sourceEvent.type==="mousedown"||w.sourceEvent.type==="touchstart")&&(j=[w.sourceEvent.clientX??w.sourceEvent.touches[0].clientX,w.sourceEvent.clientY??w.sourceEvent.touches[0].clientY])},E=w=>{const N=o();if(w.sourceEvent.type!=="mousemove"&&w.sourceEvent.type!=="touchmove"||!r)return;const A=[w.sourceEvent.clientX??w.sourceEvent.touches[0].clientX,w.sourceEvent.clientY??w.sourceEvent.touches[0].clientY],$=[A[0]-j[0],A[1]-j[1]];j=A;const F=s()*Math.max(N[2],Math.log(N[2]))*(_?-1:1),G={x:N[0]-$[0]*F,y:N[1]-$[1]*F},q=[[0,0],[p,y]];r.setViewportConstrained({x:G.x,y:G.y,zoom:N[2]},q,h)},R=og().on("start",b).on("zoom",v?E:null).on("zoom.wheel",m?k:null);a.call(R,{})}function c(){a.on("zoom",null)}return{update:u,destroy:c,pointer:mn}}const ta=t=>({x:t.x,y:t.y,zoom:t.k}),Uu=({x:t,y:r,zoom:o})=>Zl.translate(t,r).scale(o),Tr=(t,r)=>t.target.closest(`.${r}`),Tg=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),W1=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,Yu=(t,r=0,o=W1,s=()=>{})=>{const a=typeof r=="number"&&r>0;return a||s(),a?t.transition().duration(r).ease(o).on("end",s):t},Lg=t=>{const r=t.ctrlKey&&ls()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function U1({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:s,panOnScrollMode:a,panOnScrollSpeed:u,zoomOnPinch:c,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:y}){return x=>{if(Tr(x,r))return x.ctrlKey&&x.preventDefault(),!1;x.preventDefault(),x.stopImmediatePropagation();const v=o.property("__zoom").k||1;if(x.ctrlKey&&c){const b=mn(x),E=Lg(x),R=v*Math.pow(2,E);s.scaleTo(o,R,b,x);return}const m=x.deltaMode===1?20:1;let _=a===ai.Vertical?0:x.deltaX*m,k=a===ai.Horizontal?0:x.deltaY*m;!ls()&&x.shiftKey&&a!==ai.Vertical&&(_=x.deltaY*m,k=0),s.translateBy(o,-(_/v)*u,-(k/v)*u,{internal:!0});const j=ta(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?p==null||p(x,j):(t.isPanScrolling=!0,h==null||h(x,j)),t.panScrollTimeout=setTimeout(()=>{y==null||y(x,j),t.isPanScrolling=!1},150)}}function Y1({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(s,a){const u=s.type==="wheel",c=!r&&u&&!s.ctrlKey,h=Tr(s,t);if(s.ctrlKey&&u&&h&&s.preventDefault(),c||h)return null;s.preventDefault(),o.call(this,s,a)}}function G1({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return s=>{var u,c,h;if((u=s.sourceEvent)!=null&&u.internal)return;const a=ta(s.transform);t.mouseButton=((c=s.sourceEvent)==null?void 0:c.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=a,((h=s.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),o&&(o==null||o(s.sourceEvent,a))}}function X1({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:s,onPanZoom:a}){return u=>{var c,h;t.usedRightMouseButton=!!(o&&Tg(r,t.mouseButton??0)),(c=u.sourceEvent)!=null&&c.sync||s([u.transform.x,u.transform.y,u.transform.k]),a&&!((h=u.sourceEvent)!=null&&h.internal)&&(a==null||a(u.sourceEvent,ta(u.transform)))}}function q1({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:s,onPanZoomEnd:a,onPaneContextMenu:u}){return c=>{var h;if(!((h=c.sourceEvent)!=null&&h.internal)&&(t.isZoomingOrPanning=!1,u&&Tg(r,t.mouseButton??0)&&!t.usedRightMouseButton&&c.sourceEvent&&u(c.sourceEvent),t.usedRightMouseButton=!1,s(!1),a)){const p=ta(c.transform);t.prevViewport=p,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{a==null||a(c.sourceEvent,p)},o?150:0)}}}function K1({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:s,panOnDrag:a,panOnScroll:u,zoomOnDoubleClick:c,userSelectionActive:h,noWheelClassName:p,noPanClassName:y,lib:x,connectionInProgress:v}){return m=>{var E;const _=r||o,k=s&&m.ctrlKey,j=m.type==="wheel";if(m.button===1&&m.type==="mousedown"&&(Tr(m,`${x}-flow__node`)||Tr(m,`${x}-flow__edge`)||Tr(m,`${x}-flow__selection`)||Tr(m,`${x}-flow__nodesselection`)))return!0;if(!a&&!_&&!u&&!c&&!s||h||v&&!j||Tr(m,p)&&j||Tr(m,y)&&(!j||u&&j&&!r)||!s&&m.ctrlKey&&j)return!1;if(!s&&m.type==="touchstart"&&((E=m.touches)==null?void 0:E.length)>1)return m.preventDefault(),!1;if(!_&&!u&&!k&&j||!a&&(m.type==="mousedown"||m.type==="touchstart")||Array.isArray(a)&&!a.includes(m.button)&&m.type==="mousedown")return!1;const b=Array.isArray(a)&&a.includes(m.button)||!m.button||m.button<=1;return(!m.ctrlKey||j||t)&&b}}function Q1({domNode:t,minZoom:r,maxZoom:o,translateExtent:s,viewport:a,onPanZoom:u,onPanZoomStart:c,onPanZoomEnd:h,onDraggingChange:p}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},x=t.getBoundingClientRect();let v=[[0,0],[x.width,x.height]];const m=typeof ResizeObserver<"u"?new ResizeObserver(K=>{const C=K[0];C&&(v=[[0,0],[C.contentRect.width,C.contentRect.height]])}):null;m==null||m.observe(t);const _=og().extent(()=>v).scaleExtent([r,o]).translateExtent(s),k=Ut(t).call(_);N({x:a.x,y:a.y,zoom:Ji(a.zoom,r,o)},[[0,0],[x.width,x.height]],s);const j=k.on("wheel.zoom"),b=k.on("dblclick.zoom");_.wheelDelta(Lg);async function E(K,C){return k?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ko:Il).transform(Yu(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),K)}):!1}function R({noWheelClassName:K,noPanClassName:C,onPaneContextMenu:V,userSelectionActive:W,panOnScroll:U,panOnDrag:M,panOnScrollMode:D,panOnScrollSpeed:H,preventScrolling:I,zoomOnPinch:z,zoomOnScroll:ie,zoomOnDoubleClick:oe,panActivationKeyPressed:fe=!1,zoomActivationKeyPressed:he,lib:pe,onTransformChange:Z,connectionInProgress:se,paneClickDistance:me,selectionOnDrag:ke}){W&&!y.isZoomingOrPanning&&w();const ve=U&&!he&&!W;_.clickDistance(ke?1/0:!vn(me)||me<0?0:me);const re=ve?U1({zoomPanValues:y,noWheelClassName:K,d3Selection:k,d3Zoom:_,panOnScrollMode:D,panOnScrollSpeed:H,zoomOnPinch:z,onPanZoomStart:c,onPanZoom:u,onPanZoomEnd:h}):Y1({noWheelClassName:K,preventScrolling:I,d3ZoomHandler:j});k.on("wheel.zoom",re,{passive:!1});const Ne=G1({zoomPanValues:y,onDraggingChange:p,onPanZoomStart:c});_.on("start",Ne);const Ie=X1({zoomPanValues:y,panOnDrag:M,onPaneContextMenu:!!V,onPanZoom:u,onTransformChange:Z});_.on("zoom",Ie);const Le=q1({zoomPanValues:y,panOnDrag:M,panOnScroll:U,onPaneContextMenu:V,onPanZoomEnd:h,onDraggingChange:p});_.on("end",Le);const $e=K1({panActivationKeyPressed:fe,zoomActivationKeyPressed:he,panOnDrag:M,zoomOnScroll:ie,panOnScroll:U,zoomOnDoubleClick:oe,zoomOnPinch:z,userSelectionActive:W,noPanClassName:C,noWheelClassName:K,lib:pe,connectionInProgress:se});_.filter($e),oe?k.on("dblclick.zoom",b):k.on("dblclick.zoom",null)}function w(){_.on("zoom",null)}async function N(K,C,V){const W=Uu(K),U=_==null?void 0:_.constrain()(W,C,V);return U&&await E(U),U}async function A(K,C){const V=Uu(K);return await E(V,C),V}function $(K){if(k){const C=Uu(K),V=k.property("__zoom");(V.k!==K.zoom||V.x!==K.x||V.y!==K.y)&&(_==null||_.transform(k,C,null,{sync:!0}))}}function F(){const K=k?ig(k.node()):{x:0,y:0,k:1};return{x:K.x,y:K.y,zoom:K.k}}async function G(K,C){return k?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ko:Il).scaleTo(Yu(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),K)}):!1}async function q(K,C){return k?new Promise(V=>{_==null||_.interpolate((C==null?void 0:C.interpolate)==="linear"?Ko:Il).scaleBy(Yu(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>V(!0)),K)}):!1}function te(K){_==null||_.scaleExtent(K)}function ee(K){_==null||_.translateExtent(K)}function ne(K){const C=!vn(K)||K<0?0:K;_==null||_.clickDistance(C)}return{update:R,destroy:w,setViewport:A,setViewportConstrained:N,getViewport:F,scaleTo:G,scaleBy:q,setScaleExtent:te,setTranslateExtent:ee,syncViewport:$,setClickDistance:ne}}var to;(function(t){t.Line="line",t.Handle="handle"})(to||(to={}));function Z1({width:t,prevWidth:r,height:o,prevHeight:s,affectsX:a,affectsY:u}){const c=t-r,h=o-s,p=[c>0?1:c<0?-1:0,h>0?1:h<0?-1:0];return c&&a&&(p[0]=p[0]*-1),h&&u&&(p[1]=p[1]*-1),p}function zh(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),s=t.includes("left"),a=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:s,affectsY:a}}function Ir(t,r){return Math.max(0,r-t)}function Rr(t,r){return Math.max(0,t-r)}function jl(t,r,o){return Math.max(0,r-t,t-o)}function Dh(t,r){return t?!r:r}function J1(t,r,o,s,a,u,c,h){let{affectsX:p,affectsY:y}=r;const{isHorizontal:x,isVertical:v}=r,m=x&&v,{xSnapped:_,ySnapped:k}=o,{minWidth:j,maxWidth:b,minHeight:E,maxHeight:R}=s,{x:w,y:N,width:A,height:$,aspectRatio:F}=t;let G=Math.floor(x?_-t.pointerX:0),q=Math.floor(v?k-t.pointerY:0);const te=A+(p?-G:G),ee=$+(y?-q:q),ne=-u[0]*A,K=-u[1]*$;let C=jl(te,j,b),V=jl(ee,E,R);if(c){let M=0,D=0;p&&G<0?M=Ir(w+G+ne,c[0][0]):!p&&G>0&&(M=Rr(w+te+ne,c[1][0])),y&&q<0?D=Ir(N+q+K,c[0][1]):!y&&q>0&&(D=Rr(N+ee+K,c[1][1])),C=Math.max(C,M),V=Math.max(V,D)}if(h){let M=0,D=0;p&&G>0?M=Rr(w+G,h[0][0]):!p&&G<0&&(M=Ir(w+te,h[1][0])),y&&q>0?D=Rr(N+q,h[0][1]):!y&&q<0&&(D=Ir(N+ee,h[1][1])),C=Math.max(C,M),V=Math.max(V,D)}if(a){if(x){const M=jl(te/F,E,R)*F;if(C=Math.max(C,M),c){let D=0;!p&&!y||p&&!y&&m?D=Rr(N+K+te/F,c[1][1])*F:D=Ir(N+K+(p?G:-G)/F,c[0][1])*F,C=Math.max(C,D)}if(h){let D=0;!p&&!y||p&&!y&&m?D=Ir(N+te/F,h[1][1])*F:D=Rr(N+(p?G:-G)/F,h[0][1])*F,C=Math.max(C,D)}}if(v){const M=jl(ee*F,j,b)/F;if(V=Math.max(V,M),c){let D=0;!p&&!y||y&&!p&&m?D=Rr(w+ee*F+ne,c[1][0])/F:D=Ir(w+(y?q:-q)*F+ne,c[0][0])/F,V=Math.max(V,D)}if(h){let D=0;!p&&!y||y&&!p&&m?D=Ir(w+ee*F,h[1][0])/F:D=Rr(w+(y?q:-q)*F,h[0][0])/F,V=Math.max(V,D)}}}q=q+(q<0?V:-V),G=G+(G<0?C:-C),a&&(m?te>ee*F?q=(Dh(p,y)?-G:G)/F:G=(Dh(p,y)?-q:q)*F:x?(q=G/F,y=p):(G=q*F,p=y));const W=p?w+G:w,U=y?N+q:N;return{width:A+(p?-G:G),height:$+(y?-q:q),x:u[0]*G*(p?-1:1)+W,y:u[1]*q*(y?-1:1)+U}}const Ag={width:0,height:0,x:0,y:0},e_={...Ag,pointerX:0,pointerY:0,aspectRatio:1};function t_(t,r,o){const s=r.position.x+t.position.x,a=r.position.y+t.position.y,u=t.measured.width??0,c=t.measured.height??0,h=o[0]*u,p=o[1]*c;return[[s-h,a-p],[s+u-h,a+c-p]]}function n_({domNode:t,nodeId:r,getStoreItems:o,onChange:s,onEnd:a}){const u=Ut(t);let c={controlDirection:zh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:y,boundaries:x,keepAspectRatio:v,resizeDirection:m,onResizeStart:_,onResize:k,onResizeEnd:j,shouldResize:b}){let E={...Ag},R={...e_};c={boundaries:x,resizeDirection:m,keepAspectRatio:v,controlDirection:zh(y)};let w,N=null,A=[],$,F,G,q=!1;const te=Wp().on("start",ee=>{const{nodeLookup:ne,transform:K,snapGrid:C,snapToGrid:V,nodeOrigin:W,paneDomNode:U}=o();if(w=ne.get(r),!w)return;N=(U==null?void 0:U.getBoundingClientRect())??null;const{xSnapped:M,ySnapped:D}=Qo(ee.sourceEvent,{transform:K,snapGrid:C,snapToGrid:V,containerBounds:N});E={width:w.measured.width??0,height:w.measured.height??0,x:w.position.x??0,y:w.position.y??0},R={...E,pointerX:M,pointerY:D,aspectRatio:E.width/E.height},$=void 0,F=fi(w.extent)?w.extent:void 0,w.parentId&&(w.extent==="parent"||w.expandParent)&&($=ne.get(w.parentId)),$&&w.extent==="parent"&&(F=[[0,0],[$.measured.width,$.measured.height]]),A=[],G=void 0;for(const[H,I]of ne)if(I.parentId===r&&(A.push({id:H,position:{...I.position},extent:I.extent}),I.extent==="parent"||I.expandParent)){const z=t_(I,w,I.origin??W);G?G=[[Math.min(z[0][0],G[0][0]),Math.min(z[0][1],G[0][1])],[Math.max(z[1][0],G[1][0]),Math.max(z[1][1],G[1][1])]]:G=z}_==null||_(ee,{...E})}).on("drag",ee=>{const{transform:ne,snapGrid:K,snapToGrid:C,nodeOrigin:V}=o(),W=Qo(ee.sourceEvent,{transform:ne,snapGrid:K,snapToGrid:C,containerBounds:N}),U=[];if(!w)return;const{x:M,y:D,width:H,height:I}=E,z={},ie=w.origin??V,{width:oe,height:fe,x:he,y:pe}=J1(R,c.controlDirection,W,c.boundaries,c.keepAspectRatio,ie,F,G),Z=oe!==H,se=fe!==I,me=he!==M&&Z,ke=pe!==D&&se;if(!me&&!ke&&!Z&&!se)return;if((me||ke||ie[0]===1||ie[1]===1)&&(z.x=me?he:E.x,z.y=ke?pe:E.y,E.x=z.x,E.y=z.y,A.length>0)){const Ie=he-M,Le=pe-D;for(const $e of A)$e.position={x:$e.position.x-Ie+ie[0]*(oe-H),y:$e.position.y-Le+ie[1]*(fe-I)},U.push($e)}if((Z||se)&&(z.width=Z&&(!c.resizeDirection||c.resizeDirection==="horizontal")?oe:E.width,z.height=se&&(!c.resizeDirection||c.resizeDirection==="vertical")?fe:E.height,E.width=z.width,E.height=z.height),$&&w.expandParent){const Ie=ie[0]*(z.width??0);z.x&&z.x{q&&(j==null||j(ee,{...E}),a==null||a({...E}),q=!1)});u.call(te)}function p(){u.on(".drag",null)}return{update:h,destroy:p}}var Gu={exports:{}},Xu={},qu={exports:{}},Ku={};/** - * @license React - * use-sync-external-store-shim.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Oh;function r_(){if(Oh)return Ku;Oh=1;var t=cs();function r(v,m){return v===m&&(v!==0||1/v===1/m)||v!==v&&m!==m}var o=typeof Object.is=="function"?Object.is:r,s=t.useState,a=t.useEffect,u=t.useLayoutEffect,c=t.useDebugValue;function h(v,m){var _=m(),k=s({inst:{value:_,getSnapshot:m}}),j=k[0].inst,b=k[1];return u(function(){j.value=_,j.getSnapshot=m,p(j)&&b({inst:j})},[v,_,m]),a(function(){return p(j)&&b({inst:j}),v(function(){p(j)&&b({inst:j})})},[v]),c(_),_}function p(v){var m=v.getSnapshot;v=v.value;try{var _=m();return!o(v,_)}catch{return!0}}function y(v,m){return m()}var x=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:h;return Ku.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:x,Ku}var Fh;function i_(){return Fh||(Fh=1,qu.exports=r_()),qu.exports}/** - * @license React - * use-sync-external-store-shim/with-selector.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Hh;function o_(){if(Hh)return Xu;Hh=1;var t=cs(),r=i_();function o(y,x){return y===x&&(y!==0||1/y===1/x)||y!==y&&x!==x}var s=typeof Object.is=="function"?Object.is:o,a=r.useSyncExternalStore,u=t.useRef,c=t.useEffect,h=t.useMemo,p=t.useDebugValue;return Xu.useSyncExternalStoreWithSelector=function(y,x,v,m,_){var k=u(null);if(k.current===null){var j={hasValue:!1,value:null};k.current=j}else j=k.current;k=h(function(){function E($){if(!R){if(R=!0,w=$,$=m($),_!==void 0&&j.hasValue){var F=j.value;if(_(F,$))return N=F}return N=$}if(F=N,s(w,$))return F;var G=m($);return _!==void 0&&_(F,G)?(w=$,F):(w=$,N=G)}var R=!1,w,N,A=v===void 0?null:v;return[function(){return E(x())},A===null?void 0:function(){return E(A())}]},[x,v,m,_]);var b=a(y,k[0],k[1]);return c(function(){j.hasValue=!0,j.value=b},[b]),p(b),b},Xu}var Bh;function s_(){return Bh||(Bh=1,Gu.exports=o_()),Gu.exports}var l_=s_();const a_=bp(l_),u_={},Vh=t=>{let r;const o=new Set,s=(x,v)=>{const m=typeof x=="function"?x(r):x;if(!Object.is(m,r)){const _=r;r=v??(typeof m!="object"||m===null)?m:Object.assign({},r,m),o.forEach(k=>k(r,_))}},a=()=>r,p={setState:s,getState:a,getInitialState:()=>y,subscribe:x=>(o.add(x),()=>o.delete(x)),destroy:()=>{(u_?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),o.clear()}},y=r=t(s,a,p);return p},c_=t=>t?Vh(t):Vh,{useDebugValue:d_}=s0,{useSyncExternalStoreWithSelector:f_}=a_,h_=t=>t;function $g(t,r=h_,o){const s=f_(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return d_(s),s}const Wh=(t,r)=>{const o=c_(t),s=(a,u=r)=>$g(o,a,u);return Object.assign(s,o),s},p_=(t,r)=>t?Wh(t,r):Wh;function Qe(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[s,a]of t)if(!Object.is(a,r.get(s)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const s of t)if(!r.has(s))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const s of o)if(!Object.prototype.hasOwnProperty.call(r,s)||!Object.is(t[s],r[s]))return!1;return!0}Ep();const na=L.createContext(null),g_=na.Provider,zg=wn.error001("react");function De(t,r){const o=L.useContext(na);if(o===null)throw new Error(zg);return $g(o,t,r)}function Ye(){const t=L.useContext(na);if(t===null)throw new Error(zg);return L.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const Uh={display:"none"},m_={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},Dg="react-flow__node-desc",Og="react-flow__edge-desc",y_="react-flow__aria-live",v_=t=>t.ariaLiveMessage,x_=t=>t.ariaLabelConfig;function w_({rfId:t}){const r=De(v_);return d.jsx("div",{id:`${y_}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:m_,children:r})}function __({rfId:t,disableKeyboardA11y:r}){const o=De(x_);return d.jsxs(d.Fragment,{children:[d.jsx("div",{id:`${Dg}-${t}`,style:Uh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),d.jsx("div",{id:`${Og}-${t}`,style:Uh,children:o["edge.a11yDescription.default"]}),!r&&d.jsx(w_,{rfId:t})]})}const ra=L.forwardRef(({position:t="top-left",children:r,className:o,style:s,...a},u)=>{const c=`${t}`.split("-");return d.jsx("div",{className:rt(["react-flow__panel",o,...c]),style:s,ref:u,...a,children:r})});ra.displayName="Panel";const Yh="https://reactflow.dev?utm_source=attribution";function S_({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:d.jsx(ra,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Yh}`,children:d.jsx("a",{href:Yh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const k_=t=>{const r=[],o=[];for(const[,s]of t.nodeLookup)s.selected&&r.push(s.internals.userNode);for(const[,s]of t.edgeLookup)s.selected&&o.push(s);return{selectedNodes:r,selectedEdges:o}},bl=t=>t.id;function N_(t,r){return Qe(t.selectedNodes.map(bl),r.selectedNodes.map(bl))&&Qe(t.selectedEdges.map(bl),r.selectedEdges.map(bl))}function j_({onSelectionChange:t}){const r=Ye(),{selectedNodes:o,selectedEdges:s}=De(k_,N_);return L.useEffect(()=>{const a={nodes:o,edges:s};t==null||t(a),r.getState().onSelectionChangeHandlers.forEach(u=>u(a))},[o,s,t]),null}const b_=t=>!!t.onSelectionChangeHandlers;function E_({onSelectionChange:t}){const r=De(b_);return t||r?d.jsx(j_,{onSelectionChange:t}):null}const Fg=[0,0],C_={x:0,y:0,zoom:1},M_=["nodes","edges","defaultNodes","defaultEdges","onConnect","onConnectStart","onConnectEnd","onClickConnectStart","onClickConnectEnd","nodesDraggable","autoPanOnNodeFocus","nodesConnectable","nodesFocusable","edgesFocusable","edgesReconnectable","elevateNodesOnSelect","elevateEdgesOnSelect","minZoom","maxZoom","nodeExtent","onNodesChange","onEdgesChange","elementsSelectable","connectionMode","snapGrid","snapToGrid","translateExtent","connectOnClick","defaultEdgeOptions","fitView","fitViewOptions","onNodesDelete","onEdgesDelete","onDelete","onNodeDrag","onNodeDragStart","onNodeDragStop","onSelectionDrag","onSelectionDragStart","onSelectionDragStop","onMoveStart","onMove","onMoveEnd","noPanClassName","nodeOrigin","autoPanOnConnect","autoPanOnNodeDrag","onError","connectionRadius","isValidConnection","selectNodesOnDrag","nodeDragThreshold","connectionDragThreshold","onBeforeDelete","debug","autoPanSpeed","ariaLabelConfig","zIndexMode"],Gh=[...M_,"rfId"],P_=t=>({setNodes:t.setNodes,setEdges:t.setEdges,setMinZoom:t.setMinZoom,setMaxZoom:t.setMaxZoom,setTranslateExtent:t.setTranslateExtent,setNodeExtent:t.setNodeExtent,reset:t.reset,setDefaultNodesAndEdges:t.setDefaultNodesAndEdges}),Xh={translateExtent:rs,nodeOrigin:Fg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function I_(t){const{setNodes:r,setEdges:o,setMinZoom:s,setMaxZoom:a,setTranslateExtent:u,setNodeExtent:c,reset:h,setDefaultNodesAndEdges:p}=De(P_,Qe),y=Ye();L.useEffect(()=>(p(t.defaultNodes,t.defaultEdges),()=>{x.current=Xh,h()}),[]);const x=L.useRef(Xh);return L.useEffect(()=>{for(const v of Gh){const m=t[v],_=x.current[v];m!==_&&(typeof t[v]>"u"||(v==="nodes"?r(m):v==="edges"?o(m):v==="minZoom"?s(m):v==="maxZoom"?a(m):v==="translateExtent"?u(m):v==="nodeExtent"?c(m):v==="ariaLabelConfig"?y.setState({ariaLabelConfig:g1(m)}):v==="fitView"?y.setState({fitViewQueued:m}):v==="fitViewOptions"?y.setState({fitViewOptions:m}):y.setState({[v]:m})))}x.current=t},Gh.map(v=>t[v])),null}function qh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function R_(t){var s;const[r,o]=L.useState(t==="system"?null:t);return L.useEffect(()=>{if(t!=="system"){o(t);return}const a=qh(),u=()=>o(a!=null&&a.matches?"dark":"light");return u(),a==null||a.addEventListener("change",u),()=>{a==null||a.removeEventListener("change",u)}},[t]),r!==null?r:(s=qh())!=null&&s.matches?"dark":"light"}const Kh=typeof document<"u"?document:null;function as(t=null,r={target:Kh,actInsideInputWithModifier:!0}){const[o,s]=L.useState(!1),a=L.useRef(!1),u=L.useRef(new Set([])),[c,h]=L.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(v=>typeof v=="string").map(v=>v.replace(/\+/g,` -`).replace(` - -`,` -+`).split(` -`)),x=y.reduce((v,m)=>v.concat(...m),[]);return[y,x]}return[[],[]]},[t]);return L.useEffect(()=>{const p=(r==null?void 0:r.target)??Kh,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const x=_=>{var b,E;if(a.current=_.ctrlKey||_.metaKey||_.shiftKey||_.altKey,(!a.current||a.current&&!y)&&xg(_))return!1;const j=Zh(_.code,h);if(u.current.add(_[j]),Qh(c,u.current,!1)){const R=((E=(b=_.composedPath)==null?void 0:b.call(_))==null?void 0:E[0])||_.target,w=(R==null?void 0:R.nodeName)==="BUTTON"||(R==null?void 0:R.nodeName)==="A";r.preventDefault!==!1&&(a.current||!w)&&_.preventDefault(),s(!0)}},v=_=>{const k=Zh(_.code,h);Qh(c,u.current,!0)?(s(!1),u.current.clear()):u.current.delete(_[k]),_.key==="Meta"&&u.current.clear(),a.current=!1},m=()=>{u.current.clear(),s(!1)};return p==null||p.addEventListener("keydown",x),p==null||p.addEventListener("keyup",v),window.addEventListener("blur",m),window.addEventListener("contextmenu",m),()=>{p==null||p.removeEventListener("keydown",x),p==null||p.removeEventListener("keyup",v),window.removeEventListener("blur",m),window.removeEventListener("contextmenu",m)}}},[t,s]),o}function Qh(t,r,o){return t.filter(s=>o||s.length===r.size).some(s=>s.every(a=>r.has(a)))}function Zh(t,r){return r.includes(t)?"code":"key"}const T_=()=>{const t=Ye();return L.useMemo(()=>({zoomIn:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1/1.2,r):!1},zoomTo:async(r,o)=>{const{panZoom:s}=t.getState();return s?s.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[s,a,u],panZoom:c}=t.getState();return c?(await c.setViewport({x:r.x??s,y:r.y??a,zoom:r.zoom??u},o),!0):!1},getViewport:()=>{const[r,o,s]=t.getState().transform;return{x:r,y:o,zoom:s}},setCenter:async(r,o,s)=>t.getState().setCenter(r,o,s),fitBounds:async(r,o)=>{const{width:s,height:a,minZoom:u,maxZoom:c,panZoom:h}=t.getState(),p=Ec(r,s,a,u,c,(o==null?void 0:o.padding)??.1);return h?(await h.setViewport(p,{duration:o==null?void 0:o.duration,ease:o==null?void 0:o.ease,interpolate:o==null?void 0:o.interpolate}),!0):!1},screenToFlowPosition:(r,o={})=>{const{transform:s,snapGrid:a,snapToGrid:u,domNode:c}=t.getState();if(!c)return r;const{x:h,y:p}=c.getBoundingClientRect(),y={x:r.x-h,y:r.y-p},x=o.snapGrid??a,v=o.snapToGrid??u;return ms(y,s,v,x)},flowToScreenPosition:r=>{const{transform:o,domNode:s}=t.getState();if(!s)return r;const{x:a,y:u}=s.getBoundingClientRect(),c=eo(r,o);return{x:c.x+a,y:c.y+u}}}),[])};function Hg(t,r){const o=[],s=new Map,a=[];for(const u of t)if(u.type==="add"){a.push(u);continue}else if(u.type==="remove"||u.type==="replace")s.set(u.id,[u]);else{const c=s.get(u.id);c?c.push(u):s.set(u.id,[u])}for(const u of r){const c=s.get(u.id);if(!c){o.push(u);continue}if(c[0].type==="remove")continue;if(c[0].type==="replace"){o.push({...c[0].item});continue}const h={...u};for(const p of c)L_(p,h);o.push(h)}return a.length&&a.forEach(u=>{u.index!==void 0?o.splice(u.index,0,{...u.item}):o.push({...u.item})}),o}function L_(t,r){switch(t.type){case"select":{r.selected=t.selected;break}case"position":{typeof t.position<"u"&&(r.position=t.position),typeof t.dragging<"u"&&(r.dragging=t.dragging);break}case"dimensions":{typeof t.dimensions<"u"&&(r.measured={...t.dimensions},t.setAttributes&&((t.setAttributes===!0||t.setAttributes==="width")&&(r.width=t.dimensions.width),(t.setAttributes===!0||t.setAttributes==="height")&&(r.height=t.dimensions.height))),typeof t.resizing=="boolean"&&(r.resizing=t.resizing);break}}}function A_(t,r){return Hg(t,r)}function $_(t,r){return Hg(t,r)}function oi(t,r){return{id:t,type:"select",selected:r}}function Gi(t,r=new Set,o=!1){const s=[];for(const[a,u]of t){const c=r.has(a);!(u.selected===void 0&&!c)&&u.selected!==c&&(o&&(u.selected=c),s.push(oi(u.id,c)))}return s}function Jh({items:t=[],lookup:r}){var a;const o=[],s=new Map(t.map(u=>[u.id,u]));for(const[u,c]of t.entries()){const h=r.get(c.id),p=((a=h==null?void 0:h.internals)==null?void 0:a.userNode)??h;p!==void 0&&p!==c&&o.push({id:c.id,item:c,type:"replace"}),p===void 0&&o.push({item:c,type:"add",index:u})}for(const[u]of r)s.get(u)===void 0&&o.push({id:u,type:"remove"});return o}function ep(t){return{id:t.id,type:"remove"}}const z_=gg();function D_(t,r,o={}){return _1(t,r,{...o,onError:o.onError??z_})}const tp=t=>s1(t),O_=t=>cg(t);function Bg(t){return L.forwardRef(t)}const Vg=typeof window<"u"?L.useLayoutEffect:L.useEffect;function np(t){const[r,o]=L.useState(BigInt(0)),[s]=L.useState(()=>F_(()=>o(a=>a+BigInt(1))));return Vg(()=>{const a=s.get();a.length&&(t(a),s.reset())},[r]),s}function F_(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const Wg=L.createContext(null);function H_({children:t}){const r=Ye(),o=L.useCallback(h=>{const{nodes:p=[],setNodes:y,hasDefaultNodes:x,onNodesChange:v,nodeLookup:m,fitViewQueued:_,onNodesChangeMiddlewareMap:k}=r.getState();let j=p;for(const E of h)j=typeof E=="function"?E(j):E;let b=Jh({items:j,lookup:m});for(const E of k.values())b=E(b);x&&y(j),b.length>0?v==null||v(b):_&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:R,setNodes:w}=r.getState();E&&w(R)})},[]),s=np(o),a=L.useCallback(h=>{const{edges:p=[],setEdges:y,hasDefaultEdges:x,onEdgesChange:v,edgeLookup:m}=r.getState();let _=p;for(const k of h)_=typeof k=="function"?k(_):k;x?y(_):v&&v(Jh({items:_,lookup:m}))},[]),u=np(a),c=L.useMemo(()=>({nodeQueue:s,edgeQueue:u}),[]);return d.jsx(Wg.Provider,{value:c,children:t})}function B_(){const t=L.useContext(Wg);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const V_=t=>!!t.panZoom;function ia(){const t=T_(),r=Ye(),o=B_(),s=De(V_),a=L.useMemo(()=>{const u=v=>r.getState().nodeLookup.get(v),c=v=>{o.nodeQueue.push(v)},h=v=>{o.edgeQueue.push(v)},p=v=>{var E,R;const{nodeLookup:m,nodeOrigin:_}=r.getState(),k=tp(v)?v:m.get(v.id),j=k.parentId?yg(k.position,k.measured,k.parentId,m,_):k.position,b={...k,position:j,width:((E=k.measured)==null?void 0:E.width)??k.width,height:((R=k.measured)==null?void 0:R.height)??k.height};return ss(b)},y=(v,m,_={replace:!1})=>{c(k=>k.map(j=>{if(j.id===v){const b=typeof m=="function"?m(j):m;return _.replace&&tp(b)?b:{...j,...b}}return j}))},x=(v,m,_={replace:!1})=>{h(k=>k.map(j=>{if(j.id===v){const b=typeof m=="function"?m(j):m;return _.replace&&O_(b)?b:{...j,...b}}return j}))};return{getNodes:()=>r.getState().nodes.map(v=>({...v})),getNode:v=>{var m;return(m=u(v))==null?void 0:m.internals.userNode},getInternalNode:u,getEdges:()=>{const{edges:v=[]}=r.getState();return v.map(m=>({...m}))},getEdge:v=>r.getState().edgeLookup.get(v),setNodes:c,setEdges:h,addNodes:v=>{const m=Array.isArray(v)?v:[v];o.nodeQueue.push(_=>[..._,...m])},addEdges:v=>{const m=Array.isArray(v)?v:[v];o.edgeQueue.push(_=>[..._,...m])},toObject:()=>{const{nodes:v=[],edges:m=[],transform:_}=r.getState(),[k,j,b]=_;return{nodes:v.map(E=>({...E})),edges:m.map(E=>({...E})),viewport:{x:k,y:j,zoom:b}}},deleteElements:async({nodes:v=[],edges:m=[]})=>{const{nodes:_,edges:k,onNodesDelete:j,onEdgesDelete:b,triggerNodeChanges:E,triggerEdgeChanges:R,onDelete:w,onBeforeDelete:N}=r.getState(),{nodes:A,edges:$}=await d1({nodesToRemove:v,edgesToRemove:m,nodes:_,edges:k,onBeforeDelete:N}),F=$.length>0,G=A.length>0;if(F){const q=$.map(ep);b==null||b($),R(q)}if(G){const q=A.map(ep);j==null||j(A),E(q)}return(G||F)&&(w==null||w({nodes:A,edges:$})),{deletedNodes:A,deletedEdges:$}},getIntersectingNodes:(v,m=!0,_)=>{const k=bh(v),j=k?v:p(v),b=_!==void 0;return j?(_||r.getState().nodes).filter(E=>{const R=r.getState().nodeLookup.get(E.id);if(R&&!k&&(E.id===v.id||!R.internals.positionAbsolute))return!1;const w=ss(b?E:R),N=Vl(w,j);return m&&N>0||N>=w.width*w.height||N>=j.width*j.height}):[]},isNodeIntersecting:(v,m,_=!0)=>{const j=bh(v)?v:p(v);if(!j)return!1;const b=Vl(j,m);return _&&b>0||b>=m.width*m.height||b>=j.width*j.height},updateNode:y,updateNodeData:(v,m,_={replace:!1})=>{y(v,k=>{const j=typeof m=="function"?m(k):m;return _.replace?{...k,data:j}:{...k,data:{...k.data,...j}}},_)},updateEdge:x,updateEdgeData:(v,m,_={replace:!1})=>{x(v,k=>{const j=typeof m=="function"?m(k):m;return _.replace?{...k,data:j}:{...k,data:{...k.data,...j}}},_)},getNodesBounds:v=>{const{nodeLookup:m,nodeOrigin:_}=r.getState();return l1(v,{nodeLookup:m,nodeOrigin:_})},getHandleConnections:({type:v,id:m,nodeId:_})=>{var k;return Array.from(((k=r.getState().connectionLookup.get(`${_}-${v}${m?`-${m}`:""}`))==null?void 0:k.values())??[])},getNodeConnections:({type:v,handleId:m,nodeId:_})=>{var k;return Array.from(((k=r.getState().connectionLookup.get(`${_}${v?m?`-${v}-${m}`:`-${v}`:""}`))==null?void 0:k.values())??[])},fitView:async v=>{const m=r.getState().fitViewResolver??p1();return r.setState({fitViewQueued:!0,fitViewOptions:v,fitViewResolver:m}),o.nodeQueue.push(_=>[..._]),m.promise}}},[]);return L.useMemo(()=>({...a,...t,viewportInitialized:s}),[s])}const rp=t=>t.selected,W_=typeof window<"u"?window:void 0;function U_({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=Ye(),{deleteElements:s}=ia(),a=as(t,{actInsideInputWithModifier:!1}),u=as(r,{target:W_});L.useEffect(()=>{if(a){const{edges:c,nodes:h}=o.getState();s({nodes:h.filter(rp),edges:c.filter(rp)}),o.setState({nodesSelectionActive:!1})}},[a]),L.useEffect(()=>{o.setState({multiSelectionActive:u})},[u])}function Y_(t){const r=Ye();L.useEffect(()=>{const o=()=>{var a,u,c,h;if(!t.current||!(((u=(a=t.current).checkVisibility)==null?void 0:u.call(a))??!0))return!1;const s=Cc(t.current);(s.height===0||s.width===0)&&((h=(c=r.getState()).onError)==null||h.call(c,"004",wn.error004())),r.setState({width:s.width||500,height:s.height||500})};if(t.current){o(),window.addEventListener("resize",o);const s=new ResizeObserver(()=>o());return s.observe(t.current),()=>{window.removeEventListener("resize",o),s&&t.current&&s.unobserve(t.current)}}},[])}const oa={position:"absolute",width:"100%",height:"100%",top:0,left:0},G_=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function X_({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:s=!1,panActivationKeyPressed:a,panOnScrollSpeed:u=.5,panOnScrollMode:c=ai.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:y,translateExtent:x,minZoom:v,maxZoom:m,zoomActivationKeyCode:_,preventScrolling:k=!0,children:j,noWheelClassName:b,noPanClassName:E,onViewportChange:R,isControlledViewport:w,paneClickDistance:N,selectionOnDrag:A}){const $=Ye(),F=L.useRef(null),{userSelectionActive:G,lib:q,connectionInProgress:te}=De(G_,Qe),ee=as(_),ne=L.useRef();Y_(F);const K=L.useCallback(C=>{R==null||R({x:C[0],y:C[1],zoom:C[2]}),w||$.setState({transform:C})},[R,w]);return L.useEffect(()=>{if(F.current){ne.current=Q1({domNode:F.current,minZoom:v,maxZoom:m,translateExtent:x,viewport:y,onDraggingChange:U=>$.setState(M=>M.paneDragging===U?M:{paneDragging:U}),onPanZoomStart:(U,M)=>{const{onViewportChangeStart:D,onMoveStart:H}=$.getState();H==null||H(U,M),D==null||D(M)},onPanZoom:(U,M)=>{const{onViewportChange:D,onMove:H}=$.getState();H==null||H(U,M),D==null||D(M)},onPanZoomEnd:(U,M)=>{const{onViewportChangeEnd:D,onMoveEnd:H}=$.getState();H==null||H(U,M),D==null||D(M)}});const{x:C,y:V,zoom:W}=ne.current.getViewport();return $.setState({panZoom:ne.current,transform:[C,V,W],domNode:F.current.closest(".react-flow")}),()=>{var U;(U=ne.current)==null||U.destroy()}}},[]),L.useEffect(()=>{var C;(C=ne.current)==null||C.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:s,panActivationKeyPressed:a,panOnScrollSpeed:u,panOnScrollMode:c,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:ee,preventScrolling:k,noPanClassName:E,userSelectionActive:G,noWheelClassName:b,lib:q,onTransformChange:K,connectionInProgress:te,selectionOnDrag:A,paneClickDistance:N})},[t,r,o,s,a,u,c,h,p,ee,k,E,G,b,q,K,te,A,N]),d.jsx("div",{className:"react-flow__renderer",ref:F,style:oa,children:j})}const q_=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function K_(){const{userSelectionActive:t,userSelectionRect:r}=De(q_,Qe);return t&&r?d.jsx("div",{className:"react-flow__selection react-flow__container",style:{width:r.width,height:r.height,transform:`translate(${r.x}px, ${r.y}px)`}}):null}const Qu=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},Q_=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function Z_({isSelecting:t,selectionKeyPressed:r,selectionMode:o=is.Full,panOnDrag:s,autoPanOnSelection:a,paneClickDistance:u,selectionOnDrag:c,onSelectionStart:h,onSelectionEnd:p,onPaneClick:y,onPaneContextMenu:x,onPaneScroll:v,onPaneMouseEnter:m,onPaneMouseMove:_,onPaneMouseLeave:k,children:j}){const b=L.useRef(0),E=Ye(),{userSelectionActive:R,elementsSelectable:w,dragging:N,panBy:A,autoPanSpeed:$}=De(Q_,Qe),F=w&&(t||R),G=L.useRef(null),q=L.useRef(),te=L.useRef(new Set),ee=L.useRef(new Set),ne=L.useRef(!1),K=L.useRef(!1),C=L.useRef({x:0,y:0}),V=L.useRef(!1),W=Z=>{if(K.current||ne.current||E.getState().connection.inProgress){K.current=!1,ne.current=!1;return}y==null||y(Z),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},U=Z=>{if(Array.isArray(s)&&(s!=null&&s.includes(2))){Z.preventDefault();return}x==null||x(Z)},M=v?Z=>v(Z):void 0,D=Z=>{K.current&&(Z.stopPropagation(),K.current=!1)},H=Z=>{var $e,lt;if(Z.pointerType==="touch"&&s!==!1&&!r)return;const{domNode:se,transform:me}=E.getState();if(q.current=se==null?void 0:se.getBoundingClientRect(),!q.current)return;const ke=Z.target===G.current;if(!ke&&!!Z.target.closest(".nokey")||!t||!(c&&ke||r)||Z.button!==0||!Z.isPrimary)return;(lt=($e=Z.target)==null?void 0:$e.setPointerCapture)==null||lt.call($e,Z.pointerId),K.current=!1;const{x:Ne,y:Ie}=xn(Z.nativeEvent,q.current),Le=ms({x:Ne,y:Ie},me);E.setState({userSelectionRect:{width:0,height:0,startX:Le.x,startY:Le.y,x:Ne,y:Ie}}),ke||(Z.stopPropagation(),Z.preventDefault())};function I(Z,se){const{userSelectionRect:me}=E.getState();if(!me)return;const{transform:ke,nodeLookup:ve,edgeLookup:re,connectionLookup:Ne,triggerNodeChanges:Ie,triggerEdgeChanges:Le,defaultEdgeOptions:$e}=E.getState(),lt={x:me.startX,y:me.startY},{x:at,y:ut}=eo(lt,ke),Ge={startX:lt.x,startY:lt.y,x:Zmt.id)),ee.current=new Set;const gt=($e==null?void 0:$e.selectable)??!0;for(const mt of te.current){const Ct=Ne.get(mt);if(Ct)for(const{edgeId:ct}of Ct.values()){const et=re.get(ct);et&&(et.selectable??gt)&&ee.current.add(ct)}}if(!Eh(wt,te.current)){const mt=Gi(ve,te.current,!0);Ie(mt)}if(!Eh(Gt,ee.current)){const mt=Gi(re,ee.current);Le(mt)}E.setState({userSelectionRect:Ge,userSelectionActive:!0,nodesSelectionActive:!1})}function z(){if(!a||!q.current)return;const[Z,se]=bc(C.current,q.current,$);A({x:Z,y:se}).then(me=>{if(!K.current||!me){b.current=requestAnimationFrame(z);return}const{x:ke,y:ve}=C.current;I(ke,ve),b.current=requestAnimationFrame(z)})}const ie=()=>{cancelAnimationFrame(b.current),b.current=0,V.current=!1};L.useEffect(()=>()=>ie(),[]);const oe=Z=>{const{userSelectionRect:se,transform:me,resetSelectedElements:ke}=E.getState();if(!q.current||!se)return;const{x:ve,y:re}=xn(Z.nativeEvent,q.current);C.current={x:ve,y:re};const Ne=eo({x:se.startX,y:se.startY},me);if(!K.current){const Ie=r?0:u;if(Math.hypot(ve-Ne.x,re-Ne.y)<=Ie)return;ke(),h==null||h(Z)}K.current=!0,V.current||(z(),V.current=!0),I(ve,re)},fe=Z=>{var se,me;if(!F){Z.target===G.current&&E.getState().connection.inProgress&&(ne.current=!0);return}Z.button===0&&((me=(se=Z.target)==null?void 0:se.releasePointerCapture)==null||me.call(se,Z.pointerId),!R&&Z.target===G.current&&E.getState().userSelectionRect&&(W==null||W(Z)),E.setState({userSelectionActive:!1,userSelectionRect:null}),K.current&&(p==null||p(Z),E.setState({nodesSelectionActive:te.current.size>0})),ie())},he=Z=>{var se,me;(me=(se=Z.target)==null?void 0:se.releasePointerCapture)==null||me.call(se,Z.pointerId),ie()},pe=s===!0||Array.isArray(s)&&s.includes(0);return d.jsxs("div",{className:rt(["react-flow__pane",{draggable:pe,dragging:N,selection:t}]),onClick:F?void 0:Qu(W,G),onContextMenu:Qu(U,G),onWheel:Qu(M,G),onPointerEnter:F?void 0:m,onPointerMove:F?oe:_,onPointerUp:fe,onPointerCancel:F?he:void 0,onPointerDownCapture:F?H:void 0,onClickCapture:F?D:void 0,onPointerLeave:k,ref:G,style:oa,children:[j,d.jsx(K_,{})]})}function gc({id:t,store:r,unselect:o=!1,nodeRef:s}){const{addSelectedNodes:a,unselectNodesAndEdges:u,multiSelectionActive:c,nodeLookup:h,onError:p}=r.getState(),y=h.get(t);if(!y){p==null||p("012",wn.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&c)&&(u({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var x;return(x=s==null?void 0:s.current)==null?void 0:x.blur()})):a([t])}function Ug({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:s,nodeId:a,isSelectable:u,nodeClickDistance:c}){const h=Ye(),[p,y]=L.useState(!1),x=L.useRef();return L.useEffect(()=>{if(!r)return x.current=z1({getStoreItems:()=>h.getState(),onNodeMouseDown:v=>{gc({id:v,store:h,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var v;(v=x.current)==null||v.destroy(),x.current=void 0}},[r,h,t]),L.useEffect(()=>{r||!t.current||!x.current||x.current.update({noDragClassName:o,handleSelector:s,domNode:t.current,isSelectable:u,nodeId:a,nodeClickDistance:c})},[o,s,r,u,t,a,c]),p}const J_=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function Yg(){const t=Ye();return L.useCallback(o=>{const{nodeExtent:s,snapToGrid:a,snapGrid:u,nodesDraggable:c,onError:h,updateNodePositions:p,nodeLookup:y,nodeOrigin:x}=t.getState(),v=new Map,m=J_(c),_=a?u[0]:5,k=a?u[1]:5,j=o.direction.x*_*o.factor,b=o.direction.y*k*o.factor;for(const[,E]of y){if(!m(E))continue;let R={x:E.internals.positionAbsolute.x+j,y:E.internals.positionAbsolute.y+b};a&&(R=gs(R,u));const{position:w,positionAbsolute:N}=dg({nodeId:E.id,nextPosition:R,nodeLookup:y,nodeExtent:s,nodeOrigin:x,onError:h});E.position=w,E.internals.positionAbsolute=N,v.set(E.id,E)}p(v)},[])}const Lc=L.createContext(null),eS=Lc.Provider;Lc.Consumer;const Gg=()=>L.useContext(Lc),tS=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),Xg=L.createContext(null);function nS({children:t}){const r=De(tS,Qe);return d.jsx(Xg.Provider,{value:r,children:t})}function rS(){const t=L.useContext(Xg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const iS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},oS=(t,r,o)=>s=>{const{connectionClickStartHandle:a,connectionMode:u,connection:c}=s,{fromHandle:h,toHandle:p,isValid:y}=c;if(!h&&!a)return iS;const x=(p==null?void 0:p.nodeId)===t&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===o;return{connectingFrom:(h==null?void 0:h.nodeId)===t&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===o,connectingTo:x,clickConnecting:(a==null?void 0:a.nodeId)===t&&(a==null?void 0:a.id)===r&&(a==null?void 0:a.type)===o,isPossibleEndHandle:u===Zi.Strict?(h==null?void 0:h.type)!==o:t!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!a,valid:x&&y}};function sS({type:t="source",position:r=Se.Top,isValidConnection:o,isConnectable:s=!0,isConnectableStart:a=!0,isConnectableEnd:u=!0,id:c,onConnect:h,children:p,className:y,onMouseDown:x,onTouchStart:v,...m},_){var V,W;const k=c||null,j=t==="target",b=Ye(),E=Gg(),{connectOnClick:R,noPanClassName:w,rfId:N}=rS(),{connectingFrom:A,connectingTo:$,clickConnecting:F,isPossibleEndHandle:G,connectionInProcess:q,clickConnectionInProcess:te,valid:ee}=De(oS(E,k,t),Qe);E||(W=(V=b.getState()).onError)==null||W.call(V,"010",wn.error010());const ne=U=>{const{defaultEdgeOptions:M,onConnect:D,hasDefaultEdges:H}=b.getState(),I={...M,...U};if(H){const{edges:z,setEdges:ie,onError:oe}=b.getState();ie(D_(I,z,{onError:oe}))}D==null||D(I),h==null||h(I)},K=U=>{if(!E)return;const M=wg(U.nativeEvent);if(a&&(M&&U.button===0||!M)){const D=b.getState();pc.onPointerDown(U.nativeEvent,{handleDomNode:U.currentTarget,autoPanOnConnect:D.autoPanOnConnect,connectionMode:D.connectionMode,connectionRadius:D.connectionRadius,domNode:D.domNode,nodeLookup:D.nodeLookup,lib:D.lib,isTarget:j,handleId:k,nodeId:E,flowId:D.rfId,panBy:D.panBy,cancelConnection:D.cancelConnection,onConnectStart:D.onConnectStart,onConnectEnd:(...H)=>{var I,z;return(z=(I=b.getState()).onConnectEnd)==null?void 0:z.call(I,...H)},updateConnection:D.updateConnection,onConnect:ne,isValidConnection:o||((...H)=>{var I,z;return((z=(I=b.getState()).isValidConnection)==null?void 0:z.call(I,...H))??!0}),getTransform:()=>b.getState().transform,getFromHandle:()=>b.getState().connection.fromHandle,autoPanSpeed:D.autoPanSpeed,dragThreshold:D.connectionDragThreshold})}M?x==null||x(U):v==null||v(U)},C=U=>{const{onClickConnectStart:M,onClickConnectEnd:D,connectionClickStartHandle:H,connectionMode:I,isValidConnection:z,lib:ie,rfId:oe,nodeLookup:fe,connection:he}=b.getState();if(!E||!H&&!a)return;if(!H){M==null||M(U.nativeEvent,{nodeId:E,handleId:k,handleType:t}),b.setState({connectionClickStartHandle:{nodeId:E,type:t,id:k}});return}const pe=vg(U.target),Z=o||z,{connection:se,isValid:me}=pc.isValid(U.nativeEvent,{handle:{nodeId:E,id:k,type:t},connectionMode:I,fromNodeId:H.nodeId,fromHandleId:H.id||null,fromType:H.type,isValidConnection:Z,flowId:oe,doc:pe,lib:ie,nodeLookup:fe});me&&se&&ne(se);const ke=structuredClone(he);delete ke.inProgress,ke.toPosition=ke.toHandle?ke.toHandle.position:null,D==null||D(U,ke),b.setState({connectionClickStartHandle:null})};return d.jsx("div",{"data-handleid":k,"data-nodeid":E,"data-handlepos":r,"data-id":`${N}-${E}-${k}-${t}`,className:rt(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",w,y,{source:!j,target:j,connectable:s,connectablestart:a,connectableend:u,clickconnecting:F,connectingfrom:A,connectingto:$,valid:ee,connectionindicator:s&&(!q||G)&&(q||te?u:a)}]),onMouseDown:K,onTouchStart:K,onClick:R?C:void 0,ref:_,...m,children:p})}const no=L.memo(Bg(sS));function lS({data:t,isConnectable:r,sourcePosition:o=Se.Bottom}){return d.jsxs(d.Fragment,{children:[t==null?void 0:t.label,d.jsx(no,{type:"source",position:o,isConnectable:r})]})}function aS({data:t,isConnectable:r,targetPosition:o=Se.Top,sourcePosition:s=Se.Bottom}){return d.jsxs(d.Fragment,{children:[d.jsx(no,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,d.jsx(no,{type:"source",position:s,isConnectable:r})]})}function uS(){return null}function cS({data:t,isConnectable:r,targetPosition:o=Se.Top}){return d.jsxs(d.Fragment,{children:[d.jsx(no,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const Ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},ip={input:lS,default:aS,output:cS,group:uS};function dS(t){var r,o,s,a;return t.internals.handleBounds===void 0?{width:t.width??t.initialWidth??((r=t.style)==null?void 0:r.width),height:t.height??t.initialHeight??((o=t.style)==null?void 0:o.height)}:{width:t.width??((s=t.style)==null?void 0:s.width),height:t.height??((a=t.style)==null?void 0:a.height)}}const fS=t=>{const{width:r,height:o,x:s,y:a}=ps(t.nodeLookup,{filter:u=>!!u.selected});return{width:vn(r)?r:null,height:vn(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${s}px,${a}px)`}};function hS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const s=Ye(),{width:a,height:u,transformString:c,userSelectionActive:h}=De(fS,Qe),p=Yg(),y=L.useRef(null);L.useEffect(()=>{var _;o||(_=y.current)==null||_.focus({preventScroll:!0})},[o]);const x=!h&&a!==null&&u!==null;if(Ug({nodeRef:y,disabled:!x}),!x)return null;const v=t?_=>{const k=s.getState().nodes.filter(j=>j.selected);t(_,k)}:void 0,m=_=>{Object.prototype.hasOwnProperty.call(Ul,_.key)&&(_.preventDefault(),p({direction:Ul[_.key],factor:_.shiftKey?4:1}))};return d.jsx("div",{className:rt(["react-flow__nodesselection","react-flow__container",r]),style:{transform:c},children:d.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:v,tabIndex:o?void 0:-1,onKeyDown:o?void 0:m,style:{width:a,height:u}})})}const op=typeof window<"u"?window:void 0,pS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function qg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:y,selectionOnDrag:x,selectionMode:v,onSelectionStart:m,onSelectionEnd:_,multiSelectionKeyCode:k,panActivationKeyCode:j,zoomActivationKeyCode:b,elementsSelectable:E,zoomOnScroll:R,zoomOnPinch:w,panOnScroll:N,panOnScrollSpeed:A,panOnScrollMode:$,zoomOnDoubleClick:F,panOnDrag:G,autoPanOnSelection:q,defaultViewport:te,translateExtent:ee,minZoom:ne,maxZoom:K,preventScrolling:C,onSelectionContextMenu:V,noWheelClassName:W,noPanClassName:U,disableKeyboardA11y:M,onViewportChange:D,isControlledViewport:H}){const{nodesSelectionActive:I,userSelectionActive:z}=De(pS,Qe),ie=as(y,{target:op}),oe=as(j,{target:op}),fe=oe||G,he=oe||N,pe=x&&fe!==!0,Z=ie||z||pe;return U_({deleteKeyCode:p,multiSelectionKeyCode:k}),d.jsx(X_,{onPaneContextMenu:u,elementsSelectable:E,zoomOnScroll:R,zoomOnPinch:w,panOnScroll:he,panActivationKeyPressed:oe,panOnScrollSpeed:A,panOnScrollMode:$,zoomOnDoubleClick:F,panOnDrag:!ie&&fe,defaultViewport:te,translateExtent:ee,minZoom:ne,maxZoom:K,zoomActivationKeyCode:b,preventScrolling:C,noWheelClassName:W,noPanClassName:U,onViewportChange:D,isControlledViewport:H,paneClickDistance:h,selectionOnDrag:pe,children:d.jsxs(Z_,{onSelectionStart:m,onSelectionEnd:_,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,panOnDrag:fe,autoPanOnSelection:q,isSelecting:!!Z,selectionMode:v,selectionKeyPressed:ie,paneClickDistance:h,selectionOnDrag:pe,children:[t,I&&d.jsx(hS,{onSelectionContextMenu:V,noPanClassName:U,disableKeyboardA11y:M})]})})}qg.displayName="FlowRenderer";const gS=L.memo(qg),mS=t=>r=>t?jc(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(o=>o.id):Array.from(r.nodeLookup.keys());function yS(t){return De(L.useCallback(mS(t),[t]),Qe)}const vS=t=>t.updateNodeInternals;function xS(){const t=De(vS),[r]=L.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const s=new Map;o.forEach(a=>{const u=a.target.getAttribute("data-id");s.set(u,{id:u,nodeElement:a.target,force:!0})}),t(s)}));return L.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function wS({node:t,nodeType:r,hasDimensions:o,resizeObserver:s}){const a=Ye(),u=L.useRef(null),c=L.useRef(null),h=L.useRef(t.sourcePosition),p=L.useRef(t.targetPosition),y=L.useRef(r),x=o&&!!t.internals.handleBounds;return L.useEffect(()=>{u.current&&!t.hidden&&(!x||c.current!==u.current)&&(c.current&&(s==null||s.unobserve(c.current)),s==null||s.observe(u.current),c.current=u.current)},[x,t.hidden]),L.useEffect(()=>()=>{c.current&&(s==null||s.unobserve(c.current),c.current=null)},[]),L.useEffect(()=>{if(u.current){const v=y.current!==r,m=h.current!==t.sourcePosition,_=p.current!==t.targetPosition;(v||m||_)&&(y.current=r,h.current=t.sourcePosition,p.current=t.targetPosition,a.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:u.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),u}function _S({id:t,onClick:r,onMouseEnter:o,onMouseMove:s,onMouseLeave:a,onContextMenu:u,onDoubleClick:c,nodesDraggable:h,elementsSelectable:p,nodesConnectable:y,nodesFocusable:x,resizeObserver:v,noDragClassName:m,noPanClassName:_,disableKeyboardA11y:k,rfId:j,nodeTypes:b,nodeClickDistance:E,onError:R}){const{node:w,internals:N,isParent:A}=De(Z=>{const se=Z.nodeLookup.get(t),me=Z.parentLookup.has(t);return{node:se,internals:se.internals,isParent:me}},Qe);let $=w.type||"default",F=(b==null?void 0:b[$])||ip[$];F===void 0&&(R==null||R("003",wn.error003($)),$="default",F=(b==null?void 0:b.default)||ip.default);const G=!!(w.draggable||h&&typeof w.draggable>"u"),q=!!(w.selectable||p&&typeof w.selectable>"u"),te=!!(w.connectable||y&&typeof w.connectable>"u"),ee=!!(w.focusable||x&&typeof w.focusable>"u"),ne=Ye(),K=mg(w),C=wS({node:w,nodeType:$,hasDimensions:K,resizeObserver:v}),V=Ug({nodeRef:C,disabled:w.hidden||!G,noDragClassName:m,handleSelector:w.dragHandle,nodeId:t,isSelectable:q,nodeClickDistance:E}),W=Yg();if(w.hidden)return null;const U=Sn(w),M=dS(w),D=q||G||r||o||s||a,H=o?Z=>o(Z,{...N.userNode}):void 0,I=s?Z=>s(Z,{...N.userNode}):void 0,z=a?Z=>a(Z,{...N.userNode}):void 0,ie=u?Z=>u(Z,{...N.userNode}):void 0,oe=c?Z=>c(Z,{...N.userNode}):void 0,fe=Z=>{const{selectNodesOnDrag:se,nodeDragThreshold:me}=ne.getState();q&&(!se||!G||me>0)&&gc({id:t,store:ne,nodeRef:C}),r&&r(Z,{...N.userNode})},he=Z=>{if(!(xg(Z.nativeEvent)||k)){if(sg.includes(Z.key)&&q){const se=Z.key==="Escape";gc({id:t,store:ne,unselect:se,nodeRef:C})}else if(G&&w.selected&&Object.prototype.hasOwnProperty.call(Ul,Z.key)){Z.preventDefault();const{ariaLabelConfig:se}=ne.getState();ne.setState({ariaLiveMessage:se["node.a11yDescription.ariaLiveMessage"]({direction:Z.key.replace("Arrow","").toLowerCase(),x:~~N.positionAbsolute.x,y:~~N.positionAbsolute.y})}),W({direction:Ul[Z.key],factor:Z.shiftKey?4:1})}}},pe=()=>{var Ne;if(k||!((Ne=C.current)!=null&&Ne.matches(":focus-visible")))return;const{transform:Z,width:se,height:me,autoPanOnNodeFocus:ke,setCenter:ve}=ne.getState();if(!ke)return;jc(new Map([[t,w]]),{x:0,y:0,width:se,height:me},Z,!0).length>0||ve(w.position.x+U.width/2,w.position.y+U.height/2,{zoom:Z[2]})};return d.jsx("div",{className:rt(["react-flow__node",`react-flow__node-${$}`,{[_]:G},w.className,{selected:w.selected,selectable:q,parent:A,draggable:G,dragging:V}]),ref:C,style:{zIndex:N.z,transform:`translate(${N.positionAbsolute.x}px,${N.positionAbsolute.y}px)`,pointerEvents:D?"all":"none",visibility:K?"visible":"hidden",...w.style,...M},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:H,onMouseMove:I,onMouseLeave:z,onContextMenu:ie,onClick:fe,onDoubleClick:oe,onKeyDown:ee?he:void 0,tabIndex:ee?0:void 0,onFocus:ee?pe:void 0,role:w.ariaRole??(ee?"group":void 0),"aria-roledescription":"node","aria-describedby":k?void 0:`${Dg}-${j}`,"aria-label":w.ariaLabel,...w.domAttributes,children:d.jsx(eS,{value:t,children:d.jsx(F,{id:t,data:w.data,type:$,positionAbsoluteX:N.positionAbsolute.x,positionAbsoluteY:N.positionAbsolute.y,selected:w.selected??!1,selectable:q,draggable:G,deletable:w.deletable??!0,isConnectable:te,sourcePosition:w.sourcePosition,targetPosition:w.targetPosition,dragging:V,dragHandle:w.dragHandle,zIndex:N.z,parentId:w.parentId,...U})})})}var SS=L.memo(_S);const kS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function Kg(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,onError:a}=De(kS,Qe),u=yS(t.onlyRenderVisibleElements),c=xS();return d.jsx("div",{className:"react-flow__nodes",style:oa,children:u.map(h=>d.jsx(SS,{id:h,nodeTypes:t.nodeTypes,nodeExtent:t.nodeExtent,onClick:t.onNodeClick,onMouseEnter:t.onNodeMouseEnter,onMouseMove:t.onNodeMouseMove,onMouseLeave:t.onNodeMouseLeave,onContextMenu:t.onNodeContextMenu,onDoubleClick:t.onNodeDoubleClick,noDragClassName:t.noDragClassName,noPanClassName:t.noPanClassName,rfId:t.rfId,disableKeyboardA11y:t.disableKeyboardA11y,resizeObserver:c,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,nodeClickDistance:t.nodeClickDistance,onError:a},h))})}Kg.displayName="NodeRenderer";const NS=L.memo(Kg);function jS(t){return De(L.useCallback(o=>{if(!t)return o.edges.map(a=>a.id);const s=[];if(o.width&&o.height)for(const a of o.edges){const u=o.nodeLookup.get(a.source),c=o.nodeLookup.get(a.target);u&&c&&v1({sourceNode:u,targetNode:c,width:o.width,height:o.height,transform:o.transform})&&s.push(a.id)}return s},[t]),Qe)}const bS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return d.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},ES=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return d.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},sp={[os.Arrow]:bS,[os.ArrowClosed]:ES};function CS(t){const r=Ye();return L.useMemo(()=>{var a,u;return Object.prototype.hasOwnProperty.call(sp,t)?sp[t]:((u=(a=r.getState()).onError)==null||u.call(a,"009",wn.error009(t)),null)},[t])}const MS=({id:t,type:r,color:o,width:s=12.5,height:a=12.5,markerUnits:u="strokeWidth",strokeWidth:c,orient:h="auto-start-reverse"})=>{const p=CS(r);return p?d.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${s}`,markerHeight:`${a}`,viewBox:"-10 -10 20 20",markerUnits:u,orient:h,refX:"0",refY:"0",children:d.jsx(p,{color:o,strokeWidth:c})}):null},Qg=({defaultColor:t,rfId:r})=>{const o=De(u=>u.edges),s=De(u=>u.defaultEdgeOptions),a=L.useMemo(()=>b1(o,{id:r,defaultColor:t,defaultMarkerStart:s==null?void 0:s.markerStart,defaultMarkerEnd:s==null?void 0:s.markerEnd}),[o,s,r,t]);return a.length?d.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:d.jsx("defs",{children:a.map(u=>d.jsx(MS,{id:u.id,type:u.type,color:u.color,width:u.width,height:u.height,markerUnits:u.markerUnits,strokeWidth:u.strokeWidth,orient:u.orient},u.id))})}):null};Qg.displayName="MarkerDefinitions";var PS=L.memo(Qg);function Zg({x:t,y:r,label:o,labelStyle:s,labelShowBg:a=!0,labelBgStyle:u,labelBgPadding:c=[2,4],labelBgBorderRadius:h=2,children:p,className:y,...x}){const[v,m]=L.useState({x:1,y:0,width:0,height:0}),_=rt(["react-flow__edge-textwrapper",y]),k=L.useRef(null);return L.useEffect(()=>{if(k.current){const j=k.current.getBBox();m({x:j.x,y:j.y,width:j.width,height:j.height})}},[o]),o?d.jsxs("g",{transform:`translate(${t-v.width/2} ${r-v.height/2})`,className:_,visibility:v.width?"visible":"hidden",...x,children:[a&&d.jsx("rect",{width:v.width+2*c[0],x:-c[0],y:-c[1],height:v.height+2*c[1],className:"react-flow__edge-textbg",style:u,rx:h,ry:h}),d.jsx("text",{className:"react-flow__edge-text",y:v.height/2,dy:"0.3em",ref:k,style:s,children:o}),p]}):null}Zg.displayName="EdgeText";const IS=L.memo(Zg);function ys({path:t,labelX:r,labelY:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:y=20,...x}){return d.jsxs(d.Fragment,{children:[d.jsx("path",{...x,d:t,fill:"none",className:rt(["react-flow__edge-path",x.className])}),y?d.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,s&&vn(r)&&vn(o)?d.jsx(IS,{x:r,y:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function lp({pos:t,x1:r,y1:o,x2:s,y2:a}){return t===Se.Left||t===Se.Right?[.5*(r+s),o]:[r,.5*(o+a)]}function Jg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top}){const[c,h]=lp({pos:o,x1:t,y1:r,x2:s,y2:a}),[p,y]=lp({pos:u,x1:s,y1:a,x2:t,y2:r}),[x,v,m,_]=_g({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:c,sourceControlY:h,targetControlX:p,targetControlY:y});return[`M${t},${r} C${c},${h} ${p},${y} ${s},${a}`,x,v,m,_]}function em(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c,targetPosition:h,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:m,labelBgBorderRadius:_,style:k,markerEnd:j,markerStart:b,interactionWidth:E})=>{const[R,w,N]=Jg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:h}),A=t.isInternal?void 0:r;return d.jsx(ys,{id:A,path:R,labelX:w,labelY:N,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:m,labelBgBorderRadius:_,style:k,markerEnd:j,markerStart:b,interactionWidth:E})})}const RS=em({isInternal:!1}),tm=em({isInternal:!0});RS.displayName="SimpleBezierEdge";tm.displayName="SimpleBezierEdgeInternal";function nm(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:m,sourcePosition:_=Se.Bottom,targetPosition:k=Se.Top,markerEnd:j,markerStart:b,pathOptions:E,interactionWidth:R})=>{const[w,N,A]=Wl({sourceX:o,sourceY:s,sourcePosition:_,targetX:a,targetY:u,targetPosition:k,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),$=t.isInternal?void 0:r;return d.jsx(ys,{id:$,path:w,labelX:N,labelY:A,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:m,markerEnd:j,markerStart:b,interactionWidth:R})})}const rm=nm({isInternal:!1}),im=nm({isInternal:!0});rm.displayName="SmoothStepEdge";im.displayName="SmoothStepEdgeInternal";function om(t){return L.memo(({id:r,...o})=>{var a;const s=t.isInternal?void 0:r;return d.jsx(rm,{...o,id:s,pathOptions:L.useMemo(()=>{var u;return{borderRadius:0,offset:(u=o.pathOptions)==null?void 0:u.offset}},[(a=o.pathOptions)==null?void 0:a.offset])})})}const TS=om({isInternal:!1}),sm=om({isInternal:!0});TS.displayName="StepEdge";sm.displayName="StepEdgeInternal";function lm(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:m,markerEnd:_,markerStart:k,interactionWidth:j})=>{const[b,E,R]=Ng({sourceX:o,sourceY:s,targetX:a,targetY:u}),w=t.isInternal?void 0:r;return d.jsx(ys,{id:w,path:b,labelX:E,labelY:R,label:c,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:x,labelBgBorderRadius:v,style:m,markerEnd:_,markerStart:k,interactionWidth:j})})}const LS=lm({isInternal:!1}),am=lm({isInternal:!0});LS.displayName="StraightEdge";am.displayName="StraightEdgeInternal";function um(t){return L.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c=Se.Bottom,targetPosition:h=Se.Top,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:m,labelBgBorderRadius:_,style:k,markerEnd:j,markerStart:b,pathOptions:E,interactionWidth:R})=>{const[w,N,A]=Sg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:h,curvature:E==null?void 0:E.curvature}),$=t.isInternal?void 0:r;return d.jsx(ys,{id:$,path:w,labelX:N,labelY:A,label:p,labelStyle:y,labelShowBg:x,labelBgStyle:v,labelBgPadding:m,labelBgBorderRadius:_,style:k,markerEnd:j,markerStart:b,interactionWidth:R})})}const AS=um({isInternal:!1}),cm=um({isInternal:!0});AS.displayName="BezierEdge";cm.displayName="BezierEdgeInternal";const ap={default:cm,straight:am,step:sm,smoothstep:im,simplebezier:tm},up={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},$S=(t,r,o)=>o===Se.Left?t-r:o===Se.Right?t+r:t,zS=(t,r,o)=>o===Se.Top?t-r:o===Se.Bottom?t+r:t,cp="react-flow__edgeupdater";function dp({position:t,centerX:r,centerY:o,radius:s=10,onMouseDown:a,onMouseEnter:u,onMouseOut:c,type:h}){return d.jsx("circle",{onMouseDown:a,onMouseEnter:u,onMouseOut:c,className:rt([cp,`${cp}-${h}`]),cx:$S(r,s,t),cy:zS(o,s,t),r:s,stroke:"transparent",fill:"transparent"})}function DS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:s,sourceY:a,targetX:u,targetY:c,sourcePosition:h,targetPosition:p,onReconnect:y,onReconnectStart:x,onReconnectEnd:v,setReconnecting:m,setUpdateHover:_}){const k=Ye(),j=(N,A)=>{if(N.button!==0)return;const{autoPanOnConnect:$,domNode:F,connectionMode:G,connectionRadius:q,lib:te,onConnectStart:ee,cancelConnection:ne,nodeLookup:K,rfId:C,panBy:V,updateConnection:W}=k.getState(),U=A.type==="target",M=(I,z)=>{m(!1),v==null||v(I,o,A.type,z)},D=I=>y==null?void 0:y(o,I),H=(I,z)=>{m(!0),x==null||x(N,o,A.type),ee==null||ee(I,z)};pc.onPointerDown(N.nativeEvent,{autoPanOnConnect:$,connectionMode:G,connectionRadius:q,domNode:F,handleId:A.id,nodeId:A.nodeId,nodeLookup:K,isTarget:U,edgeUpdaterType:A.type,lib:te,flowId:C,cancelConnection:ne,panBy:V,isValidConnection:(...I)=>{var z,ie;return((ie=(z=k.getState()).isValidConnection)==null?void 0:ie.call(z,...I))??!0},onConnect:D,onConnectStart:H,onConnectEnd:(...I)=>{var z,ie;return(ie=(z=k.getState()).onConnectEnd)==null?void 0:ie.call(z,...I)},onReconnectEnd:M,updateConnection:W,getTransform:()=>k.getState().transform,getFromHandle:()=>k.getState().connection.fromHandle,dragThreshold:k.getState().connectionDragThreshold,handleDomNode:N.currentTarget})},b=N=>j(N,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),E=N=>j(N,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),R=()=>_(!0),w=()=>_(!1);return d.jsxs(d.Fragment,{children:[(t===!0||t==="source")&&d.jsx(dp,{position:h,centerX:s,centerY:a,radius:r,onMouseDown:b,onMouseEnter:R,onMouseOut:w,type:"source"}),(t===!0||t==="target")&&d.jsx(dp,{position:p,centerX:u,centerY:c,radius:r,onMouseDown:E,onMouseEnter:R,onMouseOut:w,type:"target"})]})}function OS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:s,onClick:a,onDoubleClick:u,onContextMenu:c,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,reconnectRadius:x,onReconnect:v,onReconnectStart:m,onReconnectEnd:_,rfId:k,edgeTypes:j,noPanClassName:b,onError:E,disableKeyboardA11y:R}){let w=De(ve=>ve.edgeLookup.get(t));const N=De(ve=>ve.defaultEdgeOptions);w=N?{...N,...w}:w;let A=w.type||"default",$=(j==null?void 0:j[A])||ap[A];$===void 0&&(E==null||E("011",wn.error011(A)),A="default",$=(j==null?void 0:j.default)||ap.default);const F=!!(w.focusable||r&&typeof w.focusable>"u"),G=typeof v<"u"&&(w.reconnectable||o&&typeof w.reconnectable>"u"),q=!!(w.selectable||s&&typeof w.selectable>"u"),te=L.useRef(null),[ee,ne]=L.useState(!1),[K,C]=L.useState(!1),V=Ye(),{zIndex:W=w.zIndex,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:I,targetPosition:z}=De(L.useCallback(ve=>{const re=ve.nodeLookup.get(w.source),Ne=ve.nodeLookup.get(w.target);if(!re||!Ne)return up;const Ie=j1({id:t,sourceNode:re,targetNode:Ne,sourceHandle:w.sourceHandle||null,targetHandle:w.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Le=y1({selected:w.selected,zIndex:w.zIndex,sourceNode:re,targetNode:Ne,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ie||up,zIndex:Le}},[w.source,w.target,w.sourceHandle,w.targetHandle,w.selected,w.zIndex,E]),Qe),ie=L.useMemo(()=>w.markerStart?`url('#${fc(w.markerStart,k)}')`:void 0,[w.markerStart,k]),oe=L.useMemo(()=>w.markerEnd?`url('#${fc(w.markerEnd,k)}')`:void 0,[w.markerEnd,k]);if(w.hidden||U===null||M===null||D===null||H===null)return null;const fe=ve=>{var Le;const{addSelectedEdges:re,unselectNodesAndEdges:Ne,multiSelectionActive:Ie}=V.getState();q&&(V.setState({nodesSelectionActive:!1}),w.selected&&Ie?(Ne({nodes:[],edges:[w]}),(Le=te.current)==null||Le.blur()):re([t])),a&&a(ve,w)},he=u?ve=>{u(ve,{...w})}:void 0,pe=c?ve=>{c(ve,{...w})}:void 0,Z=h?ve=>{h(ve,{...w})}:void 0,se=p?ve=>{p(ve,{...w})}:void 0,me=y?ve=>{y(ve,{...w})}:void 0,ke=ve=>{var re;if(!R&&sg.includes(ve.key)&&q){const{unselectNodesAndEdges:Ne,addSelectedEdges:Ie}=V.getState();ve.key==="Escape"?((re=te.current)==null||re.blur(),Ne({edges:[w]})):Ie([t])}};return d.jsx("svg",{style:{zIndex:W},children:d.jsxs("g",{className:rt(["react-flow__edge",`react-flow__edge-${A}`,w.className,b,{selected:w.selected,animated:w.animated,inactive:!q&&!a,updating:ee,selectable:q}]),onClick:fe,onDoubleClick:he,onContextMenu:pe,onMouseEnter:Z,onMouseMove:se,onMouseLeave:me,onKeyDown:F?ke:void 0,tabIndex:F?0:void 0,role:w.ariaRole??(F?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":w.ariaLabel===null?void 0:w.ariaLabel||`Edge from ${w.source} to ${w.target}`,"aria-describedby":F?`${Og}-${k}`:void 0,ref:te,...w.domAttributes,children:[!K&&d.jsx($,{id:t,source:w.source,target:w.target,type:w.type,selected:w.selected,animated:w.animated,selectable:q,deletable:w.deletable??!0,label:w.label,labelStyle:w.labelStyle,labelShowBg:w.labelShowBg,labelBgStyle:w.labelBgStyle,labelBgPadding:w.labelBgPadding,labelBgBorderRadius:w.labelBgBorderRadius,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:I,targetPosition:z,data:w.data,style:w.style,sourceHandleId:w.sourceHandle,targetHandleId:w.targetHandle,markerStart:ie,markerEnd:oe,pathOptions:"pathOptions"in w?w.pathOptions:void 0,interactionWidth:w.interactionWidth}),G&&d.jsx(DS,{edge:w,isReconnectable:G,reconnectRadius:x,onReconnect:v,onReconnectStart:m,onReconnectEnd:_,sourceX:U,sourceY:M,targetX:D,targetY:H,sourcePosition:I,targetPosition:z,setUpdateHover:ne,setReconnecting:C})]})})}var FS=L.memo(OS);const HS=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function dm({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:s,noPanClassName:a,onReconnect:u,onEdgeContextMenu:c,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:y,onEdgeClick:x,reconnectRadius:v,onEdgeDoubleClick:m,onReconnectStart:_,onReconnectEnd:k,disableKeyboardA11y:j}){const{edgesFocusable:b,edgesReconnectable:E,elementsSelectable:R,onError:w}=De(HS,Qe),N=jS(r);return d.jsxs("div",{className:"react-flow__edges",children:[d.jsx(PS,{defaultColor:t,rfId:o}),N.map(A=>d.jsx(FS,{id:A,edgesFocusable:b,edgesReconnectable:E,elementsSelectable:R,noPanClassName:a,onReconnect:u,onContextMenu:c,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,onClick:x,reconnectRadius:v,onDoubleClick:m,onReconnectStart:_,onReconnectEnd:k,rfId:o,onError:w,edgeTypes:s,disableKeyboardA11y:j},A))]})}dm.displayName="EdgeRenderer";const BS=L.memo(dm),fp=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function VS({children:t}){const r=Ye(),o=L.useRef(null),[s]=L.useState(()=>r.getState().transform);return Vg(()=>{let a=null;const u=()=>{const c=r.getState().transform;a&&c[0]===a[0]&&c[1]===a[1]&&c[2]===a[2]||(a=c,o.current&&(o.current.style.transform=fp(c)))};return u(),r.subscribe(u)},[r]),d.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:fp(s)},children:t})}function WS(t){const r=ia(),o=L.useRef(!1);L.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const US=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function YS(t){const r=De(US),o=Ye();return L.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function GS(t){return t.connection.inProgress?{...t.connection,to:ms(t.connection.to,t.transform)}:{...t.connection}}function XS(t){return GS}function qS(t){const r=XS();return De(r,Qe)}const KS=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function QS({containerStyle:t,style:r,type:o,component:s}){const{nodesConnectable:a,width:u,height:c,isValid:h,inProgress:p}=De(KS,Qe);return!(u&&a&&p)?null:d.jsx("svg",{style:t,width:u,height:c,className:"react-flow__connectionline react-flow__container",children:d.jsx("g",{className:rt(["react-flow__connection",ug(h)]),children:d.jsx(fm,{style:r,type:o,CustomComponent:s,isValid:h})})})}const fm=({style:t,type:r=Ar.Bezier,CustomComponent:o,isValid:s})=>{const{inProgress:a,from:u,fromNode:c,fromHandle:h,fromPosition:p,to:y,toNode:x,toHandle:v,toPosition:m,pointer:_}=qS();if(!a)return;if(o)return d.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:c,fromHandle:h,fromX:u.x,fromY:u.y,toX:y.x,toY:y.y,fromPosition:p,toPosition:m,connectionStatus:ug(s),toNode:x,toHandle:v,pointer:_});let k="";const j={sourceX:u.x,sourceY:u.y,sourcePosition:p,targetX:y.x,targetY:y.y,targetPosition:m};switch(r){case Ar.Bezier:[k]=Sg(j);break;case Ar.SimpleBezier:[k]=Jg(j);break;case Ar.Step:[k]=Wl({...j,borderRadius:0});break;case Ar.SmoothStep:[k]=Wl(j);break;default:[k]=Ng(j)}return d.jsx("path",{d:k,fill:"none",className:"react-flow__connection-path",style:t})};fm.displayName="ConnectionLine";const ZS={};function hp(t=ZS){L.useRef(t),Ye(),L.useEffect(()=>{},[t])}function JS(){Ye(),L.useRef(!1),L.useEffect(()=>{},[])}function hm({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:s,onEdgeClick:a,onNodeDoubleClick:u,onEdgeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:x,onSelectionContextMenu:v,onSelectionStart:m,onSelectionEnd:_,connectionLineType:k,connectionLineStyle:j,connectionLineComponent:b,connectionLineContainerStyle:E,selectionKeyCode:R,selectionOnDrag:w,selectionMode:N,multiSelectionKeyCode:A,panActivationKeyCode:$,zoomActivationKeyCode:F,deleteKeyCode:G,onlyRenderVisibleElements:q,elementsSelectable:te,defaultViewport:ee,translateExtent:ne,minZoom:K,maxZoom:C,preventScrolling:V,defaultMarkerColor:W,zoomOnScroll:U,zoomOnPinch:M,panOnScroll:D,panOnScrollSpeed:H,panOnScrollMode:I,zoomOnDoubleClick:z,panOnDrag:ie,autoPanOnSelection:oe,onPaneClick:fe,onPaneMouseEnter:he,onPaneMouseMove:pe,onPaneMouseLeave:Z,onPaneScroll:se,onPaneContextMenu:me,paneClickDistance:ke,nodeClickDistance:ve,onEdgeContextMenu:re,onEdgeMouseEnter:Ne,onEdgeMouseMove:Ie,onEdgeMouseLeave:Le,reconnectRadius:$e,onReconnect:lt,onReconnectStart:at,onReconnectEnd:ut,noDragClassName:Ge,noWheelClassName:wt,noPanClassName:Gt,disableKeyboardA11y:gt,nodeExtent:mt,rfId:Ct,viewport:ct,onViewportChange:et,nodesDraggable:Dn}){return hp(t),hp(r),JS(),WS(o),YS(ct),d.jsx(gS,{onPaneClick:fe,onPaneMouseEnter:he,onPaneMouseMove:pe,onPaneMouseLeave:Z,onPaneContextMenu:me,onPaneScroll:se,paneClickDistance:ke,deleteKeyCode:G,selectionKeyCode:R,selectionOnDrag:w,selectionMode:N,onSelectionStart:m,onSelectionEnd:_,multiSelectionKeyCode:A,panActivationKeyCode:$,zoomActivationKeyCode:F,elementsSelectable:te,zoomOnScroll:U,zoomOnPinch:M,zoomOnDoubleClick:z,panOnScroll:D,panOnScrollSpeed:H,panOnScrollMode:I,panOnDrag:ie,autoPanOnSelection:oe,defaultViewport:ee,translateExtent:ne,minZoom:K,maxZoom:C,onSelectionContextMenu:v,preventScrolling:V,noDragClassName:Ge,noWheelClassName:wt,noPanClassName:Gt,disableKeyboardA11y:gt,onViewportChange:et,isControlledViewport:!!ct,children:d.jsxs(VS,{children:[d.jsx(BS,{edgeTypes:r,onEdgeClick:a,onEdgeDoubleClick:c,onReconnect:lt,onReconnectStart:at,onReconnectEnd:ut,onlyRenderVisibleElements:q,onEdgeContextMenu:re,onEdgeMouseEnter:Ne,onEdgeMouseMove:Ie,onEdgeMouseLeave:Le,reconnectRadius:$e,defaultMarkerColor:W,noPanClassName:Gt,disableKeyboardA11y:gt,rfId:Ct}),d.jsx(QS,{style:j,type:k,component:b,containerStyle:E}),d.jsx("div",{className:"react-flow__edgelabel-renderer"}),d.jsx(NS,{nodeTypes:t,onNodeClick:s,onNodeDoubleClick:u,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:x,nodeClickDistance:ve,onlyRenderVisibleElements:q,noPanClassName:Gt,noDragClassName:Ge,disableKeyboardA11y:gt,nodeExtent:mt,rfId:Ct,nodesDraggable:Dn}),d.jsx("div",{className:"react-flow__viewport-portal"})]})})}hm.displayName="GraphView";const ek=L.memo(hm),tk=gg(),pp=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p=.5,maxZoom:y=2,nodeOrigin:x,nodeExtent:v,zIndexMode:m="basic"}={})=>{const _=new Map,k=new Map,j=new Map,b=new Map,E=s??r??[],R=o??t??[],w=x??[0,0],N=v??rs;Eg(j,b,E);const{nodesInitialized:A}=hc(R,_,k,{nodeOrigin:w,nodeExtent:N,zIndexMode:m});let $=[0,0,1];if(c&&a&&u){const F=ps(_,{filter:ee=>!!((ee.width||ee.initialWidth)&&(ee.height||ee.initialHeight))}),{x:G,y:q,zoom:te}=Ec(F,a,u,p,y,(h==null?void 0:h.padding)??.1);$=[G,q,te]}return{rfId:"1",width:a??0,height:u??0,transform:$,nodes:R,nodesInitialized:A,nodeLookup:_,parentLookup:k,edges:E,edgeLookup:b,connectionLookup:j,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:s!==void 0,panZoom:null,minZoom:p,maxZoom:y,translateExtent:rs,nodeExtent:N,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:Zi.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:w,nodeDragThreshold:1,connectionDragThreshold:1,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesReconnectable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,elevateEdgesOnSelect:!0,selectNodesOnDrag:!0,multiSelectionActive:!1,fitViewQueued:c??!1,fitViewOptions:h,fitViewResolver:null,connection:{...ag},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:tk,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:lg,zIndexMode:m,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},nk=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:x,nodeExtent:v,zIndexMode:m})=>p_((_,k)=>{async function j(){const{nodeLookup:b,panZoom:E,fitViewOptions:R,fitViewResolver:w,width:N,height:A,minZoom:$,maxZoom:F}=k();E&&(await c1({nodes:b,width:N,height:A,panZoom:E,minZoom:$,maxZoom:F},R),w==null||w.resolve(!0),_({fitViewResolver:null}))}return{...pp({nodes:t,edges:r,width:a,height:u,fitView:c,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:x,nodeExtent:v,defaultNodes:o,defaultEdges:s,zIndexMode:m}),setNodes:b=>{const{nodeLookup:E,parentLookup:R,nodeOrigin:w,nodeExtent:N,elevateNodesOnSelect:A,fitViewQueued:$,zIndexMode:F,nodesSelectionActive:G}=k(),{nodesInitialized:q,hasSelectedNodes:te}=hc(b,E,R,{nodeOrigin:w,nodeExtent:N,elevateNodesOnSelect:A,checkEquality:!0,zIndexMode:F}),ee=G&&te;$&&q?(j(),_({nodes:b,nodesInitialized:q,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:ee})):_({nodes:b,nodesInitialized:q,nodesSelectionActive:ee})},setEdges:b=>{const{connectionLookup:E,edgeLookup:R}=k();Eg(E,R,b),_({edges:b})},setDefaultNodesAndEdges:(b,E)=>{if(b){const{setNodes:R}=k();R(b),_({hasDefaultNodes:!0})}if(E){const{setEdges:R}=k();R(E),_({hasDefaultEdges:!0})}},updateNodeInternals:b=>{const{triggerNodeChanges:E,nodeLookup:R,parentLookup:w,domNode:N,nodeOrigin:A,nodeExtent:$,debug:F,fitViewQueued:G,zIndexMode:q}=k(),{changes:te,updatedInternals:ee}=T1(b,R,w,N,A,$,q);ee&&(M1(R,w,{nodeOrigin:A,nodeExtent:$,zIndexMode:q}),G?(j(),_({fitViewQueued:!1,fitViewOptions:void 0})):_({}),(te==null?void 0:te.length)>0&&(F&&console.log("React Flow: trigger node changes",te),E==null||E(te)))},updateNodePositions:(b,E=!1)=>{const R=[];let w=[];const{nodeLookup:N,triggerNodeChanges:A,connection:$,updateConnection:F,onNodesChangeMiddlewareMap:G}=k();for(const[q,te]of b){const ee=N.get(q),ne=!!(ee!=null&&ee.expandParent&&(ee!=null&&ee.parentId)&&(te!=null&&te.position)),K={id:q,type:"position",position:ne?{x:Math.max(0,te.position.x),y:Math.max(0,te.position.y)}:te.position,dragging:E};if(ee&&$.inProgress&&$.fromNode.id===ee.id){const C=hi(ee,$.fromHandle,Se.Left,!0);F({...$,from:C})}ne&&ee.parentId&&R.push({id:q,parentId:ee.parentId,rect:{...te.internals.positionAbsolute,width:te.measured.width??0,height:te.measured.height??0}}),w.push(K)}if(R.length>0){const{parentLookup:q,nodeOrigin:te}=k(),ee=Tc(R,N,q,te);w.push(...ee)}for(const q of G.values())w=q(w);A(w)},triggerNodeChanges:b=>{const{onNodesChange:E,setNodes:R,nodes:w,hasDefaultNodes:N,debug:A}=k();if(b!=null&&b.length){if(N){const $=A_(b,w);R($)}A&&console.log("React Flow: trigger node changes",b),E==null||E(b)}},triggerEdgeChanges:b=>{const{onEdgesChange:E,setEdges:R,edges:w,hasDefaultEdges:N,debug:A}=k();if(b!=null&&b.length){if(N){const $=$_(b,w);R($)}A&&console.log("React Flow: trigger edge changes",b),E==null||E(b)}},addSelectedNodes:b=>{const{multiSelectionActive:E,edgeLookup:R,nodeLookup:w,triggerNodeChanges:N,triggerEdgeChanges:A}=k();if(E){const $=b.map(F=>oi(F,!0));N($);return}N(Gi(w,new Set([...b]),!0)),A(Gi(R))},addSelectedEdges:b=>{const{multiSelectionActive:E,edgeLookup:R,nodeLookup:w,triggerNodeChanges:N,triggerEdgeChanges:A}=k();if(E){const $=b.map(F=>oi(F,!0));A($);return}A(Gi(R,new Set([...b]))),N(Gi(w,new Set,!0))},unselectNodesAndEdges:({nodes:b,edges:E}={})=>{const{edges:R,nodes:w,nodeLookup:N,triggerNodeChanges:A,triggerEdgeChanges:$}=k(),F=b||w,G=E||R,q=[];for(const ee of F){if(!ee.selected)continue;const ne=N.get(ee.id);ne&&(ne.selected=!1),q.push(oi(ee.id,!1))}const te=[];for(const ee of G)ee.selected&&te.push(oi(ee.id,!1));A(q),$(te)},setMinZoom:b=>{const{panZoom:E,maxZoom:R}=k();E==null||E.setScaleExtent([b,R]),_({minZoom:b})},setMaxZoom:b=>{const{panZoom:E,minZoom:R}=k();E==null||E.setScaleExtent([R,b]),_({maxZoom:b})},setTranslateExtent:b=>{var E;(E=k().panZoom)==null||E.setTranslateExtent(b),_({translateExtent:b})},resetSelectedElements:()=>{const{edges:b,nodes:E,triggerNodeChanges:R,triggerEdgeChanges:w,elementsSelectable:N}=k();if(!N)return;const A=E.reduce((F,G)=>G.selected?[...F,oi(G.id,!1)]:F,[]),$=b.reduce((F,G)=>G.selected?[...F,oi(G.id,!1)]:F,[]);R(A),w($)},setNodeExtent:b=>{const{nodes:E,nodeLookup:R,parentLookup:w,nodeOrigin:N,elevateNodesOnSelect:A,nodeExtent:$,zIndexMode:F}=k();b[0][0]===$[0][0]&&b[0][1]===$[0][1]&&b[1][0]===$[1][0]&&b[1][1]===$[1][1]||(hc(E,R,w,{nodeOrigin:N,nodeExtent:b,elevateNodesOnSelect:A,checkEquality:!1,zIndexMode:F}),_({nodeExtent:b}))},panBy:b=>{const{transform:E,width:R,height:w,panZoom:N,translateExtent:A}=k();return L1({delta:b,panZoom:N,transform:E,translateExtent:A,width:R,height:w})},setCenter:async(b,E,R)=>{const{width:w,height:N,maxZoom:A,panZoom:$}=k();if(!$)return!1;const F=typeof(R==null?void 0:R.zoom)<"u"?R.zoom:A;return await $.setViewport({x:w/2-b*F,y:N/2-E*F,zoom:F},{duration:R==null?void 0:R.duration,ease:R==null?void 0:R.ease,interpolate:R==null?void 0:R.interpolate}),!0},cancelConnection:()=>{_({connection:{...ag}})},updateConnection:b=>{_({connection:b})},reset:()=>_({...pp()})}},Object.is);function pm({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:s,initialWidth:a,initialHeight:u,initialMinZoom:c,initialMaxZoom:h,initialFitViewOptions:p,fitView:y,nodeOrigin:x,nodeExtent:v,zIndexMode:m,children:_}){const[k]=L.useState(()=>nk({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:y,minZoom:c,maxZoom:h,fitViewOptions:p,nodeOrigin:x,nodeExtent:v,zIndexMode:m}));return d.jsx(g_,{value:k,children:d.jsx(H_,{children:d.jsx(nS,{children:_})})})}function rk({children:t,nodes:r,edges:o,defaultNodes:s,defaultEdges:a,width:u,height:c,fitView:h,fitViewOptions:p,minZoom:y,maxZoom:x,nodeOrigin:v,nodeExtent:m,zIndexMode:_}){return L.useContext(na)?d.jsx(d.Fragment,{children:t}):d.jsx(pm,{initialNodes:r,initialEdges:o,defaultNodes:s,defaultEdges:a,initialWidth:u,initialHeight:c,fitView:h,initialFitViewOptions:p,initialMinZoom:y,initialMaxZoom:x,nodeOrigin:v,nodeExtent:m,zIndexMode:_,children:t})}const ik={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function ok({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,className:a,nodeTypes:u,edgeTypes:c,onNodeClick:h,onEdgeClick:p,onInit:y,onMove:x,onMoveStart:v,onMoveEnd:m,onConnect:_,onConnectStart:k,onConnectEnd:j,onClickConnectStart:b,onClickConnectEnd:E,onNodeMouseEnter:R,onNodeMouseMove:w,onNodeMouseLeave:N,onNodeContextMenu:A,onNodeDoubleClick:$,onNodeDragStart:F,onNodeDrag:G,onNodeDragStop:q,onNodesDelete:te,onEdgesDelete:ee,onDelete:ne,onSelectionChange:K,onSelectionDragStart:C,onSelectionDrag:V,onSelectionDragStop:W,onSelectionContextMenu:U,onSelectionStart:M,onSelectionEnd:D,onBeforeDelete:H,connectionMode:I,connectionLineType:z=Ar.Bezier,connectionLineStyle:ie,connectionLineComponent:oe,connectionLineContainerStyle:fe,deleteKeyCode:he="Backspace",selectionKeyCode:pe="Shift",selectionOnDrag:Z=!1,selectionMode:se=is.Full,panActivationKeyCode:me="Space",multiSelectionKeyCode:ke=ls()?"Meta":"Control",zoomActivationKeyCode:ve=ls()?"Meta":"Control",snapToGrid:re,snapGrid:Ne,onlyRenderVisibleElements:Ie=!1,selectNodesOnDrag:Le,nodesDraggable:$e,autoPanOnNodeFocus:lt,nodesConnectable:at,nodesFocusable:ut,nodeOrigin:Ge=Fg,edgesFocusable:wt,edgesReconnectable:Gt,elementsSelectable:gt=!0,defaultViewport:mt=C_,minZoom:Ct=.5,maxZoom:ct=2,translateExtent:et=rs,preventScrolling:Dn=!0,nodeExtent:Mt,defaultMarkerColor:kn="#b1b1b7",zoomOnScroll:oo=!0,zoomOnPinch:On=!0,panOnScroll:gi=!1,panOnScrollSpeed:lr=.5,panOnScrollMode:zr=ai.Free,zoomOnDoubleClick:Fn=!0,panOnDrag:Dr=!0,onPaneClick:ar,onPaneMouseEnter:ur,onPaneMouseMove:Ft,onPaneMouseLeave:dt,onPaneScroll:Hn,onPaneContextMenu:Bn,paneClickDistance:Nn=1,nodeClickDistance:Vn=0,children:jn,onReconnect:it,onReconnectStart:cr,onReconnectEnd:bn,onEdgeContextMenu:Pt,onEdgeDoubleClick:nn,onEdgeMouseEnter:mi,onEdgeMouseMove:Ze,onEdgeMouseLeave:He,reconnectRadius:En=10,onNodesChange:Wn,onEdgesChange:rn,noDragClassName:Or="nodrag",noWheelClassName:on="nowheel",noPanClassName:It="nopan",fitView:Xt,fitViewOptions:Un,connectOnClick:yi,attributionPosition:vi,proOptions:Rt,defaultEdgeOptions:Yn,elevateNodesOnSelect:Fr=!0,elevateEdgesOnSelect:Gn=!1,disableKeyboardA11y:dr=!1,autoPanOnConnect:Ve,autoPanOnNodeDrag:so,autoPanOnSelection:Hr=!0,autoPanSpeed:xi,connectionRadius:fr,isValidConnection:lo,onError:wi,style:Cn,id:_t,nodeDragThreshold:ao,connectionDragThreshold:yt,viewport:uo,onViewportChange:co,width:Br,height:Mn,colorMode:Xn="light",debug:Pn,onScroll:qt,ariaLabelConfig:Vr,zIndexMode:Wr="basic",...hr},Ur){const sn=_t||"1",qn=R_(Xn),_i=L.useCallback(pr=>{pr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),qt==null||qt(pr)},[qt]);return d.jsx("div",{"data-testid":"rf__wrapper",...hr,onScroll:_i,style:{...Cn,...ik},ref:Ur,className:rt(["react-flow",a,qn]),id:_t,role:"application",children:d.jsxs(rk,{nodes:t,edges:r,width:Br,height:Mn,fitView:Xt,fitViewOptions:Un,minZoom:Ct,maxZoom:ct,nodeOrigin:Ge,nodeExtent:Mt,zIndexMode:Wr,children:[d.jsx(I_,{nodes:t,edges:r,defaultNodes:o,defaultEdges:s,onConnect:_,onConnectStart:k,onConnectEnd:j,onClickConnectStart:b,onClickConnectEnd:E,nodesDraggable:$e,autoPanOnNodeFocus:lt,nodesConnectable:at,nodesFocusable:ut,edgesFocusable:wt,edgesReconnectable:Gt,elementsSelectable:gt,elevateNodesOnSelect:Fr,elevateEdgesOnSelect:Gn,minZoom:Ct,maxZoom:ct,nodeExtent:Mt,onNodesChange:Wn,onEdgesChange:rn,snapToGrid:re,snapGrid:Ne,connectionMode:I,translateExtent:et,connectOnClick:yi,defaultEdgeOptions:Yn,fitView:Xt,fitViewOptions:Un,onNodesDelete:te,onEdgesDelete:ee,onDelete:ne,onNodeDragStart:F,onNodeDrag:G,onNodeDragStop:q,onSelectionDrag:V,onSelectionDragStart:C,onSelectionDragStop:W,onMove:x,onMoveStart:v,onMoveEnd:m,noPanClassName:It,nodeOrigin:Ge,rfId:sn,autoPanOnConnect:Ve,autoPanOnNodeDrag:so,autoPanSpeed:xi,onError:wi,connectionRadius:fr,isValidConnection:lo,selectNodesOnDrag:Le,nodeDragThreshold:ao,connectionDragThreshold:yt,onBeforeDelete:H,debug:Pn,ariaLabelConfig:Vr,zIndexMode:Wr}),d.jsx(ek,{onInit:y,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:R,onNodeMouseMove:w,onNodeMouseLeave:N,onNodeContextMenu:A,onNodeDoubleClick:$,nodeTypes:u,edgeTypes:c,connectionLineType:z,connectionLineStyle:ie,connectionLineComponent:oe,connectionLineContainerStyle:fe,selectionKeyCode:pe,selectionOnDrag:Z,selectionMode:se,deleteKeyCode:he,multiSelectionKeyCode:ke,panActivationKeyCode:me,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ie,defaultViewport:mt,translateExtent:et,minZoom:Ct,maxZoom:ct,preventScrolling:Dn,zoomOnScroll:oo,zoomOnPinch:On,zoomOnDoubleClick:Fn,panOnScroll:gi,panOnScrollSpeed:lr,panOnScrollMode:zr,panOnDrag:Dr,autoPanOnSelection:Hr,onPaneClick:ar,onPaneMouseEnter:ur,onPaneMouseMove:Ft,onPaneMouseLeave:dt,onPaneScroll:Hn,onPaneContextMenu:Bn,paneClickDistance:Nn,nodeClickDistance:Vn,onSelectionContextMenu:U,onSelectionStart:M,onSelectionEnd:D,onReconnect:it,onReconnectStart:cr,onReconnectEnd:bn,onEdgeContextMenu:Pt,onEdgeDoubleClick:nn,onEdgeMouseEnter:mi,onEdgeMouseMove:Ze,onEdgeMouseLeave:He,reconnectRadius:En,defaultMarkerColor:kn,noDragClassName:Or,noWheelClassName:on,noPanClassName:It,rfId:sn,disableKeyboardA11y:dr,nodeExtent:Mt,viewport:uo,onViewportChange:co,nodesDraggable:$e}),d.jsx(E_,{onSelectionChange:K}),jn,d.jsx(S_,{proOptions:Rt,position:vi}),d.jsx(__,{rfId:sn,disableKeyboardA11y:dr})]})})}var sk=Bg(ok);function lk({dimensions:t,lineWidth:r,variant:o,className:s}){return d.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:rt(["react-flow__background-pattern",o,s])})}function ak({radius:t,className:r}){return d.jsx("circle",{cx:t,cy:t,r:t,className:rt(["react-flow__background-pattern","dots",r])})}var $r;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})($r||($r={}));const uk={[$r.Dots]:1,[$r.Lines]:1,[$r.Cross]:6},ck=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function gm({id:t,variant:r=$r.Dots,gap:o=20,size:s,lineWidth:a=1,offset:u=0,color:c,bgColor:h,style:p,className:y,patternClassName:x}){const v=L.useRef(null),{transform:m,patternId:_}=De(ck,Qe),k=s||uk[r],j=r===$r.Dots,b=r===$r.Cross,E=Array.isArray(o)?o:[o,o],R=[E[0]*m[2]||1,E[1]*m[2]||1],w=k*m[2],N=Array.isArray(u)?u:[u,u],A=b?[w,w]:R,$=[N[0]*m[2]+A[0]/2,N[1]*m[2]+A[1]/2],F=`${_}${t||""}`;return d.jsxs("svg",{className:rt(["react-flow__background",y]),style:{...p,...oa,"--xy-background-color-props":h,"--xy-background-pattern-color-props":c},ref:v,"data-testid":"rf__background",children:[d.jsx("pattern",{id:F,x:m[0]%R[0],y:m[1]%R[1],width:R[0],height:R[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${$[0]},-${$[1]})`,children:j?d.jsx(ak,{radius:w/2,className:x}):d.jsx(lk,{dimensions:A,lineWidth:a,variant:r,className:x})}),d.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${F})`})]})}gm.displayName="Background";const dk=L.memo(gm);function fk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:d.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function hk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:d.jsx("path",{d:"M0 0h32v4.2H0z"})})}function pk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:d.jsx("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"})})}function gk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:d.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"})})}function mk(){return d.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:d.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"})})}function El({children:t,className:r,...o}){return d.jsx("button",{type:"button",className:rt(["react-flow__controls-button",r]),...o,children:t})}const yk=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function mm({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:s=!0,fitViewOptions:a,onZoomIn:u,onZoomOut:c,onFitView:h,onInteractiveChange:p,className:y,children:x,position:v="bottom-left",orientation:m="vertical","aria-label":_}){const k=Ye(),{isInteractive:j,minZoomReached:b,maxZoomReached:E,ariaLabelConfig:R}=De(yk,Qe),{zoomIn:w,zoomOut:N,fitView:A}=ia(),$=()=>{w(),u==null||u()},F=()=>{N(),c==null||c()},G=()=>{A(a),h==null||h()},q=()=>{k.setState({nodesDraggable:!j,nodesConnectable:!j,elementsSelectable:!j}),p==null||p(!j)},te=m==="horizontal"?"horizontal":"vertical";return d.jsxs(ra,{className:rt(["react-flow__controls",te,y]),position:v,style:t,"data-testid":"rf__controls","aria-label":_??R["controls.ariaLabel"],children:[r&&d.jsxs(d.Fragment,{children:[d.jsx(El,{onClick:$,className:"react-flow__controls-zoomin",title:R["controls.zoomIn.ariaLabel"],"aria-label":R["controls.zoomIn.ariaLabel"],disabled:E,children:d.jsx(fk,{})}),d.jsx(El,{onClick:F,className:"react-flow__controls-zoomout",title:R["controls.zoomOut.ariaLabel"],"aria-label":R["controls.zoomOut.ariaLabel"],disabled:b,children:d.jsx(hk,{})})]}),o&&d.jsx(El,{className:"react-flow__controls-fitview",onClick:G,title:R["controls.fitView.ariaLabel"],"aria-label":R["controls.fitView.ariaLabel"],children:d.jsx(pk,{})}),s&&d.jsx(El,{className:"react-flow__controls-interactive",onClick:q,title:R["controls.interactive.ariaLabel"],"aria-label":R["controls.interactive.ariaLabel"],children:j?d.jsx(mk,{}):d.jsx(gk,{})}),x]})}mm.displayName="Controls";const vk=L.memo(mm);function xk({id:t,x:r,y:o,width:s,height:a,style:u,color:c,strokeColor:h,strokeWidth:p,className:y,borderRadius:x,shapeRendering:v,selected:m,onClick:_}){const{background:k,backgroundColor:j}=u||{},b=c||k||j;return d.jsx("rect",{className:rt(["react-flow__minimap-node",{selected:m},y]),x:r,y:o,rx:x,ry:x,width:s,height:a,style:{fill:b,stroke:h,strokeWidth:p},shapeRendering:v,onClick:_?E=>_(E,t):void 0})}const wk=L.memo(xk),_k=t=>t.nodes.map(r=>r.id),Zu=t=>t instanceof Function?t:()=>t;function Sk({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:s=5,nodeStrokeWidth:a,nodeComponent:u=wk,onClick:c}){const h=De(_k,Qe),p=Zu(r),y=Zu(t),x=Zu(o),v=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return d.jsx(d.Fragment,{children:h.map(m=>d.jsx(Nk,{id:m,nodeColorFunc:p,nodeStrokeColorFunc:y,nodeClassNameFunc:x,nodeBorderRadius:s,nodeStrokeWidth:a,NodeComponent:u,onClick:c,shapeRendering:v},m))})}function kk({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:s,nodeBorderRadius:a,nodeStrokeWidth:u,shapeRendering:c,NodeComponent:h,onClick:p}){const{node:y,x,y:v,width:m,height:_}=De(k=>{const j=k.nodeLookup.get(t);if(!j)return{node:void 0,x:0,y:0,width:0,height:0};const b=j.internals.userNode,{x:E,y:R}=j.internals.positionAbsolute,{width:w,height:N}=Sn(b);return{node:b,x:E,y:R,width:w,height:N}},Qe);return!y||y.hidden||!mg(y)?null:d.jsx(h,{x,y:v,width:m,height:_,style:y.style,selected:!!y.selected,className:s(y),color:r(y),borderRadius:a,strokeColor:o(y),strokeWidth:u,shapeRendering:c,onClick:p,id:y.id})}const Nk=L.memo(kk);var jk=L.memo(Sk);const bk=200,Ek=150,Ck=t=>!t.hidden,Mk=t=>{const r={x:-t.transform[0]/t.transform[2],y:-t.transform[1]/t.transform[2],width:t.width/t.transform[2],height:t.height/t.transform[2]};return{viewBB:r,boundingRect:t.nodeLookup.size>0?hg(ps(t.nodeLookup,{filter:Ck}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},gp=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,Pk=(t,r)=>gp(t.viewBB,r.viewBB)&&gp(t.boundingRect,r.boundingRect)&&t.rfId===r.rfId&&t.panZoom===r.panZoom&&t.translateExtent===r.translateExtent&&t.flowWidth===r.flowWidth&&t.flowHeight===r.flowHeight&&t.ariaLabelConfig===r.ariaLabelConfig,Ik="react-flow__minimap-desc";function ym({style:t,className:r,nodeStrokeColor:o,nodeColor:s,nodeClassName:a="",nodeBorderRadius:u=5,nodeStrokeWidth:c,nodeComponent:h,bgColor:p,maskColor:y,maskStrokeColor:x,maskStrokeWidth:v,position:m="bottom-right",onClick:_,onNodeClick:k,pannable:j=!1,zoomable:b=!1,ariaLabel:E,inversePan:R,zoomStep:w=1,offsetScale:N=5}){const A=Ye(),$=L.useRef(null),{boundingRect:F,viewBB:G,rfId:q,panZoom:te,translateExtent:ee,flowWidth:ne,flowHeight:K,ariaLabelConfig:C}=De(Mk,Pk),V=(t==null?void 0:t.width)??bk,W=(t==null?void 0:t.height)??Ek,U=F.width/V,M=F.height/W,D=Math.max(U,M),H=D*V,I=D*W,z=N*D,ie=F.x-(H-F.width)/2-z,oe=F.y-(I-F.height)/2-z,fe=H+z*2,he=I+z*2,pe=`${Ik}-${q}`,Z=L.useRef(0),se=L.useRef();Z.current=D,L.useEffect(()=>{if($.current&&te)return se.current=V1({domNode:$.current,panZoom:te,getTransform:()=>A.getState().transform,getViewScale:()=>Z.current}),()=>{var re;(re=se.current)==null||re.destroy()}},[te]),L.useEffect(()=>{var re;(re=se.current)==null||re.update({translateExtent:ee,width:ne,height:K,inversePan:R,pannable:j,zoomStep:w,zoomable:b})},[j,b,R,w,ee,ne,K]);const me=_?re=>{var Le;const[Ne,Ie]=((Le=se.current)==null?void 0:Le.pointer(re))||[0,0];_(re,{x:Ne,y:Ie})}:void 0,ke=k?L.useCallback((re,Ne)=>{const Ie=A.getState().nodeLookup.get(Ne).internals.userNode;k(re,Ie)},[]):void 0,ve=E??C["minimap.ariaLabel"];return d.jsx(ra,{position:m,style:{...t,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof x=="string"?x:void 0,"--xy-minimap-mask-stroke-width-props":typeof v=="number"?v*D:void 0,"--xy-minimap-node-background-color-props":typeof s=="string"?s:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof c=="number"?c:void 0},className:rt(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:d.jsxs("svg",{width:V,height:W,viewBox:`${ie} ${oe} ${fe} ${he}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":pe,ref:$,onClick:me,children:[ve&&d.jsx("title",{id:pe,children:ve}),d.jsx(jk,{onClick:ke,nodeColor:s,nodeStrokeColor:o,nodeBorderRadius:u,nodeClassName:a,nodeStrokeWidth:c,nodeComponent:h}),d.jsx("path",{className:"react-flow__minimap-mask",d:`M${ie-z},${oe-z}h${fe+z*2}v${he+z*2}h${-fe-z*2}z - M${G.x},${G.y}h${G.width}v${G.height}h${-G.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}ym.displayName="MiniMap";const Rk=L.memo(ym),Tk=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,Lk={[to.Line]:"right",[to.Handle]:"bottom-right"};function Ak({nodeId:t,position:r,variant:o=to.Handle,className:s,style:a=void 0,children:u,color:c,minWidth:h=10,minHeight:p=10,maxWidth:y=Number.MAX_VALUE,maxHeight:x=Number.MAX_VALUE,keepAspectRatio:v=!1,resizeDirection:m,autoScale:_=!0,shouldResize:k,onResizeStart:j,onResize:b,onResizeEnd:E}){const R=Gg(),w=typeof t=="string"?t:R,N=Ye(),A=L.useRef(null),$=o===to.Handle,F=De(L.useCallback(Tk($&&_),[$,_]),Qe),G=L.useRef(null),q=r??Lk[o];L.useEffect(()=>{if(!(!A.current||!w))return G.current||(G.current=n_({domNode:A.current,nodeId:w,getStoreItems:()=>{const{nodeLookup:ee,transform:ne,snapGrid:K,snapToGrid:C,nodeOrigin:V,domNode:W}=N.getState();return{nodeLookup:ee,transform:ne,snapGrid:K,snapToGrid:C,nodeOrigin:V,paneDomNode:W}},onChange:(ee,ne)=>{const{triggerNodeChanges:K,nodeLookup:C,parentLookup:V,nodeOrigin:W}=N.getState(),U=[],M={x:ee.x,y:ee.y},D=C.get(w);if(D&&D.expandParent&&D.parentId){const H=D.origin??W,I=ee.width??D.measured.width??0,z=ee.height??D.measured.height??0,ie={id:D.id,parentId:D.parentId,rect:{width:I,height:z,...yg({x:ee.x??D.position.x,y:ee.y??D.position.y},{width:I,height:z},D.parentId,C,H)}},oe=Tc([ie],C,V,W);U.push(...oe),M.x=ee.x?Math.max(H[0]*I,ee.x):void 0,M.y=ee.y?Math.max(H[1]*z,ee.y):void 0}if(M.x!==void 0&&M.y!==void 0){const H={id:w,type:"position",position:{...M}};U.push(H)}if(ee.width!==void 0&&ee.height!==void 0){const I={id:w,type:"dimensions",resizing:!0,setAttributes:m?m==="horizontal"?"width":"height":!0,dimensions:{width:ee.width,height:ee.height}};U.push(I)}for(const H of ne){const I={...H,type:"position"};U.push(I)}K(U)},onEnd:({width:ee,height:ne})=>{const K={id:w,type:"dimensions",resizing:!1,dimensions:{width:ee,height:ne}};N.getState().triggerNodeChanges([K])}})),G.current.update({controlPosition:q,boundaries:{minWidth:h,minHeight:p,maxWidth:y,maxHeight:x},keepAspectRatio:v,resizeDirection:m,onResizeStart:j,onResize:b,onResizeEnd:E,shouldResize:k}),()=>{var ee;(ee=G.current)==null||ee.destroy()}},[q,h,p,y,x,v,j,b,E,k]);const te=q.split("-");return d.jsx("div",{className:rt(["react-flow__resize-control","nodrag",...te,o,s]),ref:A,style:{...a,scale:F,...c&&{[$?"backgroundColor":"borderColor"]:c}},children:u})}L.memo(Ak);const $k={"arch.context":0,"django.app":0,"django.route":1,"django.websocket_route":1,"fastapi.route":1,"django.url_name":2,"django.view":3,"django.viewset_action":3,"django.permission":3,"django.throttle":3,"django.serializer":4,"django.form":4,"graphql.type":4,"fastapi.model":4,"django.serializer_field":5,"django.service":5,"graphql.field":5,"django.model":6,"django.field":7,"django.relation":7,"django.task":8,"django.receiver":8,"django.signal":8,"django.test":8,"django.migration_op":8,"django.admin":8,"django.management_command":8,"django.consumer":8,"django.cache_key":8,"django.feature_flag":8,"django.side_effect":8,"openapi.path":9,"graphql.operation":9,"react.api_client":10,"django.htmx":10,"react.query_key":11,"react.hook":11,"react.feature":11,"react.route":12,"react.page":12,"django.template":12,"react.component":13,"react.context":13,"react.form_schema":14,"react.test":14};function sa(t){return $k[t]??8}const us=208,ro=64,mc=88,zk=28,Dk=8;function Ok(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function vm(t,r=[]){const o=new Map;if(!t.length)return o;const s=new Map;for(const w of t){const N=sa(w.type),A=s.get(N)??[];A.push(w),s.set(N,A)}const u=[...s.keys()].sort((w,N)=>w-N).map(w=>[...s.get(w)??[]].sort((N,A)=>N.name.localeCompare(A.name)||N.id.localeCompare(A.id))),c=new Set(t.map(w=>w.id)),h=new Map,p=new Map;for(const w of t)h.set(w.id,[]),p.set(w.id,[]);for(const w of r)!c.has(w.src)||!c.has(w.dst)||w.src===w.dst||(p.get(w.src).push(w.dst),h.get(w.dst).push(w.src));const y=new Map;u.forEach((w,N)=>{for(const A of w)y.set(A.id,N)});const x=new Map,v=()=>{for(const w of u)w.forEach((N,A)=>x.set(N.id,A))};v();const m=(w,N)=>{const A=w.map(($,F)=>{const G=N($.id).map(te=>x.get(te)).filter(te=>te!==void 0),q=Ok(G);return{n:$,bary:Number.isNaN(q)?F:q,name:$.name,id:$.id}});return A.sort(($,F)=>$.bary-F.bary||$.name.localeCompare(F.name)||$.id.localeCompare(F.id)),A.map($=>$.n)},_=w=>N=>y.get(N)===w;for(let w=0;w(h.get(A)??[]).filter(_(N-1))),v();for(let N=u.length-2;N>=0;N--)u[N]=m(u[N],A=>(p.get(A)??[]).filter(_(N+1))),v()}const k=us+mc,j=ro+zk,b=Math.max(...u.map(w=>w.length),1),E=[];let R=0;for(let w=0;wG.id)),A=new Set((u[w+1]??[]).map(G=>G.id));let $=0;if(A.size)for(const G of r)N.has(G.src)&&A.has(G.dst)&&($+=1);const F=Math.min(120,Math.max(0,($-2)*12));R+=k+F}return u.forEach((w,N)=>{const A=(b-w.length)*j/2;w.forEach(($,F)=>{o.set($.id,{x:E[N]??0,y:A+F*j})})}),o}const Fk=new Set(["django.route","react.route","react.page","django.task","django.migration_op","django.permission","openapi.path","django.consumer","django.websocket_route","django.template","graphql.operation","fastapi.route"]),xm=90,Hk=new Set(["django.field","django.serializer_field","django.relation","django.test","react.test","graphql.field","django.url_name","django.throttle"]),mp={"arch.context":"#edf2f4","django.app":"#8d99ae","django.route":"#4cc9f0","django.url_name":"#4cc9f0","django.view":"#4895ef","django.viewset_action":"#4361ee","django.permission":"#7b8cde","django.serializer":"#f4a261","django.form":"#e9c46a","django.serializer_field":"#e9c46a","django.service":"#90be6d","django.model":"#2a9d8f","django.field":"#8ac926","django.task":"#e76f51","django.receiver":"#e85d04","django.signal":"#f4a261","django.test":"#6c757d","django.admin":"#adb5bd","django.migration_op":"#9d4edd","django.consumer":"#e76f51","django.websocket_route":"#4cc9f0","django.template":"#c77dff","django.htmx":"#ff6b6b","django.cache_key":"#6c757d","django.feature_flag":"#f4a261","django.side_effect":"#e85d04","graphql.type":"#00bbf9","graphql.operation":"#00bbf9","fastapi.route":"#4cc9f0","fastapi.model":"#f4a261","openapi.path":"#00bbf9","react.api_client":"#ff6b6b","react.query_key":"#adb5bd","react.hook":"#7b2cbf","react.feature":"#9d4edd","react.route":"#c77dff","react.page":"#c77dff","react.component":"#9d4edd","react.form_schema":"#ffd166","react.test":"#6c757d"},Bk=Math.PI*(3-Math.sqrt(5)),wm=220,Vk=26,Wk={0:"context",1:"routes",2:"url names",3:"views",4:"serializers",5:"services",6:"models",7:"fields",8:"jobs / signals",9:"openapi",10:"api client",11:"hooks",12:"pages",13:"components",14:"forms / tests"};function _m(t){return t.startsWith("react.")?"react":t.startsWith("openapi.")||t.startsWith("graphql.")||t.startsWith("fastapi.")?"stitch":t.startsWith("arch.")?"arch":"django"}function UN(t){return mp[t]?mp[t]:t.startsWith("react.")?"#9d4edd":t.startsWith("openapi.")?"#00bbf9":"#4a5568"}function Uk(t){return t>=xm?"3d":"2d"}function Yk(t){return t>=xm?"overview":"full"}function Gk(t,r,o=1){const s=new Set([t]);let a=new Set([t]);for(let u=0;uo.families.has(_m(h.type)));o.detail==="overview"&&(s=s.filter(h=>!Hk.has(h.type)));const a=new Set(s.map(h=>h.id)),u=r.filter(h=>a.has(h.src)&&a.has(h.dst)),c=o.focusId?Gk(o.focusId,u,1):new Set;if(o.neighborhoodOnly&&o.focusId&&c.size){s=s.filter(p=>c.has(p.id));const h=new Set(s.map(p=>p.id));return{nodes:s,edges:u.filter(p=>h.has(p.src)&&h.has(p.dst)),neighborIds:c}}return{nodes:s,edges:u,neighborIds:c}}function qk(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>`${s.name} ${s.qualified_name} ${s.type} ${s.file_path||""} ${s.context||""}`.toLowerCase().includes(o)).slice(0,24):[]}function Kk(t,r,o,s){const a=new Set(t.map(j=>j.id));if(!a.has(o))return{nodeIds:new Set,edgeIds:new Set};const u=new Map,c=new Map;for(const j of r){if(!a.has(j.src)||!a.has(j.dst))continue;const b=u.get(j.src)??[];b.push({dst:j.dst,id:j.id}),u.set(j.src,b);const E=c.get(j.dst)??[];E.push({src:j.src,id:j.id}),c.set(j.dst,E)}const h=new Set(t.filter(j=>Fk.has(j.type)).map(j=>j.id)),p=h.size?h:a,y=new Set,x=[o];for(;x.length;){const j=x.pop();if(!y.has(j)){y.add(j);for(const b of u.get(j)??[])y.has(b.dst)||x.push(b.dst)}}const v=new Set([o]),m=[...p].filter(j=>y.has(j)),_=new Set(m);for(;m.length;){const j=m.pop();v.add(j);for(const b of c.get(j)??[])y.has(b.src)&&!_.has(b.src)&&(_.add(b.src),m.push(b.src))}const k=new Set;for(const j of r)v.has(j.src)&&v.has(j.dst)&&k.add(j.id);return{nodeIds:v,edgeIds:k}}function YN(t){const r=new Map;for(const s of t){const a=sa(s.type),u=r.get(a)??[];u.push(s),r.set(a,u)}const o=new Map;for(const[s,a]of r){a.sort((c,h)=>c.name.localeCompare(h.name));const u=s*wm;a.forEach((c,h)=>{if(a.length===1){o.set(c.id,{x:u,y:0,z:0});return}const p=Vk*Math.sqrt(h+1),y=h*Bk;o.set(c.id,{x:u,y:p*Math.cos(y),z:p*Math.sin(y)})})}return o}function GN(t){const r=new Map;for(const o of t){const s=sa(o.type);r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>o[0]-s[0]).map(([o,s])=>({layer:o,x:o*wm,count:s}))}const Cl=16,Qk=12,Zk=new Set(["django.route","react.route","react.page","django.task","django.migration_op","django.permission","django.throttle","django.admin","django.management_command","openapi.path","django.consumer","django.websocket_route","django.template","django.cache_key","django.feature_flag","django.side_effect","graphql.operation","fastapi.route"]),Jk=new Set(["django.serializer","django.serializer_field","django.form","openapi.path","react.form_schema","django.route","graphql.type","graphql.field","graphql.operation","fastapi.model","fastapi.route"]),yp={"arch.context":"Ownership boundary from loadpath.yml — the context this code belongs to.","django.app":"Django app package that owns models, views, and jobs.","django.route":"HTTP URL that publishes a view. A sink: this is where a change becomes a public request.","django.url_name":"Named URL used by reverse() / {% url %} lookups.","django.view":"Request handler (class-based view, function view, or ViewSet).","django.viewset_action":"One ViewSet action (list, create, retrieve, update, destroy).","django.permission":"Auth gate on a view — who is allowed to hit this path.","django.throttle":"Rate-limit class attached to a view.","django.serializer":"Request/response contract: which fields go in and come out.","django.form":"Django form or django-filter FilterSet — the typed input contract.","django.serializer_field":"One field on a serializer or form — the typed slot on the contract.","django.service":"Internal service or use-case. Work that is not itself an HTTP sink.","django.model":"ORM model. Schema and relations live here.","django.field":"Model column. Type, indexes, and relations are the contract of the table.","django.relation":"Model-to-model relation (FK / M2M / O2O).","django.task":"Celery or Dramatiq job. Once enqueued, this is a sink.","django.receiver":"Signal handler that runs after a model event.","django.signal":"Django signal that receivers subscribe to.","django.test":"Backend test that mentions symbols on this path.","django.admin":"Django admin class for a model.","django.migration_op":"Schema migration operation (CreateModel, AlterField, …).","django.management_command":"manage.py command — an operational sink.","django.consumer":"Django Channels WebSocket/HTTP consumer. A sink once a client connects.","django.websocket_route":"ASGI WebSocket URL. A sink: this is where a change becomes a live connection.","django.template":"Django template. HTML (and HTMX) the server renders.","django.htmx":"HTMX call from a template to a URL — another published seam.","django.cache_key":"Cache get/set key. Invalidation is part of the load path.","django.feature_flag":"Feature flag checked on this path. The change may be dark-launched.","django.side_effect":"transaction.on_commit (or similar) side effect that runs after the request commits.","graphql.type":"GraphQL object/input type — a published contract.","graphql.field":"One field on a GraphQL type.","graphql.operation":"GraphQL query, mutation, or subscription. A published contract and a sink.","fastapi.route":"FastAPI path operation sitting next to Django in this repo.","fastapi.model":"Pydantic response/request model — the FastAPI contract.","openapi.path":"Generated OpenAPI operation. The typed HTTP contract between stacks.","react.api_client":"Frontend fetch or generated client call to an API path.","react.query_key":"React Query cache key. Invalidation and reads share this name.","react.hook":"Data hook wrapping query or mutation calls.","react.feature":"Frontend feature module (folder).","react.route":"Client-side route. A sink: this is a URL the user can open.","react.page":"Page or screen component rendered by a route.","react.component":"UI component.","react.form_schema":"Zod (or similar) schema — typed form inputs on the client.","react.test":"Frontend test covering a page, hook, or component.","react.context":"React context provider."},eN={field_type:"Type",fields:"Fields",form_fields:"Form fields",permissions:"Permissions",throttles:"Throttles",authentication:"Authentication",pagination:"Pagination",filterset:"Filterset",bases:"Extends",on_delete:"on_delete",related_name:"related_name",unique:"Unique",db_index:"Indexed",relation:"Relation field",looks_idempotent_on_pk:"Idempotent on pk",broker:"Broker",route:"Route",url_name:"URL name",view:"View",include:"Includes",mounted_at:"Mounted at",full_path:"Full path",method:"Method",path:"Path",operation_id:"Operation",raw:"URL",kind:"Schema",exclude:"Excludes",queryset_in_serializer:"Queryset in serializer",get_queryset:"Custom get_queryset",get_serializer_class:"Dynamic serializer",dynamic:"Dynamic",fbv:"Function view",ninja:"Django Ninja",django_form:"Django form",mutation:"Mutation",has_error_boundary:"Error boundary",invalidation:"Cache invalidation",inferred:"Inferred stitch",generated:"Generated",shared:"Shared module",element:"Renders",model_name:"Model",field_name:"Field",op:"Operation",app:"App",feature:"Feature",from_view:"From view",mentions:"Mentions",nodeid:"Test id",task:"Task",to:"Related to",doc:"Summary",template:"Template",signal:"Signal",sender:"Sender",decorators:"Decorators",nplusone:"N+1 risk",lookups:"Lookups",null:"NULL",blank:"Blank",default:"Default",max_length:"max_length",max_digits:"max_digits",decimal_places:"decimal_places",primary_key:"Primary key",help_text:"Help text",choices:"Choices",auto_now:"auto_now",auto_now_add:"auto_now_add",basename:"Router basename",args:"Args",beat:"Beat",schedule_name:"Schedule",websocket:"WebSocket",htmx:"HTMX",blocks:"Blocks",db_table:"db_table"},vp=["doc","field_type","method","path","operation_id","raw","route","mounted_at","full_path","url_name","view","element","fields","form_fields","exclude","kind","bases","permissions","authentication","throttles","pagination","filterset","on_delete","related_name","to","unique","db_index","null","blank","default","max_length","max_digits","decimal_places","primary_key","auto_now","auto_now_add","help_text","choices","relation","nplusone","lookups","template","signal","sender","decorators","basename","args","beat","schedule_name","websocket","htmx","blocks","db_table","looks_idempotent_on_pk","broker","task","model_name","field_name","op","app","feature","from_view","include","fbv","ninja","django_form","mutation","has_error_boundary","invalidation","inferred","generated","shared","queryset_in_serializer","get_queryset","get_serializer_class","dynamic","mentions","nodeid"],xp=new Set(["referenced","placeholder","booted","line","call","from","import","local","source","file","plain_handler","string_ref","pagination_sink","match","via","generated_client","django","react","superseded_by_generated","foreign_app","imported"]),tN=new Set(["looks_idempotent_on_pk","null","blank"]),nN=new Set(["inferred","generated","mutation","fbv","ninja","filterset"]);function rN(t){return yp[t]?yp[t]:t.startsWith("react.")?"A React node on the load path.":t.startsWith("django.")?"A Django node on the load path.":t.startsWith("openapi.")?"A stitch node between Django and React.":"A node on the architecture graph."}function iN(t,r,o){const s=new Map(r.map(m=>[m.id,m])),a=[];Zk.has(t.type)&&a.push("sink"),Jk.has(t.type)&&a.push("contract");const u=t.extra??{};u.inferred&&a.push("inferred"),u.generated&&a.push("generated"),u.mutation&&a.push("mutation"),u.fbv&&a.push("function view"),u.ninja&&a.push("ninja"),u.filterset===!0&&a.push("filterset");const c=o.filter(m=>m.dst===t.id),h=o.filter(m=>m.src===t.id),p=c.slice(0,Cl).map(m=>Ml(m,s,m.src)),y=h.slice(0,Cl).map(m=>Ml(m,s,m.dst)),x=t.file_path?`${t.file_path}${t.start_line?`:${t.start_line}`:""}`:void 0,v={type:t.type,typeLabel:Zo(io(t.type)),layer:Wk[sa(t.type)]??"other",purpose:rN(t.type),name:t.name,qualifiedName:t.qualified_name,file:x,context:t.context,roles:a,facts:sN(u).filter(m=>!(m.key==="app"&&m.value===t.context)),inputs:p,outputs:y,extraInputs:Math.max(0,c.length-Cl),extraOutputs:Math.max(0,h.length-Cl),degreeIn:c.length,degreeOut:h.length,inputKinds:wp(c.map(m=>Ml(m,s,m.src))),outputKinds:wp(h.map(m=>Ml(m,s,m.dst))),pathSummary:""};return v.pathSummary=oN(v),v}function wp(t){const r=new Map;for(const o of t){const s=o.edgeLabel||o.edgeType.replaceAll("_"," ");r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])).map(([o,s])=>({label:o,count:s}))}function oN(t){const r=t.inputKinds.map(s=>`${s.label} ×${s.count}`).join(", "),o=t.outputKinds.map(s=>`${s.label} ×${s.count}`).join(", ");return r&&o?`${r} → this → ${o}`:o?`this → ${o}`:r?`${r} → this`:""}function Ml(t,r,o){const s=r.get(o),a=o.includes(":")?o.slice(o.indexOf(":")+1):o;return{id:o,name:(s==null?void 0:s.name)||a,type:(s==null?void 0:s.type)||"",typeLabel:s?Zo(io(s.type)):"",edgeType:t.type,edgeLabel:Zo(t.type),inferred:t.confidence<.8}}function sN(t){const r=[...vp.filter(a=>a in t),...Object.keys(t).filter(a=>!vp.includes(a)&&!xp.has(a))],o=[],s=new Set;for(const a of r){if(s.has(a)||xp.has(a)||nN.has(a))continue;s.add(a);const u=lN(a,t[a]);u!=null&&o.push({key:a,label:eN[a]??Zo(a),value:u})}return o}function lN(t,r){if(r==null)return null;if(typeof r=="boolean")return!r&&!tN.has(t)?null:r?"yes":"no";if(typeof r=="number")return String(r);if(typeof r=="string")return r.trim()||null;if(Array.isArray(r)){if(r.some(u=>u&&typeof u=="object"))return aN(t,r);const o=r.map(u=>typeof u=="string"||typeof u=="number"?String(u):"").filter(Boolean);if(!o.length)return null;const s=o.slice(0,Qk),a=o.length-s.length;return a>0?`${s.join(", ")} +${a} more`:s.join(", ")}return null}function aN(t,r){const o=r.slice(0,4).map(a=>{if(t==="nplusone"){const c=String(a.queryset||"queryset"),h=Array.isArray(a.accessed)?a.accessed.join("."):"",p=a.line?` L${a.line}`:"";return h?`${c} → ${h}${p}`:`${c}${p}`}if(t==="lookups"){const c=Array.isArray(a.fields)?a.fields.join(", "):"",h=String(a.kind||"filter");return c?`${h} ${c}`:h}return Object.entries(a).filter(([,c])=>c!=null&&(typeof c=="string"||typeof c=="number")).slice(0,3).map(([c,h])=>`${c}=${h}`).join(" ")});if(!o.some(Boolean))return null;const s=r.length-o.length;return s>0?`${o.join("; ")} +${s} more`:o.join("; ")}const _p=12,Sp=.2,uN=.8,Yl=20,cN=ro;function dN(t,r,o){const s=o??vm(t,r),a=[...new Set([...s.values()].map(p=>p.x))].sort((p,y)=>p-y),u=[];for(const p of r){const y=s.get(p.src),x=s.get(p.dst);if(!y||!x)continue;const v=y.y+ro/2,m=x.y+ro/2;if(Math.abs(v-m)<_p)continue;const _=y.x+us,k=x.x;if(k-_<_p)continue;const b=Math.min(v,m),E=Math.max(v,m);u.push({id:p.id,y0:b,y1:E,sourceX:_,targetX:k,corridor:`${Math.round(_/8)}`})}const c=new Map;for(const p of u){const y=c.get(p.corridor)??[];y.push(p),c.set(p.corridor,y)}const h=new Map;for(const p of c.values()){const y=[...p].sort((k,j)=>k.y0-j.y0||k.y1-j.y1||k.id.localeCompare(j.id)),x=pN(y),v=Math.max(0,...x.values())+1,m=y[0].sourceX,_=fN(a,m);for(const k of y){const j=gN(x.get(k.id)??0,v),b=m+Yl+Math.max(1,_-2*Yl)*j;h.set(k.id,hN(k.sourceX,k.targetX,b))}}return h}function fN(t,r){const o=r-us,s=t.find(a=>a>o+1);return s===void 0?mc:Math.max(mc,s-r)}function hN(t,r,o){const s=r-t-2*Yl;return s<1?.5:Math.min(1,Math.max(0,(o-t-Yl)/s))}function pN(t){const r=[],o=new Map;for(const s of t){let a=-1;for(let u=0;ur[u]+cN){a=u;break}a<0?(a=r.length,r.push(s.y1)):r[a]=Math.max(r[a],s.y1),o.set(s.id,a)}return o}function gN(t,r){return r<=1?.5:Sp+(uN-Sp)*t/(r-1)}const mN=new Set,yN=L.lazy(()=>b0(()=>import("./LayeredGraph3D-BkYe4qmj.js"),[],import.meta.url).then(t=>({default:t.LayeredGraph3D}))),vN={cheap:"var(--edge-cheap)",expensive:"var(--edge-expensive)",critical:"var(--edge-critical)"};function xN({data:t,selected:r}){const o=(t.roles||[]).map(s=>`role-${s}`).join(" ");return d.jsxs("div",{className:["lp-node",r?"selected":"",t.dim?"dim":"",o].filter(Boolean).join(" "),children:[d.jsx(no,{type:"target",position:Se.Left,isConnectable:!1}),d.jsx("div",{className:"t",children:io(t.type)}),d.jsx("div",{className:"n",title:t.name,children:Lr(t.name)}),d.jsx(no,{type:"source",position:Se.Right,isConnectable:!1})]})}const wN={load:xN},_N=new Set(["django","react","stitch","arch"]);function SN({id:t,sourceX:r,sourceY:o,targetX:s,targetY:a,sourcePosition:u,targetPosition:c,style:h,markerEnd:p,markerStart:y,label:x,labelStyle:v,labelShowBg:m,labelBgStyle:_,labelBgPadding:k,labelBgBorderRadius:j,data:b,interactionWidth:E}){const[R,w,N]=Wl({sourceX:r,sourceY:o,sourcePosition:u,targetX:s,targetY:a,targetPosition:c,borderRadius:8,stepPosition:(b==null?void 0:b.stepPosition)??.5});return d.jsx(ys,{id:t,path:R,labelX:w,labelY:N,label:x,labelStyle:v,labelShowBg:m,labelBgStyle:_,labelBgPadding:k,labelBgBorderRadius:j,style:h,markerEnd:p,markerStart:y,interactionWidth:E})}const kN={loadstep:SN};function NN({topologyKey:t}){const{fitView:r}=ia();return L.useEffect(()=>{let o=0;const s=requestAnimationFrame(()=>{o=requestAnimationFrame(()=>{r({padding:.2,maxZoom:1.15})})});return()=>{cancelAnimationFrame(s),cancelAnimationFrame(o)}},[r,t]),null}function jN(t,r,o=null,s={}){const a=new Map(t.map(y=>[y.id,y])),u=vm(t,r),c=dN(t,r,u),h=t.map(y=>{var m;const x=((m=s.roles)==null?void 0:m[y.id])||[],v=!!s.testOverlay&&!x.includes("tested")&&!x.includes("untested")&&!x.includes("test")&&!x.includes("seed");return{id:y.id,type:"load",position:u.get(y.id)??{x:0,y:0},data:{name:y.name,type:y.type,file:y.file_path,roles:x,dim:v},selected:o===y.id,sourcePosition:Se.Right,targetPosition:Se.Left,width:us,height:ro,style:{width:us,height:ro}}}),p=r.filter(y=>a.has(y.src)&&a.has(y.dst)).map(y=>{const x=vN[y.weight]||"var(--edge-cheap)",v=!!(o&&(y.src===o||y.dst===o));return{id:y.id,source:y.src,target:y.dst,type:"loadstep",animated:y.weight==="critical",data:{stepPosition:c.get(y.id)??.5},style:{stroke:x,strokeWidth:y.weight==="critical"?2.4:1.2,strokeDasharray:y.confidence<.8?"6 4":void 0},markerEnd:{type:os.ArrowClosed,width:14,height:14,color:x},label:v?y.type.replaceAll("_"," "):void 0,labelStyle:v?{fill:"var(--ink)",fontSize:10,fontWeight:600}:void 0,labelBgStyle:v?{fill:"var(--graph-bg)",fillOpacity:.92}:void 0,labelBgPadding:v?[3,5]:void 0,labelBgBorderRadius:v?4:void 0}});return{rfNodes:h,rfEdges:p}}function bN({node:t,nodes:r,edges:o,onClose:s,onWhatIf:a,onSelect:u,onOpenFile:c,pinned:h,onPin:p,onIsolate:y}){const x=iN(t,r,o);return L.useEffect(()=>{const v=m=>{m.key==="Escape"&&s()};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[s]),d.jsxs("aside",{className:"inspector","data-testid":"graph-inspector",children:[d.jsxs("div",{className:"inspector-head",children:[d.jsx("div",{className:"t",children:x.typeLabel}),d.jsx("div",{className:"inspector-roles",children:x.roles.map(v=>d.jsx("span",{className:"inspector-chip",children:v},v))}),d.jsx("button",{type:"button",className:"inspector-close","data-testid":"graph-inspector-close","aria-label":"Close inspector",onClick:s,children:"×"})]}),d.jsx("div",{className:"n",children:Lr(x.name)}),d.jsx("p",{className:"inspector-purpose","data-testid":"graph-inspector-purpose",children:x.purpose}),x.context?d.jsx("div",{className:"muted",children:Lr(x.context)}):null,x.file?d.jsxs("div",{className:"file-row",children:[d.jsx("div",{className:"file",children:Lr(x.file)}),c&&t.file_path?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-open-editor",onClick:()=>c(t.file_path,t.start_line),children:"Open in editor"}):null]}):null,d.jsx("div",{className:"muted",children:Lr(x.qualifiedName)}),d.jsxs("div",{className:"muted inspector-layer",children:["layer · ",x.layer]}),d.jsxs("div",{className:"muted inspector-degree","data-testid":"graph-inspector-degree",children:[x.degreeIn," in · ",x.degreeOut," out"]}),x.pathSummary?d.jsx("p",{className:"inspector-path","data-testid":"graph-inspector-path",children:x.pathSummary}):null,x.facts.length?d.jsx("dl",{className:"inspector-facts","data-testid":"graph-inspector-facts",children:x.facts.map(v=>d.jsxs("div",{className:"inspector-fact",children:[d.jsx("dt",{children:v.label}),d.jsx("dd",{children:Lr(v.value)})]},v.key))}):null,d.jsx(kp,{title:"Inputs",testId:"graph-inspector-inputs",links:x.inputs,extra:x.extraInputs,empty:"Nothing in this graph points here.",onSelect:u}),d.jsx(kp,{title:"Outputs",testId:"graph-inspector-outputs",links:x.outputs,extra:x.extraOutputs,empty:"This node does not point at anything in this graph.",onSelect:u}),a?d.jsx("p",{className:"whatif-hint","data-testid":"whatif-hint",children:y?"Walks a new path from this node with no git range. Isolate (next) only hides the rest of this map.":"Walks a new path from this node with no git range — as if this changed, regardless of Base/Head."}):null,d.jsxs("div",{className:"btn-row",children:[a?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-whatif",title:"Start a hypothetical walk from this node. Does not use Base/Head.",onClick:()=>a(t.id),children:"What if this changes"}):null,y?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-isolate",title:"Hide nodes that are not on a path from here to a sink. Does not start a new walk.",onClick:()=>y(t.id),children:"Isolate path to sinks"}):null,p?d.jsx("button",{type:"button",className:h?"btn primary":"btn","data-testid":"btn-pin-node",onClick:()=>p(h?null:t.id),children:h?"Unpin":"Pin"}):null]})]})}function kp({title:t,testId:r,links:o,extra:s,empty:a,onSelect:u}){return d.jsxs("section",{className:"inspector-section","data-testid":r,children:[d.jsxs("h3",{children:[t,d.jsx("span",{className:"count",children:o.length+s})]}),o.length?d.jsx("ul",{children:o.map((c,h)=>d.jsx("li",{children:u?d.jsxs("button",{type:"button",className:"inspector-link",onClick:()=>u(c.id),children:[d.jsx("span",{className:"inspector-link-name",title:c.name,children:Lr(c.name)}),d.jsxs("span",{className:"inspector-link-meta",children:[c.typeLabel?`${c.typeLabel} · `:"",c.edgeLabel,c.inferred?" · inferred":""]})]}):d.jsxs(d.Fragment,{children:[d.jsx("span",{className:"inspector-link-name",title:c.name,children:Lr(c.name)}),d.jsxs("span",{className:"inspector-link-meta",children:[c.typeLabel?`${c.typeLabel} · `:"",c.edgeLabel,c.inferred?" · inferred":""]})]})},`${c.edgeType}:${c.id}:${h}`))}):d.jsx("p",{className:"muted",children:a}),s?d.jsxs("p",{className:"muted",children:["+",s," more"]}):null]})}function Ju({nodes:t,edges:r,onWhatIf:o,focusPath:s,selectedId:a,onSelect:u,nodeRoles:c,testOverlay:h=!1,isolateSource:p,onIsolate:y,repoPath:x,onOpenFile:v,pinnedId:m,onPin:_}){const[k,j]=L.useState(null),b=a!==void 0?a:k,E=re=>{a===void 0&&j(re),u==null||u(re)},[R,w]=L.useState(null),[N,A]=L.useState(null),[$,F]=L.useState(new Set(_N)),[G,q]=L.useState(!1),[te,ee]=L.useState(""),[ne,K]=L.useState(!1),C=typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,V=R??Uk(t.length),W=N??Yk(t.length),U=G?b:null,M=L.useMemo(()=>p?Kk(t,r,p):null,[t,r,p]),D=M?t.filter(re=>M.nodeIds.has(re.id)):t,H=M?r.filter(re=>M.edgeIds.has(re.id)):r,I=L.useMemo(()=>Xk(D,H,{detail:W,families:$,focusId:U,neighborhoodOnly:!!U}),[D,H,W,$,U]),z=L.useMemo(()=>`${I.nodes.map(re=>re.id).join("\0")}|${I.edges.map(re=>re.id).join("\0")}`,[I.nodes,I.edges]),ie=b?t.find(re=>re.id===b)??null:null,{rfNodes:oe,rfEdges:fe}=L.useMemo(()=>{const re=jN(I.nodes,I.edges,b,{roles:c,testOverlay:h});return C&&(re.rfEdges=re.rfEdges.map(Ne=>({...Ne,animated:!1}))),re},[I.nodes,I.edges,b,C,c,h]);L.useEffect(()=>{if(!s)return;const re=t.find(Ne=>Ne.file_path===s);re&&E(re.id)},[s,t]);const he=L.useMemo(()=>qk(t,te),[t,te]),pe=(re,Ne)=>{E(Ne.id)},Z=()=>{E(null),q(!1)},se=ie?d.jsx(bN,{node:ie,nodes:t,edges:r,onClose:Z,onWhatIf:o,onSelect:E,onOpenFile:v,pinned:m===ie.id,onPin:_,onIsolate:y?re=>{y(p===re?null:re)}:void 0}):null,me=re=>{F(Ne=>{const Ie=new Set(Ne);if(Ie.has(re)){if(Ie.size===1)return Ne;Ie.delete(re)}else Ie.add(re);return Ie})},ke=L.useMemo(()=>{const re=new Set;for(const Ne of t)re.add(_m(Ne.type));return re},[t]),ve=t.length-I.nodes.length;return d.jsxs("div",{className:"impact-graph",style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[d.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[d.jsxs("div",{className:"seg","aria-label":"Graph projection",children:[d.jsx("button",{type:"button","data-testid":"graph-view-2d",className:V==="2d"?"active":"","aria-pressed":V==="2d",onClick:()=>w("2d"),children:"2D map"}),d.jsx("button",{type:"button","data-testid":"graph-view-3d",className:V==="3d"?"active":"","aria-pressed":V==="3d",onClick:()=>w("3d"),children:"3D layers"})]}),d.jsxs("div",{className:"seg","aria-label":"Graph detail",children:[d.jsx("button",{type:"button","data-testid":"graph-detail-overview",className:W==="overview"?"active":"","aria-pressed":W==="overview",onClick:()=>A("overview"),children:"Overview"}),d.jsx("button",{type:"button","data-testid":"graph-detail-full",className:W==="full"?"active":"","aria-pressed":W==="full",onClick:()=>A("full"),children:"Full"})]}),d.jsx("div",{className:"seg","aria-label":"Graph families",children:["django","stitch","react"].filter(re=>ke.has(re)).map(re=>d.jsx("button",{type:"button","data-testid":`graph-family-${re}`,className:$.has(re)?"active":"","aria-pressed":$.has(re),onClick:()=>me(re),children:re},re))}),d.jsx("button",{type:"button",className:G?"chip-btn active":"chip-btn","data-testid":"graph-neighborhood",disabled:!b,onClick:()=>q(re=>!re),children:G?"Neighborhood":"Focus neighbors"}),p?d.jsx("button",{type:"button",className:"chip-btn active","data-testid":"graph-isolate-clear",onClick:()=>y==null?void 0:y(null),children:"Path isolate"}):null,d.jsxs("label",{className:"graph-search",children:[d.jsx("span",{className:"sr-only",children:"Search nodes"}),d.jsx("input",{"data-testid":"graph-search",placeholder:"Find a node",value:te,onChange:re=>{ee(re.target.value),K(!0)},onFocus:()=>K(!0),onBlur:()=>window.setTimeout(()=>K(!1),150)}),ne&&te.trim()&&he.length?d.jsx("ul",{className:"graph-search-hits","data-testid":"graph-search-hits",children:he.map(re=>d.jsx("li",{children:d.jsxs("button",{type:"button",onMouseDown:Ne=>Ne.preventDefault(),onClick:()=>{E(re.id),ee(""),K(!1)},children:[re.name,d.jsx("span",{className:"muted",children:io(re.type)})]})},re.id))}):null]}),d.jsxs("span",{className:"muted graph-count",children:[I.nodes.length," nodes · ",I.edges.length," edges",ve?` · ${ve} hidden`:""]})]}),d.jsx("div",{className:"graph-stage",children:V==="3d"?d.jsxs("div",{className:"graph-3d","data-testid":"graph-3d",children:[d.jsx("p",{className:"graph-3d-hint",children:"Architecture layers are stacked in depth (Django → stitch → React). Drag to orbit, scroll to zoom, click a node to inspect it."}),d.jsx(L.Suspense,{fallback:d.jsx("p",{className:"muted graph-3d-hint",children:"Loading 3D layers…"}),children:d.jsx(yN,{nodes:I.nodes,edges:I.edges,selectedId:b,neighborIds:U?I.neighborIds:mN,onSelect:re=>{E(re),re||q(!1)}})}),se]}):d.jsxs(pm,{children:[d.jsxs(sk,{nodes:oe,edges:fe,nodeTypes:wN,edgeTypes:kN,fitView:!1,minZoom:.25,nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,deleteKeyCode:null,onNodeClick:pe,onPaneClick:Z,proOptions:{hideAttribution:!1},"data-testid":"impact-graph",children:[d.jsx(NN,{topologyKey:z}),d.jsx(dk,{}),d.jsx(Rk,{pannable:!0,zoomable:!0,ariaLabel:"Impact graph overview",nodeColor:"var(--muted)",nodeStrokeColor:"transparent",nodeStrokeWidth:0,maskColor:"rgba(0, 0, 0, 0.45)",maskStrokeColor:"var(--accent)",maskStrokeWidth:1.4,bgColor:"var(--graph-bg)",style:{width:184,height:128}}),d.jsx(vk,{})]}),se]})})]})}function Sm(){const t=localStorage.getItem("loadpath.editor")||"auto";return t==="cursor"||t==="vscode"||t==="system"?t:"auto"}function EN(t){localStorage.setItem("loadpath.editor",t)}async function CN(t,r,o,s=Sm()){try{const a=await Re.openEditor(t,r,o??void 0,s);if(a.ok)return{ok:!0,message:`Opened ${r} in ${a.opened_with||"editor"}`};const u=a.urls||{},c=s==="vscode"?u.vscode:s==="cursor"?u.cursor:u.cursor||u.vscode;return c?(window.open(c,"_blank","noopener,noreferrer"),{ok:!0,message:`Opening ${r} via editor URL`}):{ok:!1,message:a.error||"Could not open editor"}}catch(a){return{ok:!1,message:a instanceof Error?a.message:String(a)}}}const Np=[{value:"HEAD",label:"HEAD",group:"preset"},{value:"HEAD~1",label:"HEAD~1",group:"preset"}],MN=["preset","branch","tag","commit"];function PN(t){var a;if(!(t!=null&&t.git))return[...Np];const r=((a=t.presets)!=null&&a.length?t.presets:Np.map(u=>u.value)).map(u=>({value:u,label:u,group:"preset"})),o=new Set(r.map(u=>u.value)),s=[...r];for(const u of t.branches||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.current?`${u.name} (current)`:u.name,detail:u.subject,group:"branch"}));for(const u of t.tags||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.name,detail:u.subject,group:"tag"}));for(const u of t.commits||[])o.has(u.sha)||(o.add(u.sha),s.push({value:u.sha,label:u.short,detail:u.subject,group:"commit"}));return s}function IN(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.value.toLowerCase().includes(o)||s.label.toLowerCase().includes(o)||(s.detail||"").toLowerCase().includes(o)):t}function RN(t){return MN.map(r=>({group:r,items:t.filter(o=>o.group===r)})).filter(r=>r.items.length>0)}function TN(t){return t==="preset"?"Common":t==="branch"?"Branches":t==="tag"?"Tags":"Recent commits"}function jp({value:t,onChange:r,placeholder:o,testId:s,menuTestId:a,refs:u,onNeedRefs:c}){const h=L.useId(),p=L.useRef(null),[y,x]=L.useState(!1),[v,m]=L.useState(null),[_,k]=L.useState(0),j=L.useMemo(()=>{const N=PN(u);return v===null?N:IN(N,v)},[u,v]),b=L.useMemo(()=>RN(j),[j]);L.useEffect(()=>{y&&c()},[y,c]),L.useEffect(()=>{k(0)},[v,y]);const E=()=>{x(!1),m(null)},R=N=>{r(N.value),E()},w=N=>{if(N.key==="ArrowDown"){if(N.preventDefault(),!y){x(!0);return}k(A=>Math.min(A+1,Math.max(j.length-1,0)))}else if(N.key==="ArrowUp"){if(N.preventDefault(),!y)return;k(A=>Math.max(A-1,0))}else if(N.key==="Enter"&&y){N.preventDefault();const A=j[_];A&&R(A)}else N.key==="Escape"&&y&&(N.preventDefault(),E())};return d.jsxs("div",{className:"combo",ref:p,onBlur:N=>{N.currentTarget.contains(N.relatedTarget)||E()},children:[d.jsxs("div",{className:"combo-row",children:[d.jsx("input",{"data-testid":s,value:t,placeholder:o,spellCheck:!1,role:"combobox","aria-expanded":y,"aria-controls":h,"aria-autocomplete":"list",onChange:N=>{r(N.target.value),y&&m(N.target.value)},onKeyDown:w}),d.jsx("button",{type:"button",className:"icon-btn combo-toggle","data-testid":`${s}-toggle`,"aria-label":"Show recent refs","aria-expanded":y,onMouseDown:N=>N.preventDefault(),onClick:()=>y?E():x(!0),children:d.jsx(k0,{})})]}),y?d.jsx("div",{className:"combo-menu",id:h,role:"listbox","data-testid":a,children:b.length===0?d.jsx("div",{className:"combo-empty muted",children:"No matching refs — the typed value is kept"}):b.map(N=>d.jsxs("div",{className:"combo-group",children:[d.jsx("div",{className:"combo-heading",children:TN(N.group)}),N.items.map(A=>{const $=j.indexOf(A);return d.jsxs("button",{type:"button",role:"option","aria-selected":$===_,className:$===_?"combo-option active":"combo-option","data-testid":`ref-option-${A.group}`,onMouseDown:F=>F.preventDefault(),onMouseEnter:()=>k($),onClick:()=>R(A),children:[d.jsx("span",{className:"combo-label",children:A.label}),A.detail?d.jsx("span",{className:"combo-detail",children:A.detail}):null]},`${A.group}:${A.value}`)})]},N.group))}):null]})}function LN({initialPath:t,onSelect:r,onClose:o}){const[s,a]=L.useState(null),[u,c]=L.useState(t),[h,p]=L.useState(null),[y,x]=L.useState(""),[v,m]=L.useState(!1),_=L.useRef(null),k=L.useRef(0),j=async w=>{const N=k.current+1;k.current=N,m(!0);try{const A=await Re.browse(w);if(k.current!==N)return;a(A),c(A.path),p(A.is_git?A.path:null),x("")}catch(A){if(k.current!==N)return;x(A instanceof Error?A.message:String(A))}finally{k.current===N&&m(!1)}};L.useEffect(()=>{var w,N;j(t),(w=_.current)==null||w.focus(),(N=_.current)==null||N.select()},[t]);const b=h||(s==null?void 0:s.path)||u,E=h&&h!==(s==null?void 0:s.path)?h.split(/[\\/]/).filter(Boolean).pop():s!=null&&s.is_git?"this repository":"this folder",R=w=>{w.key==="Escape"&&(w.preventDefault(),o())};return d.jsx("div",{className:"modal-backdrop","data-testid":"repo-explorer","data-overlay":"true",onClick:o,onKeyDown:R,children:d.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"explorer-title",onClick:w=>w.stopPropagation(),children:[d.jsxs("div",{className:"modal-head",children:[d.jsxs("div",{children:[d.jsx("h2",{id:"explorer-title",children:"Select repository"}),d.jsx("p",{className:"muted",children:"Browse to a git root, or paste the full path."})]}),d.jsx("button",{type:"button",className:"btn ghost","data-testid":"explorer-cancel",onClick:o,children:"Cancel"})]}),d.jsxs("form",{className:"explorer-path",onSubmit:w=>{w.preventDefault(),j(u)},children:[d.jsx("input",{ref:_,"data-testid":"explorer-path",value:u,onChange:w=>c(w.target.value),spellCheck:!1,"aria-label":"Directory path"}),d.jsx("button",{type:"button",className:"btn",disabled:!(s!=null&&s.parent),onClick:()=>(s==null?void 0:s.parent)&&void j(s.parent),children:"Up"}),d.jsx("button",{type:"button",className:"btn",onClick:()=>s&&void j(s.home),children:"Home"}),d.jsx("button",{type:"submit",className:"btn",children:"Go"})]}),y?d.jsx("div",{className:"error",role:"alert",children:y}):null,d.jsx("div",{className:"explorer-list",role:"listbox","aria-label":"Folders","aria-busy":v,children:s!=null&&s.entries.length?s.entries.map(w=>{const N=h===w.path;return d.jsxs("button",{type:"button",role:"option","aria-selected":N,className:N?"explorer-row active":"explorer-row","data-testid":"explorer-entry","data-path":w.path,onClick:()=>p(w.path),onDoubleClick:()=>void j(w.path),children:[d.jsx(Mp,{}),d.jsx("span",{className:"explorer-name",children:w.name}),w.is_git?d.jsx("span",{className:"chip git-badge",children:"git"}):null]},w.path)}):d.jsx("div",{className:"muted explorer-empty",children:v?"Loading…":"No folders here"})}),d.jsxs("div",{className:"modal-foot",children:[d.jsx("span",{className:"muted explorer-current",title:b,children:b}),d.jsxs("button",{type:"button",className:"btn primary","data-testid":"explorer-use",disabled:!b,onClick:()=>b&&r(b),children:["Use ",E]})]})]})})}const AN={scan:{start:0,end:20},extract:{start:20,end:88},boot:{start:88,end:94},stitch:{start:94,end:99},skipped:{start:100,end:100},done:{start:100,end:100}},$N=new Set(["scan","extract","boot","stitch"]);function zN(t){const r=t.phase||"";if(!r||r==="idle")return null;const o=AN[r];if(!o)return null;if(o.start===o.end)return o.end;const s=t.total||0;if(s<=0)return o.start;const a=Math.min(1,Math.max(0,(t.done||0)/s));return Math.round(o.start+(o.end-o.start)*a)}function DN(t){return!t.phase||t.phase==="idle"?null:typeof t.percent=="number"&&Number.isFinite(t.percent)?Math.max(0,Math.min(100,Math.round(t.percent))):zN(t)}const Gl=[{id:"obsidian",label:"Obsidian",group:"dark"},{id:"nord",label:"Nord",group:"dark"},{id:"solarized-dark",label:"Solarized Dark",group:"dark"},{id:"forest",label:"Forest",group:"dark"},{id:"rose",label:"Rose Pine",group:"dark"},{id:"amber",label:"Midnight Amber",group:"dark"},{id:"volcano",label:"Volcano",group:"dark"},{id:"lavender",label:"Lavender",group:"dark"},{id:"neon-noir",label:"Neon Noir",group:"dark"},{id:"synthwave",label:"Synthwave",group:"dark"},{id:"phosphor",label:"Phosphor",group:"dark"},{id:"aurora",label:"Aurora",group:"dark"},{id:"biolume",label:"Biolume",group:"dark"},{id:"carbon",label:"Carbon",group:"dark"},{id:"paper",label:"Paper",group:"light"},{id:"solarized-light",label:"Solarized Light",group:"light"},{id:"seafoam",label:"Seafoam",group:"light"},{id:"high-contrast",label:"High Contrast",group:"light"},{id:"sakura",label:"Sakura",group:"light"},{id:"citrus",label:"Citrus",group:"light"},{id:"peach",label:"Peach Fuzz",group:"light"},{id:"candy",label:"Cotton Candy",group:"light"},{id:"sky",label:"Clear Sky",group:"light"},{id:"coral",label:"Coral Reef",group:"light"}],ON="obsidian",km="loadpath.theme";function FN(t){return Gl.some(r=>r.id===t)}function Nm(){try{const t=localStorage.getItem(km)||"";if(FN(t))return t}catch{}return ON}function HN(t){var r;return((r=Gl.find(o=>o.id===t))==null?void 0:r.group)==="light"?"light":"dark"}function jm(t){document.documentElement.dataset.theme=t,document.documentElement.style.colorScheme=HN(t);try{localStorage.setItem(km,t)}catch{}}const ec=[{id:"review",label:"Review",testId:"tab-review",shortcut:"1",icon:v0},{id:"architecture",label:"Architecture",testId:"tab-architecture",shortcut:"2",icon:x0},{id:"graph",label:"Impact graph",testId:"tab-graph",shortcut:"3",icon:w0},{id:"prs",label:"Pull requests",testId:"tab-prs",shortcut:"4",icon:_0},{id:"settings",label:"Settings",testId:"tab-settings",shortcut:"5",icon:S0}];function tc(t,r,o){let s;try{s=new URL(t)}catch{return}if(s.protocol!=="https:"||s.username||s.password)return;const a=s.hostname.toLowerCase();a!==r&&!a.endsWith(`.${r}`)||s.pathname.startsWith(o)&&window.open(s.toString(),"_blank","noopener,noreferrer")}function BN(){var fo,Si,ho,po,go,ki,Yr,ln,an,un;const[t,r]=L.useState("review"),[o,s]=L.useState(localStorage.getItem("loadpath.repo")||""),[a,u]=L.useState(localStorage.getItem("loadpath.base")||"HEAD~1"),[c,h]=L.useState(localStorage.getItem("loadpath.head")||"HEAD"),[p,y]=L.useState(null),[x,v]=L.useState(null),[m,_]=L.useState(null),[k,j]=L.useState([]),[b,E]=L.useState("review"),[R,w]=L.useState(""),[N,A]=L.useState(""),[$,F]=L.useState(null),[G,q]=L.useState(!1),[te,ee]=L.useState(!1),[ne,K]=L.useState(""),[C,V]=L.useState({}),[W,U]=L.useState([]),[M,D]=L.useState([]),[H,I]=L.useState(localStorage.getItem("loadpath.scmRepo")||""),[z,ie]=L.useState(localStorage.getItem("loadpath.provider")||"github"),[oe,fe]=L.useState(localStorage.getItem("loadpath.prNumber")||""),[he,pe]=L.useState(localStorage.getItem("loadpath.dirty")==="1"),[Z,se]=L.useState(0),[me,ke]=L.useState(""),[ve,re]=L.useState(Nm),[Ne,Ie]=L.useState(!1),[Le,$e]=L.useState(!1),[lt,at]=L.useState(!1),[ut,Ge]=L.useState(null),[wt,Gt]=L.useState(null),[gt,mt]=L.useState(localStorage.getItem("loadpath.testOverlay")==="1"),[Ct,ct]=L.useState(null),[et,Dn]=L.useState(localStorage.getItem("loadpath.watch")==="1"),[Mt,kn]=L.useState([]),[oo,On]=L.useState(null),[gi,lr]=L.useState(null),[zr,Fn]=L.useState(null),[Dr,ar]=L.useState(()=>{try{return!!(localStorage.getItem("loadpath.lastReviewId")&&(localStorage.getItem("loadpath.repo")||"").trim())}catch{return!1}}),[ur,Ft]=L.useState(null),[dt,Hn]=L.useState(null),[Bn,Nn]=L.useState(!1),[Vn,jn]=L.useState(!1),it=L.useRef(o);it.current=o;const cr=L.useRef(he);cr.current=he;const bn=L.useRef(!1);bn.current=Le;const Pt=L.useRef(""),nn=L.useRef(""),mi=P=>{re(P),jm(P)},Ze=L.useRef(""),He=P=>{Ze.current=P,A(P)},En=P=>{let Y=0,ce=!1;F(0);const Ee=()=>{Re.indexProgress(P).then(Pe=>{if(!Ze.current)return;if(Pe.phase&&Pe.phase!=="idle"&&Pe.message&&He(Pe.message),$N.has(Pe.phase))ce=!0;else if(!ce)return;const gr=DN(Pe);gr!=null&&(Pe.phase==="scan"&&!Pe.done?Y=gr:Y=Math.max(Y,gr),F(Y))}).catch(()=>{})};Ee();const Me=window.setInterval(Ee,250);return()=>{window.clearInterval(Me),F(null)}};L.useEffect(()=>{Re.settings().then(V).catch(()=>{}).finally(()=>Ie(!0)),Re.repos().then(P=>j(P.repos)).catch(()=>{})},[]);const Wn=()=>o.trim()?!0:(w("Point at a local repository path first."),!1);L.useEffect(()=>{if(t!=="architecture"||!o.trim())return;const P=o;let Y=!1;return nn.current!==P&&Yn(P),Re.config(P).then(ce=>{!Y&&it.current===P&&lr(ce)}).catch(()=>{}),Re.architectureHealth(P).then(ce=>{!Y&&it.current===P&&Fn(ce)}).catch(()=>{}),()=>{Y=!0}},[t,o]);const rn=P=>{it.current=P,s(P),localStorage.setItem("loadpath.repo",P),P.trim()!==Pt.current&&(Pt.current="",Ft(null))},Or=L.useCallback(P=>{const Y=(P??it.current).trim();return!Y||Pt.current===Y?Promise.resolve():(Pt.current=Y,Re.gitRefs(Y).then(ce=>{it.current.trim()===Y&&Ft(ce)}).catch(()=>{Pt.current===Y&&(Pt.current="",Ft(null))}))},[]),on=(P,Y)=>{u(P),h(Y),localStorage.setItem("loadpath.base",P),localStorage.setItem("loadpath.head",Y)},It=(P,Y,ce)=>{ie(P),I(Y),localStorage.setItem("loadpath.provider",P),localStorage.setItem("loadpath.scmRepo",Y),ce!==void 0&&(fe(ce),localStorage.setItem("loadpath.prNumber",ce))},Xt=P=>{y(P),se(0),Ge(wt&&P.nodes.some(Y=>Y.id===wt)?wt:null),ct(null),On(null),P.what_if||(v(P),P.id&&localStorage.setItem("loadpath.lastReviewId",P.id))},Un=async P=>{try{const Y=await Re.reviews(P);kn(Y.reviews)}catch{kn([])}},yi=async P=>{try{Fn(await Re.architectureHealth(P))}catch{Fn(null)}},vi=P=>P==="github"?!!C.github_token_set:P==="gitlab"?!!C.gitlab_token_set:!!C.bitbucket_token_set,Rt=L.useCallback(async(P=z)=>{var Y;try{const ce=await Re.scmRepos(P);D(ce.repos),(Y=ce.user)!=null&&Y.login&&V(Ee=>({...Ee,...P==="github"?{github_user:ce.user.login}:P==="gitlab"?{gitlab_user:ce.user.login}:{bitbucket_user:ce.user.login}}))}catch{D([])}},[z]);L.useEffect(()=>{if(t!=="prs")return;let P=!1;return Rt(z).catch(()=>{P||D([])}),()=>{P=!0}},[t,z,Rt]),L.useEffect(()=>{if(!dt)return;let P=!1,Y=0;const ce=async()=>{try{const Ee=await Re.githubOAuthPoll(dt.flow_id);if(P)return;if(Ee.status==="complete"){Hn(null);const Me=await Re.settings();V(Me),K(Ee.user?`Signed in to GitHub as ${Ee.user}`:"Signed in to GitHub"),Rt("github");return}if(Ee.status==="pending"||Ee.status==="slow_down"){Y=window.setTimeout(ce,Math.max(Ee.interval||dt.interval,5)*1e3);return}Hn(null),w(Ee.status==="denied"?"GitHub sign-in was denied.":"GitHub sign-in expired. Try again.")}catch(Ee){if(P)return;Hn(null),w(Ee instanceof Error?Ee.message:String(Ee))}};return Y=window.setTimeout(ce,Math.max(dt.interval,5)*1e3),()=>{P=!0,window.clearTimeout(Y)}},[dt,Rt]),L.useEffect(()=>{if(!Bn)return;let P=!1,Y=0;const ce=Date.now(),Ee=async()=>{try{const Me=await Re.oauthStatus();if(P)return;if(Me.bitbucket.connected){Nn(!1);const Pe=await Re.settings();V(Pe),K(Me.bitbucket.user?`Signed in to Bitbucket as ${Me.bitbucket.user}`:"Signed in to Bitbucket"),Rt("bitbucket");return}if(Date.now()-ce>18e4){Nn(!1),w("Bitbucket sign-in timed out. Finish in the browser, or try again.");return}Y=window.setTimeout(Ee,1500)}catch(Me){if(P)return;Nn(!1),w(Me instanceof Error?Me.message:String(Me))}};return Y=window.setTimeout(Ee,1500),()=>{P=!0,window.clearTimeout(Y)}},[Bn,Rt]),L.useEffect(()=>{if(!Vn)return;let P=!1,Y=0;const ce=Date.now(),Ee=async()=>{try{const Me=await Re.oauthStatus();if(P)return;if(Me.gitlab.connected){jn(!1);const Pe=await Re.settings();V(Pe),K(Me.gitlab.user?`Signed in to GitLab as ${Me.gitlab.user}`:"Signed in to GitLab"),Rt("gitlab");return}if(Date.now()-ce>18e4){jn(!1),w("GitLab sign-in timed out. Finish in the browser, or try again.");return}Y=window.setTimeout(Ee,1500)}catch(Me){if(P)return;jn(!1),w(Me instanceof Error?Me.message:String(Me))}};return Y=window.setTimeout(Ee,1500),()=>{P=!0,window.clearTimeout(Y)}},[Vn,Rt]);const Yn=async(P=o,Y=!1)=>{if(!P.trim())return null;nn.current=P,ee(!0);try{const ce=await Re.architecture(P,!1);it.current===P&&_(ce);const Ee=Re.architectureGraph(P).then(Me=>{it.current===P&&_(Pe=>Pe&&{...Pe,nodes:Me.nodes,edges:Me.edges,graph_pending:!1})});return Ee.catch(()=>{_(Me=>Me&&it.current===P?{...Me,graph_pending:!1}:Me)}).finally(()=>{nn.current===P&&ee(!1)}),Y&&await Ee,ce}catch(ce){throw it.current===P&&ee(!1),ce}},Fr=async P=>{const Y=P.trim();if(!(!Y||Y===it.current)){if(Ze.current){w("Wait for the current job to finish before switching workspace.");return}w(""),K(""),y(null),v(null),_(null),E("architecture"),rn(Y),q(!0),He(`Loading ${y0(Y)}…`);try{await Promise.all([Yn(Y),Or(Y)])}catch(ce){it.current===Y&&w(ce instanceof Error?ce.message:String(ce))}finally{it.current===Y&&(He(""),q(!1))}}},Gn=async()=>{if(Ze.current||!Wn())return;w(""),K(""),He("Tracing load path…"),rn(o),on(a,c);const P=En(o);try{const Y=await Re.review(o,a,c,!0,cr.current);Xt(Y),E("review"),r("review"),await Re.repos().then(ce=>j(ce.repos)).catch(()=>{}),await Promise.all([Yn(o),Un(o),yi(o)])}catch(Y){w(Y instanceof Error?Y.message:String(Y))}finally{P(),He("")}},dr=async(P=!0)=>{if(Ze.current||!Wn())return;w(""),K(""),He(P?"Indexing…":"Full reindex…"),rn(o);const Y=En(o);try{await Re.index(o,P);const ce=await Yn(o);await Re.repos().then(Ee=>j(Ee.repos)).catch(()=>{}),ce!=null&&ce.indexed&&(E("architecture"),r("architecture"))}catch(ce){w(ce instanceof Error?ce.message:String(ce))}finally{Y(),He("")}},Ve=async()=>{if(!Ze.current&&Wn()){w(""),K(""),He("Detecting layout…"),rn(o);try{const P=await Re.init(o);K(P.message),await Re.repos().then(Y=>j(Y.repos)).catch(()=>{})}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},so=async()=>{if(p!=null&&p.markdown)try{await navigator.clipboard.writeText(p.markdown),K("Copied markdown brief")}catch(P){w(P instanceof Error?P.message:String(P))}},Hr=async()=>{if(!Ze.current){if(p!=null&&p.what_if){w("What-if walks are hypothetical — they are not posted to a pull request. Restore the git-range walk first.");return}if(!(p!=null&&p.markdown)||!H||!oe){w("Pick a pull request first (Pull requests tab), then post the brief.");return}He("Posting Loadpath brief…");try{const P=await Re.postComment(z,H,Number(oe),p.markdown);K(P.updated?"Updated the Loadpath PR comment":"Posted the Loadpath PR comment")}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},xi=async()=>{if(!Ze.current){w(""),He("Fetching pull requests…");try{const P=await Re.prs(z,H,"open",o.trim()||void 0);U(P.pull_requests);const Y=M.find(ce=>ce.slug.toLowerCase()===H.trim().toLowerCase());Y!=null&&Y.local_path&&rn(Y.local_path)}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},fr=async()=>{w("");try{const P=await Re.githubOAuthStart();Hn(P),tc(P.verification_uri_complete,"github.com","/login/device")}catch(P){w(P instanceof Error?P.message:String(P))}},lo=async()=>{w("");try{const P=await Re.bitbucketOAuthStart();Nn(!0),tc(P.authorize_url,"bitbucket.org","/site/oauth2/authorize")}catch(P){Nn(!1),w(P instanceof Error?P.message:String(P))}},wi=async()=>{w("");try{const P=await Re.gitlabOAuthStart();jn(!0),tc(P.authorize_url,new URL(P.authorize_url).hostname,"/oauth/authorize")}catch(P){jn(!1),w(P instanceof Error?P.message:String(P))}},Cn=async P=>{if(!(Ze.current||!o.trim())){w(""),He("Walking what-if path…");try{const Y=await Re.whatIf(o,P);K(`${Y.title} — ${Y.confidence.level} · ${(Y.sinks||[]).length} sinks`),Xt({...Y,markdown:Y.markdown||"",index:Y.index||(p==null?void 0:p.index),workspace:Y.workspace||(p==null?void 0:p.workspace)}),E("review"),r("review")}catch(Y){w(Y instanceof Error?Y.message:String(Y))}finally{He("")}}},_t=()=>{if(x){Xt(x),E("review"),r("review"),K("Restored the last git-range walk");return}y(null),se(0),Ge(null),ct(null),On(null),E("architecture"),r("architecture"),K("")},ao=async P=>{var Me;if(Ze.current)return;It(P.provider,P.repo,String(P.number));const Y=M.find(Pe=>Pe.slug.toLowerCase()===P.repo.toLowerCase());Y!=null&&Y.local_path&&rn(Y.local_path),w(""),He(`Fetching ${P.provider} #${P.number}…`);const ce=(Y==null?void 0:Y.local_path)||o,Ee=ce?En(ce):()=>{};try{const Pe=await Re.reviewPr(P.provider,P.repo,P.number,(Y==null?void 0:Y.local_path)||o||void 0);Xt(Pe),Pe.pull_request&&typeof Pe.pull_request.repo_path=="string"&&rn(Pe.pull_request.repo_path),on(String(Pe.base||P.target_branch),String(Pe.head||P.source_branch)),E("review"),r("review"),typeof((Me=Pe.pull_request)==null?void 0:Me.repo_path)=="string"&&Un(Pe.pull_request.repo_path)}catch(Pe){on(P.base_sha||P.target_branch,P.head_sha||P.source_branch),r("review"),w(Pe instanceof Error?Pe.message:String(Pe))}finally{Ee(),He("")}},yt=async P=>{w("");try{V(await Re.oauthDisconnect(P)),z===P&&D([]),K(`Disconnected ${P}`)}catch(Y){w(Y instanceof Error?Y.message:String(Y))}},uo=async P=>{P.preventDefault();const Y=new FormData(P.currentTarget),ce={github_token:String(Y.get("github_token")||""),github_oauth_client_id:String(Y.get("github_oauth_client_id")||""),github_host:String(Y.get("github_host")||""),gitlab_token:String(Y.get("gitlab_token")||""),gitlab_host:String(Y.get("gitlab_host")||""),gitlab_oauth_client_id:String(Y.get("gitlab_oauth_client_id")||""),gitlab_oauth_client_secret:String(Y.get("gitlab_oauth_client_secret")||""),bitbucket_token:String(Y.get("bitbucket_token")||""),bitbucket_username:String(Y.get("bitbucket_username")||""),bitbucket_oauth_client_id:String(Y.get("bitbucket_oauth_client_id")||""),bitbucket_oauth_client_secret:String(Y.get("bitbucket_oauth_client_secret")||""),ai_provider:String(Y.get("ai_provider")||"none"),ai_api_key:String(Y.get("ai_api_key")||""),ai_model:String(Y.get("ai_model")||""),ai_base_url:String(Y.get("ai_base_url")||"")},Ee=k.length?{...ce,workspaces:k.map(Me=>({path:Me.path,name:Me.name}))}:ce;try{V(await Re.saveSettings(Ee)),K("Settings saved on this machine")}catch(Me){w(Me instanceof Error?Me.message:String(Me))}},co=async()=>{if(!(!p||Ze.current)){He("Residual analysis…");try{const P=await Re.residual(p);ke(P.note)}catch(P){w(P instanceof Error?P.message:String(P))}finally{He("")}}},Br=L.useRef(Gn);Br.current=Gn;const Mn=L.useRef(t);Mn.current=t;const Xn=L.useRef(!1);Xn.current=lt;const Pn=L.useRef(p);Pn.current=p;const qt=L.useRef(Z);qt.current=Z,L.useEffect(()=>{const P=localStorage.getItem("loadpath.lastReviewId"),Y=(localStorage.getItem("loadpath.repo")||"").trim();if(!P||!Y){ar(!1);return}let ce=!1;return Re.getReview(Y,P).then(Ee=>{ce||(Xt(Ee),on(Ee.base||localStorage.getItem("loadpath.base")||"HEAD~1",Ee.head||localStorage.getItem("loadpath.head")||"HEAD"),Un(Y),yi(Y))}).catch(()=>{}).finally(()=>{ce||ar(!1)}),()=>{ce=!0}},[]);const Vr=L.useRef("");L.useEffect(()=>{if(!et||!o.trim())return;let P=!1;const Y=async()=>{try{const Ee=await Re.workspaceStatus(o);if(P)return;Vr.current&&Ee.fingerprint!==Vr.current&&!Ze.current&&(pe(!0),cr.current=!0,localStorage.setItem("loadpath.dirty","1"),Br.current()),Vr.current=Ee.fingerprint}catch{}};Y();const ce=window.setInterval(Y,2e3);return()=>{P=!0,window.clearInterval(ce)}},[et,o]),L.useEffect(()=>{const P=Y=>{var Me;if((Y.metaKey||Y.ctrlKey)&&Y.key.toLowerCase()==="k"){Y.preventDefault(),at(Pe=>!Pe);return}if(Xn.current){Y.key==="Escape"&&(Y.preventDefault(),at(!1));return}if(bn.current){Y.key==="Escape"&&(Y.preventDefault(),$e(!1));return}const ce=Y.target;if(ce&&(ce.tagName==="INPUT"||ce.tagName==="TEXTAREA"||ce.tagName==="SELECT"||ce.isContentEditable)){Y.key==="Escape"&&ce.blur();return}if(Y.key==="Escape"){w(""),K(""),Ge(wt),ct(null);return}if(Y.key==="j"||Y.key==="k"){const Pe=((Me=Pn.current)==null?void 0:Me.read_order)||[];if(!Pe.length)return;Y.preventDefault();const mo=qt.current,gr=Y.key==="j"?Math.min(Pe.length-1,mo+1):Math.max(0,mo-1);se(gr);return}const Ee=ec.find(Pe=>Pe.shortcut===Y.key);if(Ee&&!Y.metaKey&&!Y.ctrlKey&&!Y.altKey&&r(Ee.id),(Y.metaKey||Y.ctrlKey)&&Y.key==="Enter"){if(Mn.current==="settings"||Mn.current==="prs"||Ze.current)return;Y.preventDefault(),Br.current()}};return window.addEventListener("keydown",P),()=>window.removeEventListener("keydown",P)},[wt]);const Wr=async(P,Y)=>{if(!o.trim())return;const ce=await CN(o,P,Y);ce.ok?K(ce.message):w(ce.message)},hr=async()=>{if(p)try{const P=await Re.exportHtml(p),Y=URL.createObjectURL(P),ce=document.createElement("a");ce.href=Y,ce.download=`loadpath-${(p.id||"review").slice(0,8)}.html`,ce.click(),URL.revokeObjectURL(Y),K("Saved HTML brief")}catch(P){w(P instanceof Error?P.message:String(P))}},Ur=async P=>{if(o.trim()){He("Loading stored review…");try{const Y=await Re.getReview(o,P);Xt(Y),on(Y.base||a,Y.head||c),E("review"),r("review");const ce=Mt.findIndex(Me=>Me.id===P),Ee=ce>=0?Mt[ce+1]:void 0;if(Ee)try{On(await Re.reviewDiff(o,P,Ee.id))}catch{On(null)}}catch(Y){w(Y instanceof Error?Y.message:String(Y))}finally{He("")}}},sn={selectedId:ut,onSelect:Ge,nodeRoles:p==null?void 0:p.node_roles,testOverlay:gt,isolateSource:Ct,onIsolate:ct,repoPath:o,onOpenFile:Wr,pinnedId:wt,onPin:Gt},qn=[{id:"review",group:"Run",label:"Review this range",hint:"⌘/Ctrl+Enter",run:()=>void Gn()},...p!=null&&p.what_if?[{id:"exit-whatif",group:"Review",label:x?"Back to git-range walk":"Exit what-if walk",run:_t}]:[],{id:"index",group:"Run",label:"Index repository",run:()=>void dr(!0)},{id:"watch",group:"Run",label:et?"Stop watching working tree":"Watch working tree",run:()=>{const P=!et;Dn(P),localStorage.setItem("loadpath.watch",P?"1":"0")}},{id:"tests",group:"Graph",label:gt?"Hide test overlay":"Show test overlay",run:()=>{const P=!gt;mt(P),localStorage.setItem("loadpath.testOverlay",P?"1":"0")}},{id:"export",group:"Review",label:"Export HTML brief",run:()=>void hr()},...ec.map(P=>({id:`tab-${P.id}`,group:"Tabs",label:`Go to ${P.label}`,hint:P.shortcut,run:()=>r(P.id)})),...((p==null?void 0:p.nodes)||[]).slice(0,30).map(P=>({id:`node-${P.id}`,group:"Nodes",label:P.name,hint:io(P.type),run:()=>{Ge(P.id),r("graph")}})),...Mt.slice(0,12).map(P=>({id:`hist-${P.id}`,group:"History",label:P.title||P.id,hint:`${P.level||""} ${P.created_at||""}`.trim(),run:()=>void Ur(P.id)}))],_i=L.useMemo(()=>b==="architecture"?(m==null?void 0:m.nodes)??[]:(p==null?void 0:p.nodes)??[],[b,m,p]),pr=L.useMemo(()=>b==="architecture"?(m==null?void 0:m.edges)??[]:(p==null?void 0:p.edges)??[],[b,m,p]),Fe=p!=null&&p.index?`${p.index.counts.nodes} nodes · ${p.index.counts.edges} edges`:m!=null&&m.indexed?`${m.counts.nodes} nodes · ${m.counts.edges} edges`:"Not indexed",vs=((p==null?void 0:p.findings)||[]).filter(P=>!P.waived);return d.jsxs("div",{className:"app",children:[d.jsx("a",{className:"skip",href:"#main",children:"Skip to content"}),d.jsxs("nav",{className:"rail","data-testid":"rail","aria-label":"Primary",children:[d.jsxs("div",{className:"brand",children:[d.jsx("div",{className:"brand-mark",children:"Loadpath"}),d.jsx("div",{className:"brand-sub",children:"Load-path review"})]}),ec.map(P=>{const Y=P.icon,ce=t===P.id;return d.jsxs("button",{type:"button","data-testid":P.testId,className:ce?"nav-item active":"nav-item","aria-current":ce?"page":void 0,"aria-label":P.label,onClick:()=>r(P.id),children:[d.jsx(Y,{}),d.jsx("span",{children:P.label})]},P.id)}),d.jsxs("div",{className:"theme-pick",children:[d.jsx("label",{htmlFor:"theme-select",children:"Theme"}),d.jsx("select",{id:"theme-select","data-testid":"theme-select",value:ve,onChange:P=>mi(P.target.value),children:["dark","light"].map(P=>d.jsx("optgroup",{label:P==="dark"?"Dark":"Light",children:Gl.filter(Y=>Y.group===P).map(Y=>d.jsx("option",{value:Y.id,children:Y.label},Y.id))},P))})]}),d.jsxs("div",{className:"rail-foot",children:[d.jsx("div",{className:"muted",role:"status",children:N||Fe}),d.jsxs("div",{className:"kbd-hint",children:[d.jsx("kbd",{children:"1"}),"–",d.jsx("kbd",{children:"5"})," tabs · ",d.jsx("kbd",{children:"⌘"}),d.jsx("kbd",{children:"K"})," palette · ",d.jsx("kbd",{children:"j"}),"/",d.jsx("kbd",{children:"k"})," read order"]})]})]}),d.jsxs("div",{className:"main",id:"main",children:[N?d.jsxs("div",{className:$!=null?"progress determinate":"progress",role:$!=null?"progressbar":"status","aria-label":N,"aria-live":"polite","aria-busy":"true","aria-valuemin":$!=null?0:void 0,"aria-valuemax":$!=null?100:void 0,"aria-valuenow":$??void 0,"data-testid":"progress",children:[d.jsx("i",{style:$!=null?{width:`${$}%`}:void 0}),d.jsx("span",{className:"sr-only",children:N})]}):null,d.jsxs("header",{className:"topbar","data-testid":"topbar",children:[k.length>0?d.jsxs("label",{className:"field workspace",children:[d.jsx("span",{children:"Workspace"}),d.jsxs("select",{"data-testid":"workspace-select",value:k.some(P=>P.path===o)?o:"",disabled:!!N,"aria-busy":G,onChange:P=>{P.target.value&&Fr(P.target.value)},children:[d.jsx("option",{value:"",children:"Indexed repos…"}),k.map(P=>d.jsxs("option",{value:P.path,children:[P.name,P.indexed?` (${P.counts.nodes})`:""]},P.path))]})]}):null,d.jsxs("label",{className:"field path",children:[d.jsx("span",{children:"Repository"}),d.jsxs("div",{className:"path-row",children:[d.jsx("input",{"data-testid":"repo-path",placeholder:"Local monorepo path",value:o,onChange:P=>{const Y=P.target.value;s(Y),Y.trim()!==Pt.current&&(Pt.current="",Ft(null))},spellCheck:!1}),d.jsx("button",{type:"button",className:"icon-btn","data-testid":"btn-browse-repo","aria-label":"Browse for a local repository",onClick:()=>$e(!0),children:d.jsx(Mp,{})})]})]}),d.jsxs("label",{className:"field ref",children:[d.jsx("span",{children:"Base"}),d.jsx(jp,{testId:"base-ref",menuTestId:"base-ref-menu",value:a,onChange:P=>on(P,c),placeholder:"base",refs:ur,onNeedRefs:Or})]}),d.jsxs("label",{className:"field ref",children:[d.jsx("span",{children:"Head"}),d.jsx(jp,{testId:"head-ref",menuTestId:"head-ref-menu",value:c,onChange:P=>on(a,P),placeholder:"head",refs:ur,onNeedRefs:Or})]}),d.jsxs("label",{className:"field dirty",children:[d.jsx("span",{children:"Working tree"}),d.jsx("button",{type:"button",className:he?"chip-btn active":"chip-btn","data-testid":"btn-dirty","aria-pressed":he,onClick:()=>{const P=!he;pe(P),localStorage.setItem("loadpath.dirty",P?"1":"0")},children:he?"Include uncommitted":"Committed range"})]}),d.jsxs("label",{className:"field dirty",children:[d.jsx("span",{children:"Watch"}),d.jsx("button",{type:"button",className:et?"chip-btn active":"chip-btn","data-testid":"btn-watch","aria-pressed":et,onClick:()=>{const P=!et;Dn(P),localStorage.setItem("loadpath.watch",P?"1":"0")},children:et?"Watching":"Paused"})]}),p?d.jsxs("div",{className:`merge-box compact ${p.confidence.level}`,"data-testid":"merge-box",children:[d.jsx("div",{className:`level ${p.confidence.level}`,children:p.confidence.level.toUpperCase()}),d.jsxs("div",{className:"muted",children:[p.what_if?"what-if · ":"",p.confidence.covered_sinks,"/",p.confidence.sinks," sinks"]})]}):null,d.jsxs("div",{className:"topbar-actions",children:[d.jsx("button",{type:"button","data-testid":"btn-init",disabled:!!N,onClick:Ve,children:"Draft config"}),d.jsx("button",{type:"button","data-testid":"btn-index",disabled:!!N,onClick:()=>dr(!0),children:"Index"}),d.jsx("button",{type:"button","data-testid":"btn-review",className:"btn primary",disabled:!!N,onClick:Gn,children:"Review"})]})]}),d.jsxs("div",{className:"alerts",children:[R?d.jsxs("div",{className:"error","data-testid":"error",role:"alert",children:[d.jsx("span",{children:R}),d.jsx("button",{type:"button",className:"dismiss",onClick:()=>w(""),"aria-label":"Dismiss error",children:"×"})]}):null,ne?d.jsxs("div",{className:"banner","data-testid":"status-note",children:[d.jsx("span",{children:ne}),d.jsx("button",{type:"button",className:"dismiss",onClick:()=>K(""),"aria-label":"Dismiss",children:"×"})]}):null,((fo=p==null?void 0:p.index)!=null&&fo.stale||m!=null&&m.stale)&&(t==="review"||t==="architecture")?d.jsx("div",{className:"banner stale","data-testid":"index-stale",children:"Index is stale — files changed since the last extract. Index again before trusting this walk."}):null,((Si=p==null?void 0:p.index)==null?void 0:Si.django_boot)==="failed"||(m==null?void 0:m.django_boot)==="failed"?d.jsx("div",{className:"banner warn","data-testid":"django-boot-failed",children:((ho=p==null?void 0:p.index)==null?void 0:ho.django_boot_detail)||(m==null?void 0:m.django_boot_detail)||"django.setup() failed"}):null,(po=p==null?void 0:p.workspace)!=null&&po.dirty_overlaps_review&&t==="review"?d.jsxs("div",{className:"banner warn","data-testid":"dirty-tree",children:["Uncommitted files overlap this review: ",(p.workspace.dirty_overlap||[]).slice(0,6).join(", ")]}):null,p!=null&&p.what_if?d.jsxs("div",{className:"banner whatif","data-testid":"whatif-banner",children:[d.jsxs("span",{children:["Hypothetical walk from"," ",d.jsx("strong",{children:((go=p.node)==null?void 0:go.name)||"this node"}),". Loadpath ignored Base/Head and asked which sinks would feel this node change — not a filter of the current map."]}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-exit-whatif",onClick:_t,children:x?"Back to git range":"Back to architecture"})]}):null,G?d.jsx("div",{className:"banner","data-testid":"workspace-loading",children:N||"Loading workspace…"}):null]}),d.jsxs("div",{className:"stage","aria-busy":G||te,children:[t==="review"&&d.jsxs("div",{className:"content","data-testid":"review-layout",children:[d.jsx("aside",{className:"brief","data-testid":"brief",children:p?d.jsx(VN,{review:p,findings:vs,aiNote:me,busy:!!N,tourIndex:Z,onTour:se,onAskAi:co,onCopy:so,onPost:Hr,onSelect:Ge,onOpenFile:Wr,onExport:hr,history:Mt,diff:oo,onReopen:Ur,onWaiver:(P,Y)=>{o.trim()&&Re.addWaiver(o,P,Y||void 0,"from review").then(ce=>{lr(ce),K(`Waived ${P} in loadpath.yml`)})}}):Dr?d.jsxs("div",{className:"empty","data-testid":"review-restoring",children:[d.jsx("h2",{children:"Restoring last review"}),d.jsx("p",{children:"Loading the walk this machine stored last time Loadpath was open."})]}):d.jsxs("div",{className:"empty","data-testid":"review-empty",children:[d.jsx("h2",{children:"Trace the force of this diff"}),d.jsx("p",{children:"The graph is the architecture. The brief is where this change travels — not a hunk list."}),d.jsxs("ol",{children:[d.jsx("li",{children:"Point at a Django + React monorepo, or pick an indexed workspace."}),d.jsxs("li",{children:["Index it. Missing ",d.jsx("code",{children:"loadpath.yml"})," is drafted from ",d.jsx("code",{children:"manage.py"})," and"," ",d.jsx("code",{children:"src/features"}),"."]}),d.jsx("li",{children:"Review a git range, or open a pull request so base/head become a three-dot merge-base."})]})]})}),d.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:p?d.jsx(Ju,{nodes:p.nodes,edges:p.edges,onWhatIf:Cn,focusPath:(ki=p.read_order[Z])==null?void 0:ki.path,...sn}):null})]}),t==="architecture"&&d.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[d.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:m!=null&&m.indexed?d.jsx(WN,{architecture:m,busy:!!N,onReindex:()=>dr(!1),onReview:Gn,onSelect:Ge,config:gi,health:zr,onSaveConfig:P=>{Re.saveConfig(o,P).then(Y=>{lr(Y),K("Wrote loadpath.yml")})},onWaiver:(P,Y,ce)=>{Re.addWaiver(o,P,Y,ce).then(Ee=>{lr(Ee),K(`Waived ${P}`)})}}):G?d.jsx("p",{className:"muted","data-testid":"architecture-loading",children:"Loading the index summary…"}):d.jsx("p",{className:"muted","data-testid":"architecture-empty",children:"Index this repo to build the architecture graph. Review then walks that same graph for a git range — it does not start from a hunk list."})}),d.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:(te||m!=null&&m.graph_pending)&&!((m==null?void 0:m.nodes)||[]).length?d.jsxs("div",{className:"empty graph-loading","data-testid":"graph-loading",children:[d.jsx("h2",{children:"Drawing the architecture map…"}),d.jsx("p",{children:(Yr=m==null?void 0:m.counts)!=null&&Yr.nodes?`${m.counts.nodes} indexed nodes. The brief is ready while the graph loads.`:"Fetching the indexed graph."})]}):m!=null&&m.indexed?d.jsx(Ju,{nodes:m.nodes,edges:m.edges,onWhatIf:Cn,...sn,isolateSource:null,onIsolate:void 0}):null})]}),t==="graph"&&d.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%"},children:[d.jsxs("div",{className:"graph-modes",children:[d.jsxs("div",{className:"seg","aria-label":"Graph scope",children:[d.jsx("button",{type:"button","aria-pressed":b==="review","data-testid":"graph-mode-review",className:b==="review"?"active":"",onClick:()=>E("review"),children:"This review"}),d.jsx("button",{type:"button","aria-pressed":b==="architecture","data-testid":"graph-mode-architecture",className:b==="architecture"?"active":"",onClick:()=>E("architecture"),children:"Indexed architecture"})]}),d.jsxs("div",{className:"legend","aria-hidden":"true",children:[d.jsxs("span",{children:[d.jsx("i",{})," cheap"]}),d.jsxs("span",{children:[d.jsx("i",{className:"exp"})," expensive"]}),d.jsxs("span",{children:[d.jsx("i",{className:"crit"})," critical"]}),d.jsxs("span",{children:[d.jsx("i",{className:"dash"})," inferred"]}),d.jsxs("span",{children:[d.jsx("i",{className:"seed"})," changed"]}),d.jsxs("span",{children:[d.jsx("i",{className:"down"})," downstream"]})]}),d.jsx("button",{type:"button",className:gt?"chip-btn active":"chip-btn","data-testid":"graph-test-overlay","aria-pressed":gt,onClick:()=>{const P=!gt;mt(P),localStorage.setItem("loadpath.testOverlay",P?"1":"0")},children:"Tests"})]}),_i.length?d.jsx(Ju,{nodes:_i,edges:pr,onWhatIf:Cn,...sn,...b==="architecture"?{isolateSource:null,onIsolate:void 0,nodeRoles:void 0,testOverlay:!1}:{}}):te||m!=null&&m.graph_pending?d.jsx("p",{className:"empty","data-testid":"graph-loading",children:"Drawing the architecture map…"}):d.jsx("p",{className:"empty","data-testid":"graph-empty",children:"Index the repo or run a review first. Click a node to inspect it."})]}),t==="prs"&&d.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[d.jsxs("div",{className:"pr-toolbar",children:[d.jsxs("label",{className:"field provider",children:[d.jsx("span",{children:"Provider"}),d.jsxs("select",{"data-testid":"pr-provider",value:z,onChange:P=>It(P.target.value,H,oe),children:[d.jsx("option",{value:"github",children:"GitHub"}),d.jsx("option",{value:"gitlab",children:"GitLab"}),d.jsx("option",{value:"bitbucket",children:"Bitbucket"})]})]}),d.jsxs("label",{className:"field",children:[d.jsx("span",{children:"Repository"}),d.jsx("input",{"data-testid":"pr-repo",placeholder:M.length?"Search your repos":"owner/repo",value:H,onChange:P=>It(z,P.target.value,oe),list:"scm-repos",spellCheck:!1}),d.jsx("datalist",{id:"scm-repos",children:M.map(P=>d.jsxs("option",{value:P.slug,children:[P.private?"private":"public",P.local_path?" · local":""]},P.slug))})]}),d.jsx("button",{type:"button","data-testid":"btn-refresh-repos",className:"btn",disabled:!!N||!vi(z),onClick:()=>{Rt(z)},children:"My repos"}),d.jsx("button",{type:"button","data-testid":"btn-list-prs",className:"btn",disabled:!!N,onClick:xi,children:"List PRs"})]}),M.length>0?d.jsxs("p",{className:"muted scm-count","data-testid":"scm-repo-count",children:[M.length," ",z," repositor",M.length===1?"y":"ies",z==="github"&&C.github_user?` · @${String(C.github_user)}`:"",z==="gitlab"&&C.gitlab_user?` · @${String(C.gitlab_user)}`:"",z==="bitbucket"&&C.bitbucket_user?` · ${String(C.bitbucket_user)}`:""]}):null,W.length===0?d.jsxs("div",{className:"empty","data-testid":"pr-empty",children:[d.jsx("h2",{children:"No pull requests loaded"}),d.jsx("p",{children:"Sign in under Settings (or paste a token), load your repositories, then list open PRs. Reviewing a PR fills base and head from its SHAs."})]}):W.map(P=>{var Y;return d.jsxs("article",{className:"pr","data-testid":`pr-${P.number}`,children:[d.jsxs("h3",{children:["#",P.number," ",P.title]}),d.jsxs("div",{className:"pr-meta muted",children:[d.jsx("span",{className:`chip ${P.draft?"":"open"}`,children:P.draft?"draft":P.state}),d.jsx("span",{children:P.author}),d.jsxs("span",{children:[P.source_branch," → ",P.target_branch]}),P.loadpath?d.jsxs("span",{className:`chip ${P.loadpath.level||""}`,"data-testid":`pr-loadpath-${P.number}`,children:[((Y=P.loadpath.level)==null?void 0:Y.toUpperCase())||"REVIEWED",P.loadpath.contract_break&&P.loadpath.contract_break!=="none"?` · ${P.loadpath.contract_break}`:""]}):d.jsx("span",{className:"muted",children:"no Loadpath walk yet"})]}),d.jsxs("div",{className:"pr-actions",children:[d.jsxs("a",{href:P.url,target:"_blank",rel:"noreferrer",children:["Open on ",P.provider]}),d.jsx("button",{type:"button",className:"btn primary","data-testid":`pr-review-${P.number}`,onClick:()=>void ao(P),children:"Review this PR"})]})]},`${P.provider}-${P.number}`)})]}),t==="settings"&&Ne&&d.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:uo,children:[d.jsxs("div",{children:[d.jsx("h1",{children:"Settings"}),d.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. AI runs only on residual uncertainty the graph could not close."})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Appearance"}),d.jsx("p",{className:"muted",children:"Local to this browser. High contrast is a first-class theme, not an afterthought."}),d.jsx("div",{className:"theme-grid","data-testid":"theme-grid",children:Gl.map(P=>d.jsxs("button",{type:"button","data-theme":P.id,className:ve===P.id?"theme-swatch active":"theme-swatch","data-testid":`theme-${P.id}`,onClick:()=>mi(P.id),children:[d.jsx("div",{className:"swatch-bar","aria-hidden":"true"}),d.jsx("div",{className:"name",children:P.label}),d.jsx("div",{className:"group",children:P.group})]},P.id))})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Editor"}),d.jsx("p",{className:"muted",children:"Open files from the inspector and read-order in Cursor, VS Code, or the system handler."}),d.jsx("label",{htmlFor:"editor-pref",children:"Preferred editor"}),d.jsxs("select",{id:"editor-pref","data-testid":"editor-pref",defaultValue:Sm(),onChange:P=>EN(P.target.value),children:[d.jsx("option",{value:"auto",children:"Auto (Cursor, then VS Code)"}),d.jsx("option",{value:"cursor",children:"Cursor"}),d.jsx("option",{value:"vscode",children:"VS Code"}),d.jsx("option",{value:"system",children:"System default"})]})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Source control"}),d.jsx("p",{className:"muted",children:"Sign in with OAuth to list every repository the account can access. Tokens stay in ~/.loadpath/settings.json. A classic PAT still works if you prefer not to register an OAuth app."}),d.jsxs("div",{className:"scm-login","data-testid":"scm-github",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"GitHub"}),d.jsx("p",{className:"muted",children:C.github_token_set?C.github_user?`Signed in as @${String(C.github_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.github_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-github-disconnect",onClick:()=>void yt("github"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-github-login",disabled:!!dt||!C.github_oauth_ready,onClick:()=>void fr(),children:dt?"Waiting for GitHub…":"Sign in with GitHub"})})]}),dt?d.jsxs("p",{className:"oauth-code","data-testid":"github-user-code",children:["Enter ",d.jsx("code",{children:dt.user_code})," at GitHub if the browser did not fill it in."]}):null,C.github_oauth_ready?null:d.jsx("p",{className:"muted",children:"Sign-in needs a GitHub OAuth App with Device Flow enabled. Set LOADPATH_GITHUB_CLIENT_ID or paste the client ID below."}),d.jsx("label",{htmlFor:"github_oauth_client_id",children:"GitHub OAuth client ID"}),d.jsx("input",{id:"github_oauth_client_id",name:"github_oauth_client_id","data-testid":"github-oauth-client-id",placeholder:"Ov23…",defaultValue:String(C.github_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"github_token",children:"GitHub token (optional PAT)"}),d.jsx("input",{id:"github_token",name:"github_token",type:"password",placeholder:"ghp_…",autoComplete:"off"}),d.jsx("label",{htmlFor:"github_host",children:"GitHub host (Enterprise)"}),d.jsx("input",{id:"github_host",name:"github_host","data-testid":"github-host",placeholder:"github.com",defaultValue:String(C.github_host||""),autoComplete:"off"}),d.jsxs("div",{className:"scm-login","data-testid":"scm-gitlab",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"GitLab"}),d.jsx("p",{className:"muted",children:C.gitlab_token_set?C.gitlab_user?`Signed in as @${String(C.gitlab_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.gitlab_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-gitlab-disconnect",onClick:()=>void yt("gitlab"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-gitlab-login",disabled:Vn||!C.gitlab_oauth_ready,onClick:()=>void wi(),children:Vn?"Waiting for GitLab…":"Sign in with GitLab"})})]}),d.jsx("label",{htmlFor:"gitlab_host",children:"GitLab host"}),d.jsx("input",{id:"gitlab_host",name:"gitlab_host","data-testid":"gitlab-host",placeholder:"gitlab.com",defaultValue:String(C.gitlab_host||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_oauth_client_id",children:"GitLab OAuth application ID"}),d.jsx("input",{id:"gitlab_oauth_client_id",name:"gitlab_oauth_client_id","data-testid":"gitlab-oauth-client-id",defaultValue:String(C.gitlab_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_oauth_client_secret",children:"GitLab OAuth secret"}),d.jsx("input",{id:"gitlab_oauth_client_secret",name:"gitlab_oauth_client_secret",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"gitlab_token",children:"GitLab token (optional PAT)"}),d.jsx("input",{id:"gitlab_token",name:"gitlab_token",type:"password",placeholder:"glpat-…",autoComplete:"off"}),d.jsxs("div",{className:"scm-login","data-testid":"scm-bitbucket",children:[d.jsxs("div",{children:[d.jsx("strong",{children:"Bitbucket"}),d.jsx("p",{className:"muted",children:C.bitbucket_token_set?C.bitbucket_user?`Signed in as ${String(C.bitbucket_user)}`:"Token saved on this machine":"Not connected"})]}),d.jsx("div",{className:"btn-row",children:C.bitbucket_token_set?d.jsx("button",{type:"button",className:"btn","data-testid":"btn-bitbucket-disconnect",onClick:()=>void yt("bitbucket"),children:"Disconnect"}):d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-bitbucket-login",disabled:Bn||!C.bitbucket_oauth_ready,onClick:()=>void lo(),children:Bn?"Waiting for Bitbucket…":"Sign in with Bitbucket"})})]}),C.bitbucket_oauth_ready?null:d.jsxs("p",{className:"muted",children:["Sign-in needs a Bitbucket OAuth consumer (key + secret). Callback URL:"," ",d.jsx("code",{children:"/api/oauth/bitbucket/callback"})," on this app origin."]}),d.jsx("label",{htmlFor:"bitbucket_oauth_client_id",children:"Bitbucket OAuth key"}),d.jsx("input",{id:"bitbucket_oauth_client_id",name:"bitbucket_oauth_client_id","data-testid":"bitbucket-oauth-client-id",defaultValue:String(C.bitbucket_oauth_client_id||""),autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_oauth_client_secret",children:"Bitbucket OAuth secret"}),d.jsx("input",{id:"bitbucket_oauth_client_secret",name:"bitbucket_oauth_client_secret",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_token",children:"Bitbucket token (optional app password)"}),d.jsx("input",{id:"bitbucket_token",name:"bitbucket_token",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"bitbucket_username",children:"Bitbucket username (app passwords)"}),d.jsx("input",{id:"bitbucket_username",name:"bitbucket_username",defaultValue:String(C.bitbucket_username||"")})]}),d.jsxs("section",{className:"settings-card",children:[d.jsx("h2",{children:"Residual AI"}),d.jsx("label",{htmlFor:"ai_provider",children:"Provider"}),d.jsxs("select",{id:"ai_provider",name:"ai_provider",defaultValue:String(((ln=C.ai)==null?void 0:ln.provider)||"none"),children:[d.jsx("option",{value:"none",children:"none (graph only)"}),d.jsx("option",{value:"anthropic",children:"Anthropic"}),d.jsx("option",{value:"openai",children:"OpenAI"}),d.jsx("option",{value:"grok",children:"Grok / xAI"}),d.jsx("option",{value:"deepseek",children:"DeepSeek"}),d.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),d.jsx("option",{value:"ollama",children:"Ollama local"})]}),d.jsx("label",{htmlFor:"ai_api_key",children:"API key"}),d.jsx("input",{id:"ai_api_key",name:"ai_api_key",type:"password",autoComplete:"off"}),d.jsx("label",{htmlFor:"ai_model",children:"Model"}),d.jsx("input",{id:"ai_model",name:"ai_model","data-testid":"ai-model",placeholder:"optional override",defaultValue:String(((an=C.ai)==null?void 0:an.model)||"")}),d.jsx("label",{htmlFor:"ai_base_url",children:"Base URL"}),d.jsx("input",{id:"ai_base_url",name:"ai_base_url","data-testid":"ai-base-url",placeholder:"optional, OpenAI-compatible",defaultValue:String(((un=C.ai)==null?void 0:un.base_url)||"")}),d.jsx("button",{className:"btn primary",type:"submit","data-testid":"btn-save-settings",children:"Save"})]})]})]})]}),d.jsx(p0,{open:lt,actions:qn,onClose:()=>at(!1)}),Le?d.jsx(LN,{initialPath:o,onClose:()=>$e(!1),onSelect:P=>{if(Ze.current){w("Wait for the current job to finish before switching workspace.");return}$e(!1),Fr(P)}}):null]})}function VN({review:t,findings:r,aiNote:o,busy:s,tourIndex:a,onTour:u,onAskAi:c,onCopy:h,onPost:p,onSelect:y,onOpenFile:x,onExport:v,history:m,diff:_,onReopen:k,onWaiver:j}){var E,R,w,N,A,$,F,G,q,te,ee,ne,K,C,V,W,U;const b=[...new Set(t.confidence.reasons||[])];return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:`merge-box ${t.confidence.level}`,children:[d.jsxs("div",{className:`level ${t.confidence.level}`,children:[t.confidence.level.toUpperCase()," — ",t.title]}),b.length?d.jsx("ul",{className:"reasons",children:b.map(M=>d.jsx("li",{children:M},M))}):null,t.what_if?d.jsx("span",{className:"chip whatif","data-testid":"whatif-chip",children:"what-if"}):null,t.low_risk?d.jsx("span",{className:"chip",children:"low-risk"}):null,t.change_kinds.map(M=>d.jsx("span",{className:"chip",children:Zo(M)},M)),(E=t.contract_break)!=null&&E.kind&&t.contract_break.kind!=="none"?d.jsxs("span",{className:`chip ${t.contract_break.kind==="breaking"?"blocker":""}`,"data-testid":"contract-kind",children:["contract ",t.contract_break.kind]}):null]}),d.jsxs("div",{className:"metrics",children:[d.jsxs("div",{className:"metric",children:[d.jsxs("div",{className:"n",children:[t.confidence.covered_sinks,"/",t.confidence.sinks]}),d.jsx("div",{className:"l",children:"Sinks tested"})]}),d.jsxs("div",{className:"metric",children:[d.jsx("div",{className:"n",children:r.length}),d.jsx("div",{className:"l",children:"Findings"})]}),d.jsxs("div",{className:"metric",children:[d.jsx("div",{className:"n",children:t.residuals.length}),d.jsx("div",{className:"l",children:"Residuals"})]})]}),d.jsx("pre",{className:"headline",children:t.headline}),(t.checklist||[]).length?d.jsxs("details",{className:"section",open:!0,"data-testid":"merge-checklist",children:[d.jsxs("summary",{children:["Merge checklist"," ",d.jsx("span",{className:"count",children:(t.checklist||[]).filter(M=>M.status==="todo").length})]}),(t.checklist||[]).map(M=>d.jsxs("div",{className:`check-item ${M.status}`,children:[d.jsxs("button",{type:"button",className:"linkish",onClick:()=>M.node_id&&y(M.node_id),children:[d.jsx("span",{className:`chip ${M.status}`,children:M.status}),M.title]}),M.detail?d.jsx("div",{className:"why",children:M.detail}):null,M.body?d.jsx("button",{type:"button",className:"btn",onClick:()=>{navigator.clipboard.writeText(M.body||"")},children:"Copy test"}):null,M.kind==="finding"&&M.status==="todo"&&M.rule?d.jsx("button",{type:"button",className:"btn",onClick:()=>j(M.rule,M.node_id),children:"Waive in loadpath.yml"}):null]},M.id))]}):null,t.index?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Index ",d.jsx("span",{className:"count",children:t.index.counts.nodes})]}),d.jsxs("div",{className:"muted",children:["Walked ",t.index.counts.nodes," nodes / ",t.index.counts.edges," edges",t.index.reindex_skipped?" from an unchanged index":t.index.reindexed?" after an incremental refresh":" from the existing index",t.index.django_boot&&t.index.django_boot!=="off"?` · Django boot ${t.index.django_boot}`:"",(R=t.workspace)!=null&&R.three_dot?" · three-dot range":""]})]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Read this ",d.jsx("span",{className:"count",children:t.read_order.length})]}),t.read_order.map((M,D)=>d.jsxs("div",{className:D===a?"read-item tour-current":"read-item",children:[d.jsxs("button",{type:"button",className:"linkish file",onClick:()=>u(D),children:[D+1,". ",M.path]}),d.jsx("div",{className:"why",children:M.why}),d.jsx("button",{type:"button",className:"btn",onClick:()=>x(M.path),children:"Open"})]},M.path)),t.read_order.length>0?d.jsxs("div",{className:"btn-row tour-row",children:[d.jsx("button",{type:"button",className:"btn","data-testid":"btn-tour-prev",disabled:a<=0,onClick:()=>u(Math.max(0,a-1)),children:"Previous"}),d.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-tour-next",disabled:a>=t.read_order.length-1,onClick:()=>u(Math.min(t.read_order.length-1,a+1)),children:"Next in read order"}),d.jsxs("span",{className:"muted",children:[a+1,"/",t.read_order.length]})]}):null]}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Clusters ",d.jsx("span",{className:"count",children:t.clusters.length})]}),t.clusters.map(M=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:M.title})," — ",M.files.join(", ")]},M.id))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Architecture ",d.jsx("span",{className:"count",children:r.length})]}),r.length===0?d.jsx("div",{className:"muted",children:t.architecture_note}):r.map(M=>d.jsx("div",{className:"finding",children:d.jsxs("button",{type:"button",className:"linkish",onClick:()=>M.node_id&&y(M.node_id),children:[d.jsx("span",{className:`chip ${M.severity}`,children:M.severity}),M.message]})},M.rule+M.message))]}),d.jsx(bm,{cards:t.deepening}),(N=(w=t.contract_break)==null?void 0:w.reasons)!=null&&N.length?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Contract ",d.jsx("span",{className:"count",children:t.contract_break.kind})]}),t.contract_break.reasons.map(M=>d.jsx("div",{className:"muted",children:M},M)),($=(A=t.contract_break.sides)==null?void 0:A.rows)!=null&&$.length?d.jsxs("table",{className:"type-table","data-testid":"contract-sides",children:[d.jsx("thead",{children:d.jsxs("tr",{children:[d.jsx("th",{children:"Field"}),d.jsx("th",{children:"Serializer"}),d.jsx("th",{children:"Zod"}),d.jsx("th",{children:"GraphQL"})]})}),d.jsx("tbody",{children:t.contract_break.sides.rows.map(M=>d.jsxs("tr",{className:M.status,children:[d.jsx("td",{children:M.field}),d.jsx("td",{children:M.serializer?"yes":"—"}),d.jsx("td",{children:M.zod?"yes":"—"}),d.jsx("td",{children:M.graphql?"yes":"—"})]},M.field))})]}):null]}):null,(F=t.auth)!=null&&F.note?d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Auth"}),d.jsx("div",{className:"muted",children:t.auth.note}),(t.auth.missing_permissions||[]).map(M=>d.jsxs("div",{className:"finding",children:[d.jsx("span",{className:"chip warning",children:"missing"}),M.name]},M.id))]}):null,(t.suggested_tests||[]).length?d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Suggested tests ",d.jsx("span",{className:"count",children:(G=t.suggested_tests)==null?void 0:G.length})]}),(t.suggested_tests||[]).map(M=>d.jsxs("div",{className:"residual",children:[d.jsx("strong",{children:M.title}),d.jsx("pre",{className:"headline",children:M.body}),d.jsx("button",{type:"button",className:"btn",onClick:()=>{navigator.clipboard.writeText(M.body)},children:"Copy sketch"})]},M.title))]}):null,(q=t.trend)!=null&&q.note?d.jsxs("details",{className:"section",children:[d.jsx("summary",{children:"Confidence trend"}),d.jsx("div",{className:"muted",children:t.trend.note}),(t.trend.points||[]).slice(0,6).map(M=>d.jsxs("div",{className:"muted",children:[M.level," · ",nc(M.created_at),M.sinks!=null?` · ${M.sinks} sinks`:""]},M.id))]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Residual ",d.jsx("span",{className:"count",children:t.residuals.length})]}),d.jsx("p",{className:"muted",children:"AI is only used here, on what the graph could not close."}),t.residuals.map(M=>d.jsx("div",{className:"residual muted",children:M},M))]}),m.length?d.jsxs("details",{className:"section","data-testid":"review-history",children:[d.jsxs("summary",{children:["History ",d.jsx("span",{className:"count",children:m.length})]}),_?d.jsx("div",{className:"muted",children:_.note}):null,m.slice(0,12).map(M=>d.jsxs("button",{type:"button",className:M.id===t.id?"history-item current":"history-item",onClick:()=>k(M.id),children:[d.jsx("span",{className:`chip ${M.level||""}`,children:M.level||"walk"}),M.title||M.id.slice(0,8),d.jsx("span",{className:"muted",children:M.created_at?nc(M.created_at):""})]},M.id))]}):null,(ee=(te=t.evolution)==null?void 0:te.notes)!=null&&ee.length||(K=(ne=t.evolution)==null?void 0:ne.hotspots)!=null&&K.some(M=>M.commits)?d.jsxs("details",{className:"section",children:[d.jsx("summary",{children:"Churn & coupling"}),(((C=t.evolution)==null?void 0:C.notes)||[]).map(M=>d.jsx("div",{className:"muted",children:M},M)),(((V=t.evolution)==null?void 0:V.hotspots)||[]).filter(M=>M.commits).slice(0,6).map(M=>d.jsxs("div",{className:"muted",children:[d.jsx("span",{className:"file",children:M.path})," — ",M.commits," commits, bus factor ",M.bus_factor]},M.path))]}):null,d.jsxs("div",{className:"btn-row",children:[d.jsx("button",{type:"button",className:"btn",disabled:s,onClick:c,children:"Ask configured model"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-copy-markdown",onClick:h,children:"Copy markdown"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-export-html",onClick:v,children:"Save HTML"}),d.jsx("button",{type:"button",className:"btn","data-testid":"btn-post-comment",disabled:s||!!t.what_if,title:t.what_if?"Hypothetical walks are not posted to a pull request":void 0,onClick:p,children:"Post to PR"})]}),o?d.jsx("pre",{className:"headline",children:o}):null,d.jsx("div",{className:"kicker",children:"Reviewers"}),d.jsx("div",{className:"muted",children:t.suggested_reviewers.join(", ")||"—"}),(W=t.codeowners_reviewers)!=null&&W.length?d.jsxs("div",{className:"muted",children:["CODEOWNERS: ",t.codeowners_reviewers.join(", ")]}):null,(U=t.knowledge_owners)!=null&&U.length?d.jsxs("div",{className:"muted",children:["Knowledge: ",t.knowledge_owners.join(", ")]}):null]})}function WN({architecture:t,busy:r,onReindex:o,onReview:s,onSelect:a,config:u,health:c,onSaveConfig:h,onWaiver:p}){var x;const y=t.findings.filter(v=>!v.waived);return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:"merge-box high",children:[d.jsxs("div",{className:"level high",children:["INDEXED — ",t.counts.nodes," nodes"]}),d.jsxs("div",{className:"muted",style:{marginTop:8},children:[t.indexed_at?`Last index ${nc(t.indexed_at)}`:"Indexed",t.incremental?" · incremental":" · full",t.stale?" · stale":"",t.django_boot&&t.django_boot!=="off"?` · Django boot ${t.django_boot}`:""]}),d.jsxs("span",{className:"chip",children:[t.counts.edges," edges"]}),t.has_config?d.jsx("span",{className:"chip",children:"loadpath.yml"}):null]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Bounded contexts"}),Object.values(t.contexts).map(v=>d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:v.name})," — ",(v.django_apps||[]).join(", ")||"no apps"," ·"," ",(v.owners||[]).join(", ")||"unowned"]},v.name))]}),d.jsxs("details",{className:"section",children:[d.jsxs("summary",{children:["Rules ",d.jsx("span",{className:"count",children:(t.rules||[]).length})]}),(t.rules||[]).map(v=>d.jsx("div",{className:"muted",children:v},v))]}),d.jsxs("details",{className:"section",open:!0,children:[d.jsxs("summary",{children:["Findings ",d.jsx("span",{className:"count",children:y.length})]}),y.length===0?d.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):y.map(v=>d.jsx("div",{className:"finding",children:d.jsxs("button",{type:"button",className:"linkish",onClick:()=>v.node_id&&a(v.node_id),children:[d.jsx("span",{className:`chip ${v.severity}`,children:v.severity}),v.message]})},v.rule+v.message))]}),d.jsx(bm,{cards:t.deepening}),(x=c==null?void 0:c.points)!=null&&x.length?d.jsxs("details",{className:"section",open:!0,"data-testid":"architecture-health",children:[d.jsxs("summary",{children:["Health over time ",d.jsx("span",{className:"count",children:c.points.length})]}),d.jsx("div",{className:"sparkline","aria-hidden":"true",children:c.points.map(v=>d.jsx("i",{className:v.level||"",title:`${v.level} · ${v.findings} findings`,style:{height:`${8+Math.min(24,(v.findings||0)*4)}px`}},v.id||v.created_at))}),Object.entries(c.contexts).map(([v,m])=>{var _;return d.jsxs("div",{className:"muted",children:[d.jsx("strong",{children:v})," — last ",((_=m[m.length-1])==null?void 0:_.findings)??0," findings"]},v)})]}):null,u?d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"loadpath.yml"}),d.jsx(g0,{config:u,busy:r,onSave:h,onWaiver:p})]}):null,d.jsxs("details",{className:"section",open:!0,children:[d.jsx("summary",{children:"Types"}),d.jsx("table",{className:"type-table",children:d.jsx("tbody",{children:Object.entries(t.type_counts||{}).sort((v,m)=>m[1]-v[1]).slice(0,12).map(([v,m])=>d.jsxs("tr",{children:[d.jsx("td",{children:io(v)}),d.jsx("td",{children:m})]},v))})})]}),d.jsxs("div",{className:"btn-row",children:[d.jsx("button",{type:"button",className:"btn",disabled:r,onClick:o,"data-testid":"btn-full-reindex",children:"Full reindex"}),d.jsx("button",{type:"button",className:"btn primary",disabled:r,onClick:s,children:"Review against this index"})]})]})}function bm({cards:t}){const r=t||[];return r.length?d.jsxs("details",{className:"section",open:!0,"data-testid":"deepening-list",children:[d.jsxs("summary",{children:["Depth ",d.jsx("span",{className:"count",children:r.length})]}),d.jsx("p",{className:"muted",children:"Deepening opportunities: more behaviour behind a smaller interface, at a real seam."}),r.map(o=>d.jsxs("div",{className:"finding","data-testid":"deepening-card",children:[d.jsx("span",{className:`chip ${o.strength}`,children:m0(o.strength)}),o.top?d.jsx("span",{className:"chip",children:"top"}):null,d.jsx("strong",{children:o.title}),d.jsx("div",{className:"why",children:o.message}),o.deletion_test?d.jsxs("div",{className:"muted",children:["Deletion test: ",o.deletion_test]}):null,o.before&&o.after?d.jsxs("div",{className:"muted",children:[o.before," → ",o.after]}):null]},o.rule+o.title))]}):null}jm(Nm());d0.createRoot(document.getElementById("root")).render(d.jsx(L.StrictMode,{children:d.jsx(BN,{})}));export{Wk as L,GN as a,UN as c,d as j,YN as l,L as r,io as t}; diff --git a/src/loadpath/static/index.html b/src/loadpath/static/index.html index 39c4e6e..608e9fe 100644 --- a/src/loadpath/static/index.html +++ b/src/loadpath/static/index.html @@ -17,8 +17,8 @@ - - + +
diff --git a/src/loadpath/stitch/openapi.py b/src/loadpath/stitch/openapi.py index eca60c7..b6aab0e 100644 --- a/src/loadpath/stitch/openapi.py +++ b/src/loadpath/stitch/openapi.py @@ -265,19 +265,30 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s ) ) - # Serializer field ↔ Zod field overlap - fields_by_serializer: dict[str, list[dict]] = {} + # Serializer / Pydantic / GraphQL field ↔ Zod / codegen schema overlap + contract_parents: list[dict] = [] + contract_parents.extend(serializers) + contract_parents.extend(store.nodes([NodeType.PYDANTIC_MODEL])) + contract_parents.extend(store.nodes([NodeType.GRAPHQL_TYPE])) + fields_by_parent: dict[str, list[dict]] = {} for f in ser_fields: parent = f["qualified_name"].rsplit(".", 1)[0] - fields_by_serializer.setdefault(parent, []).append(f) + fields_by_parent.setdefault(parent, []).append(f) + for f in store.nodes([NodeType.GRAPHQL_FIELD]): + parent = f["qualified_name"].rsplit(".", 1)[0] + fields_by_parent.setdefault(parent, []).append(f) for schema in schemas: zod_fields = set((schema.get("extra") or {}).get("fields") or []) if not zod_fields: continue + schema_kind = (schema.get("extra") or {}).get("kind") or "zod" + typed = schema_kind == "graphql-codegen" or (schema.get("extra") or {}).get("generated") best: tuple[float, dict, set[str]] | None = None - for ser in serializers: - names = {f["name"] for f in fields_by_serializer.get(ser["qualified_name"], [])} + for ser in contract_parents: + names = {f["name"] for f in fields_by_parent.get(ser["qualified_name"], [])} + extra_fields = (ser.get("extra") or {}).get("fields") or [] + names.update(extra_fields) if not names: continue overlap = zod_fields & names @@ -287,21 +298,28 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s best = (score, ser, overlap) if best: score, ser, overlap = best + inferred = not typed store.upsert_edge( Edge( src=ser["id"], dst=schema["id"], type=EdgeType.MATCHES_SCHEMA, - confidence=min(0.85, 0.4 + score), - extra={"overlap": sorted(overlap), "score": score, "inferred": True}, + confidence=min(0.95, 0.55 + score) if typed else min(0.85, 0.4 + score), + extra={ + "overlap": sorted(overlap), + "score": score, + "inferred": inferred, + "via": schema_kind, + }, ) ) - residuals.append( - f"Inferred serializer/Zod overlap {ser['name']} ↔ {schema['name']} " - f"fields={sorted(overlap)} score={score:.2f}" - ) + if inferred: + residuals.append( + f"Inferred serializer/Zod overlap {ser['name']} ↔ {schema['name']} " + f"fields={sorted(overlap)} score={score:.2f}" + ) # field-level edges - ser_fields_map = {f["name"]: f for f in fields_by_serializer.get(ser["qualified_name"], [])} + ser_fields_map = {f["name"]: f for f in fields_by_parent.get(ser["qualified_name"], [])} for fname in overlap: if fname in ser_fields_map: store.upsert_edge( @@ -309,8 +327,8 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s src=ser_fields_map[fname]["id"], dst=schema["id"], type=EdgeType.MATCHES_SCHEMA, - confidence=0.6, - extra={"field": fname, "inferred": True}, + confidence=0.85 if typed else 0.6, + extra={"field": fname, "inferred": inferred}, ) ) @@ -333,6 +351,8 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s residuals.extend(_stitch_graphql(store)) residuals.extend(_stitch_htmx(store)) + residuals.extend(_stitch_e2e(store)) + residuals.extend(_stitch_trpc(store, routes)) store.conn.commit() return residuals @@ -370,6 +390,44 @@ def match_server(name: str) -> dict | None: extra={"via": "graphql", "operation": client["name"], "server": match["name"]}, ) ) + schemas = [ + n + for n in store.nodes([NodeType.FORM_SCHEMA]) + if (n.get("extra") or {}).get("kind") == "graphql-codegen" + ] + types = store.nodes([NodeType.GRAPHQL_TYPE]) + type_fields = store.nodes([NodeType.GRAPHQL_FIELD]) + fields_by_type: dict[str, set[str]] = {} + for f in type_fields: + parent = f["qualified_name"].rsplit(".", 1)[0] + fields_by_type.setdefault(parent, set()).add(f["name"]) + for schema in schemas: + zod = set((schema.get("extra") or {}).get("fields") or []) + if not zod: + continue + best: tuple[float, dict, set[str]] | None = None + for gql in types: + names = set(fields_by_type.get(gql["qualified_name"]) or []) + names.update((gql.get("extra") or {}).get("fields") or []) + if not names: + continue + overlap = zod & names + union = zod | names + score = len(overlap) / len(union) if union else 0 + if score >= 0.4 and (best is None or score > best[0]): + best = (score, gql, overlap) + if not best: + continue + score, gql, overlap = best + store.upsert_edge( + Edge( + src=gql["id"], + dst=schema["id"], + type=EdgeType.MATCHES_SCHEMA, + confidence=min(0.95, 0.6 + score), + extra={"via": "graphql-codegen", "overlap": sorted(overlap), "score": score, "inferred": False}, + ) + ) return residuals @@ -409,26 +467,146 @@ def _stitch_htmx(store: GraphStore) -> list[str]: return residuals +def _stitch_e2e(store: GraphStore) -> list[str]: + residuals: list[str] = [] + tests = [n for n in store.nodes([NodeType.REACT_TEST]) if (n.get("extra") or {}).get("e2e")] + if not tests: + return residuals + routes = [ + n + for n in store.nodes([NodeType.ROUTE, NodeType.FASTAPI_ROUTE, NodeType.REACT_ROUTE, NodeType.OPENAPI_PATH]) + if not (n.get("extra") or {}).get("include") + ] + pages = store.nodes([NodeType.PAGE]) + for test in tests: + visits = [(normalize_url_template(str(v)), str(v)) for v in ((test.get("extra") or {}).get("visits") or [])] + for tmpl, raw in visits: + matched = False + for route in routes: + extra = route.get("extra") or {} + if route["type"] == NodeType.OPENAPI_PATH.value: + rtmpl = django_route_to_template(str(extra.get("path") or route["name"])) + elif route["type"] == NodeType.REACT_ROUTE.value: + rtmpl = normalize_url_template(str(route["name"])) + else: + rtmpl = django_route_to_template(str(published_route(route))) + if not _paths_match(tmpl, rtmpl) and tmpl.replace("{id}", ":id") != rtmpl: + continue + store.upsert_edge( + Edge( + src=route["id"], + dst=test["id"], + type=EdgeType.TESTED_BY, + confidence=0.9, + extra={"via": "e2e", "visit": raw}, + ) + ) + matched = True + for page in pages: + proute = str((page.get("extra") or {}).get("route") or "") + if proute and _paths_match(tmpl, normalize_url_template(proute)): + store.upsert_edge( + Edge( + src=page["id"], + dst=test["id"], + type=EdgeType.TESTED_BY, + confidence=0.9, + extra={"via": "e2e", "visit": raw}, + ) + ) + matched = True + if not matched and tmpl.startswith("/api/"): + residuals.append(f"E2E visit {tmpl} has no matching route ({test.get('file_path')})") + return residuals + + +def _stitch_trpc(store: GraphStore, routes: list[dict]) -> list[str]: + residuals: list[str] = [] + clients = [ + n + for n in store.nodes([NodeType.API_CLIENT]) + if (n.get("extra") or {}).get("typed_client") == "trpc" + ] + if not clients: + return residuals + ops = store.nodes([NodeType.GRAPHQL_OPERATION]) + for client in clients: + proc = str((client.get("extra") or {}).get("procedure") or client["name"]) + last = proc.split(".")[-1].lower() + full = proc.lower() + aliases = {full, full.replace(".", "_")} + if last not in {"get", "list", "create", "update", "delete", "query", "mutate"}: + aliases.add(last) + matched = False + for op in ops: + if op["name"].lower() in aliases: + store.upsert_edge( + Edge( + src=op["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=0.8, + extra={"via": "trpc", "procedure": proc}, + ) + ) + matched = True + for route in routes: + rraw = published_route(route).lower() + if f"/trpc/{full}" in rraw or rraw.rstrip("/").endswith("/" + full.replace(".", "/")): + store.upsert_edge( + Edge( + src=route["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=0.7, + extra={"via": "trpc", "procedure": proc, "inferred": True}, + ) + ) + matched = True + if not matched: + residuals.append( + f"tRPC procedure {proc} has no matching GraphQL field or route ({client.get('file_path')})" + ) + return residuals + + +_API_MOUNTS = {"api", "v1", "v2", "v3", "backend"} + + +def _path_segments(path: str) -> list[str]: + return [part for part in path.strip("/").split("/") if part] + + +def _seg_eq(a: str, b: str) -> bool: + if a == b: + return True + def is_param(s: str) -> bool: + return s.startswith("{") or s.startswith(":") or s.startswith("<") + return is_param(a) and is_param(b) + + +def _segs_match(a: list[str], b: list[str]) -> bool: + return len(a) == len(b) and all(_seg_eq(x, y) for x, y in zip(a, b)) + + def _paths_match(a: str, b: str) -> bool: a = normalize_url_template(a) b = django_route_to_template(b) if a == b: return True - a_base = re.sub(r"""/\{id\}$""", "", a) - b_base = re.sub(r"""/\{id\}$""", "", b) - if a_base == b_base: + sa, sb = _path_segments(a), _path_segments(b) + if _segs_match(sa, sb): + return True + if len(sa) == len(sb) + 1 and sa[0].lower() in _API_MOUNTS and _segs_match(sa[1:], sb): return True - # included Django urls often omit the /api mount until composed - a_tail = a.rsplit("/", 2)[-2:] - b_tail = b.rsplit("/", 2)[-2:] - if a.endswith(b) or b.endswith(a): + if len(sb) == len(sa) + 1 and sb[0].lower() in _API_MOUNTS and _segs_match(sb[1:], sa): return True - return "/".join(a_tail) == "/".join(b_tail) and len(a_tail[-1]) > 2 + return False def _client_is_generated(client: dict, generated_files: list[str]) -> bool: extra = client.get("extra") or {} - if extra.get("generated"): + if extra.get("generated") or extra.get("typed_client"): return True fp = str(client.get("file_path") or extra.get("file") or "").replace("\\", "/") if not fp: diff --git a/src/loadpath/types.py b/src/loadpath/types.py index 1eb7dcc..cea9cfb 100644 --- a/src/loadpath/types.py +++ b/src/loadpath/types.py @@ -61,6 +61,7 @@ class NodeType(StrEnum): FORM_SCHEMA = "react.form_schema" CONTEXT_PROVIDER = "react.context" REACT_TEST = "react.test" + SERVER_ACTION = "react.server_action" # Stitch OPENAPI_PATH = "openapi.path" @@ -156,6 +157,7 @@ class EdgeWeight(StrEnum): NodeType.SIDE_EFFECT, NodeType.GRAPHQL_OPERATION, NodeType.FASTAPI_ROUTE, + NodeType.SERVER_ACTION, } CONTRACT_TYPES = { diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index 30c8fd8..beb373d 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -49,13 +49,21 @@ def live_app(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Iterator[tuple[ thread.join(timeout=5) +def force_2d_graph(page) -> None: + btn = page.get_by_test_id("graph-view-2d") + if btn.count(): + btn.first.click() + + def wait_visible_graph(page, timeout: int = 15_000) -> None: """Wait until React Flow has painted a node and at least one edge. `.react-flow__edge` first can stay `visibility: hidden` (unmeasured or clipped) even when other edges are visible, so prefer a visible edge and fall back to an attached path so a clipped pane does not fail the wait. + Large reviews default to 3D; switch back so Playwright can see the 2D map. """ + force_2d_graph(page) page.locator(".react-flow__node").first.wait_for(timeout=timeout) visible = page.locator(".react-flow__edge").filter(visible=True) try: diff --git a/tests/e2e/test_ui_flows.py b/tests/e2e/test_ui_flows.py index d8366ff..6132a0f 100644 --- a/tests/e2e/test_ui_flows.py +++ b/tests/e2e/test_ui_flows.py @@ -5,7 +5,7 @@ import pytest -from tests.e2e.conftest import wait_visible_graph +from tests.e2e.conftest import force_2d_graph, wait_visible_graph def _wait_fonts(page) -> None: @@ -107,9 +107,25 @@ def test_ui_index_review_graph_copy_and_workspace(live_app, browser_page): assert "MEDIUM" in brief or "LOW" in brief or "HIGH" in brief assert "billing-team" in brief assert "MePage" not in brief - page.locator(".react-flow__node").filter(has_text="InvoicePage").first.wait_for(timeout=15_000) wait_visible_graph(page) + invoice = page.locator(".react-flow__node").filter(has_text="InvoicePage").first + invoice.wait_for(timeout=15_000) assert page.locator(".react-flow__node").filter(has_text="MePage").count() == 0 + layout = page.get_by_test_id("graph-layout") + layout.wait_for() + assert layout.input_value() == "layers" + before = invoice.get_attribute("style") + layout.select_option("radial") + page.wait_for_function( + """before => { + const n = [...document.querySelectorAll('.react-flow__node')] + .find(el => (el.textContent || '').includes('InvoicePage')); + return Boolean(n && n.getAttribute('style') !== before); + }""", + arg=before, + timeout=10_000, + ) + assert layout.input_value() == "radial" page.get_by_test_id("tab-graph").click() page.get_by_test_id("graph-full").wait_for() @@ -147,9 +163,11 @@ def test_ui_index_review_graph_copy_and_workspace(live_app, browser_page): page.get_by_test_id("graph-view-3d").click() assert page.get_by_test_id("graph-view-3d").get_attribute("aria-pressed") == "true" page.get_by_test_id("graph-3d").wait_for(timeout=15_000) + assert page.get_by_test_id("graph-layout").count() == 0 page.locator("[data-testid='graph-3d-canvas'], [data-testid='graph-3d-fallback']").first.wait_for(timeout=20_000) page.get_by_test_id("graph-view-2d").click() page.locator(".react-flow__node").first.wait_for(timeout=15_000) + page.get_by_test_id("graph-layout").wait_for() page.get_by_test_id("graph-mode-architecture").click() assert page.get_by_test_id("graph-mode-architecture").get_attribute("aria-pressed") == "true" diff --git a/tests/unit/test_depth.py b/tests/unit/test_depth.py index 017c9c6..69348fb 100644 --- a/tests/unit/test_depth.py +++ b/tests/unit/test_depth.py @@ -26,12 +26,40 @@ def test_fixture_leaks_queryset_past_query_module(tmp_path: Path): store.close() -def test_fixture_tests_bypass_published_route_seam(tmp_path: Path): +def test_fixture_e2e_covers_published_invoice_seam(tmp_path: Path): store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) findings = evaluate_depth(store, load_config(FIXTURE)) hits = [f for f in findings if f.rule == "tests_bypass_interface"] - assert hits, [f.message for f in findings] - assert any("interface is the test surface" in f.message for f in hits) + blob = " ".join(f.message for f in hits) + assert "/api/invoices/{id}" not in blob + assert "/invoices/{id}" not in blob + e2e = [ + e + for e in store.edges() + if e["type"] == "tested_by" and (e.get("extra") or {}).get("via") == "e2e" + ] + assert e2e + store.close() + + +def test_tests_bypass_when_only_serializer_is_tested(tmp_path: Path): + from loadpath.graph.store import GraphStore + from loadpath.types import Edge, EdgeType, Node, NodeType, node_id + + store = GraphStore(tmp_path / "g.sqlite3") + route = Node(id=node_id(NodeType.ROUTE, "billing:/secret"), type=NodeType.ROUTE, name="/secret", qualified_name="billing:/secret", extra={"route": "/secret"}) + view = Node(id=node_id(NodeType.VIEW, "billing.SecretView"), type=NodeType.VIEW, name="SecretView", qualified_name="billing.SecretView") + ser = Node(id=node_id(NodeType.SERIALIZER, "billing.SecretSerializer"), type=NodeType.SERIALIZER, name="SecretSerializer", qualified_name="billing.SecretSerializer") + test = Node(id=node_id(NodeType.TEST, "billing.test_secret"), type=NodeType.TEST, name="test_secret", qualified_name="billing.test_secret") + for n in (route, view, ser, test): + store.upsert_node(n) + store.upsert_edge(Edge(src=route.id, dst=view.id, type=EdgeType.PUBLISHES_ROUTE)) + store.upsert_edge(Edge(src=view.id, dst=ser.id, type=EdgeType.USES_SERIALIZER)) + store.upsert_edge(Edge(src=ser.id, dst=test.id, type=EdgeType.TESTED_BY)) + store.conn.commit() + hits = [f for f in evaluate_depth(store, load_config(FIXTURE)) if f.rule == "tests_bypass_interface"] + assert hits + assert any("SecretSerializer" in f.message and "/secret" in f.message for f in hits) store.close() diff --git a/tests/unit/test_django_extractors.py b/tests/unit/test_django_extractors.py index 2d387c8..fe59745 100644 --- a/tests/unit/test_django_extractors.py +++ b/tests/unit/test_django_extractors.py @@ -699,3 +699,75 @@ def test_filterset_is_a_form_and_links_from_the_view(): for e in vg.edges ) + +def test_resolves_get_serializer_class_returns(): + source = (FIXTURE / "backend/billing/views.py").read_text() + g = extract_django_file("backend/billing/views.py", source, _cfg()) + detail = next(n for n in g.nodes if n.name == "InvoiceDetailViewSet") + assert detail.extra.get("get_serializer_class") is True + assert set(detail.extra.get("serializer_classes") or []) >= {"InvoiceSerializer", "InvoiceDetailSerializer"} + assert not any("get_serializer_class" in r and "InvoiceDetailViewSet" in r for r in g.residuals) + assert any( + e.src == detail.id and "InvoiceDetailSerializer" in e.dst and e.type.value == "uses_serializer" + for e in g.edges + ) + + +def test_unresolved_get_serializer_class_is_residual(): + source = ( + "from rest_framework.viewsets import ModelViewSet\n" + "class InvoiceViewSet(ModelViewSet):\n" + " def get_serializer_class(self):\n" + " return registry[self.action]\n" + ) + g = extract_django_file("backend/billing/views.py", source, _cfg()) + assert any("get_serializer_class" in r for r in g.residuals) + + +def test_nested_method_field_and_to_representation(): + source = (FIXTURE / "backend/billing/serializers.py").read_text() + g = extract_django_file("backend/billing/serializers.py", source, _cfg()) + detail = next(n for n in g.nodes if n.name == "InvoiceDetailSerializer") + assert "LineSerializer" in (detail.extra.get("nested_serializers") or []) + assert "display_total" in (detail.extra.get("method_fields") or []) + assert "display_total" in (detail.extra.get("to_representation_fields") or []) + lines = next(n for n in g.nodes if n.name == "lines" and "InvoiceDetailSerializer" in n.qualified_name) + assert lines.extra.get("nested_serializer") == "LineSerializer" + assert any(e.extra.get("nested") and "LineSerializer" in e.dst for e in g.edges) + + +def test_unparsed_to_representation_is_residual(): + source = ( + "from rest_framework import serializers\n" + "class InvoiceSerializer(serializers.Serializer):\n" + " def to_representation(self, instance):\n" + " return helper(instance)\n" + ) + g = extract_django_file("backend/billing/serializers.py", source, _cfg()) + assert any("to_representation" in r for r in g.residuals) + + +def test_dead_serializer_dict_does_not_resolve_get_serializer_class(): + source = ( + "from rest_framework.viewsets import ModelViewSet\n" + "class InvoiceViewSet(ModelViewSet):\n" + " def get_serializer_class(self):\n" + " unused = {\"list\": InvoiceSerializer}\n" + " return registry[self.action]\n" + ) + g = extract_django_file("backend/billing/views.py", source, _cfg()) + assert any("get_serializer_class" in r for r in g.residuals) + + +def test_marshmallow_schema_is_not_ninja_when_router_imported(): + source = ( + "from ninja import Router\n" + "from marshmallow import Schema\n" + "router = Router()\n" + "class Weird(Schema):\n" + " amount: str\n" + ) + g = extract_django_file("backend/billing/api.py", source, _cfg()) + assert not any(n.extra.get("ninja_schema") for n in g.nodes) + + diff --git a/tests/unit/test_index_and_stitch.py b/tests/unit/test_index_and_stitch.py index 6f9dd4a..47d423b 100644 --- a/tests/unit/test_index_and_stitch.py +++ b/tests/unit/test_index_and_stitch.py @@ -26,6 +26,34 @@ def test_index_stitches_django_route_to_react_client(tmp_path: Path): assert any((e.get("extra") or {}).get("superseded_by_generated") for e in inferred) schema_edges = [e for e in edges if e["type"] == "matches_schema"] assert schema_edges, "serializer fields should overlap invoiceSchema" + typed = [ + n + for n in store.nodes([NodeType.API_CLIENT]) + if (n.get("extra") or {}).get("typed_client") in {"rtk", "openapi-fetch"} + ] + assert typed, "RTK / openapi-fetch clients should be indexed" + e2e = [ + e + for e in edges + if e["type"] == "tested_by" and (e.get("extra") or {}).get("via") == "e2e" + ] + assert e2e, "Playwright visits should stitch tested_by onto routes" + gql_schema = [ + e + for e in schema_edges + if (e.get("extra") or {}).get("via") == "graphql-codegen" + ] + assert gql_schema, "graphql-codegen InvoiceType should match the server GraphQL type" + assert any(n["type"] == "react.server_action" for n in store.nodes()) + assert any(n["type"] == "react.page" and (n.get("extra") or {}).get("next_app") for n in store.nodes()) + by_id = {n["id"]: n for n in store.nodes()} + for e in consumed: + src = by_id.get(e["src"]) or {} + dst = by_id.get(e["dst"]) or {} + blob = f"{src.get('name','')} {dst.get('name','')} {e.get('extra')}" + assert "/internal/invoices" not in blob + if (dst.get("extra") or {}).get("typed_client") == "trpc": + assert "websocket" not in (src.get("type") or "") store.close() @@ -179,3 +207,14 @@ def test_regex_include_join_strips_anchors(tmp_path: Path): assert child is not None assert child["name"] == "/base" store.close() + + +def test_paths_match_allows_api_mount_but_not_internal_or_collection(): + from loadpath.stitch.openapi import _paths_match + + assert _paths_match("/api/invoices/{id}", "/invoices/{id}") + assert _paths_match("/api/invoices/{id}", "/api/invoices/{pk}") + assert not _paths_match("/api/invoices/{id}", "/internal/invoices/{id}") + assert not _paths_match("/api/invoices/{id}", "/api/invoices") + assert not _paths_match("/api/invoices/{id}", "/api/invoices/{id}/ledger") + diff --git a/tests/unit/test_overlays.py b/tests/unit/test_overlays.py index 7638d57..f106f0d 100644 --- a/tests/unit/test_overlays.py +++ b/tests/unit/test_overlays.py @@ -63,6 +63,9 @@ def test_extracts_fastapi_next_to_django_not_ninja(): ) assert not any(n.type is NodeType.FASTAPI_ROUTE for n in ninja.nodes) assert any(n.type is NodeType.ROUTE and n.extra.get("ninja") for n in ninja.nodes) + assert any(n.type is NodeType.PYDANTIC_MODEL and n.name == "InvoiceSchema" for n in ninja.nodes) + assert any(n.name == "LedgerLineSchema" for n in ninja.nodes) + assert any(e.type is EdgeType.USES_SERIALIZER and "InvoiceSchema" in e.dst for e in ninja.edges) mixed = extract_django_file( "backend/billing/api.py", "from fastapi import Depends\nfrom ninja import Router\napi = Router()\n@api.get('/ledger')\ndef ledger():\n return {}\n", diff --git a/tests/unit/test_react_extractors.py b/tests/unit/test_react_extractors.py index e5885ae..a9723e9 100644 --- a/tests/unit/test_react_extractors.py +++ b/tests/unit/test_react_extractors.py @@ -117,3 +117,175 @@ def test_invalidate_queries_marked(): assert any((n.extra or {}).get("invalidation") for n in keys) hook = next(n for n in g.nodes if n.name == "useSaveInvoice") assert hook.extra.get("mutation") is True + + +def test_extracts_next_app_router_page_and_server_action(): + page = extract_react_file( + "frontend/src/app/invoices/[id]/page.tsx", + (FIXTURE / "frontend/src/app/invoices/[id]/page.tsx").read_text(), + _cfg(), + ) + routes = [n for n in page.nodes if n.type is NodeType.REACT_ROUTE] + assert any(n.name == "/invoices/{id}" for n in routes) + assert any(n.type is NodeType.PAGE and (n.extra or {}).get("next_app") for n in page.nodes) + actions = extract_react_file( + "frontend/src/app/invoices/[id]/actions.ts", + (FIXTURE / "frontend/src/app/invoices/[id]/actions.ts").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.SERVER_ACTION and n.name == "saveInvoice" for n in actions.nodes) + + +def test_extracts_rtk_openapi_fetch_and_trpc_clients(): + rtk = extract_react_file( + "frontend/src/features/billing/invoiceApi.ts", + (FIXTURE / "frontend/src/features/billing/invoiceApi.ts").read_text(), + _cfg(), + ) + clients = [n for n in rtk.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices/{id}" and c.extra.get("typed_client") == "rtk" for c in clients) + assert all(not c.extra.get("inferred") for c in clients) + fetch = extract_react_file( + "frontend/src/features/billing/openapiFetch.ts", + (FIXTURE / "frontend/src/features/billing/openapiFetch.ts").read_text(), + _cfg(), + ) + assert any( + c.type is NodeType.API_CLIENT and c.extra.get("typed_client") == "openapi-fetch" + for c in fetch.nodes + ) + trpc = extract_react_file( + "frontend/src/features/billing/trpc.ts", + (FIXTURE / "frontend/src/features/billing/trpc.ts").read_text(), + _cfg(), + ) + assert any(n.extra.get("typed_client") == "trpc" and n.name == "invoice.get" for n in trpc.nodes) + + +def test_extracts_playwright_e2e_visits(): + g = extract_react_file( + "frontend/e2e/invoice.spec.ts", + (FIXTURE / "frontend/e2e/invoice.spec.ts").read_text(), + _cfg(), + ) + tests = [n for n in g.nodes if n.type is NodeType.REACT_TEST] + assert tests + assert tests[0].extra.get("e2e") is True + visits = tests[0].extra.get("visits") or [] + assert "/invoices/{id}" in visits + assert "/api/invoices/{id}" in visits + assert any(e.type.value == "tested_by" for e in g.edges) + + +def test_extracts_graphql_codegen_and_document(): + g = extract_react_file( + "frontend/src/generated/graphql.ts", + (FIXTURE / "frontend/src/generated/graphql.ts").read_text(), + _cfg(), + ) + schemas = [n for n in g.nodes if n.type is NodeType.FORM_SCHEMA] + assert any(n.name == "InvoiceType" and n.extra.get("kind") == "graphql-codegen" for n in schemas) + doc = extract_react_file( + "frontend/src/features/billing/invoice.graphql", + (FIXTURE / "frontend/src/features/billing/invoice.graphql").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.GRAPHQL_OPERATION and n.name == "Invoice" and n.extra.get("client") for n in doc.nodes) + + +def test_extracts_ts_rest_path_contract(): + src = """ +import { initContract } from '@ts-rest/core'; +const c = initContract(); +export const invoiceContract = c.router({ + getInvoice: { + method: 'GET', + path: '/api/invoices/:id', + responses: { 200: c.type() }, + }, +}); +""" + g = extract_react_file("frontend/src/features/billing/contract.ts", src, _cfg()) + clients = [n for n in g.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices/{id}" and c.extra.get("typed_client") == "ts-rest" for c in clients) + + +def test_rtk_ignores_http_method_literals(): + src = """ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +export const invoiceApi = createApi({ + baseQuery: fetchBaseQuery({ baseUrl: "/api" }), + endpoints: (builder) => ({ + save: builder.mutation({ + query: (body) => ({ method: "POST", url: "/invoices", body }), + }), + }), +}); +""" + g = extract_react_file("frontend/src/features/billing/invoiceApi.ts", src, _cfg()) + clients = [n for n in g.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices" for c in clients) + assert not any("POST" in c.name for c in clients) + + +def test_does_not_treat_generic_post_as_openapi_fetch(): + src = """ +export function save() { + return api.POST("/api/invoices", { body: {} }); +} +""" + g = extract_react_file("frontend/src/features/billing/api.ts", src, _cfg()) + typed = [n for n in g.nodes if n.type is NodeType.API_CLIENT and n.extra.get("typed_client") == "openapi-fetch"] + assert not typed + + +def test_does_not_treat_api_usequery_as_trpc(): + src = """ +export function useBilling() { + return api.billing.list.useQuery(); +} +""" + g = extract_react_file("frontend/src/features/billing/useBilling.ts", src, _cfg()) + assert not any(n.extra.get("typed_client") == "trpc" for n in g.nodes) + + +def test_ts_rest_ignores_react_router_paths(): + src = """ +import { initContract } from '@ts-rest/core'; +const c = initContract(); +export const routes = [{ path: '/settings/profile', element: }]; +""" + g = extract_react_file("frontend/src/features/billing/contract.ts", src, _cfg()) + assert not any(n.extra.get("typed_client") == "ts-rest" for n in g.nodes) + + +def test_app_router_route_handler_is_not_a_page(): + src = """ +export async function GET() { + return Response.json({}); +} +""" + g = extract_react_file("frontend/src/app/api/invoices/route.ts", src, _cfg()) + assert not any(n.type is NodeType.PAGE for n in g.nodes) + assert not any(n.name == "GET" for n in g.nodes) + assert any(n.type is NodeType.API_CLIENT and n.extra.get("next_api") for n in g.nodes) + + +def test_server_action_arrow_export(): + src = """ +"use server"; +export const saveInvoice = async (formData: FormData) => { + return String(formData.get("id") || ""); +}; +""" + g = extract_react_file("frontend/src/app/invoices/[id]/actions.ts", src, _cfg()) + assert any(n.type is NodeType.SERVER_ACTION and n.name == "saveInvoice" for n in g.nodes) + + +def test_typename_alone_is_not_graphql_codegen(): + src = """ +export type ButtonProps = { __typename?: string; label: string }; +""" + g = extract_react_file("frontend/src/components/Button.tsx", src, _cfg()) + assert not any(n.extra.get("kind") == "graphql-codegen" for n in g.nodes) + diff --git a/ui/src/ImpactGraph.test.ts b/ui/src/ImpactGraph.test.ts index 7b18f9a..301510f 100644 --- a/ui/src/ImpactGraph.test.ts +++ b/ui/src/ImpactGraph.test.ts @@ -29,6 +29,20 @@ describe("toReactFlowElements", () => { expect(rfEdges[0].markerEnd).toMatchObject({ type: MarkerType.ArrowClosed }); expect(rfEdges[0].label).toBeUndefined(); expect(rfEdges[0].data).toMatchObject({ stepPosition: 0.5 }); + expect(rfEdges[0].sourceHandle).toBe("src-e"); + expect(rfEdges[0].targetHandle).toBe("tgt-w"); + }); + + it("uses bezier edges and different positions for radial layout", () => { + const layered = toReactFlowElements(nodes, edges); + const radial = toReactFlowElements(nodes, edges, null, { layout: "radial" }); + expect(radial.rfEdges[0]?.type).toBe("default"); + expect(radial.rfEdges[0]?.sourceHandle).toMatch(/^src-/); + const moved = layered.rfNodes.some((n, i) => { + const other = radial.rfNodes[i]!; + return n.position.x !== other.position.x || n.position.y !== other.position.y; + }); + expect(moved).toBe(true); }); it("labels only edges incident to the selected node", () => { diff --git a/ui/src/ImpactGraph.tsx b/ui/src/ImpactGraph.tsx index 3a6ebb9..449efe1 100644 --- a/ui/src/ImpactGraph.tsx +++ b/ui/src/ImpactGraph.tsx @@ -19,14 +19,20 @@ import { import "@xyflow/react/dist/style.css"; import { typeLabel, wrapHint } from "./format"; import { + GRAPH_LAYOUTS, defaultDetail, defaultProjection, familyFor, isolatePathIds, + layoutGraph, + layoutUsesColumns, + readGraphLayout, searchNodes, visibleGraph, + writeGraphLayout, type GraphDetail, type GraphFamily, + type GraphLayoutId, type GraphProjection, } from "./graphView"; import { inspectNode, type InspectorLink } from "./nodeInspector"; @@ -34,7 +40,6 @@ import { assignEdgeStepPositions } from "./graphEdges"; import { GRAPH_NODE_HEIGHT, GRAPH_NODE_WIDTH, - layoutNodes, type GraphEdge, type GraphNode, } from "./types"; @@ -51,6 +56,25 @@ const WEIGHT_COLOR: Record = { critical: "var(--edge-critical)", }; +const HANDLE_POS = { + n: Position.Top, + e: Position.Right, + s: Position.Bottom, + w: Position.Left, +} as const; + +function facingHandles( + from: { x: number; y: number }, + to: { x: number; y: number }, +): { source: keyof typeof HANDLE_POS; target: keyof typeof HANDLE_POS } { + const dx = to.x - from.x; + const dy = to.y - from.y; + if (Math.abs(dx) >= Math.abs(dy)) { + return dx >= 0 ? { source: "e", target: "w" } : { source: "w", target: "e" }; + } + return dy >= 0 ? { source: "s", target: "n" } : { source: "n", target: "s" }; +} + function LoadNode({ data, selected, @@ -61,12 +85,16 @@ function LoadNode({ const roles = (data.roles || []).map((role) => `role-${role}`).join(" "); return (
- + {(["n", "e", "s", "w"] as const).map((side) => ( + + ))}
{typeLabel(data.type)}
{wrapHint(data.name)}
- + {(["n", "e", "s", "w"] as const).map((side) => ( + + ))}
); } @@ -147,10 +175,12 @@ export function toReactFlowElements( nodes: GraphNode[], edges: GraphEdge[], selectedId: string | null = null, - opts: { roles?: Record; testOverlay?: boolean } = {}, + opts: { roles?: Record; testOverlay?: boolean; layout?: GraphLayoutId } = {}, ): { rfNodes: Node[]; rfEdges: Edge[] } { const byId = new Map(nodes.map((n) => [n.id, n])); - const pos = layoutNodes(nodes, edges); + const layout = opts.layout ?? "layers"; + const columns = layoutUsesColumns(layout); + const pos = layoutGraph(nodes, edges, layout); const stepByEdge = assignEdgeStepPositions(nodes, edges, pos); const rfNodes: Node[] = nodes.map((n) => { const roles = opts.roles?.[n.id] || []; @@ -178,11 +208,18 @@ export function toReactFlowElements( .map((e) => { const stroke = WEIGHT_COLOR[e.weight] || "var(--edge-cheap)"; const labeled = Boolean(selectedId && (e.src === selectedId || e.dst === selectedId)); + const from = pos.get(e.src) ?? { x: 0, y: 0 }; + const to = pos.get(e.dst) ?? { x: 0, y: 0 }; + const facing = columns ? { source: "e" as const, target: "w" as const } : facingHandles(from, to); return { id: e.id, source: e.src, target: e.dst, - type: "loadstep", + sourceHandle: `src-${facing.source}`, + targetHandle: `tgt-${facing.target}`, + sourcePosition: HANDLE_POS[facing.source], + targetPosition: HANDLE_POS[facing.target], + type: columns ? "loadstep" : "default", animated: e.weight === "critical", data: { stepPosition: stepByEdge.get(e.id) ?? 0.5 }, style: { @@ -457,6 +494,7 @@ export function ImpactGraph({ }; const [projection, setProjection] = useState(null); const [detail, setDetail] = useState(null); + const [layout, setLayout] = useState(() => readGraphLayout()); const [families, setFamilies] = useState>(new Set(ALL_FAMILIES)); const [neighborhoodOnly, setNeighborhoodOnly] = useState(false); const [query, setQuery] = useState(""); @@ -484,20 +522,21 @@ export function ImpactGraph({ [scopedNodes, scopedEdges, level, families, neighborhoodFocus], ); const topologyKey = useMemo( - () => `${visible.nodes.map((n) => n.id).join("\0")}|${visible.edges.map((e) => e.id).join("\0")}`, - [visible.nodes, visible.edges], + () => `${layout}|${visible.nodes.map((n) => n.id).join("\0")}|${visible.edges.map((e) => e.id).join("\0")}`, + [layout, visible.nodes, visible.edges], ); const selected = selectedId ? nodes.find((n) => n.id === selectedId) ?? null : null; const { rfNodes, rfEdges } = useMemo(() => { const elements = toReactFlowElements(visible.nodes, visible.edges, selectedId, { roles: nodeRoles, testOverlay, + layout, }); if (reduceMotion) { elements.rfEdges = elements.rfEdges.map((edge) => ({ ...edge, animated: false })); } return elements; - }, [visible.nodes, visible.edges, selectedId, reduceMotion, nodeRoles, testOverlay]); + }, [visible.nodes, visible.edges, selectedId, reduceMotion, nodeRoles, testOverlay, layout]); useEffect(() => { if (!focusPath) return; @@ -617,6 +656,29 @@ export function ImpactGraph({ ))} + {view === "2d" ? ( + + ) : null}