@kerros/editor 0.0.0-stage → 0.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +35 -2
- package/dist/SitePlanner.js +1189 -0
- package/dist/SitePlanner.js.map +1 -0
- package/dist/adapters/basemap.js +11 -0
- package/dist/adapters/basemap.js.map +1 -0
- package/dist/adapters/persistence.js +121 -0
- package/dist/adapters/persistence.js.map +1 -0
- package/dist/adapters/status.js +11 -0
- package/dist/adapters/status.js.map +1 -0
- package/dist/adapters/useProjectPersistence.js +56 -0
- package/dist/adapters/useProjectPersistence.js.map +1 -0
- package/dist/components/AiImportPanel.js +635 -0
- package/dist/components/AiImportPanel.js.map +1 -0
- package/dist/components/AnalysisPreview.js +179 -0
- package/dist/components/AnalysisPreview.js.map +1 -0
- package/dist/components/ElevatorPanel.js +120 -0
- package/dist/components/ElevatorPanel.js.map +1 -0
- package/dist/components/Icons.js +57 -0
- package/dist/components/Icons.js.map +1 -0
- package/dist/components/ImportDialog.js +467 -0
- package/dist/components/ImportDialog.js.map +1 -0
- package/dist/components/Inspector.js +1184 -0
- package/dist/components/Inspector.js.map +1 -0
- package/dist/components/NavigatePanel.js +301 -0
- package/dist/components/NavigatePanel.js.map +1 -0
- package/dist/components/NavigationGraph.js +234 -0
- package/dist/components/NavigationGraph.js.map +1 -0
- package/dist/components/StructureExplorer.js +510 -0
- package/dist/components/StructureExplorer.js.map +1 -0
- package/dist/components/StructureView.js +286 -0
- package/dist/components/StructureView.js.map +1 -0
- package/dist/components/controls.js +209 -0
- package/dist/components/controls.js.map +1 -0
- package/dist/components/graphLayout.js +27 -0
- package/dist/components/graphLayout.js.map +1 -0
- package/dist/host.js +175 -0
- package/dist/host.js.map +1 -0
- package/dist/i18n.js +88 -0
- package/dist/i18n.js.map +1 -0
- package/dist/import/analysisPreview.js +41 -0
- package/dist/import/analysisPreview.js.map +1 -0
- package/dist/import/brief.js +29 -0
- package/dist/import/brief.js.map +1 -0
- package/dist/import/checkpoint.js +50 -0
- package/dist/import/checkpoint.js.map +1 -0
- package/dist/import/detect.js +120 -0
- package/dist/import/detect.js.map +1 -0
- package/dist/import/documentSvg.js +49 -0
- package/dist/import/documentSvg.js.map +1 -0
- package/dist/import/instructions.js +20 -0
- package/dist/import/instructions.js.map +1 -0
- package/dist/import/openings.js +61 -0
- package/dist/import/openings.js.map +1 -0
- package/dist/import/planImport.js +233 -0
- package/dist/import/planImport.js.map +1 -0
- package/dist/import/register.js +47 -0
- package/dist/import/register.js.map +1 -0
- package/dist/import/runs.js +67 -0
- package/dist/import/runs.js.map +1 -0
- package/dist/import/session.js +23 -0
- package/dist/import/session.js.map +1 -0
- package/dist/import/types.js +13 -0
- package/dist/import/types.js.map +1 -0
- package/dist/import/usage.js +29 -0
- package/dist/import/usage.js.map +1 -0
- package/dist/import/walls.js +112 -0
- package/dist/import/walls.js.map +1 -0
- package/dist/index.js +178 -0
- package/dist/index.js.map +1 -0
- package/dist/map/CabinMaterials.js +81 -0
- package/dist/map/CabinMaterials.js.map +1 -0
- package/dist/map/CabinMirror.js +43 -0
- package/dist/map/CabinMirror.js.map +1 -0
- package/dist/map/Doors.js +80 -0
- package/dist/map/Doors.js.map +1 -0
- package/dist/map/ElevatorCabin.js +93 -0
- package/dist/map/ElevatorCabin.js.map +1 -0
- package/dist/map/FixtureLights.js +117 -0
- package/dist/map/FixtureLights.js.map +1 -0
- package/dist/map/MapCanvas.js +2161 -0
- package/dist/map/MapCanvas.js.map +1 -0
- package/dist/map/Passenger.js +69 -0
- package/dist/map/Passenger.js.map +1 -0
- package/dist/map/SceneLayer.js +1534 -0
- package/dist/map/SceneLayer.js.map +1 -0
- package/dist/map/UndergroundContext.js +153 -0
- package/dist/map/UndergroundContext.js.map +1 -0
- package/dist/map/ambience.js +194 -0
- package/dist/map/ambience.js.map +1 -0
- package/dist/map/architecture.js +305 -0
- package/dist/map/architecture.js.map +1 -0
- package/dist/map/bathMusic.js +92 -0
- package/dist/map/bathMusic.js.map +1 -0
- package/dist/map/cameraAim.js +33 -0
- package/dist/map/cameraAim.js.map +1 -0
- package/dist/map/elevators.js +56 -0
- package/dist/map/elevators.js.map +1 -0
- package/dist/map/excavation.js +52 -0
- package/dist/map/excavation.js.map +1 -0
- package/dist/map/exteriors.js +25 -0
- package/dist/map/exteriors.js.map +1 -0
- package/dist/map/features.js +218 -0
- package/dist/map/features.js.map +1 -0
- package/dist/map/fences.js +29 -0
- package/dist/map/fences.js.map +1 -0
- package/dist/map/journey.js +112 -0
- package/dist/map/journey.js.map +1 -0
- package/dist/map/levels.js +6 -0
- package/dist/map/levels.js.map +1 -0
- package/dist/map/lighting.js +143 -0
- package/dist/map/lighting.js.map +1 -0
- package/dist/map/loadBasemap.js +26 -0
- package/dist/map/loadBasemap.js.map +1 -0
- package/dist/map/materials.js +183 -0
- package/dist/map/materials.js.map +1 -0
- package/dist/map/poolLighting.js +39 -0
- package/dist/map/poolLighting.js.map +1 -0
- package/dist/map/projection.js +24 -0
- package/dist/map/projection.js.map +1 -0
- package/dist/map/rampGeometry.js +38 -0
- package/dist/map/rampGeometry.js.map +1 -0
- package/dist/map/route.js +107 -0
- package/dist/map/route.js.map +1 -0
- package/dist/map/stairSurfaces.js +115 -0
- package/dist/map/stairSurfaces.js.map +1 -0
- package/dist/map/surfaces.js +136 -0
- package/dist/map/surfaces.js.map +1 -0
- package/dist/map/textures.js +95 -0
- package/dist/map/textures.js.map +1 -0
- package/dist/map/underground.js +34 -0
- package/dist/map/underground.js.map +1 -0
- package/dist/map/walk.js +433 -0
- package/dist/map/walk.js.map +1 -0
- package/dist/map/walkContext.js +46 -0
- package/dist/map/walkContext.js.map +1 -0
- package/dist/map/walkDimensions.js +7 -0
- package/dist/map/walkDimensions.js.map +1 -0
- package/dist/map/walkJourney.js +85 -0
- package/dist/map/walkJourney.js.map +1 -0
- package/dist/map/walkSurfaces.js +106 -0
- package/dist/map/walkSurfaces.js.map +1 -0
- package/dist/map/wallJoins.js +70 -0
- package/dist/map/wallJoins.js.map +1 -0
- package/dist/map/water.js +274 -0
- package/dist/map/water.js.map +1 -0
- package/dist/model/authoring.js +99 -0
- package/dist/model/authoring.js.map +1 -0
- package/dist/model/boundaries.js +548 -0
- package/dist/model/boundaries.js.map +1 -0
- package/dist/model/coverage.js +30 -0
- package/dist/model/coverage.js.map +1 -0
- package/dist/model/document.js +52 -0
- package/dist/model/document.js.map +1 -0
- package/dist/model/doors.js +47 -0
- package/dist/model/doors.js.map +1 -0
- package/dist/model/factory.js +56 -0
- package/dist/model/factory.js.map +1 -0
- package/dist/model/geometry.js +454 -0
- package/dist/model/geometry.js.map +1 -0
- package/dist/model/history.js +29 -0
- package/dist/model/history.js.map +1 -0
- package/dist/model/imports.js +45 -0
- package/dist/model/imports.js.map +1 -0
- package/dist/model/inference.js +182 -0
- package/dist/model/inference.js.map +1 -0
- package/dist/model/materials.js +11 -0
- package/dist/model/materials.js.map +1 -0
- package/dist/model/mutations.js +157 -0
- package/dist/model/mutations.js.map +1 -0
- package/dist/model/navigation.js +275 -0
- package/dist/model/navigation.js.map +1 -0
- package/dist/model/ontology.js +109 -0
- package/dist/model/ontology.js.map +1 -0
- package/dist/model/passages.js +5 -0
- package/dist/model/passages.js.map +1 -0
- package/dist/model/portals.js +42 -0
- package/dist/model/portals.js.map +1 -0
- package/dist/model/precision.js +11 -0
- package/dist/model/precision.js.map +1 -0
- package/dist/model/project.js +31 -0
- package/dist/model/project.js.map +1 -0
- package/dist/model/ramps.js +10 -0
- package/dist/model/ramps.js.map +1 -0
- package/dist/model/roomNavigation.js +87 -0
- package/dist/model/roomNavigation.js.map +1 -0
- package/dist/model/routeClearance.js +72 -0
- package/dist/model/routeClearance.js.map +1 -0
- package/dist/model/spaces.js +104 -0
- package/dist/model/spaces.js.map +1 -0
- package/dist/model/stairGeometry.js +40 -0
- package/dist/model/stairGeometry.js.map +1 -0
- package/dist/model/stairTraversal.js +48 -0
- package/dist/model/stairTraversal.js.map +1 -0
- package/dist/model/topology.js +63 -0
- package/dist/model/topology.js.map +1 -0
- package/dist/model/types.js +35 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validate.js +240 -0
- package/dist/model/validate.js.map +1 -0
- package/dist/model/vertical.js +129 -0
- package/dist/model/vertical.js.map +1 -0
- package/dist/model/walls.js +261 -0
- package/dist/model/walls.js.map +1 -0
- package/dist/planner/DrawingDock.js +231 -0
- package/dist/planner/DrawingDock.js.map +1 -0
- package/dist/planner/FloorControls.js +93 -0
- package/dist/planner/FloorControls.js.map +1 -0
- package/dist/planner/MapSettings.js +143 -0
- package/dist/planner/MapSettings.js.map +1 -0
- package/dist/planner/PlannerHelp.js +57 -0
- package/dist/planner/PlannerHelp.js.map +1 -0
- package/dist/planner/ProjectSidebar.js +246 -0
- package/dist/planner/ProjectSidebar.js.map +1 -0
- package/dist/planner/floors.js +18 -0
- package/dist/planner/floors.js.map +1 -0
- package/dist/planner/useDrawingTools.js +341 -0
- package/dist/planner/useDrawingTools.js.map +1 -0
- package/dist/planner/useMapDisplay.js +51 -0
- package/dist/planner/useMapDisplay.js.map +1 -0
- package/dist/planner/usePlannerKeyboard.js +138 -0
- package/dist/planner/usePlannerKeyboard.js.map +1 -0
- package/dist/planner/useReferenceAlignment.js +50 -0
- package/dist/planner/useReferenceAlignment.js.map +1 -0
- package/dist/styles.css +4931 -0
- package/dist/theme/index.js +34 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/types/SitePlanner.d.ts +5 -0
- package/dist/types/adapters/basemap.d.ts +2 -0
- package/dist/types/adapters/persistence.d.ts +29 -0
- package/dist/types/adapters/status.d.ts +4 -0
- package/dist/types/adapters/useProjectPersistence.d.ts +13 -0
- package/dist/types/components/AiImportPanel.d.ts +9 -0
- package/dist/types/components/AnalysisPreview.d.ts +4 -0
- package/dist/types/components/ElevatorPanel.d.ts +18 -0
- package/dist/types/components/Icons.d.ts +8 -0
- package/dist/types/components/ImportDialog.d.ts +42 -0
- package/dist/types/components/Inspector.d.ts +38 -0
- package/dist/types/components/NavigatePanel.d.ts +27 -0
- package/dist/types/components/NavigationGraph.d.ts +10 -0
- package/dist/types/components/StructureExplorer.d.ts +8 -0
- package/dist/types/components/StructureView.d.ts +22 -0
- package/dist/types/components/controls.d.ts +52 -0
- package/dist/types/components/graphLayout.d.ts +9 -0
- package/dist/types/editor/host.d.ts +9 -0
- package/dist/types/editor/index.d.ts +2 -0
- package/dist/types/i18n.d.ts +85 -0
- package/dist/types/import/analysisPreview.d.ts +27 -0
- package/dist/types/import/brief.d.ts +22 -0
- package/dist/types/import/checkpoint.d.ts +49 -0
- package/dist/types/import/detect.d.ts +34 -0
- package/dist/types/import/documentSvg.d.ts +2 -0
- package/dist/types/import/index.d.ts +10 -0
- package/dist/types/import/instructions.d.ts +7 -0
- package/dist/types/import/openings.d.ts +22 -0
- package/dist/types/import/planImport.d.ts +22 -0
- package/dist/types/import/register.d.ts +25 -0
- package/dist/types/import/runs.d.ts +31 -0
- package/dist/types/import/session.d.ts +33 -0
- package/dist/types/import/types.d.ts +56 -0
- package/dist/types/import/usage.d.ts +10 -0
- package/dist/types/import/walls.d.ts +37 -0
- package/dist/types/map/CabinMaterials.d.ts +18 -0
- package/dist/types/map/CabinMirror.d.ts +13 -0
- package/dist/types/map/Doors.d.ts +11 -0
- package/dist/types/map/ElevatorCabin.d.ts +20 -0
- package/dist/types/map/FixtureLights.d.ts +35 -0
- package/dist/types/map/MapCanvas.d.ts +87 -0
- package/dist/types/map/Passenger.d.ts +18 -0
- package/dist/types/map/SceneLayer.d.ts +306 -0
- package/dist/types/map/UndergroundContext.d.ts +18 -0
- package/dist/types/map/ambience.d.ts +29 -0
- package/dist/types/map/architecture.d.ts +8 -0
- package/dist/types/map/bathMusic.d.ts +14 -0
- package/dist/types/map/cameraAim.d.ts +20 -0
- package/dist/types/map/elevators.d.ts +16 -0
- package/dist/types/map/excavation.d.ts +9 -0
- package/dist/types/map/exteriors.d.ts +3 -0
- package/dist/types/map/features.d.ts +33 -0
- package/dist/types/map/fences.d.ts +4 -0
- package/dist/types/map/journey.d.ts +36 -0
- package/dist/types/map/levels.d.ts +4 -0
- package/dist/types/map/lighting.d.ts +103 -0
- package/dist/types/map/loadBasemap.d.ts +4 -0
- package/dist/types/map/materials.d.ts +38 -0
- package/dist/types/map/poolLighting.d.ts +11 -0
- package/dist/types/map/projection.d.ts +9 -0
- package/dist/types/map/rampGeometry.d.ts +8 -0
- package/dist/types/map/route.d.ts +59 -0
- package/dist/types/map/stairSurfaces.d.ts +29 -0
- package/dist/types/map/surfaces.d.ts +36 -0
- package/dist/types/map/textures.d.ts +8 -0
- package/dist/types/map/underground.d.ts +30 -0
- package/dist/types/map/walk.d.ts +232 -0
- package/dist/types/map/walkContext.d.ts +11 -0
- package/dist/types/map/walkDimensions.d.ts +5 -0
- package/dist/types/map/walkJourney.d.ts +33 -0
- package/dist/types/map/walkSurfaces.d.ts +27 -0
- package/dist/types/map/wallJoins.d.ts +6 -0
- package/dist/types/map/water.d.ts +12 -0
- package/dist/types/model/authoring.d.ts +38 -0
- package/dist/types/model/boundaries.d.ts +41 -0
- package/dist/types/model/coverage.d.ts +8 -0
- package/dist/types/model/document.d.ts +9 -0
- package/dist/types/model/doors.d.ts +19 -0
- package/dist/types/model/factory.d.ts +5 -0
- package/dist/types/model/geometry.d.ts +99 -0
- package/dist/types/model/history.d.ts +10 -0
- package/dist/types/model/host.d.ts +154 -0
- package/dist/types/model/imports.d.ts +7 -0
- package/dist/types/model/inference.d.ts +46 -0
- package/dist/types/model/live.d.ts +60 -0
- package/dist/types/model/materials.d.ts +28 -0
- package/dist/types/model/mutations.d.ts +178 -0
- package/dist/types/model/navigation.d.ts +70 -0
- package/dist/types/model/ontology.d.ts +43 -0
- package/dist/types/model/passages.d.ts +2 -0
- package/dist/types/model/portals.d.ts +9 -0
- package/dist/types/model/precision.d.ts +11 -0
- package/dist/types/model/project.d.ts +8 -0
- package/dist/types/model/ramps.d.ts +7 -0
- package/dist/types/model/roomNavigation.d.ts +15 -0
- package/dist/types/model/routeClearance.d.ts +11 -0
- package/dist/types/model/spaces.d.ts +46 -0
- package/dist/types/model/stairGeometry.d.ts +27 -0
- package/dist/types/model/stairTraversal.d.ts +8 -0
- package/dist/types/model/topology.d.ts +14 -0
- package/dist/types/model/types.d.ts +369 -0
- package/dist/types/model/validate.d.ts +38 -0
- package/dist/types/model/vertical.d.ts +145 -0
- package/dist/types/model/walls.d.ts +71 -0
- package/dist/types/planner/DrawingDock.d.ts +16 -0
- package/dist/types/planner/FloorControls.d.ts +17 -0
- package/dist/types/planner/MapSettings.d.ts +16 -0
- package/dist/types/planner/PlannerHelp.d.ts +3 -0
- package/dist/types/planner/ProjectSidebar.d.ts +32 -0
- package/dist/types/planner/floors.d.ts +3 -0
- package/dist/types/planner/types.d.ts +3 -0
- package/dist/types/planner/useDrawingTools.d.ts +52 -0
- package/dist/types/planner/useMapDisplay.d.ts +29 -0
- package/dist/types/planner/usePlannerKeyboard.d.ts +18 -0
- package/dist/types/planner/useReferenceAlignment.d.ts +30 -0
- package/dist/types/schema/index.d.ts +25 -0
- package/dist/types/theme/index.d.ts +55 -0
- package/package.json +58 -4
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { jsx as e, jsxs as a, Fragment as A } from "react/jsx-runtime";
|
|
2
|
+
import { lazy as T, Suspense as B, useState as H, useMemo as V } from "react";
|
|
3
|
+
import { isSpace as W } from "../model/types.js";
|
|
4
|
+
import { zoneSpaces as D, addZone as j, perimeter as G, captive as J, setZoneMembers as K, removeZone as Q, entryInto as L } from "../model/ontology.js";
|
|
5
|
+
import { refreshPortals as X } from "../model/inference.js";
|
|
6
|
+
import { Plus as Y, RefreshCw as _, Shapes as q, ChevronDown as E, ChevronRight as ee, LocateFixed as R, Trash2 as ne, DoorOpen as te, MoveHorizontal as se, Layers as ae } from "lucide-react";
|
|
7
|
+
const ie = T(
|
|
8
|
+
() => import("./StructureExplorer.js").then((s) => ({ default: s.StructureExplorer }))
|
|
9
|
+
), le = "Outdoor site";
|
|
10
|
+
function re(s, p) {
|
|
11
|
+
const g = L(s, p) !== null, N = L(s, s.a === p ? s.b : s.a) !== null;
|
|
12
|
+
return g && N ? "both ways" : g ? "in only" : N ? "out only" : "sealed";
|
|
13
|
+
}
|
|
14
|
+
function be(s) {
|
|
15
|
+
return /* @__PURE__ */ e(
|
|
16
|
+
B,
|
|
17
|
+
{
|
|
18
|
+
fallback: /* @__PURE__ */ e("p", { className: "structure-empty", role: "status", children: "Loading structure…" }),
|
|
19
|
+
children: /* @__PURE__ */ e(ie, { ...s, renderZones: (p) => /* @__PURE__ */ e(ce, { ...s, ...p }) })
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
function ce({
|
|
24
|
+
project: s,
|
|
25
|
+
selected: p,
|
|
26
|
+
onSelect: g,
|
|
27
|
+
onFloorChange: N,
|
|
28
|
+
onEdit: h,
|
|
29
|
+
onLocate: y,
|
|
30
|
+
query: $,
|
|
31
|
+
floor: S
|
|
32
|
+
}) {
|
|
33
|
+
var F;
|
|
34
|
+
const [P, U] = H(null), c = p && s.objects.find((r) => r.id === p && W(r.kind)), I = V(() => {
|
|
35
|
+
const r = new Map(s.objects.map((i) => [i.id, i])), u = new Map(s.floors.map((i) => [i.id, i.name])), t = s.zones ?? [], m = /* @__PURE__ */ new Map();
|
|
36
|
+
for (const i of t) {
|
|
37
|
+
const b = D(s, i).map((o) => r.get(o)).filter(Boolean), z = [i.name, i.id, i.purpose, ...b.map((o) => o == null ? void 0 : o.name)].join(" ").toLowerCase();
|
|
38
|
+
if ($.trim() && !z.includes($.trim().toLowerCase()) || S !== "all" && !b.some((o) => {
|
|
39
|
+
var n;
|
|
40
|
+
return ((o == null ? void 0 : o.floorId) ?? "outdoors") === S || ((n = o == null ? void 0 : o.servedFloorIds) == null ? void 0 : n.includes(S));
|
|
41
|
+
}))
|
|
42
|
+
continue;
|
|
43
|
+
const f = i.purpose ?? "other", k = m.get(f);
|
|
44
|
+
k ? k.push(i) : m.set(f, [i]);
|
|
45
|
+
}
|
|
46
|
+
return { byId: r, floors: u, groups: m };
|
|
47
|
+
}, [s, $, S]), w = (r) => {
|
|
48
|
+
var u;
|
|
49
|
+
return ((u = I.byId.get(r)) == null ? void 0 : u.name) ?? "Unknown";
|
|
50
|
+
}, x = (r) => {
|
|
51
|
+
var t;
|
|
52
|
+
const u = ((t = I.byId.get(r)) == null ? void 0 : t.floorId) ?? null;
|
|
53
|
+
return { floorId: u, label: u === null ? le : I.floors.get(u) ?? "Unknown level" };
|
|
54
|
+
}, Z = (r) => {
|
|
55
|
+
g == null || g(r), N == null || N(x(r).floorId);
|
|
56
|
+
}, M = h ? /* @__PURE__ */ a("div", { className: "structure-actions", children: [
|
|
57
|
+
/* @__PURE__ */ a(
|
|
58
|
+
"button",
|
|
59
|
+
{
|
|
60
|
+
type: "button",
|
|
61
|
+
className: "text-button",
|
|
62
|
+
disabled: !c,
|
|
63
|
+
title: c ? `New zone containing ${c.name}` : "Select an area on the plan first",
|
|
64
|
+
onClick: () => {
|
|
65
|
+
c && h((r) => j(r, `${c.name} zone`, [c.id], "security"));
|
|
66
|
+
},
|
|
67
|
+
children: [
|
|
68
|
+
/* @__PURE__ */ e(Y, { size: 13 }),
|
|
69
|
+
" New zone"
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
/* @__PURE__ */ a(
|
|
74
|
+
"button",
|
|
75
|
+
{
|
|
76
|
+
type: "button",
|
|
77
|
+
className: "text-button",
|
|
78
|
+
title: "Re-read portals from the plan, keeping any you have edited",
|
|
79
|
+
onClick: () => h((r) => X(r)),
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ e(_, { size: 13 }),
|
|
82
|
+
" Re-read portals"
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
] }) : null;
|
|
87
|
+
return I.groups.size ? /* @__PURE__ */ a("div", { className: "structure-zone-list", children: [
|
|
88
|
+
M,
|
|
89
|
+
/* @__PURE__ */ e("div", { className: "inspector-scroll structure-scroll", children: [...I.groups].map(([r, u]) => /* @__PURE__ */ a("section", { className: "structure-group", children: [
|
|
90
|
+
/* @__PURE__ */ e("h3", { children: r }),
|
|
91
|
+
u.map((t) => {
|
|
92
|
+
var k, o;
|
|
93
|
+
const m = P === t.id, i = D(s, t), b = G(s, t), z = m ? J(s, t) : [], f = new Set(i);
|
|
94
|
+
return /* @__PURE__ */ a("div", { className: `structure-zone ${m ? "open" : ""}`, children: [
|
|
95
|
+
/* @__PURE__ */ a("div", { className: "structure-zone-toolbar", children: [
|
|
96
|
+
/* @__PURE__ */ a(
|
|
97
|
+
"button",
|
|
98
|
+
{
|
|
99
|
+
type: "button",
|
|
100
|
+
className: "structure-zone-head",
|
|
101
|
+
"aria-expanded": m,
|
|
102
|
+
onClick: () => U(m ? null : t.id),
|
|
103
|
+
children: [
|
|
104
|
+
m ? /* @__PURE__ */ e(E, { size: 14 }) : /* @__PURE__ */ e(ee, { size: 14 }),
|
|
105
|
+
/* @__PURE__ */ e("strong", { children: t.name }),
|
|
106
|
+
/* @__PURE__ */ a("span", { className: "structure-counts", children: [
|
|
107
|
+
i.length,
|
|
108
|
+
" ",
|
|
109
|
+
i.length === 1 ? "space" : "spaces",
|
|
110
|
+
b.length > 0 && ` · ${b.length} in`,
|
|
111
|
+
t.connects && ` · ${{ all: "lift", adjacent: "stairs", up: "escalator up", down: "escalator down" }[t.connects]}`
|
|
112
|
+
] })
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
/* @__PURE__ */ e(
|
|
117
|
+
"button",
|
|
118
|
+
{
|
|
119
|
+
className: "structure-locate",
|
|
120
|
+
"aria-label": `Find ${t.name} on map`,
|
|
121
|
+
title: "Find on map",
|
|
122
|
+
disabled: !i.length,
|
|
123
|
+
onClick: () => y ? y({ objectIds: i }) : Z(i[0]),
|
|
124
|
+
children: /* @__PURE__ */ e(R, { size: 13 })
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] }),
|
|
128
|
+
m && /* @__PURE__ */ a("div", { className: "structure-detail", children: [
|
|
129
|
+
h && /* @__PURE__ */ a("div", { className: "structure-edit", children: [
|
|
130
|
+
/* @__PURE__ */ e(
|
|
131
|
+
"input",
|
|
132
|
+
{
|
|
133
|
+
"aria-label": "Zone name",
|
|
134
|
+
value: t.name,
|
|
135
|
+
onChange: (n) => {
|
|
136
|
+
const l = n.target.value;
|
|
137
|
+
h((d) => {
|
|
138
|
+
var C;
|
|
139
|
+
const v = (C = d.zones) == null ? void 0 : C.find((O) => O.id === t.id);
|
|
140
|
+
v && (v.name = l);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ a(
|
|
146
|
+
"select",
|
|
147
|
+
{
|
|
148
|
+
"aria-label": "Connects",
|
|
149
|
+
value: t.connects ?? "",
|
|
150
|
+
onChange: (n) => {
|
|
151
|
+
const l = n.target.value;
|
|
152
|
+
h((d) => {
|
|
153
|
+
var C;
|
|
154
|
+
const v = (C = d.zones) == null ? void 0 : C.find((O) => O.id === t.id);
|
|
155
|
+
v && (v.connects = l || void 0);
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ e("option", { value: "", children: "No implied route" }),
|
|
160
|
+
/* @__PURE__ */ e("option", { value: "all", children: "Lift · any landing to any" }),
|
|
161
|
+
/* @__PURE__ */ e("option", { value: "adjacent", children: "Stair · level by level" }),
|
|
162
|
+
/* @__PURE__ */ e("option", { value: "up", children: "Escalator · up only" }),
|
|
163
|
+
/* @__PURE__ */ e("option", { value: "down", children: "Escalator · down only" })
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
/* @__PURE__ */ e(
|
|
168
|
+
"button",
|
|
169
|
+
{
|
|
170
|
+
type: "button",
|
|
171
|
+
className: "text-button",
|
|
172
|
+
disabled: !c,
|
|
173
|
+
title: c ? f.has(c.id) ? `Remove ${c.name}` : `Add ${c.name}` : "Select an area on the plan first",
|
|
174
|
+
onClick: () => {
|
|
175
|
+
if (!c) return;
|
|
176
|
+
const n = !f.has(c.id);
|
|
177
|
+
h((l) => K(l, t.id, [c.id], n));
|
|
178
|
+
},
|
|
179
|
+
children: c && f.has(c.id) ? "Remove selected" : "Add selected"
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
/* @__PURE__ */ e(
|
|
183
|
+
"button",
|
|
184
|
+
{
|
|
185
|
+
type: "button",
|
|
186
|
+
className: "icon-button",
|
|
187
|
+
"aria-label": `Delete ${t.name}`,
|
|
188
|
+
onClick: () => h((n) => Q(n, t.id)),
|
|
189
|
+
children: /* @__PURE__ */ e(ne, { size: 14 })
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
] }),
|
|
193
|
+
b.length > 0 && /* @__PURE__ */ a(A, { children: [
|
|
194
|
+
/* @__PURE__ */ a("h4", { children: [
|
|
195
|
+
/* @__PURE__ */ e(te, { size: 12 }),
|
|
196
|
+
" Ways in"
|
|
197
|
+
] }),
|
|
198
|
+
/* @__PURE__ */ e("ul", { children: b.map((n) => {
|
|
199
|
+
const l = f.has(n.a) ? n.a : n.b, d = l === n.a ? n.b : n.a;
|
|
200
|
+
return /* @__PURE__ */ a("li", { className: "structure-member", children: [
|
|
201
|
+
/* @__PURE__ */ a("span", { className: "structure-member-title", children: [
|
|
202
|
+
/* @__PURE__ */ e("span", { className: "structure-from", children: w(d) }),
|
|
203
|
+
/* @__PURE__ */ e(se, { size: 11 }),
|
|
204
|
+
/* @__PURE__ */ e("span", { children: w(l) }),
|
|
205
|
+
/* @__PURE__ */ e("em", { children: re(n, l) })
|
|
206
|
+
] }),
|
|
207
|
+
/* @__PURE__ */ e(
|
|
208
|
+
"button",
|
|
209
|
+
{
|
|
210
|
+
type: "button",
|
|
211
|
+
className: "structure-locate",
|
|
212
|
+
title: "Find on map",
|
|
213
|
+
"aria-label": `Find passage from ${w(d)} to ${w(l)} on map`,
|
|
214
|
+
onClick: () => y ? y({
|
|
215
|
+
objectIds: n.openingId ? [n.openingId] : [l, d],
|
|
216
|
+
floorId: x(d).floorId
|
|
217
|
+
}) : Z(n.openingId ?? l),
|
|
218
|
+
children: /* @__PURE__ */ e(R, { size: 13 })
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
] }, n.id);
|
|
222
|
+
}) })
|
|
223
|
+
] }),
|
|
224
|
+
!!((k = t.childZoneIds) != null && k.length) && /* @__PURE__ */ a("div", { className: "structure-note", children: [
|
|
225
|
+
"Contains zones:",
|
|
226
|
+
" ",
|
|
227
|
+
t.childZoneIds.map((n) => {
|
|
228
|
+
var l, d;
|
|
229
|
+
return ((d = (l = s.zones) == null ? void 0 : l.find((v) => v.id === n)) == null ? void 0 : d.name) ?? n;
|
|
230
|
+
}).join(", ")
|
|
231
|
+
] }),
|
|
232
|
+
((o = s.zones) == null ? void 0 : o.some((n) => {
|
|
233
|
+
var l;
|
|
234
|
+
return (l = n.childZoneIds) == null ? void 0 : l.includes(t.id);
|
|
235
|
+
})) && /* @__PURE__ */ a("div", { className: "structure-note", children: [
|
|
236
|
+
"Part of:",
|
|
237
|
+
" ",
|
|
238
|
+
s.zones.filter((n) => {
|
|
239
|
+
var l;
|
|
240
|
+
return (l = n.childZoneIds) == null ? void 0 : l.includes(t.id);
|
|
241
|
+
}).map((n) => n.name).join(", ")
|
|
242
|
+
] }),
|
|
243
|
+
/* @__PURE__ */ a("h4", { children: [
|
|
244
|
+
/* @__PURE__ */ e(ae, { size: 12 }),
|
|
245
|
+
" Spaces"
|
|
246
|
+
] }),
|
|
247
|
+
/* @__PURE__ */ e("ul", { children: i.map((n) => /* @__PURE__ */ a("li", { className: "structure-member", children: [
|
|
248
|
+
/* @__PURE__ */ a("span", { className: "structure-member-title", children: [
|
|
249
|
+
/* @__PURE__ */ e("span", { children: w(n) }),
|
|
250
|
+
/* @__PURE__ */ e("em", { children: x(n).label })
|
|
251
|
+
] }),
|
|
252
|
+
/* @__PURE__ */ e(
|
|
253
|
+
"button",
|
|
254
|
+
{
|
|
255
|
+
type: "button",
|
|
256
|
+
className: "structure-locate",
|
|
257
|
+
title: "Find on map",
|
|
258
|
+
"aria-label": `Find ${w(n)} on map`,
|
|
259
|
+
onClick: () => y ? y({ objectIds: [n] }) : Z(n),
|
|
260
|
+
children: /* @__PURE__ */ e(R, { size: 13 })
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
] }, n)) }),
|
|
264
|
+
z.length > 0 && /* @__PURE__ */ a("p", { className: "structure-note", children: [
|
|
265
|
+
z.length,
|
|
266
|
+
" portal",
|
|
267
|
+
z.length > 1 ? "s" : "",
|
|
268
|
+
" inside this zone — crossing one does not leave it."
|
|
269
|
+
] })
|
|
270
|
+
] })
|
|
271
|
+
] }, t.id);
|
|
272
|
+
})
|
|
273
|
+
] }, r)) })
|
|
274
|
+
] }) : /* @__PURE__ */ a("div", { className: "structure-zone-list", children: [
|
|
275
|
+
M,
|
|
276
|
+
/* @__PURE__ */ a("div", { className: "structure-empty", children: [
|
|
277
|
+
/* @__PURE__ */ e(q, { size: 22 }),
|
|
278
|
+
/* @__PURE__ */ e("strong", { children: (F = s.zones) != null && F.length ? "No zones match these filters" : "No semantic zones yet" }),
|
|
279
|
+
/* @__PURE__ */ e("p", { children: "Spaces and portals are available in their own tabs. Select a space on the plan to create a named zone." })
|
|
280
|
+
] })
|
|
281
|
+
] });
|
|
282
|
+
}
|
|
283
|
+
export {
|
|
284
|
+
be as StructureView
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=StructureView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StructureView.js","sources":["../../../../src/components/StructureView.tsx"],"sourcesContent":["// Browsing the building as a structure rather than a picture.\n//\n// A map is the wrong instrument for most of what the ontology says. A zone spanning eleven floors, a\n// lift shaft, \"everywhere a contractor may go\" — none of those have a shape, and drawing them on a\n// plan either lies about them or hides them. This view reads the same document as a list of what\n// groups with what and what opens onto what, which is the form those questions actually take.\nimport { lazy, Suspense, useMemo, useState } from 'react';\nimport { isSpace, type Point, type Portal, type ProjectDocument, type SiteObject, type Zone } from '../model/types';\nimport { addZone, captive, entryInto, perimeter, removeZone, setZoneMembers, zoneSpaces } from '../model/ontology';\nimport { refreshPortals } from '../model/inference';\nconst StructureExplorer = lazy(() =>\n import('./StructureExplorer').then(module => ({ default: module.StructureExplorer })),\n);\nimport {\n ChevronDown,\n ChevronRight,\n DoorOpen,\n Layers,\n LocateFixed,\n MoveHorizontal,\n Plus,\n RefreshCw,\n Shapes,\n Trash2,\n} from 'lucide-react';\n\nexport interface StructureViewProps {\n project: ProjectDocument;\n selected?: string | null;\n /** Fires when a space or opening is picked, so a host can follow along on the plan. */\n onSelect?: (id: string) => void;\n /** Fires alongside onSelect when the pick lives on a particular floor. */\n onFloorChange?: (floorId: string | null) => void;\n onLocate?: (target: StructureTarget) => void;\n onGraphView?: (floorId?: string | null) => void;\n /** Omit to keep the panel read-only. Given, the panel can author zones: the host applies the\n * mutation to a draft and owns undo, exactly as the map tools do. */\n onEdit?: (change: (draft: ProjectDocument) => void) => void;\n}\nexport interface StructureTarget {\n objectIds?: string[];\n floorId?: string | null;\n position?: Point;\n}\n\nconst OUTDOORS = 'Outdoor site';\n/** Direction, said the way a person would: which way this portal lets you go, relative to a zone. */\nfunction passageLabel(portal: Portal, insideId: string): string {\n const inward = entryInto(portal, insideId) !== null;\n const outward = entryInto(portal, portal.a === insideId ? portal.b : portal.a) !== null;\n if (inward && outward) return 'both ways';\n if (inward) return 'in only';\n if (outward) return 'out only';\n return 'sealed';\n}\n\nexport function StructureView(props: StructureViewProps) {\n return (\n <Suspense\n fallback={\n <p className=\"structure-empty\" role=\"status\">\n Loading structure…\n </p>\n }\n >\n <StructureExplorer {...props} renderZones={filter => <ZoneList {...props} {...filter} />} />\n </Suspense>\n );\n}\n\nfunction ZoneList({\n project,\n selected,\n onSelect,\n onFloorChange,\n onEdit,\n onLocate,\n query,\n floor,\n}: StructureViewProps & { query: string; floor: string }) {\n const [open, setOpen] = useState<string | null>(null);\n const selectedSpace = selected && project.objects.find(o => o.id === selected && isSpace(o.kind));\n const model = useMemo(() => {\n const byId = new Map(project.objects.map(o => [o.id, o]));\n const floors = new Map(project.floors.map(f => [f.id, f.name]));\n const zones = project.zones ?? [];\n const groups = new Map<string, Zone[]>();\n for (const z of zones) {\n const members = zoneSpaces(project, z)\n .map(id => byId.get(id))\n .filter(Boolean);\n const text = [z.name, z.id, z.purpose, ...members.map(o => o?.name)].join(' ').toLowerCase();\n if (query.trim() && !text.includes(query.trim().toLowerCase())) continue;\n if (\n floor !== 'all' &&\n !members.some(o => (o?.floorId ?? 'outdoors') === floor || o?.servedFloorIds?.includes(floor))\n )\n continue;\n const key = z.purpose ?? 'other';\n const list = groups.get(key);\n if (list) list.push(z);\n else groups.set(key, [z]);\n }\n return { byId, floors, groups };\n }, [project, query, floor]);\n\n const name = (id: string) => model.byId.get(id)?.name ?? 'Unknown';\n const floorOf = (id: string) => {\n const floorId = model.byId.get(id)?.floorId ?? null;\n return { floorId, label: floorId === null ? OUTDOORS : (model.floors.get(floorId) ?? 'Unknown level') };\n };\n const pick = (id: string) => {\n onSelect?.(id);\n onFloorChange?.(floorOf(id).floorId);\n };\n\n const actions = onEdit ? (\n <div className=\"structure-actions\">\n <button\n type=\"button\"\n className=\"text-button\"\n disabled={!selectedSpace}\n title={selectedSpace ? `New zone containing ${selectedSpace.name}` : 'Select an area on the plan first'}\n onClick={() => {\n if (!selectedSpace) return;\n onEdit(d => addZone(d, `${selectedSpace.name} zone`, [selectedSpace.id], 'security'));\n }}\n >\n <Plus size={13} /> New zone\n </button>\n <button\n type=\"button\"\n className=\"text-button\"\n title=\"Re-read portals from the plan, keeping any you have edited\"\n onClick={() => onEdit(d => refreshPortals(d))}\n >\n <RefreshCw size={13} /> Re-read portals\n </button>\n </div>\n ) : null;\n\n if (!model.groups.size)\n return (\n <div className=\"structure-zone-list\">\n {actions}\n <div className=\"structure-empty\">\n <Shapes size={22} />\n <strong>{project.zones?.length ? 'No zones match these filters' : 'No semantic zones yet'}</strong>\n <p>Spaces and portals are available in their own tabs. Select a space on the plan to create a named zone.</p>\n </div>\n </div>\n );\n\n return (\n <div className=\"structure-zone-list\">\n {actions}\n <div className=\"inspector-scroll structure-scroll\">\n {[...model.groups].map(([purpose, zones]) => (\n <section key={purpose} className=\"structure-group\">\n <h3>{purpose}</h3>\n {zones.map(zone => {\n const isOpen = open === zone.id;\n const members = zoneSpaces(project, zone);\n const ways = perimeter(project, zone);\n const inner = isOpen ? captive(project, zone) : [];\n const inside = new Set(members);\n return (\n <div key={zone.id} className={`structure-zone ${isOpen ? 'open' : ''}`}>\n <div className=\"structure-zone-toolbar\">\n <button\n type=\"button\"\n className=\"structure-zone-head\"\n aria-expanded={isOpen}\n onClick={() => setOpen(isOpen ? null : zone.id)}\n >\n {isOpen ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n <strong>{zone.name}</strong>\n <span className=\"structure-counts\">\n {members.length} {members.length === 1 ? 'space' : 'spaces'}\n {ways.length > 0 && ` · ${ways.length} in`}\n {zone.connects &&\n ` · ${{ all: 'lift', adjacent: 'stairs', up: 'escalator up', down: 'escalator down' }[zone.connects]}`}\n </span>\n </button>\n <button\n className=\"structure-locate\"\n aria-label={`Find ${zone.name} on map`}\n title=\"Find on map\"\n disabled={!members.length}\n onClick={() => (onLocate ? onLocate({ objectIds: members }) : pick(members[0]))}\n >\n <LocateFixed size={13} />\n </button>\n </div>\n {isOpen && (\n <div className=\"structure-detail\">\n {onEdit && (\n <div className=\"structure-edit\">\n <input\n aria-label=\"Zone name\"\n value={zone.name}\n onChange={e => {\n const name = e.target.value;\n onEdit(d => {\n const z = d.zones?.find(x => x.id === zone.id);\n if (z) z.name = name;\n });\n }}\n />\n <select\n aria-label=\"Connects\"\n value={zone.connects ?? ''}\n onChange={e => {\n const v = e.target.value;\n onEdit(d => {\n const z = d.zones?.find(x => x.id === zone.id);\n if (z) z.connects = (v || undefined) as Zone['connects'];\n });\n }}\n >\n <option value=\"\">No implied route</option>\n <option value=\"all\">Lift · any landing to any</option>\n <option value=\"adjacent\">Stair · level by level</option>\n <option value=\"up\">Escalator · up only</option>\n <option value=\"down\">Escalator · down only</option>\n </select>\n <button\n type=\"button\"\n className=\"text-button\"\n disabled={!selectedSpace}\n title={\n !selectedSpace\n ? 'Select an area on the plan first'\n : inside.has(selectedSpace.id)\n ? `Remove ${selectedSpace.name}`\n : `Add ${selectedSpace.name}`\n }\n onClick={() => {\n if (!selectedSpace) return;\n const add = !inside.has(selectedSpace.id);\n onEdit(d => setZoneMembers(d, zone.id, [selectedSpace.id], add));\n }}\n >\n {selectedSpace && inside.has(selectedSpace.id) ? 'Remove selected' : 'Add selected'}\n </button>\n <button\n type=\"button\"\n className=\"icon-button\"\n aria-label={`Delete ${zone.name}`}\n onClick={() => onEdit(d => removeZone(d, zone.id))}\n >\n <Trash2 size={14} />\n </button>\n </div>\n )}\n {ways.length > 0 && (\n <>\n <h4>\n <DoorOpen size={12} /> Ways in\n </h4>\n <ul>\n {ways.map(portal => {\n const insideId = inside.has(portal.a) ? portal.a : portal.b;\n const outsideId = insideId === portal.a ? portal.b : portal.a;\n return (\n <li key={portal.id} className=\"structure-member\">\n <span className=\"structure-member-title\">\n <span className=\"structure-from\">{name(outsideId)}</span>\n <MoveHorizontal size={11} />\n <span>{name(insideId)}</span>\n <em>{passageLabel(portal, insideId)}</em>\n </span>\n <button\n type=\"button\"\n className=\"structure-locate\"\n title=\"Find on map\"\n aria-label={`Find passage from ${name(outsideId)} to ${name(insideId)} on map`}\n onClick={() =>\n onLocate\n ? onLocate({\n objectIds: portal.openingId ? [portal.openingId] : [insideId, outsideId],\n floorId: floorOf(outsideId).floorId,\n })\n : pick(portal.openingId ?? insideId)\n }\n >\n <LocateFixed size={13} />\n </button>\n </li>\n );\n })}\n </ul>\n </>\n )}\n {!!zone.childZoneIds?.length && (\n <div className=\"structure-note\">\n Contains zones:{' '}\n {zone.childZoneIds.map(id => project.zones?.find(z => z.id === id)?.name ?? id).join(', ')}\n </div>\n )}\n {project.zones?.some(z => z.childZoneIds?.includes(zone.id)) && (\n <div className=\"structure-note\">\n Part of:{' '}\n {project.zones\n .filter(z => z.childZoneIds?.includes(zone.id))\n .map(z => z.name)\n .join(', ')}\n </div>\n )}\n <h4>\n <Layers size={12} /> Spaces\n </h4>\n <ul>\n {members.map(id => (\n <li key={id} className=\"structure-member\">\n <span className=\"structure-member-title\">\n <span>{name(id)}</span>\n <em>{floorOf(id).label}</em>\n </span>\n <button\n type=\"button\"\n className=\"structure-locate\"\n title=\"Find on map\"\n aria-label={`Find ${name(id)} on map`}\n onClick={() => (onLocate ? onLocate({ objectIds: [id] }) : pick(id))}\n >\n <LocateFixed size={13} />\n </button>\n </li>\n ))}\n </ul>\n {inner.length > 0 && (\n <p className=\"structure-note\">\n {inner.length} portal{inner.length > 1 ? 's' : ''} inside this zone — crossing one does not\n leave it.\n </p>\n )}\n </div>\n )}\n </div>\n );\n })}\n </section>\n ))}\n </div>\n </div>\n );\n}\n\n/** Exported for hosts that want the same grouping without the chrome. */\nexport const zoneMembers = (project: ProjectDocument, zone: Zone): SiteObject[] =>\n zoneSpaces(project, zone)\n .map(id => project.objects.find(o => o.id === id))\n .filter((o): o is SiteObject => !!o);\n"],"names":["StructureExplorer","lazy","module","OUTDOORS","passageLabel","portal","insideId","inward","entryInto","outward","StructureView","props","jsx","Suspense","filter","ZoneList","project","selected","onSelect","onFloorChange","onEdit","onLocate","query","floor","open","setOpen","useState","selectedSpace","o","isSpace","model","useMemo","byId","floors","f","zones","groups","z","members","zoneSpaces","id","text","_a","key","list","name","floorOf","floorId","pick","actions","jsxs","d","addZone","Plus","refreshPortals","RefreshCw","purpose","zone","isOpen","ways","perimeter","inner","captive","inside","ChevronDown","ChevronRight","LocateFixed","e","x","v","add","setZoneMembers","removeZone","Trash2","Fragment","DoorOpen","outsideId","MoveHorizontal","_b","Layers","Shapes"],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { jsxs as t, jsx as r, Fragment as D } from "react/jsx-runtime";
|
|
2
|
+
import { X as S, ChevronDown as E, Search as x } from "lucide-react";
|
|
3
|
+
import { useRef as k, useEffect as v, useState as b } from "react";
|
|
4
|
+
function $({
|
|
5
|
+
title: c,
|
|
6
|
+
subtitle: l,
|
|
7
|
+
onClose: s,
|
|
8
|
+
children: i,
|
|
9
|
+
wide: a = !1,
|
|
10
|
+
fullscreen: o = !1
|
|
11
|
+
}) {
|
|
12
|
+
const f = k(null);
|
|
13
|
+
return v(() => {
|
|
14
|
+
var m;
|
|
15
|
+
const n = f.current;
|
|
16
|
+
n == null || n.showModal();
|
|
17
|
+
const d = n == null ? void 0 : n.querySelector("input, select, textarea"), u = n == null ? void 0 : n.querySelectorAll("footer button");
|
|
18
|
+
return (m = d ?? (u == null ? void 0 : u[u.length - 1])) == null || m.focus(), () => n == null ? void 0 : n.close();
|
|
19
|
+
}, []), /* @__PURE__ */ t(
|
|
20
|
+
"dialog",
|
|
21
|
+
{
|
|
22
|
+
className: `modal ${a ? "wide" : ""} ${o ? "fullscreen" : ""}`,
|
|
23
|
+
"aria-label": c,
|
|
24
|
+
ref: f,
|
|
25
|
+
onCancel: s,
|
|
26
|
+
onClick: (n) => {
|
|
27
|
+
n.target === n.currentTarget && s();
|
|
28
|
+
},
|
|
29
|
+
children: [
|
|
30
|
+
/* @__PURE__ */ t("header", { children: [
|
|
31
|
+
/* @__PURE__ */ t("div", { children: [
|
|
32
|
+
/* @__PURE__ */ r("h2", { children: c }),
|
|
33
|
+
l && /* @__PURE__ */ r("p", { children: l })
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ r("button", { className: "icon-button", "aria-label": "Close dialog", onClick: s, children: /* @__PURE__ */ r(S, { size: 20 }) })
|
|
36
|
+
] }),
|
|
37
|
+
i
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
function q({
|
|
43
|
+
label: c,
|
|
44
|
+
value: l,
|
|
45
|
+
onChange: s,
|
|
46
|
+
type: i = "text",
|
|
47
|
+
suffix: a,
|
|
48
|
+
min: o,
|
|
49
|
+
max: f,
|
|
50
|
+
step: n
|
|
51
|
+
}) {
|
|
52
|
+
return /* @__PURE__ */ t("label", { className: "field", children: [
|
|
53
|
+
/* @__PURE__ */ r("span", { children: c }),
|
|
54
|
+
/* @__PURE__ */ t("div", { className: "input-wrap", children: [
|
|
55
|
+
/* @__PURE__ */ r(
|
|
56
|
+
"input",
|
|
57
|
+
{
|
|
58
|
+
"aria-label": c,
|
|
59
|
+
type: i,
|
|
60
|
+
defaultValue: l,
|
|
61
|
+
min: o,
|
|
62
|
+
max: f,
|
|
63
|
+
step: n ?? (i === "number" ? 0.1 : void 0),
|
|
64
|
+
onBlur: (d) => {
|
|
65
|
+
String(l) !== d.currentTarget.value && s(d.currentTarget.value);
|
|
66
|
+
},
|
|
67
|
+
onKeyDown: (d) => {
|
|
68
|
+
d.key === "Enter" && d.currentTarget.blur();
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
String(l)
|
|
72
|
+
),
|
|
73
|
+
a && /* @__PURE__ */ r("em", { children: a })
|
|
74
|
+
] })
|
|
75
|
+
] });
|
|
76
|
+
}
|
|
77
|
+
function z({
|
|
78
|
+
label: c,
|
|
79
|
+
value: l,
|
|
80
|
+
onChange: s,
|
|
81
|
+
description: i
|
|
82
|
+
}) {
|
|
83
|
+
return /* @__PURE__ */ t("button", { className: "toggle-row", role: "switch", "aria-checked": l, onClick: s, children: [
|
|
84
|
+
/* @__PURE__ */ t("span", { children: [
|
|
85
|
+
c,
|
|
86
|
+
i && /* @__PURE__ */ r("small", { children: i })
|
|
87
|
+
] }),
|
|
88
|
+
/* @__PURE__ */ r("i", { className: `toggle ${l ? "on" : ""}` })
|
|
89
|
+
] });
|
|
90
|
+
}
|
|
91
|
+
function A({
|
|
92
|
+
label: c,
|
|
93
|
+
value: l,
|
|
94
|
+
options: s,
|
|
95
|
+
onChange: i,
|
|
96
|
+
description: a
|
|
97
|
+
}) {
|
|
98
|
+
return /* @__PURE__ */ t("div", { className: "toggle-row choice-row", children: [
|
|
99
|
+
/* @__PURE__ */ t("div", { className: "choice-head", children: [
|
|
100
|
+
/* @__PURE__ */ r("span", { children: c }),
|
|
101
|
+
/* @__PURE__ */ r("div", { className: "choice", role: "radiogroup", "aria-label": c, children: s.map((o) => /* @__PURE__ */ r(
|
|
102
|
+
"button",
|
|
103
|
+
{
|
|
104
|
+
role: "radio",
|
|
105
|
+
"aria-checked": l === o.value,
|
|
106
|
+
className: l === o.value ? "active" : "",
|
|
107
|
+
title: o.title,
|
|
108
|
+
onClick: () => i(o.value),
|
|
109
|
+
children: o.label
|
|
110
|
+
},
|
|
111
|
+
o.value
|
|
112
|
+
)) })
|
|
113
|
+
] }),
|
|
114
|
+
a && /* @__PURE__ */ r("small", { children: a })
|
|
115
|
+
] });
|
|
116
|
+
}
|
|
117
|
+
function F({
|
|
118
|
+
entries: c,
|
|
119
|
+
value: l,
|
|
120
|
+
onPick: s,
|
|
121
|
+
ariaLabel: i
|
|
122
|
+
}) {
|
|
123
|
+
const [a, o] = b(!1), [f, n] = b(""), [d, u] = b(0), m = k(null), C = k(null), N = c.find((e) => e.id === l), p = f.trim().toLowerCase(), g = a ? c.filter(
|
|
124
|
+
(e) => !p || e.name.toLowerCase().includes(p) || e.code.toLowerCase().includes(p) || (e.hint ?? "").toLowerCase().includes(p)
|
|
125
|
+
).slice(0, 60) : [];
|
|
126
|
+
v(() => {
|
|
127
|
+
const e = (h) => {
|
|
128
|
+
var w;
|
|
129
|
+
(w = m.current) != null && w.contains(h.target) || o(!1);
|
|
130
|
+
};
|
|
131
|
+
return window.addEventListener("pointerdown", e), () => window.removeEventListener("pointerdown", e);
|
|
132
|
+
}, []), v(() => {
|
|
133
|
+
u(0);
|
|
134
|
+
}, [p, a]), v(() => {
|
|
135
|
+
var e;
|
|
136
|
+
a && ((e = C.current) == null || e.focus());
|
|
137
|
+
}, [a]);
|
|
138
|
+
const y = (e) => {
|
|
139
|
+
s(e), o(!1), n("");
|
|
140
|
+
};
|
|
141
|
+
return /* @__PURE__ */ t("div", { className: "floor-select", ref: m, children: [
|
|
142
|
+
/* @__PURE__ */ t(
|
|
143
|
+
"button",
|
|
144
|
+
{
|
|
145
|
+
"aria-label": i,
|
|
146
|
+
"data-value": l,
|
|
147
|
+
className: "floor-select-value",
|
|
148
|
+
onClick: () => {
|
|
149
|
+
o(!a), n("");
|
|
150
|
+
},
|
|
151
|
+
children: [
|
|
152
|
+
N ? /* @__PURE__ */ t(D, { children: [
|
|
153
|
+
/* @__PURE__ */ r("b", { children: N.code }),
|
|
154
|
+
/* @__PURE__ */ r("span", { children: N.name })
|
|
155
|
+
] }) : i,
|
|
156
|
+
/* @__PURE__ */ r(E, { size: 14 })
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
a && /* @__PURE__ */ t("div", { className: "place-options floor-select-options", role: "listbox", children: [
|
|
161
|
+
/* @__PURE__ */ t("div", { className: "place-input", children: [
|
|
162
|
+
/* @__PURE__ */ r(x, { size: 13 }),
|
|
163
|
+
/* @__PURE__ */ r(
|
|
164
|
+
"input",
|
|
165
|
+
{
|
|
166
|
+
ref: C,
|
|
167
|
+
"aria-label": "Search floors",
|
|
168
|
+
placeholder: "Search floors…",
|
|
169
|
+
value: f,
|
|
170
|
+
onChange: (e) => n(e.target.value),
|
|
171
|
+
onBlur: () => setTimeout(() => o(!1), 120),
|
|
172
|
+
onKeyDown: (e) => {
|
|
173
|
+
e.key === "ArrowDown" ? (e.preventDefault(), u((h) => Math.min(h + 1, g.length - 1))) : e.key === "ArrowUp" ? (e.preventDefault(), u((h) => Math.max(h - 1, 0))) : e.key === "Enter" ? (e.preventDefault(), g[d] && y(g[d].id)) : e.key === "Escape" && (e.stopPropagation(), o(!1));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
] }),
|
|
178
|
+
g.map((e, h) => /* @__PURE__ */ t(
|
|
179
|
+
"button",
|
|
180
|
+
{
|
|
181
|
+
role: "option",
|
|
182
|
+
"aria-selected": e.id === l,
|
|
183
|
+
className: `place-option ${h === d ? "cursor" : ""} ${e.id === l ? "chosen" : ""}`,
|
|
184
|
+
onPointerDown: (w) => {
|
|
185
|
+
w.preventDefault(), y(e.id);
|
|
186
|
+
},
|
|
187
|
+
onMouseEnter: () => u(h),
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ r("span", { className: "floor-number", children: e.code }),
|
|
190
|
+
/* @__PURE__ */ t("span", { children: [
|
|
191
|
+
e.name,
|
|
192
|
+
e.hint && /* @__PURE__ */ r("small", { children: e.hint })
|
|
193
|
+
] })
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
e.id
|
|
197
|
+
)),
|
|
198
|
+
!g.length && /* @__PURE__ */ r("p", { className: "place-none", children: "No floors match." })
|
|
199
|
+
] })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
A as Choice,
|
|
204
|
+
q as Field,
|
|
205
|
+
F as FloorSelect,
|
|
206
|
+
$ as Modal,
|
|
207
|
+
z as Toggle
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.js","sources":["../../../../src/components/controls.tsx"],"sourcesContent":["import { ChevronDown, Search, X } from 'lucide-react';\nimport { useEffect, useRef, useState, type ReactNode } from 'react';\nexport function Modal({\n title,\n subtitle,\n onClose,\n children,\n wide = false,\n fullscreen = false,\n}: {\n title: string;\n subtitle?: string;\n onClose: () => void;\n children: ReactNode;\n wide?: boolean;\n fullscreen?: boolean;\n}) {\n const dialog = useRef<HTMLDialogElement>(null);\n useEffect(() => {\n const el = dialog.current;\n el?.showModal();\n // Put the keyboard where the dialog is asking you to act.\n //\n // Left alone, a dialog focuses its first focusable child, which here is the X in the corner: the\n // one control that throws the dialog away. Enter then dismisses the question instead of\n // answering it, which is the opposite of what pressing Enter on a confirmation should do.\n //\n // A dialog that wants typing wants its first field — opening \"Add a floor\" and having to reach\n // for the mouse to click into the name is the wrong first move. Anything else wants the last\n // button in its footer, which is where the action sits.\n const field = el?.querySelector<HTMLElement>('input, select, textarea');\n const actions = el?.querySelectorAll<HTMLElement>('footer button');\n (field ?? actions?.[actions.length - 1])?.focus();\n return () => el?.close();\n }, []);\n return (\n <dialog\n className={`modal ${wide ? 'wide' : ''} ${fullscreen ? 'fullscreen' : ''}`}\n aria-label={title}\n ref={dialog}\n onCancel={onClose}\n onClick={e => {\n if (e.target === e.currentTarget) onClose();\n }}\n >\n <header>\n <div>\n <h2>{title}</h2>\n {subtitle && <p>{subtitle}</p>}\n </div>\n <button className=\"icon-button\" aria-label=\"Close dialog\" onClick={onClose}>\n <X size={20} />\n </button>\n </header>\n {children}\n </dialog>\n );\n}\nexport function Field({\n label,\n value,\n onChange,\n type = 'text',\n suffix,\n min,\n max,\n step,\n}: {\n label: string;\n value: string | number;\n onChange: (value: string) => void;\n type?: string;\n suffix?: string;\n min?: number;\n max?: number;\n step?: number;\n}) {\n return (\n <label className=\"field\">\n <span>{label}</span>\n <div className=\"input-wrap\">\n <input\n key={String(value)}\n aria-label={label}\n type={type}\n defaultValue={value}\n min={min}\n max={max}\n step={step ?? (type === 'number' ? 0.1 : undefined)}\n onBlur={e => {\n if (String(value) !== e.currentTarget.value) onChange(e.currentTarget.value);\n }}\n onKeyDown={e => {\n if (e.key === 'Enter') e.currentTarget.blur();\n }}\n />\n {suffix && <em>{suffix}</em>}\n </div>\n </label>\n );\n}\nexport function Toggle({\n label,\n value,\n onChange,\n description,\n}: {\n label: string;\n value: boolean;\n onChange: () => void;\n description?: string;\n}) {\n return (\n <button className=\"toggle-row\" role=\"switch\" aria-checked={value} onClick={onChange}>\n <span>\n {label}\n {description && <small>{description}</small>}\n </span>\n <i className={`toggle ${value ? 'on' : ''}`} />\n </button>\n );\n}\n\n/** A row of mutually exclusive choices, for a setting that has three answers rather than two.\n * Same shape as `Toggle` — label, optional description, the control on the right — so a panel of\n * switches does not acquire a second visual language for the one setting that needs a third state. */\nexport function Choice<T extends string>({\n label,\n value,\n options,\n onChange,\n description,\n}: {\n label: string;\n value: T;\n options: { value: T; label: string; title?: string }[];\n onChange: (value: T) => void;\n description?: string;\n}) {\n return (\n <div className=\"toggle-row choice-row\">\n <div className=\"choice-head\">\n <span>{label}</span>\n <div className=\"choice\" role=\"radiogroup\" aria-label={label}>\n {options.map(o => (\n <button\n key={o.value}\n role=\"radio\"\n aria-checked={value === o.value}\n className={value === o.value ? 'active' : ''}\n title={o.title}\n onClick={() => onChange(o.value)}\n >\n {o.label}\n </button>\n ))}\n </div>\n </div>\n {description && <small>{description}</small>}\n </div>\n );\n}\n\n/** Searchable dropdown for level selection: projects like the Silo carry a hundred floors. */\nexport interface FloorEntry {\n id: string;\n code: string;\n name: string;\n hint?: string;\n}\nexport function FloorSelect({\n entries,\n value,\n onPick,\n ariaLabel,\n}: {\n entries: FloorEntry[];\n value: string;\n onPick: (id: string) => void;\n ariaLabel: string;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [cursor, setCursor] = useState(0);\n const wrap = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const current = entries.find(e => e.id === value);\n const q = query.trim().toLowerCase();\n const matches = open\n ? entries\n .filter(\n e =>\n !q ||\n e.name.toLowerCase().includes(q) ||\n e.code.toLowerCase().includes(q) ||\n (e.hint ?? '').toLowerCase().includes(q),\n )\n .slice(0, 60)\n : [];\n useEffect(() => {\n const away = (e: PointerEvent) => {\n if (!wrap.current?.contains(e.target as Node)) setOpen(false);\n };\n window.addEventListener('pointerdown', away);\n return () => window.removeEventListener('pointerdown', away);\n }, []);\n useEffect(() => {\n setCursor(0);\n }, [q, open]);\n useEffect(() => {\n if (open) input.current?.focus();\n }, [open]);\n const pick = (id: string) => {\n onPick(id);\n setOpen(false);\n setQuery('');\n };\n return (\n <div className=\"floor-select\" ref={wrap}>\n <button\n aria-label={ariaLabel}\n data-value={value}\n className=\"floor-select-value\"\n onClick={() => {\n setOpen(!open);\n setQuery('');\n }}\n >\n {current ? (\n <>\n <b>{current.code}</b>\n <span>{current.name}</span>\n </>\n ) : (\n ariaLabel\n )}\n <ChevronDown size={14} />\n </button>\n {open && (\n <div className=\"place-options floor-select-options\" role=\"listbox\">\n <div className=\"place-input\">\n <Search size={13} />\n <input\n ref={input}\n aria-label=\"Search floors\"\n placeholder=\"Search floors…\"\n value={query}\n onChange={e => setQuery(e.target.value)}\n onBlur={() => setTimeout(() => setOpen(false), 120)}\n onKeyDown={e => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setCursor(v => Math.min(v + 1, matches.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setCursor(v => Math.max(v - 1, 0));\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (matches[cursor]) pick(matches[cursor].id);\n } else if (e.key === 'Escape') {\n e.stopPropagation();\n setOpen(false);\n }\n }}\n />\n </div>\n {matches.map((e, i) => (\n <button\n key={e.id}\n role=\"option\"\n aria-selected={e.id === value}\n className={`place-option ${i === cursor ? 'cursor' : ''} ${e.id === value ? 'chosen' : ''}`}\n onPointerDown={ev => {\n ev.preventDefault();\n pick(e.id);\n }}\n onMouseEnter={() => setCursor(i)}\n >\n <span className=\"floor-number\">{e.code}</span>\n <span>\n {e.name}\n {e.hint && <small>{e.hint}</small>}\n </span>\n </button>\n ))}\n {!matches.length && <p className=\"place-none\">No floors match.</p>}\n </div>\n )}\n </div>\n );\n}\n"],"names":["Modal","title","subtitle","onClose","children","wide","fullscreen","dialog","useRef","useEffect","el","field","actions","_a","jsxs","e","jsx","X","Field","label","value","onChange","type","suffix","min","max","step","Toggle","description","Choice","options","FloorSelect","entries","onPick","ariaLabel","open","setOpen","useState","query","setQuery","cursor","setCursor","wrap","input","current","q","matches","away","pick","id","Fragment","ChevronDown","Search","v","i","ev"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function r(n, l, M) {
|
|
2
|
+
const v = Math.max(1, Math.ceil(n.length / 80)), y = Math.max(0.08, 1 - M / 360);
|
|
3
|
+
for (let t = 0; t < n.length; t++) {
|
|
4
|
+
const a = n[t];
|
|
5
|
+
a.vx -= a.x * 1e-3 * y, a.vy -= a.y * 1e-3 * y;
|
|
6
|
+
for (let x = (t + M) % v; x < n.length; x += v) {
|
|
7
|
+
if (x === t) continue;
|
|
8
|
+
const c = n[x];
|
|
9
|
+
let e = a.x - c.x, h = a.y - c.y;
|
|
10
|
+
Math.abs(e) + Math.abs(h) < 0.01 && (e = t < x ? -0.1 : 0.1, h = 0.1);
|
|
11
|
+
const o = 90 * v * y / Math.max(25, e * e + h * h);
|
|
12
|
+
a.vx += e * o, a.vy += h * o;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
for (const [t, a] of l) {
|
|
16
|
+
const x = n[t], c = n[a];
|
|
17
|
+
if (!x || !c || t === a) continue;
|
|
18
|
+
const e = c.x - x.x, h = c.y - x.y, o = Math.hypot(e, h) || 1, f = (o - 50) / o * 0.018 * y;
|
|
19
|
+
x.vx += e * f, x.vy += h * f, c.vx -= e * f, c.vy -= h * f;
|
|
20
|
+
}
|
|
21
|
+
for (const t of n)
|
|
22
|
+
t.pinned || (t.x += Math.max(-6, Math.min(6, t.vx)), t.y += Math.max(-6, Math.min(6, t.vy))), t.vx *= 0.7, t.vy *= 0.7;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
r as balanceGraph
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=graphLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphLayout.js","sources":["../../../../src/components/graphLayout.ts"],"sourcesContent":["export interface GraphPoint {\n x: number;\n y: number;\n vx: number;\n vy: number;\n pinned?: boolean;\n}\n/** Bounded sampled repulsion keeps large navigation graphs out of quadratic per-frame work. */\nexport function balanceGraph(points: GraphPoint[], links: [number, number][], tick: number): void {\n const stride = Math.max(1, Math.ceil(points.length / 80));\n const alpha = Math.max(0.08, 1 - tick / 360);\n for (let i = 0; i < points.length; i++) {\n const p = points[i];\n p.vx -= p.x * 0.001 * alpha;\n p.vy -= p.y * 0.001 * alpha;\n for (let j = (i + tick) % stride; j < points.length; j += stride) {\n if (j === i) continue;\n const q = points[j];\n let dx = p.x - q.x,\n dy = p.y - q.y;\n if (Math.abs(dx) + Math.abs(dy) < 0.01) {\n dx = i < j ? -0.1 : 0.1;\n dy = 0.1;\n }\n const force = (90 * stride * alpha) / Math.max(25, dx * dx + dy * dy);\n p.vx += dx * force;\n p.vy += dy * force;\n }\n }\n for (const [a, b] of links) {\n const p = points[a],\n q = points[b];\n if (!p || !q || a === b) continue;\n const dx = q.x - p.x,\n dy = q.y - p.y,\n length = Math.hypot(dx, dy) || 1;\n const force = ((length - 50) / length) * 0.018 * alpha;\n p.vx += dx * force;\n p.vy += dy * force;\n q.vx -= dx * force;\n q.vy -= dy * force;\n }\n for (const p of points) {\n if (!p.pinned) {\n p.x += Math.max(-6, Math.min(6, p.vx));\n p.y += Math.max(-6, Math.min(6, p.vy));\n }\n p.vx *= 0.7;\n p.vy *= 0.7;\n }\n}\n"],"names":["balanceGraph","points","links","tick","stride","alpha","i","p","j","q","dx","dy","force","a","b","length"],"mappings":"AAQO,SAASA,EAAaC,GAAsBC,GAA2BC,GAAoB;AAChG,QAAMC,IAAS,KAAK,IAAI,GAAG,KAAK,KAAKH,EAAO,SAAS,EAAE,CAAC,GAClDI,IAAQ,KAAK,IAAI,MAAM,IAAIF,IAAO,GAAG;AAC3C,WAASG,IAAI,GAAGA,IAAIL,EAAO,QAAQK,KAAK;AACtC,UAAMC,IAAIN,EAAOK,CAAC;AAClB,IAAAC,EAAE,MAAMA,EAAE,IAAI,OAAQF,GACtBE,EAAE,MAAMA,EAAE,IAAI,OAAQF;AACtB,aAASG,KAAKF,IAAIH,KAAQC,GAAQI,IAAIP,EAAO,QAAQO,KAAKJ,GAAQ;AAChE,UAAII,MAAMF,EAAG;AACb,YAAMG,IAAIR,EAAOO,CAAC;AAClB,UAAIE,IAAKH,EAAE,IAAIE,EAAE,GACfE,IAAKJ,EAAE,IAAIE,EAAE;AACf,MAAI,KAAK,IAAIC,CAAE,IAAI,KAAK,IAAIC,CAAE,IAAI,SAChCD,IAAKJ,IAAIE,IAAI,OAAO,KACpBG,IAAK;AAEP,YAAMC,IAAS,KAAKR,IAASC,IAAS,KAAK,IAAI,IAAIK,IAAKA,IAAKC,IAAKA,CAAE;AACpE,MAAAJ,EAAE,MAAMG,IAAKE,GACbL,EAAE,MAAMI,IAAKC;AAAA,IACf;AAAA,EACF;AACA,aAAW,CAACC,GAAGC,CAAC,KAAKZ,GAAO;AAC1B,UAAMK,IAAIN,EAAOY,CAAC,GAChBJ,IAAIR,EAAOa,CAAC;AACd,QAAI,CAACP,KAAK,CAACE,KAAKI,MAAMC,EAAG;AACzB,UAAMJ,IAAKD,EAAE,IAAIF,EAAE,GACjBI,IAAKF,EAAE,IAAIF,EAAE,GACbQ,IAAS,KAAK,MAAML,GAAIC,CAAE,KAAK,GAC3BC,KAAUG,IAAS,MAAMA,IAAU,QAAQV;AACjD,IAAAE,EAAE,MAAMG,IAAKE,GACbL,EAAE,MAAMI,IAAKC,GACbH,EAAE,MAAMC,IAAKE,GACbH,EAAE,MAAME,IAAKC;AAAA,EACf;AACA,aAAWL,KAAKN;AACd,IAAKM,EAAE,WACLA,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,GAAGA,EAAE,EAAE,CAAC,GACrCA,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,GAAGA,EAAE,EAAE,CAAC,IAEvCA,EAAE,MAAM,KACRA,EAAE,MAAM;AAEZ;"}
|