@eyeon/map 2.0.3 → 2.0.4

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.
Files changed (149) hide show
  1. package/dist/assets/MapViewer.css +1 -1
  2. package/dist/assets/index.css +1 -1
  3. package/dist/chunks/MapViewer.js +2557 -1432
  4. package/dist/chunks/MapViewer.js.map +1 -1
  5. package/dist/chunks/stacking.js +1263 -745
  6. package/dist/chunks/stacking.js.map +1 -1
  7. package/dist/chunks/wheelZoom.js +259 -0
  8. package/dist/chunks/wheelZoom.js.map +1 -0
  9. package/dist/core/assignment.d.ts +97 -0
  10. package/dist/core/assignment.d.ts.map +1 -0
  11. package/dist/core/color.d.ts +5 -0
  12. package/dist/core/color.d.ts.map +1 -0
  13. package/dist/core/entranceIcon.d.ts +12 -0
  14. package/dist/core/entranceIcon.d.ts.map +1 -0
  15. package/dist/core/hostChrome.d.ts +2 -4
  16. package/dist/core/hostChrome.d.ts.map +1 -1
  17. package/dist/core/index.d.ts +6 -0
  18. package/dist/core/index.d.ts.map +1 -1
  19. package/dist/core/index.js +161 -89
  20. package/dist/core/labelAlign.d.ts +7 -0
  21. package/dist/core/labelAlign.d.ts.map +1 -0
  22. package/dist/core/layerStyles.d.ts +40 -7
  23. package/dist/core/layerStyles.d.ts.map +1 -1
  24. package/dist/core/outdoorDecoration.d.ts +1 -1
  25. package/dist/core/outdoorDecoration.d.ts.map +1 -1
  26. package/dist/core/publish/index.d.ts +6 -4
  27. package/dist/core/publish/index.d.ts.map +1 -1
  28. package/dist/core/stacking.d.ts +50 -3
  29. package/dist/core/stacking.d.ts.map +1 -1
  30. package/dist/core/types.d.ts +29 -1
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/core/voids.d.ts +41 -0
  33. package/dist/core/voids.d.ts.map +1 -0
  34. package/dist/core/wheelZoom.d.ts +30 -0
  35. package/dist/core/wheelZoom.d.ts.map +1 -0
  36. package/dist/editor/FieldResetButton.d.ts +7 -0
  37. package/dist/editor/FieldResetButton.d.ts.map +1 -0
  38. package/dist/editor/MapEditor.d.ts +12 -2
  39. package/dist/editor/MapEditor.d.ts.map +1 -1
  40. package/dist/editor/canvas/EditorCanvas.d.ts +6 -2
  41. package/dist/editor/canvas/EditorCanvas.d.ts.map +1 -1
  42. package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts +2 -1
  43. package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts.map +1 -1
  44. package/dist/editor/canvas/coords.d.ts +26 -3
  45. package/dist/editor/canvas/coords.d.ts.map +1 -1
  46. package/dist/editor/canvas/editorFill.d.ts +3 -1
  47. package/dist/editor/canvas/editorFill.d.ts.map +1 -1
  48. package/dist/editor/canvas/editorHover.d.ts +4 -0
  49. package/dist/editor/canvas/editorHover.d.ts.map +1 -1
  50. package/dist/editor/canvas/underlayHint.d.ts +8 -0
  51. package/dist/editor/canvas/underlayHint.d.ts.map +1 -1
  52. package/dist/editor/connectorAssignments.d.ts +61 -0
  53. package/dist/editor/connectorAssignments.d.ts.map +1 -1
  54. package/dist/editor/draftOps.d.ts +8 -0
  55. package/dist/editor/draftOps.d.ts.map +1 -1
  56. package/dist/editor/editorSectionReturn.d.ts.map +1 -1
  57. package/dist/editor/ellipseDraw.d.ts +12 -0
  58. package/dist/editor/ellipseDraw.d.ts.map +1 -0
  59. package/dist/editor/entranceIcon.d.ts +15 -0
  60. package/dist/editor/entranceIcon.d.ts.map +1 -0
  61. package/dist/editor/hexColor.d.ts +2 -0
  62. package/dist/editor/hexColor.d.ts.map +1 -1
  63. package/dist/editor/index.css +824 -72
  64. package/dist/editor/index.d.ts +2 -0
  65. package/dist/editor/index.d.ts.map +1 -1
  66. package/dist/editor/index.js +6700 -4160
  67. package/dist/editor/index.js.map +1 -1
  68. package/dist/editor/labelText.d.ts +12 -2
  69. package/dist/editor/labelText.d.ts.map +1 -1
  70. package/dist/editor/labels.d.ts +8 -0
  71. package/dist/editor/labels.d.ts.map +1 -1
  72. package/dist/editor/panels/AssignForm.d.ts +17 -0
  73. package/dist/editor/panels/AssignForm.d.ts.map +1 -0
  74. package/dist/editor/panels/AssignmentStyleFields.d.ts +14 -0
  75. package/dist/editor/panels/AssignmentStyleFields.d.ts.map +1 -0
  76. package/dist/editor/panels/BulkAssignForm.d.ts +11 -0
  77. package/dist/editor/panels/BulkAssignForm.d.ts.map +1 -0
  78. package/dist/editor/panels/CatalogKioskForm.d.ts +18 -0
  79. package/dist/editor/panels/CatalogKioskForm.d.ts.map +1 -0
  80. package/dist/editor/panels/ConnectorAssign.d.ts +6 -2
  81. package/dist/editor/panels/ConnectorAssign.d.ts.map +1 -1
  82. package/dist/editor/panels/CopyToLevelButton.d.ts +10 -0
  83. package/dist/editor/panels/CopyToLevelButton.d.ts.map +1 -0
  84. package/dist/editor/panels/EntranceIconForm.d.ts +11 -0
  85. package/dist/editor/panels/EntranceIconForm.d.ts.map +1 -0
  86. package/dist/editor/panels/Inspector.d.ts +24 -3
  87. package/dist/editor/panels/Inspector.d.ts.map +1 -1
  88. package/dist/editor/panels/LeftRail.d.ts +17 -6
  89. package/dist/editor/panels/LeftRail.d.ts.map +1 -1
  90. package/dist/editor/panels/PreviewOverlay.d.ts +9 -3
  91. package/dist/editor/panels/PreviewOverlay.d.ts.map +1 -1
  92. package/dist/editor/panels/TextLabelForm.d.ts +11 -0
  93. package/dist/editor/panels/TextLabelForm.d.ts.map +1 -0
  94. package/dist/editor/panels/formRows.d.ts +41 -0
  95. package/dist/editor/panels/formRows.d.ts.map +1 -0
  96. package/dist/editor/portalSurface.d.ts +10 -2
  97. package/dist/editor/portalSurface.d.ts.map +1 -1
  98. package/dist/editor/previewDocument.d.ts +2 -1
  99. package/dist/editor/previewDocument.d.ts.map +1 -1
  100. package/dist/editor/railAssignments.d.ts +9 -2
  101. package/dist/editor/railAssignments.d.ts.map +1 -1
  102. package/dist/editor/railKiosks.d.ts +27 -0
  103. package/dist/editor/railKiosks.d.ts.map +1 -0
  104. package/dist/editor/railListCopy.d.ts +31 -0
  105. package/dist/editor/railListCopy.d.ts.map +1 -0
  106. package/dist/editor/routeStubs.d.ts +1 -1
  107. package/dist/editor/routeStubs.d.ts.map +1 -1
  108. package/dist/editor/shapeCopy.d.ts +40 -0
  109. package/dist/editor/shapeCopy.d.ts.map +1 -0
  110. package/dist/editor/shapeSelection.d.ts +6 -0
  111. package/dist/editor/shapeSelection.d.ts.map +1 -0
  112. package/dist/editor/tools.d.ts +12 -2
  113. package/dist/editor/tools.d.ts.map +1 -1
  114. package/dist/fonts/assets.d.ts +4 -0
  115. package/dist/fonts/mapFont.d.ts +5 -0
  116. package/dist/fonts/mapFont.d.ts.map +1 -0
  117. package/dist/fonts/mapFontUrl.d.ts +8 -0
  118. package/dist/fonts/mapFontUrl.d.ts.map +1 -0
  119. package/dist/specialIcons.d.ts +39 -0
  120. package/dist/specialIcons.d.ts.map +1 -0
  121. package/dist/ui/ModernSelect.d.ts.map +1 -1
  122. package/dist/ui/selectSearch.d.ts +3 -0
  123. package/dist/ui/selectSearch.d.ts.map +1 -1
  124. package/dist/viewer/MapViewer.d.ts +14 -1
  125. package/dist/viewer/MapViewer.d.ts.map +1 -1
  126. package/dist/viewer/camera.d.ts +82 -1
  127. package/dist/viewer/camera.d.ts.map +1 -1
  128. package/dist/viewer/components/CameraRig.d.ts +18 -1
  129. package/dist/viewer/components/CameraRig.d.ts.map +1 -1
  130. package/dist/viewer/components/LevelMeshes.d.ts +15 -4
  131. package/dist/viewer/components/LevelMeshes.d.ts.map +1 -1
  132. package/dist/viewer/components/MapScene.d.ts +10 -4
  133. package/dist/viewer/components/MapScene.d.ts.map +1 -1
  134. package/dist/viewer/components/OpeningWell.d.ts +7 -0
  135. package/dist/viewer/components/OpeningWell.d.ts.map +1 -0
  136. package/dist/viewer/components/RouteLine.d.ts.map +1 -1
  137. package/dist/viewer/components/SvgVectorLayer.d.ts +3 -1
  138. package/dist/viewer/components/SvgVectorLayer.d.ts.map +1 -1
  139. package/dist/viewer/components/openingGeometry.d.ts +7 -0
  140. package/dist/viewer/components/openingGeometry.d.ts.map +1 -0
  141. package/dist/viewer/index.css +151 -19
  142. package/dist/viewer/index.js +3 -3
  143. package/dist/viewer/pointer.d.ts +26 -0
  144. package/dist/viewer/pointer.d.ts.map +1 -0
  145. package/dist/viewer/ui/MapControls.d.ts.map +1 -1
  146. package/dist/viewer/ui/RuntimeChrome.d.ts.map +1 -1
  147. package/package.json +4 -2
  148. package/dist/chunks/graph-tools.js +0 -246
  149. package/dist/chunks/graph-tools.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"stacking.js","sources":["../../src/core/layerStyles.ts","../../src/core/types.ts","../../src/core/hostChrome.ts","../../src/core/mediaUrl.ts","../../src/core/geometry/index.ts","../../src/core/import/svgStyle.ts","../../src/core/import/svgTransform.ts","../../src/core/import/index.ts","../../src/core/filletPolygon.ts","../../src/core/routing/pathfinding.ts","../../src/core/publish/index.ts","../../src/core/stacking.ts"],"sourcesContent":["/**\n * Code-only static layer styling for recognized SVG layer-name prefixes.\n * Never loaded from or saved to portal / database theme settings — mirrors\n * v1 `staticMapLayerSettings` in `@eyeon/threejs-map`.\n */\n\nexport interface StaticLayerStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n renderOrder: number;\n extrudeHeight?: number;\n}\n\n/**\n * v1 walking-path has no portal setting — it keeps the SVG fill, and every\n * published mall file uses this icy walkway color. v2 locks the same hex.\n */\nexport const WALKING_PATH_COLOR = '#E9F7FC';\n\n/**\n * Prefix → house style. Matching is normalized so `parking-lane`,\n * `parking_lane`, and `parking-lanes` all resolve to the same entry.\n */\nexport const STATIC_LAYER_STYLES: Record<string, StaticLayerStyle> = {\n 'green-area': {\n fill: '#C4DDAB',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'water-area': {\n fill: '#5cc0f9',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'parking-lane': {\n fill: '#F6F6F6',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'parking-line': {\n stroke: '#DDDDDD',\n strokeWidth: 0.6,\n renderOrder: 6,\n extrudeHeight: 0.5,\n },\n 'parking-icon': {\n fill: '#CCCCCC',\n renderOrder: 7,\n extrudeHeight: 1,\n },\n 'walking-path': {\n fill: WALKING_PATH_COLOR,\n renderOrder: 2,\n extrudeHeight: 1,\n },\n};\n\n/** Collapse punctuation so `parking_lane_2` and `parking-lanes` compare as words. */\nexport function normalizeLayerName(label: string): string {\n return label\n .toLowerCase()\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/**\n * Resolve a static house style from an SVG element / group id.\n * Returns null when the name is not a reserved decoration layer.\n *\n * Matches when the normalized name equals the key, starts with the key as a\n * word (`parking lane 2`), or is a simple plural (`parking lanes`).\n */\nexport function resolveLayerStyle(layerName: string | null | undefined): StaticLayerStyle | null {\n if (!layerName) return null;\n const normalized = normalizeLayerName(layerName);\n if (!normalized) return null;\n\n const keys = Object.keys(STATIC_LAYER_STYLES).sort((a, b) => b.length - a.length);\n for (const key of keys) {\n const keyNorm = normalizeLayerName(key);\n if (normalized === keyNorm) return STATIC_LAYER_STYLES[key];\n // `parking lane 2`, `parking lane-extra`\n if (normalized.startsWith(`${keyNorm} `)) return STATIC_LAYER_STYLES[key];\n // Plural: `parking lanes` from `parking-lanes`\n if (normalized === `${keyNorm}s`) return STATIC_LAYER_STYLES[key];\n if (normalized.startsWith(`${keyNorm}s `)) return STATIC_LAYER_STYLES[key];\n }\n return null;\n}\n\n/**\n * sourceSvgId values the live outdoor SVG should skip because `cm_shapes`\n * already owns them. Static house layers stay in the SVG so walking-path\n * (and parking / green) keep their code colors even when an older import\n * also persisted a walkable row.\n */\nexport function svgIdsOwnedByShapes(\n shapes: Iterable<{ sourceSvgId?: string | null }>,\n options?: { omitStaticLayers?: boolean },\n): Set<string> {\n const omitStatic = options?.omitStaticLayers === true;\n const ids = new Set<string>();\n for (const shape of shapes) {\n const id = shape.sourceSvgId;\n if (!id) continue;\n if (omitStatic && resolveLayerStyle(id)) continue;\n ids.add(id);\n }\n return ids;\n}\n","/**\n * @eyeon/map/core — shared document model types.\n * Pure TypeScript; no React / Three.js.\n */\n\nimport { WALKING_PATH_COLOR } from './layerStyles';\n\nexport type MapVersion = 1 | 2;\n\n/**\n * Surface the map is embedded in.\n *\n * - `PORTAL` — admin Center Map editor (`MapEditor`). Left rail is Map options\n * (Floors, Kiosks, Settings) plus Edit Map — never viewer chrome. Default\n * center is MapViewer (click-to-assign, no editor grid). Edit Map swaps\n * in the geometry canvas and grid.\n * - `PORTAL_ASSIGN` — admin editor default center (`MapViewer` for click-to-\n * assign). Floors + zoom only — no search / amenities.\n * - `WEBSITE` — public website (`MapViewer`).\n * - `DISPLAY_APP` — kiosk (`MapViewer`).\n */\nexport type MapHost =\n | 'PORTAL'\n | 'PORTAL_ASSIGN'\n | 'WEBSITE'\n | 'DISPLAY_APP';\n\n/** Staff editor host. `PORTAL` always shows Map options inside the library. */\nexport type MapEditorHost = Extract<MapHost, 'PORTAL' | 'WEBSITE'>;\n\n/** Public / assign viewer. Never includes Map options. */\nexport type MapViewerHost = Extract<\n MapHost,\n 'WEBSITE' | 'DISPLAY_APP' | 'PORTAL_ASSIGN'\n>;\n\nexport type LevelKind = 'outdoor' | 'floor';\n\nexport type ShapeKind =\n | 'unit'\n | 'amenity'\n | 'kiosk_screen'\n | 'connector'\n | 'entrance'\n | 'walkable'\n | 'void'\n | 'wall'\n | 'boundary'\n | 'floorplate'\n | 'decor'\n | 'label'\n | 'zone'\n | 'parking_zone'\n | 'green_area'\n | 'water'\n | 'parking_icon';\n\nexport type AnchorKind = 'unit' | 'junction' | 'connector' | 'entrance';\n\nexport type EdgeKind = 'walk' | 'unit_link' | 'connector' | 'entrance_link';\n\nexport type ConnectorKind =\n | 'escalator'\n | 'elevator'\n | 'stairs'\n | 'ramp'\n | 'travelator';\n\nexport type ConnectorDirection = 'up' | 'down' | 'both';\n\nexport type UnitStatus =\n | 'occupied'\n | 'vacant'\n | 'coming_soon'\n | 'under_renovation';\n\nexport type AssignmentTargetType =\n | 'retailer'\n | 'amenity'\n | 'kiosk'\n | 'none';\n\nexport type ShapeOrigin = 'import' | 'manual';\n\nexport type DeviceType = 'display_app' | 'desktop' | 'tablet' | 'mobile';\n\nexport type MapRenderMode = '2D' | '3D';\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Vec3 {\n x: number;\n y: number;\n z: number;\n}\n\nexport interface BBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface ViewBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Absolute SVG path subpath preserving Illustrator beziers. */\nexport interface PathSubpath {\n d: string;\n closed: boolean;\n}\n\nexport interface ShapeGeometry {\n /** Absolute path data (Illustrator-compatible). */\n paths: PathSubpath[];\n /** Cached polygon approximation for hit-testing / routing. */\n polygons: Vec2[][];\n}\n\nexport interface ShapeStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n extrudeHeight?: number;\n transparent?: boolean;\n}\n\nexport interface ShapeLabel {\n text?: string;\n imageKey?: string;\n size?: number;\n rotate?: number;\n offsetX?: number;\n offsetY?: number;\n color?: string;\n autoFit?: boolean;\n}\n\nexport interface LevelTransform {\n translateX: number;\n translateY: number;\n scale: number;\n rotate: number;\n}\n\nexport interface ThemeDefaults {\n MAP_STYLE: MapRenderMode;\n MAP_BACKGROUND_COLOR: string;\n ACCENT_COLOR: string;\n STORE_DEFAULT_COLOR: string;\n STORE_TEXT_COLOR: string;\n STORE_HEIGHT: number;\n /** Viewer-only corner radius for store (`unit`) polygons. Edit Map stays sharp. */\n STORE_RADIUS: number;\n WALL_COLOR: string;\n WALL_THICKNESS: number;\n BOUNDARY_COLOR: string;\n BOUNDARY_THICKNESS: number;\n BASE_COLOR: string;\n OVERLAY_COLOR: string;\n OVERLAY_OPACITY: number;\n PARKING_ZONE_COLOR: string;\n GREEN_AREA_COLOR: string;\n WATER_COLOR: string;\n WALKABLE_COLOR: string;\n KIOSK_SIZE: number;\n ZOOM_STEP: number;\n CAMERA_MAX_DISTANCE: number;\n CAMERA_MIN_DISTANCE: number;\n}\n\nexport const DEFAULT_THEME: ThemeDefaults = {\n MAP_STYLE: '2D',\n MAP_BACKGROUND_COLOR: '#FFFFFF',\n ACCENT_COLOR: '#2563eb',\n STORE_DEFAULT_COLOR: '#e2e8f0',\n STORE_TEXT_COLOR: '#1e293b',\n STORE_HEIGHT: 4,\n STORE_RADIUS: 0,\n WALL_COLOR: '#64748b',\n WALL_THICKNESS: 0.4,\n BOUNDARY_COLOR: '#334155',\n BOUNDARY_THICKNESS: 0.6,\n BASE_COLOR: '#ffffff',\n OVERLAY_COLOR: '#000000',\n OVERLAY_OPACITY: 0.15,\n PARKING_ZONE_COLOR: '#cbd5e1',\n GREEN_AREA_COLOR: '#86efac',\n WATER_COLOR: '#7dd3fc',\n WALKABLE_COLOR: WALKING_PATH_COLOR,\n KIOSK_SIZE: 12,\n ZOOM_STEP: 0.5,\n CAMERA_MAX_DISTANCE: 2000,\n CAMERA_MIN_DISTANCE: 50,\n};\n\n/** Early v2 default; same as canvas, so parking-lane #F6F6F6 disappeared. */\nconst LEGACY_V2_MAP_BACKGROUND = '#f5f5f5';\n\n/** Pre-house-color walkway fills — colder gray, then the beige guess. */\nconst LEGACY_WALKABLE_COLORS = new Set(['#f8fafc', '#f1efea']);\n\nconst MAX_STORE_RADIUS = 500;\n\n/** Non-negative store corner radius in SVG units. Invalid values become 0. */\nexport function clampStoreRadius(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(n) || n <= 0) return 0;\n return Math.min(n, MAX_STORE_RADIUS);\n}\n\nexport function mergeTheme(\n ...partials: Array<Partial<ThemeDefaults> | null | undefined>\n): ThemeDefaults {\n const theme = Object.assign({}, DEFAULT_THEME, ...partials.filter(Boolean));\n if (theme.MAP_BACKGROUND_COLOR.toLowerCase() === LEGACY_V2_MAP_BACKGROUND) {\n theme.MAP_BACKGROUND_COLOR = DEFAULT_THEME.MAP_BACKGROUND_COLOR;\n }\n if (LEGACY_WALKABLE_COLORS.has(theme.WALKABLE_COLOR.toLowerCase())) {\n theme.WALKABLE_COLOR = WALKING_PATH_COLOR;\n }\n theme.STORE_RADIUS = clampStoreRadius(theme.STORE_RADIUS);\n return theme;\n}\n\nexport interface CmMap {\n id: number;\n centerId: number;\n baseSvgKey: string | null;\n baseViewbox: ViewBox | null;\n unitsPerMeter: number;\n theme: Partial<ThemeDefaults>;\n /** Current production document row in cm_revisions (overwritten in place). */\n publishedRevisionId: number | null;\n draftUpdatedAt: string | null;\n createdAt: string;\n}\n\nexport interface CmBuilding {\n id: number;\n mapId: number;\n name: string;\n ordering: number;\n}\n\nexport interface CmLevel {\n id: number;\n mapId: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgKey: string | null;\n /** Resolved CDN URL for editor preview (not persisted). */\n sourceSvgUrl?: string | null;\n sourceViewbox: ViewBox | null;\n transform: LevelTransform;\n isActive: boolean;\n}\n\nexport interface CmShape {\n id: number;\n levelId: number;\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n zIndex: number;\n style: ShapeStyle;\n label: ShapeLabel;\n sourceSvgId: string | null;\n origin: ShapeOrigin;\n /** When true, outdoor re-import never overwrites geometry/bbox. */\n geometryLocked?: boolean;\n /** Set when sourceSvgId disappeared from a re-upload; filtered from public docs. */\n orphanedAt?: string | null;\n}\n\nexport interface CmShapeAssignment {\n shapeId: number;\n targetType: AssignmentTargetType;\n retailerId: number | null;\n amenityId: number | null;\n kioskId: number | null;\n unitStatus: UnitStatus;\n unitNumber: string | null;\n customLabel: string | null;\n customImageKey: string | null;\n}\n\nexport interface CmAnchor {\n id: number;\n levelId: number;\n shapeId: number | null;\n kind: AnchorKind;\n x: number;\n y: number;\n connectorId: number | null;\n}\n\nexport interface CmRouteEdge {\n id: number;\n mapId: number;\n fromAnchorId: number;\n toAnchorId: number;\n weight: number | null;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface CmConnector {\n id: number;\n mapId: number;\n kind: ConnectorKind;\n name: string;\n direction: ConnectorDirection;\n accessible: boolean;\n}\n\nexport interface CmAmenityCatalogItem {\n id: number;\n centerId: number | null;\n code: string;\n name: string;\n iconKey: string | null;\n builtinIcon: string | null;\n ordering: number;\n isActive: boolean;\n}\n\nexport interface CmResponsiveOverride {\n id: number;\n mapId: number;\n levelId: number | null;\n device: DeviceType;\n camera: Vec3;\n controls: Vec3;\n}\n\nexport interface PublishedGraphNode {\n id: number;\n levelId: number;\n x: number;\n y: number;\n kind: AnchorKind;\n shapeId: number | null;\n connectorId: number | null;\n}\n\nexport interface PublishedGraphEdge {\n id: number;\n from: number;\n to: number;\n weight: number;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface PublishedLevel {\n id: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgUrl: string | null;\n viewbox: ViewBox | null;\n transform: LevelTransform;\n shapes: Array<CmShape & { assignment?: CmShapeAssignment | null }>;\n anchors: CmAnchor[];\n}\n\nexport interface PublishedDocument {\n version: 2;\n revisionId: number;\n revisionNumber: number;\n centerId: number;\n mapId: number;\n theme: ThemeDefaults;\n baseSvgUrl: string | null;\n baseViewbox: ViewBox | null;\n buildings: CmBuilding[];\n levels: PublishedLevel[];\n connectors: CmConnector[];\n amenities: CmAmenityCatalogItem[];\n graph: {\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n };\n responsiveOverrides: CmResponsiveOverride[];\n publishedAt: string;\n}\n\nexport interface ImportClassification {\n sourceSvgId: string;\n kind: ShapeKind | null;\n guessed: boolean;\n message?: string;\n}\n\nexport interface ImportReport {\n classified: ImportClassification[];\n unrecognized: string[];\n guessed: ImportClassification[];\n walkableCount: number;\n voidCount: number;\n unitCount: number;\n warnings: string[];\n}\n\nexport type DiffChangeType = 'added' | 'removed' | 'moved' | 'unchanged' | 'kind_changed';\n\nexport interface ImportDiffItem {\n sourceSvgId: string;\n change: DiffChangeType;\n existingShapeId?: number;\n newKind?: ShapeKind | null;\n existingKind?: ShapeKind | null;\n preserve?: {\n key?: string;\n assignment?: boolean;\n anchors?: boolean;\n };\n /** True when portal Edit Map owns this shape's geometry. */\n geometryLocked?: boolean;\n}\n\nexport interface ImportDiff {\n items: ImportDiffItem[];\n shapes: Array<{\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n sourceSvgId: string;\n style: ShapeStyle;\n }>;\n viewbox: ViewBox | null;\n}\n\nexport interface WeldResult {\n survivingAnchorId: number;\n removedAnchorIds: number[];\n rewiredEdgeIds: number[];\n}\n\nexport interface AutoConnectResult {\n unitAnchorId: number;\n junctionAnchor: { x: number; y: number; existingId?: number };\n edge: { fromAnchorId: number; toAnchorId?: number };\n}\n\nexport interface SkeletonSuggestion {\n anchors: Array<{ tempId: string; x: number; y: number; kind: AnchorKind }>;\n edges: Array<{ fromTempId: string; toTempId: string }>;\n}\n\nexport interface PathResult {\n anchorIds: number[];\n points: Array<Vec2 & { levelId: number }>;\n totalWeight: number;\n levelChanges: Array<{ fromLevelId: number; toLevelId: number; connectorId: number | null }>;\n}\n\nexport type BatchOp =\n | { op: 'upsert_shape'; shape: Partial<CmShape> & { levelId: number; key: string } }\n | { op: 'delete_shape'; shapeId: number }\n | { op: 'upsert_assignment'; assignment: CmShapeAssignment }\n | { op: 'delete_assignment'; shapeId: number }\n | { op: 'upsert_anchor'; anchor: Partial<CmAnchor> & { levelId: number; x: number; y: number; kind: AnchorKind } }\n | { op: 'delete_anchor'; anchorId: number }\n | { op: 'upsert_edge'; edge: Partial<CmRouteEdge> & { mapId: number; fromAnchorId: number; toAnchorId: number } }\n | { op: 'delete_edge'; edgeId: number }\n | { op: 'weld_anchors'; anchorIds: number[]; tolerance?: number }\n | { op: 'upsert_level'; level: Partial<CmLevel> & { mapId: number; name: string; kind: LevelKind } }\n | { op: 'delete_level'; levelId: number }\n | { op: 'upsert_building'; building: Partial<CmBuilding> & { mapId: number; name: string } }\n | { op: 'delete_building'; buildingId: number }\n | { op: 'update_theme'; theme: Partial<ThemeDefaults> }\n | { op: 'upsert_connector'; connector: Partial<CmConnector> & { mapId: number; kind: ConnectorKind; name: string } }\n | { op: 'delete_connector'; connectorId: number };\n\nexport const INTERACTIVE_SHAPE_KINDS: ShapeKind[] = [\n 'unit',\n 'amenity',\n 'kiosk_screen',\n 'connector',\n 'entrance',\n 'parking_zone',\n];\n\nexport const FLOOR_CHANGE_PENALTY = 10000;\n\nexport const DEFAULT_WELD_TOLERANCE = 2.5;\n","import type { MapHost, MapViewerHost } from './types';\n\n/** Which library surface a host should mount. `PORTAL` is the staff editor. */\nexport function mapSurface(host: MapHost): 'editor' | 'viewer' {\n return host === 'PORTAL' ? 'editor' : 'viewer';\n}\n\n/**\n * Public chrome. Mirrors v1 MapBox (`UIComponent` + `SceneComponent`):\n * floors + zoom/reset on every viewer host; amenity icons on WEBSITE\n * (v1 hides them for PORTAL and DISPLAY_APP); kiosk origin only on DISPLAY_APP.\n * Search is v2-owned (v1 MapBox has none) and follows the public directory hosts.\n */\nexport interface ViewerChrome {\n search: boolean;\n amenities: boolean;\n floors: boolean;\n zoomReset: boolean;\n kioskOrigin: boolean;\n fetchDraft: boolean;\n}\n\nconst PUBLIC_CHROME: ViewerChrome = {\n search: true,\n amenities: true,\n floors: true,\n zoomReset: true,\n kioskOrigin: false,\n fetchDraft: false,\n};\n\nconst VIEWER_CHROME: Record<MapViewerHost, ViewerChrome> = {\n WEBSITE: PUBLIC_CHROME,\n /** Assign mode: click shapes, no public directory chrome. */\n PORTAL_ASSIGN: {\n search: false,\n amenities: false,\n floors: true,\n zoomReset: true,\n kioskOrigin: false,\n fetchDraft: false,\n },\n DISPLAY_APP: {\n search: false,\n amenities: false,\n floors: true,\n zoomReset: true,\n kioskOrigin: true,\n fetchDraft: false,\n },\n};\n\nexport function viewerChrome(host: MapViewerHost): ViewerChrome {\n return VIEWER_CHROME[host];\n}\n\nexport function isMapViewerHost(host: MapHost): host is MapViewerHost {\n return host !== 'PORTAL';\n}\n","/** Same contract as v1 `getMediaProxyUrl`: proxy base + encoded URL, no query key. */\nexport function resolveFetchUrl(url: string, imageProxyUrl?: string | null): string {\n if (!imageProxyUrl) return url;\n return imageProxyUrl + encodeURIComponent(url);\n}\n","import type { BBox, PathSubpath, ShapeGeometry, Vec2, ViewBox } from '../types';\n\n/**\n * Mirror points about the middle of a viewbox height.\n *\n * Never call this on stored geometry. Stored geometry keeps SVG user space\n * (Y down) so `paths`, `polygons`, anchors and the designer SVG all agree;\n * the viewer flips once at render. This helper exists only for render-side\n * and ad-hoc conversions.\n */\nexport function flipY(points: Vec2[], viewboxHeight: number): Vec2[] {\n return points.map((p) => ({ x: p.x, y: viewboxHeight - p.y }));\n}\n\nexport function distance(a: Vec2, b: Vec2): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.hypot(dx, dy);\n}\n\nexport function bboxOf(points: Vec2[]): BBox {\n if (points.length === 0) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 };\n }\n let minX = points[0].x;\n let minY = points[0].y;\n let maxX = points[0].x;\n let maxY = points[0].y;\n for (let i = 1; i < points.length; i++) {\n const p = points[i];\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport function bboxUnion(a: BBox, b: BBox): BBox {\n return {\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n };\n}\n\nexport function centroid(points: Vec2[]): Vec2 {\n if (points.length === 0) return { x: 0, y: 0 };\n let sx = 0;\n let sy = 0;\n for (const p of points) {\n sx += p.x;\n sy += p.y;\n }\n return { x: sx / points.length, y: sy / points.length };\n}\n\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x;\n const yi = polygon[i].y;\n const xj = polygon[j].x;\n const yj = polygon[j].y;\n const intersect =\n yi > point.y !== yj > point.y &&\n point.x < ((xj - xi) * (point.y - yi)) / (yj - yi + Number.EPSILON) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\nexport function pointInPolygons(point: Vec2, polygons: Vec2[][]): boolean {\n return polygons.some((poly) => pointInPolygon(point, poly));\n}\n\n/** Project point onto segment; returns closest point and t in [0,1]. */\nexport function projectOntoSegment(\n point: Vec2,\n a: Vec2,\n b: Vec2,\n): { point: Vec2; t: number; distance: number } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return { point: { ...a }, t: 0, distance: distance(point, a) };\n }\n let t = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n const proj = { x: a.x + t * dx, y: a.y + t * dy };\n return { point: proj, t, distance: distance(point, proj) };\n}\n\nexport function nearestPointOnPolyline(\n point: Vec2,\n polyline: Vec2[],\n): { point: Vec2; segmentIndex: number; distance: number } | null {\n if (polyline.length < 2) return null;\n let best: { point: Vec2; segmentIndex: number; distance: number } | null = null;\n for (let i = 0; i < polyline.length - 1; i++) {\n const proj = projectOntoSegment(point, polyline[i], polyline[i + 1]);\n if (!best || proj.distance < best.distance) {\n best = { point: proj.point, segmentIndex: i, distance: proj.distance };\n }\n }\n return best;\n}\n\n/**\n * Approximate a cubic bezier into line segments.\n */\nexport function approximateCubic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n segments = 8,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x:\n u * u * u * p0.x +\n 3 * u * u * t * p1.x +\n 3 * u * t * t * p2.x +\n t * t * t * p3.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * p1.y +\n 3 * u * t * t * p2.y +\n t * t * t * p3.y,\n });\n }\n return out;\n}\n\nexport function approximateQuadratic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n segments = 6,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n });\n }\n return out;\n}\n\n/**\n * A quarter turn is about the largest sweep a single cubic approximates well,\n * so an arc gets `approximateCubic`'s 8 segments per 90° of sweep. An arc and a\n * visually equivalent cubic therefore flatten to comparable point counts.\n */\nconst ARC_SEGMENTS_PER_QUADRANT = 8;\n\n/**\n * Flatten an SVG elliptical arc, using the endpoint-to-centre parameterisation\n * of SVG 1.1 appendix F.6.\n *\n * Returns `p0` first, like `approximateCubic`, so callers append `slice(1)`.\n */\nexport function approximateArc(\n p0: Vec2,\n rx: number,\n ry: number,\n xAxisRotationDeg: number,\n largeArc: boolean,\n sweep: boolean,\n p1: Vec2,\n): Vec2[] {\n // F.6.2: coincident endpoints drop the arc; a zero radius becomes a line.\n if (p0.x === p1.x && p0.y === p1.y) return [{ ...p0 }];\n let arx = Math.abs(rx);\n let ary = Math.abs(ry);\n if (arx === 0 || ary === 0 || !Number.isFinite(arx) || !Number.isFinite(ary)) {\n return [{ ...p0 }, { ...p1 }];\n }\n\n const phi = ((xAxisRotationDeg % 360) * Math.PI) / 180;\n const cosPhi = Math.cos(phi);\n const sinPhi = Math.sin(phi);\n\n // F.6.5.1 — half the chord, rotated into the ellipse's own frame.\n const dx2 = (p0.x - p1.x) / 2;\n const dy2 = (p0.y - p1.y) / 2;\n const x1p = cosPhi * dx2 + sinPhi * dy2;\n const y1p = -sinPhi * dx2 + cosPhi * dy2;\n\n // F.6.6.2 — radii too small to span the endpoints are scaled by sqrt(Λ).\n const lambda = (x1p * x1p) / (arx * arx) + (y1p * y1p) / (ary * ary);\n if (lambda > 1) {\n const scale = Math.sqrt(lambda);\n arx *= scale;\n ary *= scale;\n }\n\n // F.6.5.2 — centre in the ellipse frame.\n const rxSq = arx * arx;\n const rySq = ary * ary;\n const numerator = rxSq * rySq - rxSq * y1p * y1p - rySq * x1p * x1p;\n const denominator = rxSq * y1p * y1p + rySq * x1p * x1p;\n const factor =\n Math.sqrt(Math.max(0, numerator / denominator)) * (largeArc === sweep ? -1 : 1);\n const cxp = (factor * arx * y1p) / ary;\n const cyp = (-factor * ary * x1p) / arx;\n\n // F.6.5.3 — centre back in user space.\n const cx = cosPhi * cxp - sinPhi * cyp + (p0.x + p1.x) / 2;\n const cy = sinPhi * cxp + cosPhi * cyp + (p0.y + p1.y) / 2;\n\n // F.6.5.5 / F.6.5.6 — start angle and swept angle.\n const ux = (x1p - cxp) / arx;\n const uy = (y1p - cyp) / ary;\n const vx = (-x1p - cxp) / arx;\n const vy = (-y1p - cyp) / ary;\n const theta1 = Math.atan2(uy, ux);\n let deltaTheta = Math.atan2(ux * vy - uy * vx, ux * vx + uy * vy);\n if (!sweep && deltaTheta > 0) deltaTheta -= 2 * Math.PI;\n else if (sweep && deltaTheta < 0) deltaTheta += 2 * Math.PI;\n\n // Round rather than ceil the quadrant count. A chord that is almost exactly\n // the ellipse diameter is a near-degenerate half turn, so tiny coordinate\n // noise — a rewritten `d` rounded by the transform baker, say — swings the\n // sweep either side of pi. Rounding is stable at whole quadrants, which is\n // precisely where those degeneracies sit; ceil would flip a segment count\n // there and desynchronise `paths[].d` from `polygons`.\n const ideal = (Math.abs(deltaTheta) / (Math.PI / 2)) * ARC_SEGMENTS_PER_QUADRANT;\n const segments = Math.max(1, Math.round(ideal));\n\n const out: Vec2[] = [{ ...p0 }];\n for (let i = 1; i <= segments; i++) {\n const theta = theta1 + (deltaTheta * i) / segments;\n const cosT = Math.cos(theta);\n const sinT = Math.sin(theta);\n out.push({\n x: cx + arx * cosPhi * cosT - ary * sinPhi * sinT,\n y: cy + arx * sinPhi * cosT + ary * cosPhi * sinT,\n });\n }\n // Trig round-off must not leave a gap before the next command.\n out[out.length - 1] = { ...p1 };\n return out;\n}\n\nconst WHITESPACE_RE = /[\\s,]/;\n\n/**\n * Split path data into command letters and numbers.\n *\n * A plain number regex cannot do this: arc flags may be written without any\n * separator, so `a1 1 0 011 1` is legal and means flags `0` then `1` followed\n * by the coordinate `1`. Tracking the argument slot lets the two flag\n * positions of every `A`/`a` group consume exactly one character.\n */\nexport function tokenizePathData(d: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n let cmd = '';\n let argIndex = 0;\n\n while (i < d.length) {\n const ch = d[i];\n if (WHITESPACE_RE.test(ch)) {\n i++;\n continue;\n }\n if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {\n cmd = ch;\n argIndex = 0;\n tokens.push(ch);\n i++;\n continue;\n }\n\n // Slots 3 and 4 of each 7-argument arc group are single-character flags.\n const arcSlot = cmd === 'A' || cmd === 'a' ? argIndex % 7 : -1;\n if ((arcSlot === 3 || arcSlot === 4) && (ch === '0' || ch === '1')) {\n tokens.push(ch);\n i++;\n argIndex++;\n continue;\n }\n\n const start = i;\n let digits = 0;\n if (ch === '+' || ch === '-') i++;\n while (i < d.length && d[i] >= '0' && d[i] <= '9') {\n i++;\n digits++;\n }\n if (d[i] === '.') {\n i++;\n while (i < d.length && d[i] >= '0' && d[i] <= '9') {\n i++;\n digits++;\n }\n }\n if (digits > 0 && (d[i] === 'e' || d[i] === 'E')) {\n const beforeExponent = i;\n i++;\n if (d[i] === '+' || d[i] === '-') i++;\n if (i < d.length && d[i] >= '0' && d[i] <= '9') {\n while (i < d.length && d[i] >= '0' && d[i] <= '9') i++;\n } else {\n i = beforeExponent;\n }\n }\n if (digits === 0) {\n // Not a number at all — step over it rather than looping forever.\n i = start + 1;\n continue;\n }\n tokens.push(d.slice(start, i));\n argIndex++;\n }\n\n return tokens;\n}\n\n/**\n * Parse SVG path `d` into absolute polygon approximations.\n * Supports M/L/H/V/C/Q/S/T/A/Z (absolute and relative).\n *\n * Output stays in the input's coordinate space — deliberately no Y flip, so\n * `paths[].d`, `polygons`, anchors and route geometry never diverge. The\n * viewer applies the single flip at render time.\n */\nexport function pathToPolygons(d: string): Vec2[][] {\n const tokens = tokenizePathData(d);\n const polygons: Vec2[][] = [];\n let current: Vec2[] = [];\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n let lastCtrl: Vec2 | null = null;\n let i = 0;\n let cmd = '';\n\n const readNum = () => Number(tokens[i++]);\n\n while (i < tokens.length) {\n const t = tokens[i];\n if (/[a-zA-Z]/.test(t)) {\n cmd = t;\n i++;\n }\n\n switch (cmd) {\n case 'M':\n case 'm': {\n const isRel = cmd === 'm';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n if (current.length > 0) polygons.push(current);\n current = [{ x, y }];\n startX = x;\n startY = y;\n lastCtrl = null;\n cmd = isRel ? 'l' : 'L';\n break;\n }\n case 'L':\n case 'l': {\n const isRel = cmd === 'l';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'H':\n case 'h': {\n const isRel = cmd === 'h';\n const nx = readNum();\n x = isRel ? x + nx : nx;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'V':\n case 'v': {\n const isRel = cmd === 'v';\n const ny = readNum();\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'C':\n case 'c': {\n const isRel = cmd === 'c';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'Q':\n case 'q': {\n const isRel = cmd === 'q';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: x1, y: y1 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x1, y: y1 };\n x = nx;\n y = ny;\n break;\n }\n case 'S':\n case 's': {\n const isRel = cmd === 's';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: cx, y: cy },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'T':\n case 't': {\n const isRel = cmd === 't';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: cx, y: cy },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: cx, y: cy };\n x = nx;\n y = ny;\n break;\n }\n case 'A':\n case 'a': {\n const isRel = cmd === 'a';\n const rx = readNum();\n const ry = readNum();\n const rot = readNum();\n const largeArc = readNum() !== 0;\n const sweep = readNum() !== 0;\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateArc(\n { x, y },\n rx,\n ry,\n rot,\n largeArc,\n sweep,\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = null;\n x = nx;\n y = ny;\n break;\n }\n case 'Z':\n case 'z': {\n current.push({ x: startX, y: startY });\n polygons.push(current);\n current = [];\n x = startX;\n y = startY;\n lastCtrl = null;\n break;\n }\n default:\n // Unknown command — skip one token to avoid infinite loop\n i++;\n break;\n }\n }\n\n if (current.length > 0) polygons.push(current);\n\n return polygons;\n}\n\n/** First absolute `M` of a path, or null when the path does not start with one. */\nfunction firstMoveTo(d: string): Vec2 | null {\n const m = d.match(\n /^\\s*M\\s*(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)[\\s,]+(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/i,\n );\n if (!m) return null;\n const x = Number(m[1]);\n const y = Number(m[2]);\n return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;\n}\n\n/**\n * Rows written before the Y-flip removal hold `polygons` mirrored about the\n * viewbox while `paths[].d` stayed in SVG space, which renders the map upside\n * down. `paths` is authoritative, so rebuild `polygons` whenever the two\n * disagree. Comparing only the opening `M` keeps healthy geometry O(1).\n */\nexport function isGeometrySpaceStale(geometry: ShapeGeometry): boolean {\n const d = geometry.paths[0]?.d;\n if (!d) return false;\n if (geometry.polygons.length === 0) return false;\n const start = firstMoveTo(d);\n const first = geometry.polygons[0]?.[0];\n if (!start || !first) return false;\n return Math.abs(start.x - first.x) > 0.01 || Math.abs(start.y - first.y) > 0.01;\n}\n\n/** Return geometry with `polygons` rebuilt from `paths` when they disagree. */\nexport function normalizeGeometrySpace(geometry: ShapeGeometry): ShapeGeometry {\n if (!isGeometrySpaceStale(geometry)) return geometry;\n const polygons = geometry.paths.flatMap((p) => pathToPolygons(p.d));\n if (polygons.length === 0) return geometry;\n return { paths: geometry.paths, polygons };\n}\n\n/** `paths` keeps the original `d`; `polygons` must stay in the same space. */\nexport function buildGeometryFromPaths(pathDs: string[]): ShapeGeometry {\n const paths: PathSubpath[] = pathDs.map((d) => ({\n d,\n closed: /z/i.test(d),\n }));\n const polygons = pathDs.flatMap((d) => pathToPolygons(d));\n return { paths, polygons };\n}\n\nexport function geometryBBox(geometry: ShapeGeometry): BBox {\n const all = geometry.polygons.flat();\n return bboxOf(all);\n}\n\nexport function geometryCentroid(geometry: ShapeGeometry): Vec2 {\n return centroid(geometry.polygons.flat());\n}\n\n/**\n * Snap a delta angle to the nearest increment around a base angle.\n * baseDeg is the working orientation (e.g. from \"match this wall\").\n */\nexport function snapAngle(\n from: Vec2,\n to: Vec2,\n baseDeg = 0,\n increments: number[] = [15, 45, 90],\n): Vec2 {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return { ...to };\n\n const rawDeg = (Math.atan2(dy, dx) * 180) / Math.PI;\n const relative = rawDeg - baseDeg;\n let best = relative;\n let bestDiff = Infinity;\n for (const step of increments) {\n const snapped = Math.round(relative / step) * step;\n const diff = Math.abs(relative - snapped);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = snapped;\n }\n }\n const finalDeg = ((best + baseDeg) * Math.PI) / 180;\n return {\n x: from.x + Math.cos(finalDeg) * len,\n y: from.y + Math.sin(finalDeg) * len,\n };\n}\n\n/** Derive working base angle from two wall points (degrees). */\nexport function angleFromWall(a: Vec2, b: Vec2): number {\n return (Math.atan2(b.y - a.y, b.x - a.x) * 180) / Math.PI;\n}\n\nexport function parseViewBox(raw: string | null | undefined): ViewBox | null {\n if (!raw) return null;\n const parts = raw.trim().split(/[\\s,]+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], width: parts[2], height: parts[3] };\n}\n","/**\n * Inline CSS class rules from `<style>` tags as SVG presentation attributes.\n * Works in Node (no DOM) so the SVG importer can resolve fills/strokes.\n * Mirrors v1 `inlineSvgStyles` behaviour for class→attribute mapping.\n */\n\nconst CSS_TO_SVG_ATTR: Record<string, string> = {\n fill: 'fill',\n 'fill-opacity': 'fill-opacity',\n stroke: 'stroke',\n 'stroke-width': 'stroke-width',\n 'stroke-opacity': 'stroke-opacity',\n opacity: 'opacity',\n};\n\nfunction parseCssDeclarations(block: string): Record<string, string> {\n const declarations: Record<string, string> = {};\n for (const declaration of block.split(';')) {\n const sep = declaration.indexOf(':');\n if (sep === -1) continue;\n const property = declaration.slice(0, sep).trim().toLowerCase();\n const value = declaration.slice(sep + 1).trim();\n if (property && value) declarations[property] = value;\n }\n return declarations;\n}\n\nfunction parseCssClassRules(cssText: string): Map<string, Record<string, string>> {\n const classStyles = new Map<string, Record<string, string>>();\n const normalizedCss = cssText.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n for (const match of normalizedCss.matchAll(/([^{]+)\\{([^}]*)\\}/g)) {\n const selectors = match[1].split(',').map((s) => s.trim());\n const declarations = parseCssDeclarations(match[2]);\n for (const selector of selectors) {\n const classMatch = selector.match(/^\\.([a-zA-Z0-9_-]+)$/);\n if (!classMatch) continue;\n const className = classMatch[1];\n classStyles.set(className, {\n ...(classStyles.get(className) || {}),\n ...declarations,\n });\n }\n }\n return classStyles;\n}\n\nfunction mergeClassStyles(\n classAttr: string,\n classStyles: Map<string, Record<string, string>>,\n): Record<string, string> {\n const merged: Record<string, string> = {};\n for (const name of classAttr.split(/\\s+/).map((c) => c.trim()).filter(Boolean)) {\n Object.assign(merged, classStyles.get(name) || {});\n }\n return merged;\n}\n\n/**\n * Rewrite SVG text so class-based fills/strokes become presentation attributes.\n * Safe to call in Node — pure string rewrite, no DOMParser.\n */\nexport function inlineSvgStyles(svgText: string): string {\n const styleBlocks: string[] = [];\n const withoutComments = svgText.replace(/<!--[\\s\\S]*?-->/g, '');\n for (const m of withoutComments.matchAll(/<style\\b[^>]*>([\\s\\S]*?)<\\/style>/gi)) {\n styleBlocks.push(m[1]);\n }\n if (styleBlocks.length === 0) return svgText;\n\n const classStyles = new Map<string, Record<string, string>>();\n for (const block of styleBlocks) {\n for (const [name, decls] of parseCssClassRules(block)) {\n classStyles.set(name, { ...(classStyles.get(name) || {}), ...decls });\n }\n }\n if (classStyles.size === 0) return svgText;\n\n return svgText.replace(\n /<(path|polygon|polyline|line|rect|g|circle|ellipse)\\b([^>]*)>/gi,\n (full, tag: string, attrs: string) => {\n // `[^>]*` swallows the `/` in `/>`, so strip it before rewriting attrs.\n const selfClosing = /\\/\\s*$/.test(attrs);\n const cleanAttrs = attrs.replace(/\\/\\s*$/, '');\n const classMatch = cleanAttrs.match(/\\bclass\\s*=\\s*[\"']([^\"']*)[\"']/i);\n if (!classMatch) return full;\n const merged = mergeClassStyles(classMatch[1], classStyles);\n let nextAttrs = cleanAttrs;\n for (const [cssProp, value] of Object.entries(merged)) {\n const svgAttr = CSS_TO_SVG_ATTR[cssProp];\n if (!svgAttr) continue;\n if (new RegExp(`\\\\b${svgAttr}\\\\s*=`, 'i').test(nextAttrs)) continue;\n nextAttrs += ` ${svgAttr}=\"${value}\"`;\n }\n return `<${tag}${nextAttrs}${selfClosing ? ' /' : ''}>`;\n },\n );\n}\n\nexport interface SvgPresentationStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n}\n\n/** Read presentation attributes from an attribute string. */\nexport function readPresentationStyle(attrs: string): SvgPresentationStyle {\n const out: SvgPresentationStyle = {};\n const fill = attrs.match(/\\bfill\\s*=\\s*[\"']([^\"']*)[\"']/i)?.[1];\n const stroke = attrs.match(/\\bstroke\\s*=\\s*[\"']([^\"']*)[\"']/i)?.[1];\n const strokeWidth = attrs.match(/\\bstroke-width\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n const opacity = attrs.match(/\\bopacity\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n const fillOpacity = attrs.match(/\\bfill-opacity\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n if (fill && fill.toLowerCase() !== 'none') out.fill = fill;\n if (stroke && stroke.toLowerCase() !== 'none') out.stroke = stroke;\n if (strokeWidth != null && !Number.isNaN(Number(strokeWidth))) {\n out.strokeWidth = Number(strokeWidth);\n }\n if (opacity != null && !Number.isNaN(Number(opacity))) {\n out.opacity = Number(opacity);\n } else if (fillOpacity != null && !Number.isNaN(Number(fillOpacity))) {\n out.opacity = Number(fillOpacity);\n }\n return out;\n}\n\n/** Merge child over parent — child wins when set. */\nexport function mergePresentationStyle(\n parent: SvgPresentationStyle,\n child: SvgPresentationStyle,\n): SvgPresentationStyle {\n return {\n fill: child.fill ?? parent.fill,\n stroke: child.stroke ?? parent.stroke,\n strokeWidth: child.strokeWidth ?? parent.strokeWidth,\n opacity: child.opacity ?? parent.opacity,\n };\n}\n","/**\n * SVG `transform` attribute support for the importer.\n *\n * Pure string/matrix math — no DOM, so it runs in Node during server-side\n * import. Geometry stays in raw SVG user space (Y down); these helpers only\n * bake `transform` attributes into coordinates, they never flip axes.\n */\n\nimport type { Vec2 } from '../types';\nimport { tokenizePathData } from '../geometry';\n\n/**\n * 2D affine matrix in SVG order:\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n */\nexport interface Matrix2D {\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n}\n\nexport const IDENTITY_MATRIX: Matrix2D = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n\n/**\n * Matrix product `outer × inner`: the returned matrix applies `inner` first,\n * then `outer`. SVG composes `transform=\"A B\"` the same way — the rightmost\n * transform is applied to the geometry first, and an ancestor `<g>` transform\n * is the outer one relative to its descendants.\n */\nexport function multiplyMatrix(outer: Matrix2D, inner: Matrix2D): Matrix2D {\n return {\n a: outer.a * inner.a + outer.c * inner.b,\n b: outer.b * inner.a + outer.d * inner.b,\n c: outer.a * inner.c + outer.c * inner.d,\n d: outer.b * inner.c + outer.d * inner.d,\n e: outer.a * inner.e + outer.c * inner.f + outer.e,\n f: outer.b * inner.e + outer.d * inner.f + outer.f,\n };\n}\n\nexport function applyMatrix(m: Matrix2D, p: Vec2): Vec2 {\n return {\n x: m.a * p.x + m.c * p.y + m.e,\n y: m.b * p.x + m.d * p.y + m.f,\n };\n}\n\nexport function isIdentityMatrix(m: Matrix2D, epsilon = 1e-9): boolean {\n return (\n Math.abs(m.a - 1) < epsilon &&\n Math.abs(m.b) < epsilon &&\n Math.abs(m.c) < epsilon &&\n Math.abs(m.d - 1) < epsilon &&\n Math.abs(m.e) < epsilon &&\n Math.abs(m.f) < epsilon\n );\n}\n\nfunction translateMatrix(tx: number, ty: number): Matrix2D {\n return { a: 1, b: 0, c: 0, d: 1, e: tx, f: ty };\n}\n\nfunction rotateMatrix(deg: number): Matrix2D {\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n return { a: cos, b: sin, c: -sin, d: cos, e: 0, f: 0 };\n}\n\nfunction transformFunctionMatrix(name: string, args: number[]): Matrix2D | null {\n switch (name) {\n case 'matrix':\n if (args.length < 6) return null;\n return { a: args[0], b: args[1], c: args[2], d: args[3], e: args[4], f: args[5] };\n case 'translate':\n if (args.length < 1) return null;\n return translateMatrix(args[0], args[1] ?? 0);\n case 'scale': {\n if (args.length < 1) return null;\n const sx = args[0];\n const sy = args[1] ?? sx;\n return { a: sx, b: 0, c: 0, d: sy, e: 0, f: 0 };\n }\n case 'rotate': {\n if (args.length < 1) return null;\n const rot = rotateMatrix(args[0]);\n if (args.length < 3) return rot;\n const cx = args[1];\n const cy = args[2];\n return multiplyMatrix(\n multiplyMatrix(translateMatrix(cx, cy), rot),\n translateMatrix(-cx, -cy),\n );\n }\n case 'skewx':\n if (args.length < 1) return null;\n return { a: 1, b: 0, c: Math.tan((args[0] * Math.PI) / 180), d: 1, e: 0, f: 0 };\n case 'skewy':\n if (args.length < 1) return null;\n return { a: 1, b: Math.tan((args[0] * Math.PI) / 180), c: 0, d: 1, e: 0, f: 0 };\n default:\n return null;\n }\n}\n\nconst TRANSFORM_FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\n/**\n * Parse an SVG `transform` attribute into a single affine matrix.\n * Unknown functions are skipped. Returns identity for empty / unparseable input.\n */\nexport function parseTransform(raw: string | null | undefined): Matrix2D {\n if (!raw) return IDENTITY_MATRIX;\n let result = IDENTITY_MATRIX;\n TRANSFORM_FN_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = TRANSFORM_FN_RE.exec(raw)) !== null) {\n const name = match[1].toLowerCase();\n const args = match[2]\n .trim()\n .split(/[\\s,]+/)\n .filter(Boolean)\n .map(Number);\n if (args.some((n) => Number.isNaN(n))) continue;\n const next = transformFunctionMatrix(name, args);\n if (!next) continue;\n // Leftmost function is outermost: earlier entries apply last.\n result = multiplyMatrix(result, next);\n }\n return result;\n}\n\n/** Trim float noise so rewritten `d` strings stay readable and stable. */\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return '0';\n const rounded = Math.round(n * 1e4) / 1e4;\n return Object.is(rounded, -0) ? '0' : String(rounded);\n}\n\n/**\n * Re-express an elliptical arc under an affine map.\n * The ellipse basis is `A · R(phi) · diag(rx, ry)`; its singular values are the\n * new radii and the left rotation is the new x-axis-rotation.\n */\nfunction transformArc(\n m: Matrix2D,\n rx: number,\n ry: number,\n phiDeg: number,\n): { rx: number; ry: number; phiDeg: number } {\n const phi = (phiDeg * Math.PI) / 180;\n const cos = Math.cos(phi);\n const sin = Math.sin(phi);\n // Ellipse basis in user space, then the matrix linear part.\n const e11 = cos * rx;\n const e21 = sin * rx;\n const e12 = -sin * ry;\n const e22 = cos * ry;\n const m11 = m.a * e11 + m.c * e21;\n const m21 = m.b * e11 + m.d * e21;\n const m12 = m.a * e12 + m.c * e22;\n const m22 = m.b * e12 + m.d * e22;\n // Closed-form 2x2 SVD.\n const E = (m11 + m22) / 2;\n const F = (m11 - m22) / 2;\n const G = (m21 + m12) / 2;\n const H = (m21 - m12) / 2;\n const q = Math.hypot(E, H);\n const r = Math.hypot(F, G);\n const outRx = Math.abs(q + r);\n const outRy = Math.abs(q - r);\n const a1 = Math.atan2(G, F);\n const a2 = Math.atan2(H, E);\n const outPhi = ((a2 + a1) / 2) * (180 / Math.PI);\n return { rx: outRx, ry: outRy, phiDeg: outPhi };\n}\n\n/**\n * Bake an affine matrix into a path `d` string, emitting absolute commands.\n *\n * Flattening a bezier commutes with an affine map (control points transform\n * independently, sampling parameters do not change), so\n * `pathToPolygons(transformPathD(d, m))` equals `pathToPolygons(d)` mapped\n * through `m`. That is what keeps `geometry.paths[].d` and `geometry.polygons`\n * in the same coordinate space.\n *\n * Arcs commute exactly under a similarity (translate / rotate / uniform scale /\n * mirror), which covers Illustrator output. A shear or non-uniform scale maps\n * the same curve but reparameterises it, so individual sample points may shift\n * along the outline even though the outline itself is right.\n */\nexport function transformPathD(d: string, m: Matrix2D): string {\n if (!d || isIdentityMatrix(m)) return d;\n const tokens = tokenizePathData(d);\n const out: string[] = [];\n const flipsOrientation = m.a * m.d - m.b * m.c < 0;\n\n let i = 0;\n let cmd = '';\n // Current point / subpath start in *source* space.\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n\n const readNum = () => {\n const n = Number(tokens[i++]);\n return Number.isNaN(n) ? 0 : n;\n };\n const emit = (letter: string, ...coords: number[]) => {\n out.push(letter + (coords.length ? ' ' + coords.map(fmt).join(' ') : ''));\n };\n const point = (px: number, py: number): [number, number] => {\n const p = applyMatrix(m, { x: px, y: py });\n return [p.x, p.y];\n };\n\n while (i < tokens.length) {\n const t = tokens[i];\n if (/[a-zA-Z]/.test(t)) {\n cmd = t;\n i++;\n }\n\n switch (cmd) {\n case 'M':\n case 'm': {\n const rel = cmd === 'm';\n const nx = readNum();\n const ny = readNum();\n x = rel ? x + nx : nx;\n y = rel ? y + ny : ny;\n startX = x;\n startY = y;\n emit('M', ...point(x, y));\n cmd = rel ? 'l' : 'L';\n break;\n }\n case 'L':\n case 'l': {\n const rel = cmd === 'l';\n const nx = readNum();\n const ny = readNum();\n x = rel ? x + nx : nx;\n y = rel ? y + ny : ny;\n emit('L', ...point(x, y));\n break;\n }\n case 'H':\n case 'h': {\n const rel = cmd === 'h';\n const nx = readNum();\n x = rel ? x + nx : nx;\n // A rotation or skew makes a horizontal run non-horizontal.\n emit('L', ...point(x, y));\n break;\n }\n case 'V':\n case 'v': {\n const rel = cmd === 'v';\n const ny = readNum();\n y = rel ? y + ny : ny;\n emit('L', ...point(x, y));\n break;\n }\n case 'C':\n case 'c': {\n const rel = cmd === 'c';\n const x1 = rel ? x + readNum() : readNum();\n const y1 = rel ? y + readNum() : readNum();\n const x2 = rel ? x + readNum() : readNum();\n const y2 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('C', ...point(x1, y1), ...point(x2, y2), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'S':\n case 's': {\n const rel = cmd === 's';\n const x2 = rel ? x + readNum() : readNum();\n const y2 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n // Reflection of the previous control point is affine-covariant.\n emit('S', ...point(x2, y2), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'Q':\n case 'q': {\n const rel = cmd === 'q';\n const x1 = rel ? x + readNum() : readNum();\n const y1 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('Q', ...point(x1, y1), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'T':\n case 't': {\n const rel = cmd === 't';\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('T', ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'A':\n case 'a': {\n const rel = cmd === 'a';\n const rx = readNum();\n const ry = readNum();\n const rot = readNum();\n const largeArc = readNum();\n const sweep = readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n const arc = transformArc(m, rx, ry, rot);\n const [tx, ty] = point(nx, ny);\n out.push(\n `A ${fmt(arc.rx)} ${fmt(arc.ry)} ${fmt(arc.phiDeg)} ${largeArc ? 1 : 0} ` +\n `${(sweep ? 1 : 0) ^ (flipsOrientation ? 1 : 0)} ${fmt(tx)} ${fmt(ty)}`,\n );\n x = nx;\n y = ny;\n break;\n }\n case 'Z':\n case 'z': {\n out.push('Z');\n x = startX;\n y = startY;\n break;\n }\n default:\n // Unknown command — skip a token so we cannot loop forever.\n i++;\n break;\n }\n }\n\n return out.join(' ');\n}\n","import type {\n BBox,\n ImportClassification,\n ImportDiff,\n ImportDiffItem,\n ImportReport,\n ShapeGeometry,\n ShapeKind,\n ShapeStyle,\n ViewBox,\n} from '../types';\nimport { INTERACTIVE_SHAPE_KINDS } from '../types';\nimport {\n buildGeometryFromPaths,\n geometryBBox,\n geometryCentroid,\n parseViewBox,\n} from '../geometry';\nimport { resolveLayerStyle } from '../layerStyles';\nimport {\n inlineSvgStyles,\n mergePresentationStyle,\n readPresentationStyle,\n type SvgPresentationStyle,\n} from './svgStyle';\nimport {\n IDENTITY_MATRIX,\n multiplyMatrix,\n parseTransform,\n transformPathD,\n type Matrix2D,\n} from './svgTransform';\n\n/** Prefix → shape kind for floor SVGs. */\nconst FLOOR_PREFIXES: Array<{ prefix: string; kind: ShapeKind }> = [\n { prefix: 'walkable', kind: 'walkable' },\n { prefix: 'void', kind: 'void' },\n { prefix: 'unit', kind: 'unit' },\n { prefix: 'store', kind: 'unit' }, // v1 compatibility\n { prefix: 'wall', kind: 'wall' },\n { prefix: 'boundary', kind: 'boundary' },\n { prefix: 'outer-wall', kind: 'wall' },\n { prefix: 'amenity-', kind: 'amenity' },\n { prefix: 'kiosk-', kind: 'kiosk_screen' },\n { prefix: 'escalator-', kind: 'connector' },\n { prefix: 'elevator-', kind: 'connector' },\n { prefix: 'stairs-', kind: 'connector' },\n { prefix: 'entrance-', kind: 'entrance' },\n { prefix: 'zone-', kind: 'zone' },\n { prefix: 'label-', kind: 'label' },\n { prefix: 'floorplate', kind: 'floorplate' },\n { prefix: 'base', kind: 'floorplate' },\n { prefix: 'decor', kind: 'decor' },\n { prefix: 'special-shape', kind: 'decor' },\n { prefix: 'overlay', kind: 'decor' },\n { prefix: 'green-area', kind: 'green_area' },\n { prefix: 'parking-lane', kind: 'parking_zone' },\n { prefix: 'parking-line', kind: 'decor' },\n { prefix: 'parking-icon', kind: 'parking_icon' },\n { prefix: 'walking-path', kind: 'walkable' },\n { prefix: 'water', kind: 'water' },\n];\n\n/** Prefix → shape kind for outdoor / base layer. */\nconst BASE_PREFIXES: Array<{ prefix: string; kind: ShapeKind }> = [\n { prefix: 'parking-zone', kind: 'parking_zone' },\n { prefix: 'parking-lane', kind: 'parking_zone' },\n { prefix: 'parking-line', kind: 'decor' },\n { prefix: 'parking-icon', kind: 'parking_icon' },\n { prefix: 'green-area', kind: 'green_area' },\n { prefix: 'water', kind: 'water' },\n { prefix: 'walking-path', kind: 'walkable' },\n { prefix: 'decor', kind: 'decor' },\n { prefix: 'entrance-', kind: 'entrance' },\n { prefix: 'unit', kind: 'unit' },\n { prefix: 'store', kind: 'unit' },\n { prefix: 'interactive-', kind: 'unit' },\n { prefix: 'walkable', kind: 'walkable' },\n { prefix: 'void', kind: 'void' },\n { prefix: 'amenity-', kind: 'amenity' },\n { prefix: 'kiosk-', kind: 'kiosk_screen' },\n // Connectors also appear in outdoor artboards (car-park decks, ramps).\n { prefix: 'escalator-', kind: 'connector' },\n { prefix: 'elevator-', kind: 'connector' },\n { prefix: 'stairs-', kind: 'connector' },\n];\n\n/** v1 / Illustrator walking-path ids (`route-path`, `route-path-12`). */\nexport function isRoutePathLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return n === 'route path' || n.startsWith('route path ');\n}\n\n/** Folder that holds walking paths (`ROUTES`, `route-path`, `WAYFINDING`). */\nexport function isRouteFolderLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return (\n n === 'routes' ||\n n === 'route' ||\n n === 'wayfinding' ||\n n === 'wayfinding routes' ||\n isRoutePathLabel(label)\n );\n}\n\n/**\n * Outdoor / base imports only persist interactive polygons (+ walkable/void for\n * autoroute). Decoration stays in the live SVG renderer.\n */\nexport const IMPORT_PERSISTED_KINDS: readonly ShapeKind[] = [\n ...INTERACTIVE_SHAPE_KINDS,\n 'walkable',\n 'void',\n];\n\n/** Centroid shift (world units) above which a matched shape is flagged `moved`. */\nexport const IMPORT_DRIFT_THRESHOLD = 8;\n\nexport interface RawSvgElement {\n id: string;\n tag: string;\n d?: string;\n points?: string;\n x1?: number;\n y1?: number;\n x2?: number;\n y2?: number;\n /** True when data-interactive is set or the element is inside an INTERACTIVE group. */\n interactive?: boolean;\n /** Resolved fill/stroke after group inheritance + CSS class inlining. */\n style?: SvgPresentationStyle;\n}\n\ninterface GroupFrame {\n id: string | null;\n /** Named INTERACTIVE* group (not NON_INTERACTIVE*). Children are assignable units. */\n interactiveContainer: boolean;\n /** Named NON_INTERACTIVE* group. Children keep prefix classification only. */\n nonInteractiveContainer: boolean;\n /** STORES / UNITS / store-layer — Illustrator folder, never a shape. */\n storeFolder: boolean;\n /** This group or an INTERACTIVE/STORES ancestor applies (unless a closer NON_INTERACTIVE wins). */\n inInteractive: boolean;\n collectedPaths: string[];\n style: SvgPresentationStyle;\n /** Own `transform` composed with every ancestor `<g>` transform. */\n matrix: Matrix2D;\n /** A descendant carried its own `id` — this group behaves like a folder. */\n hasNamedChild: boolean;\n /** ROUTES / route-path folder — unnamed children are walking paths. */\n routeContainer: boolean;\n}\n\nexport interface ParsedSvg {\n viewbox: ViewBox | null;\n elements: RawSvgElement[];\n routePathDs: string[];\n /** Structural problems worth surfacing in the import report. */\n warnings: string[];\n}\n\nexport function classifyId(\n id: string,\n mode: 'floor' | 'base' = 'floor',\n): { kind: ShapeKind | null; guessed: boolean } {\n // Layer folders first — `store` prefix must not claim `STORES`.\n if (isLayerContainerLabel(id)) {\n return { kind: null, guessed: false };\n }\n const lower = id.toLowerCase();\n const table = mode === 'base' ? BASE_PREFIXES : FLOOR_PREFIXES;\n for (const { prefix, kind } of table) {\n if (lower === prefix || lower.startsWith(prefix)) {\n return { kind, guessed: false };\n }\n }\n // interactive-* or data-interactive attribute handled by caller\n if (lower.startsWith('interactive')) {\n return { kind: 'unit', guessed: true };\n }\n return { kind: null, guessed: false };\n}\n\n/** Collapse Illustrator id / data-name punctuation so labels compare as words. */\nexport function normalizeLayerLabel(label: string): string {\n return label\n .toLowerCase()\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Illustrator / designer NON_INTERACTIVE, NON-INTERACTIVE, \"NON INTERACTIVE ITEMS\". */\nexport function isNonInteractiveGroupLabel(label: string): boolean {\n return /non[-_ ]?interactive/i.test(label);\n}\n\n/**\n * INTERACTIVE, INTERACTIVE_ITEMS, INTERACTIVE-2, data-name=\"INTERACTIVE ITEMS\".\n * Excludes NON_INTERACTIVE* and generated ids like interactive-anon-1.\n */\nexport function isInteractiveGroupLabel(label: string): boolean {\n if (isNonInteractiveGroupLabel(label)) return false;\n return /^interactive( items)?( \\d+)?$/.test(normalizeLayerLabel(label));\n}\n\n/**\n * STORES, store-layer, UNITS — folder names only.\n * Does not match store-46 / unit-12 (those are leaf stores).\n */\nexport function isStoreFolderLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return n === 'stores' || n === 'store layer' || n === 'units' || n === 'unit layer';\n}\n\n/**\n * Illustrator layer / folder: never emit as a shape, never join descendants into one `d`.\n */\nexport function isLayerContainerLabel(label: string): boolean {\n return (\n isInteractiveGroupLabel(label) ||\n isNonInteractiveGroupLabel(label) ||\n isStoreFolderLabel(label) ||\n isRouteFolderLabel(label)\n );\n}\n\nfunction isContainerFrame(frame: GroupFrame): boolean {\n return frame.interactiveContainer || frame.nonInteractiveContainer || frame.storeFolder;\n}\n\nfunction attrValue(attrs: string, name: string): string | null {\n const m = attrs.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`, 'i'));\n return m ? m[1] : null;\n}\n\nfunction numAttr(attrs: string, name: string): number {\n const m = attrs.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']?(-?[\\\\d.]+)`, 'i'));\n return m ? Number(m[1]) : 0;\n}\n\nfunction hasDataInteractive(attrs: string): boolean {\n return /\\bdata-interactive\\s*=\\s*[\"']?(true|1|yes)/i.test(attrs);\n}\n\nfunction labelsFromAttrs(attrs: string): string[] {\n return [attrValue(attrs, 'id'), attrValue(attrs, 'data-name')].filter(\n (s): s is string => Boolean(s),\n );\n}\n\nfunction groupKindFromLabels(labels: string[]): {\n interactiveContainer: boolean;\n nonInteractiveContainer: boolean;\n storeFolder: boolean;\n} {\n if (labels.some(isNonInteractiveGroupLabel)) {\n return { interactiveContainer: false, nonInteractiveContainer: true, storeFolder: false };\n }\n if (labels.some(isInteractiveGroupLabel)) {\n return { interactiveContainer: true, nonInteractiveContainer: false, storeFolder: false };\n }\n if (labels.some(isStoreFolderLabel)) {\n return { interactiveContainer: false, nonInteractiveContainer: false, storeFolder: true };\n }\n return { interactiveContainer: false, nonInteractiveContainer: false, storeFolder: false };\n}\n\nfunction pointsToPath(points: string): string {\n const nums = points.trim().split(/[\\s,]+/).map(Number);\n if (nums.length < 4) return '';\n let d = `M ${nums[0]} ${nums[1]}`;\n for (let i = 2; i < nums.length; i += 2) {\n d += ` L ${nums[i]} ${nums[i + 1]}`;\n }\n d += ' Z';\n return d;\n}\n\nfunction lineToPath(x1: number, y1: number, x2: number, y2: number): string {\n return `M ${x1} ${y1} L ${x2} ${y2}`;\n}\n\nfunction geometryFromTag(tag: string, attrs: string): string | undefined {\n if (tag === 'path') {\n return attrValue(attrs, 'd') ?? undefined;\n }\n if (tag === 'polygon' || tag === 'polyline') {\n const points = attrValue(attrs, 'points');\n return points ? pointsToPath(points) : undefined;\n }\n if (tag === 'line') {\n return lineToPath(\n numAttr(attrs, 'x1'),\n numAttr(attrs, 'y1'),\n numAttr(attrs, 'x2'),\n numAttr(attrs, 'y2'),\n );\n }\n if (tag === 'rect') {\n const x = numAttr(attrs, 'x');\n const y = numAttr(attrs, 'y');\n const w = numAttr(attrs, 'width');\n const h = numAttr(attrs, 'height');\n return `M ${x} ${y} L ${x + w} ${y} L ${x + w} ${y + h} L ${x} ${y + h} Z`;\n }\n return undefined;\n}\n\n/**\n * Lightweight SVG string parser — no DOM required (works in Node).\n * Scans tags sequentially and tracks `<g>` ancestry so Illustrator folders\n * (INTERACTIVE, STORES, NON_INTERACTIVE*) are never joined into one shape.\n */\nexport function parseSvgString(svg: string): ParsedSvg {\n const stripped = inlineSvgStyles(svg).replace(/<!--[\\s\\S]*?-->/g, '');\n const viewboxMatch = stripped.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n const viewbox = parseViewBox(viewboxMatch?.[1]);\n\n const elements: RawSvgElement[] = [];\n const routePathDs: string[] = [];\n const warnings: string[] = [];\n const stack: GroupFrame[] = [];\n let anon = 0;\n\n const inRouteContainer = (): boolean =>\n stack.some((frame) => frame.routeContainer);\n\n const parentStyle = (): SvgPresentationStyle => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const s = stack[i].style;\n if (s.fill || s.stroke || s.strokeWidth != null || s.opacity != null) {\n // Merge from root → leaf\n break;\n }\n }\n let merged: SvgPresentationStyle = {};\n for (const frame of stack) {\n merged = mergePresentationStyle(merged, frame.style);\n }\n return merged;\n };\n\n const inInteractive = (): boolean => {\n for (let i = stack.length - 1; i >= 0; i--) {\n if (stack[i].nonInteractiveContainer) return false;\n if (stack[i].interactiveContainer || stack[i].storeFolder) return true;\n }\n return false;\n };\n\n /** Accumulated `<g>` transform for the element currently being read. */\n const parentMatrix = (): Matrix2D =>\n stack.length > 0 ? stack[stack.length - 1].matrix : IDENTITY_MATRIX;\n\n const markNamedChild = () => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (isContainerFrame(frame)) continue;\n if (frame.id) {\n frame.hasNamedChild = true;\n return;\n }\n }\n };\n\n const findCollector = (): GroupFrame | null => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (isContainerFrame(frame)) continue;\n if (frame.id) return frame;\n }\n return null;\n };\n\n const closeGroup = (frame: GroupFrame) => {\n if (frame.routeContainer) {\n for (const collected of frame.collectedPaths) emitRoute('path', collected);\n return;\n }\n if (isContainerFrame(frame)) return;\n if (!frame.id || frame.collectedPaths.length === 0) return;\n if (frame.hasNamedChild) {\n // A folder-like group (KIOSK, ESCALATORS, …) that also holds a stray\n // unnamed path: the stray silently merges into one shape keyed after\n // the group. Classification is unchanged — the designer gets a warning.\n warnings.push(\n `Group ${frame.id} mixes named children with ${frame.collectedPaths.length} unnamed path(s); ` +\n `the unnamed paths were merged into a single shape \"${frame.id}\" — give them ids if they are separate shapes`,\n );\n }\n elements.push({\n id: frame.id,\n tag: 'g',\n d: frame.collectedPaths.join(' '),\n interactive: frame.inInteractive,\n style: mergePresentationStyle(parentStyle(), frame.style),\n });\n };\n\n const emitRoute = (tag: string, d: string | undefined) => {\n if (!d) return;\n const open =\n tag === 'polyline' || tag === 'polygon' || tag === 'path'\n ? d.replace(/\\s*Z\\s*$/i, '')\n : d;\n if (routePathDs.includes(open)) return;\n routePathDs.push(open);\n };\n\n const tokenRe = /<(\\/?)(path|polygon|polyline|line|rect|g)\\b([^>]*)(\\/?)>/gi;\n let match: RegExpExecArray | null;\n while ((match = tokenRe.exec(stripped)) !== null) {\n const closing = match[1] === '/';\n const tag = match[2].toLowerCase();\n const attrs = match[3] ?? '';\n const selfClosing = match[4] === '/' || /\\/\\s*$/.test(attrs);\n\n if (closing) {\n if (tag === 'g') {\n const frame = stack.pop();\n if (frame) closeGroup(frame);\n }\n continue;\n }\n\n if (tag === 'g') {\n const id = attrValue(attrs, 'id');\n const labels = labelsFromAttrs(attrs);\n const { interactiveContainer, nonInteractiveContainer, storeFolder } =\n groupKindFromLabels(labels);\n const parentInteractive = inInteractive();\n if (id) markNamedChild();\n const frame: GroupFrame = {\n id,\n interactiveContainer,\n nonInteractiveContainer,\n storeFolder,\n inInteractive:\n interactiveContainer ||\n storeFolder ||\n hasDataInteractive(attrs) ||\n (parentInteractive && !nonInteractiveContainer),\n collectedPaths: [],\n style: readPresentationStyle(attrs),\n matrix: multiplyMatrix(parentMatrix(), parseTransform(attrValue(attrs, 'transform'))),\n hasNamedChild: false,\n routeContainer:\n labels.some(isRouteFolderLabel) || inRouteContainer(),\n };\n if (!selfClosing) stack.push(frame);\n continue;\n }\n\n const id = attrValue(attrs, 'id');\n const raw = geometryFromTag(tag, attrs);\n // Bake own + inherited group transforms so every emitted `d` is in root\n // user space, matching the polygons derived from it later.\n const matrix = multiplyMatrix(parentMatrix(), parseTransform(attrValue(attrs, 'transform')));\n const d = raw ? transformPathD(raw, matrix) : raw;\n const interactive = hasDataInteractive(attrs) || inInteractive();\n const style = mergePresentationStyle(parentStyle(), readPresentationStyle(attrs));\n\n const dataName = attrValue(attrs, 'data-name');\n const routeNamed =\n (id != null && isRoutePathLabel(id)) ||\n (dataName != null && isRoutePathLabel(dataName));\n if (routeNamed || (!id && inRouteContainer())) {\n emitRoute(tag, d);\n continue;\n }\n\n if (id) {\n markNamedChild();\n if (d) {\n elements.push({ id, tag, d, interactive, style });\n }\n continue;\n }\n\n if (!d) continue;\n\n const collector = findCollector();\n if (collector) {\n collector.collectedPaths.push(d);\n // Prefer first child style onto the collector when empty\n if (!collector.style.fill && style.fill) collector.style = style;\n } else if (interactive) {\n anon += 1;\n elements.push({\n id: `interactive-anon-${anon}`,\n tag,\n d,\n interactive: true,\n style,\n });\n }\n }\n\n while (stack.length > 0) {\n closeGroup(stack.pop()!);\n }\n\n return { viewbox, elements, routePathDs, warnings };\n}\n\nexport interface ImportedShapeDraft {\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n sourceSvgId: string;\n style: ShapeStyle;\n}\n\nfunction slugKey(id: string): string {\n return id\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 80);\n}\n\nfunction styleFromElement(\n el: RawSvgElement,\n sourceSvgId: string,\n): ShapeStyle {\n const layer = resolveLayerStyle(sourceSvgId);\n const style: ShapeStyle = {};\n if (layer?.fill) style.fill = layer.fill;\n else if (el.style?.fill) style.fill = el.style.fill;\n if (layer?.stroke) style.stroke = layer.stroke;\n else if (el.style?.stroke) style.stroke = el.style.stroke;\n if (layer?.strokeWidth != null) style.strokeWidth = layer.strokeWidth;\n else if (el.style?.strokeWidth != null) style.strokeWidth = el.style.strokeWidth;\n if (el.style?.opacity != null) style.opacity = el.style.opacity;\n if (layer?.extrudeHeight != null) style.extrudeHeight = layer.extrudeHeight;\n return style;\n}\n\nfunction viewBoxesEqual(a: ViewBox | null, b: ViewBox | null): boolean {\n if (a == null && b == null) return true;\n if (a == null || b == null) return false;\n return (\n Math.abs(a.x - b.x) < 0.01 &&\n Math.abs(a.y - b.y) < 0.01 &&\n Math.abs(a.width - b.width) < 0.01 &&\n Math.abs(a.height - b.height) < 0.01\n );\n}\n\nexport interface ImportSvgOptions {\n /** Previous level viewBox — used to detect artboard changes on re-upload. */\n previousViewbox?: ViewBox | null;\n}\n\nexport function importSvg(\n svg: string,\n mode: 'floor' | 'base' = 'floor',\n options: ImportSvgOptions = {},\n): {\n report: ImportReport;\n shapes: ImportedShapeDraft[];\n viewbox: ViewBox | null;\n routePathDs: string[];\n viewBoxChanged: boolean;\n} {\n const parsed = parseSvgString(svg);\n const classified: ImportClassification[] = [];\n const unrecognized: string[] = [];\n const guessed: ImportClassification[] = [];\n const warnings: string[] = [...parsed.warnings];\n const shapes: ImportedShapeDraft[] = [];\n\n let walkableCount = 0;\n let voidCount = 0;\n let unitCount = 0;\n\n const viewBoxChanged =\n options.previousViewbox != null &&\n parsed.viewbox != null &&\n !viewBoxesEqual(options.previousViewbox, parsed.viewbox);\n\n if (viewBoxChanged) {\n warnings.push(\n 'SVG viewBox differs from the stored artboard — re-upload blocked until the designer restores the original viewBox',\n );\n }\n\n for (const el of parsed.elements) {\n if (isLayerContainerLabel(el.id)) continue;\n let { kind, guessed: isGuessed } = classifyId(el.id, mode);\n if (el.interactive && !kind) {\n kind = 'unit';\n isGuessed = true;\n }\n\n const entry: ImportClassification = {\n sourceSvgId: el.id,\n kind,\n guessed: isGuessed,\n };\n\n // Floor mode: keep unrecognized as decor so discarding the SVG loses nothing.\n // Outdoor / base mode: skip unrecognized — live SVG renderer draws them.\n if (!kind) {\n unrecognized.push(el.id);\n if (mode === 'floor') {\n kind = 'decor';\n entry.kind = 'decor';\n entry.message = 'No matching prefix; imported as decor (floor mode)';\n } else {\n entry.message = 'No matching prefix; skipped (outdoor decor stays in SVG)';\n classified.push(entry);\n continue;\n }\n }\n\n if (!el.d) {\n warnings.push(`Element ${el.id} has no drawable geometry`);\n continue;\n }\n\n // Outdoor: only persist interactive (+ walkable/void). Decoration stays in SVG.\n // Static house-style layers (green-area, parking-lane, …) are never rows.\n if (mode === 'base') {\n const isStaticDecor = resolveLayerStyle(el.id) != null;\n const shouldPersist =\n !isStaticDecor &&\n (IMPORT_PERSISTED_KINDS.includes(kind) || Boolean(el.interactive));\n if (!shouldPersist) {\n classified.push({\n ...entry,\n message: isStaticDecor\n ? 'Static decoration — rendered from outdoor SVG'\n : 'Decoration — not persisted; rendered from outdoor SVG',\n });\n continue;\n }\n }\n\n if (isGuessed) {\n guessed.push(entry);\n entry.message = entry.message ?? 'Guessed kind from interactive/fallback rule';\n }\n classified.push(entry);\n\n if (kind === 'walkable') walkableCount++;\n if (kind === 'void') voidCount++;\n if (kind === 'unit') unitCount++;\n\n const geometry = buildGeometryFromPaths([el.d]);\n const bbox = geometryBBox(geometry);\n\n shapes.push({\n key: slugKey(el.id),\n kind,\n geometry,\n bbox,\n sourceSvgId: el.id,\n style: styleFromElement(el, el.id),\n });\n }\n\n if (mode === 'floor' && walkableCount === 0) {\n warnings.push(\n 'No walkable layer found — auto-skeleton will be unavailable for this level',\n );\n }\n\n return {\n report: {\n classified,\n unrecognized,\n guessed,\n walkableCount,\n voidCount,\n unitCount,\n warnings,\n },\n shapes,\n viewbox: parsed.viewbox,\n routePathDs: parsed.routePathDs,\n viewBoxChanged,\n };\n}\n\nexport interface ExistingShapeRef {\n id: number;\n sourceSvgId: string | null;\n kind: ShapeKind;\n key: string;\n /** When set, centroid drift is measured against the new draft. */\n bbox?: BBox | null;\n geometryLocked?: boolean;\n}\n\n/**\n * Diff newly imported shapes against existing level shapes by source_svg_id.\n * Emits `moved` when a matched id's centroid drifts past IMPORT_DRIFT_THRESHOLD.\n */\nexport function diffImport(\n imported: ImportedShapeDraft[],\n existing: ExistingShapeRef[],\n viewbox: ViewBox | null,\n options: { driftThreshold?: number } = {},\n): ImportDiff {\n const driftThreshold = options.driftThreshold ?? IMPORT_DRIFT_THRESHOLD;\n const existingBySource = new Map(\n existing\n .filter((e) => e.sourceSvgId)\n .map((e) => [e.sourceSvgId as string, e]),\n );\n const seen = new Set<string>();\n const items: ImportDiffItem[] = [];\n\n for (const shape of imported) {\n const prev = existingBySource.get(shape.sourceSvgId);\n seen.add(shape.sourceSvgId);\n if (!prev) {\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change: 'added',\n newKind: shape.kind,\n });\n } else if (prev.kind !== shape.kind) {\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change: 'kind_changed',\n existingShapeId: prev.id,\n existingKind: prev.kind,\n newKind: shape.kind,\n preserve: { key: prev.key, assignment: true, anchors: true },\n geometryLocked: prev.geometryLocked,\n });\n } else {\n let change: ImportDiffItem['change'] = 'unchanged';\n if (prev.bbox) {\n const prevCx = (prev.bbox.minX + prev.bbox.maxX) / 2;\n const prevCy = (prev.bbox.minY + prev.bbox.maxY) / 2;\n const next = geometryCentroid(shape.geometry);\n const drift = Math.hypot(next.x - prevCx, next.y - prevCy);\n if (drift > driftThreshold) change = 'moved';\n }\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change,\n existingShapeId: prev.id,\n existingKind: prev.kind,\n newKind: shape.kind,\n preserve: { key: prev.key, assignment: true, anchors: true },\n geometryLocked: prev.geometryLocked,\n });\n }\n }\n\n for (const prev of existing) {\n if (prev.sourceSvgId && !seen.has(prev.sourceSvgId)) {\n items.push({\n sourceSvgId: prev.sourceSvgId,\n change: 'removed',\n existingShapeId: prev.id,\n existingKind: prev.kind,\n geometryLocked: prev.geometryLocked,\n });\n }\n }\n\n return {\n items,\n shapes: imported,\n viewbox,\n };\n}\n\nexport {\n inlineSvgStyles,\n readPresentationStyle,\n mergePresentationStyle,\n} from './svgStyle';\n\nexport {\n IDENTITY_MATRIX,\n applyMatrix,\n isIdentityMatrix,\n multiplyMatrix,\n parseTransform,\n transformPathD,\n type Matrix2D,\n} from './svgTransform';\n","import { distance } from './geometry';\nimport { clampStoreRadius, type Vec2 } from './types';\n\nconst EPS = 1e-6;\n/** Illustrator-style: only corner anchors, not smooth wall wobble. */\nconst MIN_CORNER_TURN = (15 * Math.PI) / 180;\nconst EDGE_GAP = 1e-3;\nconst TWO_PI = Math.PI * 2;\n\nfunction almostSame(a: Vec2, b: Vec2): boolean {\n return Math.abs(a.x - b.x) < EPS && Math.abs(a.y - b.y) < EPS;\n}\n\nfunction add(a: Vec2, b: Vec2): Vec2 {\n return { x: a.x + b.x, y: a.y + b.y };\n}\n\nfunction sub(a: Vec2, b: Vec2): Vec2 {\n return { x: a.x - b.x, y: a.y - b.y };\n}\n\nfunction scale(a: Vec2, s: number): Vec2 {\n return { x: a.x * s, y: a.y * s };\n}\n\nfunction pointOnCircle(center: Vec2, radius: number, angle: number): Vec2 {\n return {\n x: center.x + Math.cos(angle) * radius,\n y: center.y + Math.sin(angle) * radius,\n };\n}\n\n/** Drop duplicate consecutive points and a repeated closing vertex. */\nexport function uniqueClosedRing(points: Vec2[]): Vec2[] {\n const ring: Vec2[] = [];\n for (const point of points) {\n const last = ring[ring.length - 1];\n if (last && almostSame(last, point)) continue;\n ring.push(point);\n }\n if (ring.length >= 2 && almostSame(ring[0], ring[ring.length - 1])) ring.pop();\n return ring;\n}\n\n/**\n * Illustrator Round Corners: replace each real corner with a circular arc\n * tangent to both walls. The arc stays at the corner (never the long way\n * through the store). Shallow wall bends are left alone.\n */\nexport function filletPolygon(points: Vec2[], radius: number): Vec2[] {\n const r = clampStoreRadius(radius);\n const ring = uniqueClosedRing(points);\n if (ring.length < 3 || r <= 0) return points;\n\n const n = ring.length;\n const inN: Vec2[] = new Array(n);\n const outN: Vec2[] = new Array(n);\n const outLen: number[] = new Array(n);\n const turn: number[] = new Array(n);\n const inD = new Array(n).fill(0);\n const outD = new Array(n).fill(0);\n const fillet = new Array(n).fill(false);\n\n for (let i = 0; i < n; i++) {\n const prev = ring[(i - 1 + n) % n];\n const curr = ring[i];\n const next = ring[(i + 1) % n];\n const incoming = distance(prev, curr);\n const outgoing = distance(curr, next);\n outLen[i] = outgoing;\n if (incoming < EPS || outgoing < EPS) {\n inN[i] = { x: 1, y: 0 };\n outN[i] = { x: 1, y: 0 };\n turn[i] = 0;\n continue;\n }\n inN[i] = scale(sub(curr, prev), 1 / incoming);\n outN[i] = scale(sub(next, curr), 1 / outgoing);\n const cross = inN[i].x * outN[i].y - inN[i].y * outN[i].x;\n const dot = inN[i].x * outN[i].x + inN[i].y * outN[i].y;\n turn[i] = Math.atan2(cross, dot);\n const absTurn = Math.abs(turn[i]);\n if (absTurn < MIN_CORNER_TURN) continue;\n // Illustrator uses the same offset for convex and concave:\n // d = r / tan((π − |turn|)/2). Splitting those cases made\n // store-40's inner notch bulge instead of a tight inner radius.\n const wedge = Math.PI - absTurn;\n const tanHalf = Math.tan(wedge / 2);\n if (tanHalf < EPS || wedge <= EPS || wedge >= Math.PI - EPS) continue;\n const desired = r / tanHalf;\n inD[i] = desired;\n outD[i] = desired;\n fillet[i] = true;\n }\n\n for (let i = 0; i < n; i++) {\n const j = (i + 1) % n;\n const need = outD[i] + inD[j];\n const available = Math.max(0, outLen[i] - EDGE_GAP);\n if (need <= available || need <= EPS) continue;\n const scaleDown = available / need;\n outD[i] *= scaleDown;\n inD[j] *= scaleDown;\n }\n\n const out: Vec2[] = [];\n for (let i = 0; i < n; i++) {\n const curr = ring[i];\n const d = Math.min(inD[i], outD[i]);\n const absTurn = Math.abs(turn[i]);\n const wedge = Math.PI - absTurn;\n const actualR = d * Math.tan(wedge / 2);\n if (!fillet[i] || actualR < EPS || d < EPS) {\n out.push({ ...curr });\n continue;\n }\n\n const start = add(curr, scale(inN[i], -d));\n const end = add(curr, scale(outN[i], d));\n const sign = turn[i] > 0 ? 1 : -1;\n const center = add(start, {\n x: -inN[i].y * sign * actualR,\n y: inN[i].x * sign * actualR,\n });\n const a0 = Math.atan2(start.y - center.y, start.x - center.x);\n const a1 = Math.atan2(end.y - center.y, end.x - center.x);\n const sweepCCW = (a1 - a0 + TWO_PI) % TWO_PI;\n const sweepCW = (a0 - a1 + TWO_PI) % TWO_PI;\n const midCCW = pointOnCircle(center, actualR, a0 + sweepCCW / 2);\n const midCW = pointOnCircle(center, actualR, a0 - sweepCW / 2);\n const useCCW = distance(midCCW, curr) <= distance(midCW, curr);\n const sweep = useCCW ? sweepCCW : sweepCW;\n const steps = Math.max(8, Math.min(28, Math.ceil((sweep * actualR) / 2)));\n\n for (let s = 0; s <= steps; s++) {\n const t = s / steps;\n const ang = useCCW ? a0 + sweep * t : a0 - sweep * t;\n out.push(pointOnCircle(center, actualR, ang));\n }\n }\n\n return out;\n}\n","import createGraph, { type Graph } from 'ngraph.graph';\nimport path from 'ngraph.path';\nimport type {\n CmAnchor,\n CmConnector,\n CmRouteEdge,\n PathResult,\n PublishedGraphEdge,\n PublishedGraphNode,\n} from '../types';\nimport { FLOOR_CHANGE_PENALTY } from '../types';\nimport { distance } from '../geometry';\n\nexport interface CompiledGraph {\n graph: Graph;\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n anchorById: Map<number, CmAnchor>;\n}\n\nexport function compileGraph(\n anchors: CmAnchor[],\n edges: CmRouteEdge[],\n connectors: CmConnector[] = [],\n): CompiledGraph {\n const graph = createGraph();\n const anchorById = new Map(anchors.map((a) => [a.id, a]));\n const connectorById = new Map(connectors.map((c) => [c.id, c]));\n\n const nodes: PublishedGraphNode[] = anchors.map((a) => ({\n id: a.id,\n levelId: a.levelId,\n x: a.x,\n y: a.y,\n kind: a.kind,\n shapeId: a.shapeId,\n connectorId: a.connectorId,\n }));\n\n for (const n of nodes) {\n graph.addNode(n.id, n);\n }\n\n const publishedEdges: PublishedGraphEdge[] = [];\n\n for (const e of edges) {\n const from = anchorById.get(e.fromAnchorId);\n const to = anchorById.get(e.toAnchorId);\n if (!from || !to) continue;\n\n let weight = e.weight;\n if (weight == null) {\n weight = distance(from, to);\n if (from.levelId !== to.levelId) {\n weight += FLOOR_CHANGE_PENALTY;\n }\n }\n\n // Accessibility: connector edges inherit connector.accessible\n let accessible = e.accessible;\n if (e.kind === 'connector' && from.connectorId != null) {\n const conn = connectorById.get(from.connectorId);\n if (conn) accessible = conn.accessible;\n }\n\n const pub: PublishedGraphEdge = {\n id: e.id,\n from: e.fromAnchorId,\n to: e.toAnchorId,\n weight,\n directed: e.directed,\n accessible,\n kind: e.kind,\n };\n publishedEdges.push(pub);\n\n graph.addLink(e.fromAnchorId, e.toAnchorId, pub);\n if (!e.directed) {\n graph.addLink(e.toAnchorId, e.fromAnchorId, pub);\n }\n }\n\n return { graph, nodes, edges: publishedEdges, anchorById };\n}\n\nexport interface FindPathOptions {\n accessibleOnly?: boolean;\n}\n\n/**\n * NBA* pathfinding over the compiled graph.\n * Returns null if no path exists.\n */\nexport function findPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n toAnchorId: number,\n options: FindPathOptions = {},\n): PathResult | null {\n const { graph, anchorById } = compiled;\n if (!anchorById.has(fromAnchorId) || !anchorById.has(toAnchorId)) {\n return null;\n }\n\n const finder = path.nba(graph, {\n oriented: true,\n distance(fromNode, toNode, link) {\n const data = link.data as PublishedGraphEdge | undefined;\n if (options.accessibleOnly && data && !data.accessible) {\n return Number.POSITIVE_INFINITY;\n }\n return data?.weight ?? 1;\n },\n heuristic(fromNode, toNode) {\n const a = anchorById.get(fromNode.id as number);\n const b = anchorById.get(toNode.id as number);\n if (!a || !b) return 0;\n let d = distance(a, b);\n if (a.levelId !== b.levelId) d += FLOOR_CHANGE_PENALTY;\n return d;\n },\n });\n\n const raw = finder.find(fromAnchorId, toAnchorId);\n if (!raw || raw.length === 0) return null;\n\n // ngraph returns destination → start; reverse\n const nodes = raw.reverse();\n const anchorIds = nodes.map((n) => n.id as number);\n const points: PathResult['points'] = [];\n const levelChanges: PathResult['levelChanges'] = [];\n let totalWeight = 0;\n\n for (let i = 0; i < anchorIds.length; i++) {\n const a = anchorById.get(anchorIds[i])!;\n points.push({ x: a.x, y: a.y, levelId: a.levelId });\n if (i > 0) {\n const prev = anchorById.get(anchorIds[i - 1])!;\n totalWeight += distance(prev, a);\n if (prev.levelId !== a.levelId) {\n totalWeight += FLOOR_CHANGE_PENALTY;\n levelChanges.push({\n fromLevelId: prev.levelId,\n toLevelId: a.levelId,\n connectorId: a.connectorId ?? prev.connectorId,\n });\n }\n }\n }\n\n return { anchorIds, points, totalWeight, levelChanges };\n}\n\n/**\n * Find the nearest matching amenity shape anchor from a start point.\n */\nexport function findNearestAmenityPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n amenityAnchorIds: number[],\n options: FindPathOptions = {},\n): PathResult | null {\n let best: PathResult | null = null;\n for (const targetId of amenityAnchorIds) {\n const result = findPath(compiled, fromAnchorId, targetId, options);\n if (!result) continue;\n if (!best || result.totalWeight < best.totalWeight) {\n best = result;\n }\n }\n return best;\n}\n","import type {\n CmAmenityCatalogItem,\n CmAnchor,\n CmBuilding,\n CmConnector,\n CmLevel,\n CmResponsiveOverride,\n CmRouteEdge,\n CmShape,\n CmShapeAssignment,\n PublishedDocument,\n ThemeDefaults,\n ViewBox,\n} from '../types';\nimport { mergeTheme } from '../types';\nimport { compileGraph } from '../routing/pathfinding';\nimport { geometryBBox, normalizeGeometrySpace } from '../geometry';\n\nexport interface PublishInput {\n revisionId: number;\n revisionNumber: number;\n centerId: number;\n mapId: number;\n theme: Partial<ThemeDefaults>;\n baseSvgUrl: string | null;\n baseViewbox: ViewBox | null;\n buildings: CmBuilding[];\n levels: CmLevel[];\n shapes: CmShape[];\n assignments: CmShapeAssignment[];\n anchors: CmAnchor[];\n edges: CmRouteEdge[];\n connectors: CmConnector[];\n amenities: CmAmenityCatalogItem[];\n responsiveOverrides: CmResponsiveOverride[];\n /** Resolve S3 key → CDN URL for level source SVGs. */\n resolveSvgUrl?: (key: string | null) => string | null;\n publishedAt?: string;\n}\n\n/**\n * Compile live cm_* rows into the current production document.\n * Used by Save Changes (overwrite-in-place) and draft preview (?draft=1).\n */\nexport function compileDocument(input: PublishInput): PublishedDocument {\n const theme: ThemeDefaults = mergeTheme(input.theme);\n const assignmentByShape = new Map(\n input.assignments.map((a) => [a.shapeId, a]),\n );\n const resolve = input.resolveSvgUrl ?? ((k: string | null) => k);\n\n const levels = input.levels\n .filter((l) => l.isActive)\n .sort((a, b) => a.ordering - b.ordering)\n .map((level) => {\n const levelShapes = input.shapes\n .filter((s) => s.levelId === level.id)\n .map((s) => {\n // Heals rows imported before the Y-flip removal without a re-import.\n const geometry = normalizeGeometrySpace(s.geometry);\n return {\n ...s,\n geometry,\n bbox: geometry === s.geometry ? s.bbox : geometryBBox(geometry),\n assignment: assignmentByShape.get(s.id) ?? null,\n };\n });\n const levelAnchors = input.anchors.filter((a) => a.levelId === level.id);\n return {\n id: level.id,\n buildingId: level.buildingId,\n kind: level.kind,\n name: level.name,\n levelIndex: level.levelIndex,\n ordering: level.ordering,\n sourceSvgUrl: resolve(level.sourceSvgKey) ?? level.sourceSvgUrl ?? null,\n viewbox: level.sourceViewbox,\n transform: level.transform,\n shapes: levelShapes,\n anchors: levelAnchors,\n };\n });\n\n const { nodes, edges } = compileGraph(\n input.anchors,\n input.edges,\n input.connectors,\n );\n\n return {\n version: 2,\n revisionId: input.revisionId,\n revisionNumber: input.revisionNumber,\n centerId: input.centerId,\n mapId: input.mapId,\n theme,\n baseSvgUrl: input.baseSvgUrl,\n baseViewbox: input.baseViewbox,\n buildings: input.buildings,\n levels,\n connectors: input.connectors,\n amenities: input.amenities.filter((a) => a.isActive),\n graph: { nodes, edges },\n responsiveOverrides: input.responsiveOverrides,\n publishedAt: input.publishedAt ?? new Date().toISOString(),\n };\n}\n\n/**\n * Heal a document that was compiled before the Y-flip removal. Viewer hosts\n * load `cm_revisions` JSON as-is (they never re-run `compileDocument`), so\n * stale polygons would otherwise render upside down relative to the editor.\n */\nexport function normalizePublishedDocument(\n doc: PublishedDocument,\n): PublishedDocument {\n let changed = false;\n const levels = doc.levels.map((level) => {\n let levelChanged = false;\n const shapes = level.shapes.map((shape) => {\n const geometry = normalizeGeometrySpace(shape.geometry);\n if (geometry === shape.geometry) return shape;\n levelChanged = true;\n return {\n ...shape,\n geometry,\n bbox: geometryBBox(geometry),\n };\n });\n if (!levelChanged) return level;\n changed = true;\n return { ...level, shapes };\n });\n return changed ? { ...doc, levels } : doc;\n}\n","import type { LevelKind, PublishedLevel, ViewBox } from './types';\n\nexport interface StackLevel {\n id: number;\n kind: LevelKind;\n ordering: number;\n levelIndex: number;\n}\n\n/** Same comparator as admin FloorsPanel `buildingFloors`. */\nexport function compareBuildingFloors(\n a: { ordering: number; levelIndex: number },\n b: { ordering: number; levelIndex: number },\n): number {\n return a.ordering - b.ordering || a.levelIndex - b.levelIndex;\n}\n\nexport interface SceneBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n cx: number;\n cy: number;\n size: number;\n}\n\nexport function isOutdoorLevel(level: { kind: string }): boolean {\n return level.kind === 'outdoor';\n}\n\n/**\n * Persistent base + optional building-floor overlay.\n * Outdoor/base is never dropped when a floor is selected.\n * Selecting Outdoor hides building floors (base stays).\n */\nexport function viewerLevelStack<T extends { id: number; kind: string }>(\n levels: T[],\n activeLevelId: number | null,\n): T[] {\n const outdoor = levels.filter(isOutdoorLevel);\n const active =\n activeLevelId == null\n ? null\n : (levels.find((level) => level.id === activeLevelId) ?? null);\n\n if (!active || isOutdoorLevel(active)) {\n return outdoor;\n }\n\n if (outdoor.some((level) => level.id === active.id)) {\n return outdoor;\n }\n return [...outdoor, active];\n}\n\n/** Building floors only, same order as the admin Floors list. */\nexport function floorSwitcherLevels<T extends StackLevel>(levels: T[]): T[] {\n return levels\n .filter((level) => level.kind === 'floor')\n .slice()\n .sort(compareBuildingFloors);\n}\n\n/**\n * Switcher buttons top-to-bottom — same order as the admin Floors list.\n * Do not reverse: staff order the list (upper level at the top) and the map\n * must match that.\n */\nexport function floorSwitcherDisplayLevels<T extends StackLevel>(levels: T[]): T[] {\n return floorSwitcherLevels(levels);\n}\n\n/** Hide the map floor list when there is only one building floor. */\nexport function shouldShowFloorSwitcher<T extends StackLevel>(levels: T[]): boolean {\n return floorSwitcherLevels(levels).length > 1;\n}\n\n/**\n * Prefer the last building floor in admin Floors order (bottom of the list).\n * The list stays upper-to-ground top-to-bottom; visitors should land on ground.\n */\nexport function defaultViewerLevelId(\n levels: Array<{ id: number; kind: string; ordering: number; levelIndex: number }>,\n): number | null {\n return floorSwitcherLevels(levels as StackLevel[]).at(-1)?.id ?? levels[0]?.id ?? null;\n}\n\nexport function viewBoxToBounds(viewbox: ViewBox): SceneBounds {\n return {\n minX: viewbox.x,\n minY: viewbox.y,\n maxX: viewbox.x + viewbox.width,\n maxY: viewbox.y + viewbox.height,\n cx: viewbox.x + viewbox.width / 2,\n cy: viewbox.y + viewbox.height / 2,\n size: Math.max(viewbox.width, viewbox.height, 100),\n };\n}\n\nexport function expandBounds(target: SceneBounds, next: SceneBounds): SceneBounds {\n const minX = Math.min(target.minX, next.minX);\n const minY = Math.min(target.minY, next.minY);\n const maxX = Math.max(target.maxX, next.maxX);\n const maxY = Math.max(target.maxY, next.maxY);\n return {\n minX,\n minY,\n maxX,\n maxY,\n cx: (minX + maxX) / 2,\n cy: (minY + maxY) / 2,\n size: Math.max(maxX - minX, maxY - minY, 100),\n };\n}\n\nexport function boundsFromStackedLevels(\n levels: PublishedLevel[],\n activeLevelId: number | null,\n baseViewbox?: ViewBox | null,\n): SceneBounds {\n let bounds: SceneBounds | null = baseViewbox ? viewBoxToBounds(baseViewbox) : null;\n\n for (const level of viewerLevelStack(levels, activeLevelId)) {\n if (level.viewbox) {\n const vb = viewBoxToBounds(level.viewbox);\n bounds = bounds ? expandBounds(bounds, vb) : vb;\n }\n for (const shape of level.shapes) {\n const shapeBounds: SceneBounds = {\n minX: shape.bbox.minX,\n minY: shape.bbox.minY,\n maxX: shape.bbox.maxX,\n maxY: shape.bbox.maxY,\n cx: (shape.bbox.minX + shape.bbox.maxX) / 2,\n cy: (shape.bbox.minY + shape.bbox.maxY) / 2,\n size: Math.max(\n shape.bbox.maxX - shape.bbox.minX,\n shape.bbox.maxY - shape.bbox.minY,\n 100,\n ),\n };\n bounds = bounds ? expandBounds(bounds, shapeBounds) : shapeBounds;\n }\n }\n\n return bounds ?? { minX: 0, minY: 0, maxX: 500, maxY: 500, cx: 250, cy: 250, size: 500 };\n}\n\nexport function unionViewBox(\n primary: ViewBox | null | undefined,\n secondary: ViewBox | null | undefined,\n): ViewBox {\n if (!primary && !secondary) return { x: 0, y: 0, width: 1000, height: 800 };\n if (!primary) return secondary!;\n if (!secondary) return primary;\n const minX = Math.min(primary.x, secondary.x);\n const minY = Math.min(primary.y, secondary.y);\n const maxX = Math.max(primary.x + primary.width, secondary.x + secondary.width);\n const maxY = Math.max(primary.y + primary.height, secondary.y + secondary.height);\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n"],"names":["WALKING_PATH_COLOR","STATIC_LAYER_STYLES","normalizeLayerName","label","resolveLayerStyle","layerName","normalized","keys","a","b","key","keyNorm","svgIdsOwnedByShapes","shapes","options","omitStatic","ids","shape","id","DEFAULT_THEME","LEGACY_V2_MAP_BACKGROUND","LEGACY_WALKABLE_COLORS","MAX_STORE_RADIUS","clampStoreRadius","value","n","mergeTheme","partials","theme","INTERACTIVE_SHAPE_KINDS","FLOOR_CHANGE_PENALTY","DEFAULT_WELD_TOLERANCE","mapSurface","host","PUBLIC_CHROME","VIEWER_CHROME","viewerChrome","isMapViewerHost","resolveFetchUrl","url","imageProxyUrl","flipY","points","viewboxHeight","p","distance","dx","dy","bboxOf","minX","minY","maxX","maxY","bboxUnion","centroid","sx","sy","pointInPolygon","point","polygon","inside","i","j","xi","yi","xj","yj","pointInPolygons","polygons","poly","projectOntoSegment","lenSq","t","proj","nearestPointOnPolyline","polyline","best","approximateCubic","p0","p1","p2","p3","segments","out","u","approximateQuadratic","ARC_SEGMENTS_PER_QUADRANT","approximateArc","rx","ry","xAxisRotationDeg","largeArc","sweep","arx","ary","phi","cosPhi","sinPhi","dx2","dy2","x1p","y1p","lambda","scale","rxSq","rySq","numerator","denominator","factor","cxp","cyp","cx","cy","ux","uy","vx","vy","theta1","deltaTheta","ideal","theta","cosT","sinT","WHITESPACE_RE","tokenizePathData","d","tokens","cmd","argIndex","ch","arcSlot","start","digits","beforeExponent","pathToPolygons","current","x","y","startX","startY","lastCtrl","readNum","isRel","nx","ny","x1","y1","x2","y2","approx","rot","firstMoveTo","m","isGeometrySpaceStale","geometry","_a","first","_b","normalizeGeometrySpace","buildGeometryFromPaths","pathDs","paths","geometryBBox","all","geometryCentroid","snapAngle","from","to","baseDeg","increments","len","relative","bestDiff","step","snapped","diff","finalDeg","angleFromWall","parseViewBox","raw","parts","CSS_TO_SVG_ATTR","parseCssDeclarations","block","declarations","declaration","sep","property","parseCssClassRules","cssText","classStyles","normalizedCss","match","selectors","s","selector","classMatch","className","mergeClassStyles","classAttr","merged","name","c","inlineSvgStyles","svgText","styleBlocks","withoutComments","decls","full","tag","attrs","selfClosing","cleanAttrs","nextAttrs","cssProp","svgAttr","readPresentationStyle","fill","stroke","strokeWidth","_c","opacity","_d","fillOpacity","_e","mergePresentationStyle","parent","child","IDENTITY_MATRIX","multiplyMatrix","outer","inner","applyMatrix","isIdentityMatrix","epsilon","translateMatrix","tx","ty","rotateMatrix","deg","rad","cos","sin","transformFunctionMatrix","args","TRANSFORM_FN_RE","parseTransform","result","next","fmt","rounded","transformArc","phiDeg","e11","e21","e12","e22","m11","m21","m12","m22","E","F","G","H","q","r","outRx","outRy","a1","outPhi","transformPathD","flipsOrientation","emit","letter","coords","px","py","rel","arc","FLOOR_PREFIXES","BASE_PREFIXES","isRoutePathLabel","normalizeLayerLabel","isRouteFolderLabel","IMPORT_PERSISTED_KINDS","IMPORT_DRIFT_THRESHOLD","classifyId","mode","isLayerContainerLabel","lower","table","prefix","kind","isNonInteractiveGroupLabel","isInteractiveGroupLabel","isStoreFolderLabel","isContainerFrame","frame","attrValue","numAttr","hasDataInteractive","labelsFromAttrs","groupKindFromLabels","labels","pointsToPath","nums","lineToPath","geometryFromTag","w","h","parseSvgString","svg","stripped","viewboxMatch","viewbox","elements","routePathDs","warnings","stack","anon","inRouteContainer","parentStyle","inInteractive","parentMatrix","markNamedChild","findCollector","closeGroup","collected","emitRoute","open","tokenRe","closing","interactiveContainer","nonInteractiveContainer","storeFolder","parentInteractive","matrix","interactive","style","dataName","collector","slugKey","styleFromElement","el","sourceSvgId","layer","viewBoxesEqual","importSvg","parsed","classified","unrecognized","guessed","walkableCount","voidCount","unitCount","viewBoxChanged","isGuessed","entry","isStaticDecor","bbox","diffImport","imported","existing","driftThreshold","existingBySource","e","seen","items","prev","change","prevCx","prevCy","EPS","MIN_CORNER_TURN","EDGE_GAP","TWO_PI","almostSame","add","sub","pointOnCircle","center","radius","angle","uniqueClosedRing","ring","last","filletPolygon","inN","outN","outLen","turn","inD","outD","fillet","curr","incoming","outgoing","cross","dot","absTurn","wedge","tanHalf","desired","need","available","scaleDown","actualR","end","sign","a0","sweepCCW","sweepCW","midCCW","midCW","useCCW","steps","ang","compileGraph","anchors","edges","connectors","graph","createGraph","anchorById","connectorById","nodes","publishedEdges","weight","accessible","conn","pub","findPath","compiled","fromAnchorId","toAnchorId","path","fromNode","toNode","link","data","anchorIds","levelChanges","totalWeight","findNearestAmenityPath","amenityAnchorIds","targetId","compileDocument","input","assignmentByShape","resolve","k","levels","l","level","levelShapes","levelAnchors","normalizePublishedDocument","doc","changed","levelChanged","compareBuildingFloors","isOutdoorLevel","viewerLevelStack","activeLevelId","outdoor","active","floorSwitcherLevels","floorSwitcherDisplayLevels","shouldShowFloorSwitcher","defaultViewerLevelId","viewBoxToBounds","expandBounds","target","boundsFromStackedLevels","baseViewbox","bounds","vb","shapeBounds","unionViewBox","primary","secondary"],"mappings":"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"}
1
+ {"version":3,"file":"stacking.js","sources":["../../src/core/color.ts","../../src/core/layerStyles.ts","../../src/core/types.ts","../../src/core/entranceIcon.ts","../../src/core/labelAlign.ts","../../src/core/assignment.ts","../../src/core/hostChrome.ts","../../src/core/mediaUrl.ts","../../src/core/geometry/index.ts","../../src/core/import/svgStyle.ts","../../src/core/import/svgTransform.ts","../../src/core/import/index.ts","../../src/core/filletPolygon.ts","../../src/core/routing/pathfinding.ts","../../src/core/publish/index.ts","../../src/core/voids.ts","../../src/core/stacking.ts"],"sourcesContent":["/** Stored value for an explicit transparent fill / text color. */\nexport const TRANSPARENT_COLOR = 'transparent';\n\n/** True when the field is an explicit transparent choice (not an unset inherit). */\nexport function isTransparentColor(value: string | null | undefined): boolean {\n const text = (value ?? '').trim().toLowerCase();\n return text === TRANSPARENT_COLOR || text === 'none';\n}\n","import { isTransparentColor } from './color';\n\n/**\n * House styles for recognized outdoor SVG layer-name prefixes.\n * Defaults stay in this file (v1 `staticMapLayerSettings`). Settings may\n * override the colors and persist them on the map theme; Reset restores these.\n */\n\nexport interface StaticLayerStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n renderOrder: number;\n extrudeHeight?: number;\n}\n\n/**\n * v1 walking-path has no portal setting — it keeps the SVG fill, and every\n * published mall file uses this icy walkway color. v2 defaults to the same hex.\n */\nexport const WALKING_PATH_COLOR = '#E9F7FC';\n\nexport const STATIC_LAYER_KEYS = [\n 'green-area',\n 'water-area',\n 'parking-lane',\n 'parking-line',\n 'parking-icon',\n 'walking-path',\n] as const;\n\nexport type StaticLayerKey = (typeof STATIC_LAYER_KEYS)[number];\n\n/**\n * Theme field that Settings uses to override a house layer.\n * `parking-line` stays a house stroke only — it is not an assignable shape\n * and is omitted from Settings.\n */\nexport const STATIC_LAYER_THEME_KEYS = {\n 'green-area': 'GREEN_AREA_COLOR',\n 'water-area': 'WATER_COLOR',\n 'parking-lane': 'PARKING_LANE_COLOR',\n 'parking-icon': 'PARKING_ICON_COLOR',\n 'walking-path': 'WALKABLE_COLOR',\n} as const satisfies Partial<Record<StaticLayerKey, string>>;\n\nexport type StaticLayerThemeKey =\n (typeof STATIC_LAYER_THEME_KEYS)[keyof typeof STATIC_LAYER_THEME_KEYS];\n\n/**\n * Prefix → house style. Matching is normalized so `parking-lane`,\n * `parking_lane`, and `parking-lanes` all resolve to the same entry.\n */\nexport const STATIC_LAYER_STYLES: Record<StaticLayerKey, StaticLayerStyle> = {\n 'green-area': {\n fill: '#C4DDAB',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'water-area': {\n fill: '#5cc0f9',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'parking-lane': {\n fill: '#F6F6F6',\n renderOrder: 2,\n extrudeHeight: 1,\n },\n 'parking-line': {\n stroke: '#DDDDDD',\n strokeWidth: 0.6,\n renderOrder: 6,\n extrudeHeight: 0.5,\n },\n 'parking-icon': {\n fill: '#CCCCCC',\n renderOrder: 7,\n extrudeHeight: 1,\n },\n 'walking-path': {\n fill: WALKING_PATH_COLOR,\n renderOrder: 2,\n extrudeHeight: 1,\n },\n};\n\n/** Built-in fill/stroke for a reserved outdoor layer. */\nexport function staticLayerHouseColor(key: StaticLayerKey): string {\n const style = STATIC_LAYER_STYLES[key];\n return style.fill ?? style.stroke ?? '';\n}\n\n/** Theme defaults that match the code house colors. */\nexport function staticLayerThemeDefaults(): Record<StaticLayerThemeKey, string> {\n return {\n GREEN_AREA_COLOR: staticLayerHouseColor('green-area'),\n WATER_COLOR: staticLayerHouseColor('water-area'),\n PARKING_LANE_COLOR: staticLayerHouseColor('parking-lane'),\n PARKING_ICON_COLOR: staticLayerHouseColor('parking-icon'),\n WALKABLE_COLOR: staticLayerHouseColor('walking-path'),\n };\n}\n\n/** Collapse punctuation so `parking_lane_2` and `parking-lanes` compare as words. */\nexport function normalizeLayerName(label: string): string {\n return label\n .toLowerCase()\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction namesMatchLayer(normalized: string, key: StaticLayerKey): boolean {\n const keyNorm = normalizeLayerName(key);\n if (normalized === keyNorm) return true;\n if (normalized.startsWith(`${keyNorm} `)) return true;\n if (normalized === `${keyNorm}s`) return true;\n if (normalized.startsWith(`${keyNorm}s `)) return true;\n return false;\n}\n\nexport function resolveStaticLayerKey(\n layerName: string | null | undefined,\n): StaticLayerKey | null {\n if (!layerName) return null;\n const normalized = normalizeLayerName(layerName);\n if (!normalized) return null;\n\n const keys = [...STATIC_LAYER_KEYS].sort((a, b) => b.length - a.length);\n for (const key of keys) {\n if (namesMatchLayer(normalized, key)) return key;\n }\n return null;\n}\n\nfunction applyLayerTheme(\n style: StaticLayerStyle,\n key: StaticLayerKey,\n theme?: Partial<Record<string, string>> | null,\n): StaticLayerStyle {\n const field = STATIC_LAYER_THEME_KEYS[key];\n if (!field) return style;\n const override = theme?.[field];\n if (typeof override !== 'string') return style;\n if (isTransparentColor(override)) {\n if (style.fill) return { ...style, fill: 'transparent' };\n if (style.stroke) return { ...style, stroke: 'transparent' };\n return style;\n }\n if (!override.trim()) return style;\n if (style.fill) return { ...style, fill: override };\n if (style.stroke) return { ...style, stroke: override };\n return style;\n}\n\n/**\n * Resolve a static house style from an SVG element / group id.\n * Returns null when the name is not a reserved decoration layer.\n *\n * Optional `theme` overlays Settings colors on fill. Omit it to keep\n * the code house colors.\n *\n * Matches when the normalized name equals the key, starts with the key as a\n * word (`parking lane 2`), or is a simple plural (`parking lanes`).\n */\nexport function resolveLayerStyle(\n layerName: string | null | undefined,\n theme?: Partial<Record<string, string>> | null,\n): StaticLayerStyle | null {\n const key = resolveStaticLayerKey(layerName);\n if (!key) return null;\n return applyLayerTheme(STATIC_LAYER_STYLES[key], key, theme);\n}\n\n/**\n * sourceSvgId values the live outdoor SVG should skip because `cm_shapes`\n * already owns them. Static house layers stay in the SVG so walking-path\n * (and parking / green) keep their colors even when an older import\n * also persisted a walkable row.\n */\nexport function svgIdsOwnedByShapes(\n shapes: Iterable<{ sourceSvgId?: string | null }>,\n options?: { omitStaticLayers?: boolean },\n): Set<string> {\n const omitStatic = options?.omitStaticLayers === true;\n const ids = new Set<string>();\n for (const shape of shapes) {\n const id = shape.sourceSvgId;\n if (!id) continue;\n if (omitStatic && resolveLayerStyle(id)) continue;\n ids.add(id);\n }\n return ids;\n}\n\n/**\n * Outdoor SVG ids the default map must skip. Interactive / imported ids from\n * every level are hidden so a combined base SVG cannot keep drawing another\n * floor. House decoration layers (parking, walking-path, green) stay visible.\n */\nexport function outdoorSvgSuppressIds(\n levels: Array<{\n shapes: Iterable<{ sourceSvgId?: string | null }>;\n }>,\n): Set<string> {\n return svgIdsOwnedByShapes(\n levels.flatMap((level) => [...level.shapes]),\n { omitStaticLayers: true },\n );\n}\n","/**\n * @eyeon/map/core — shared document model types.\n * Pure TypeScript; no React / Three.js.\n */\n\nimport { staticLayerThemeDefaults, WALKING_PATH_COLOR } from './layerStyles';\n\nexport type MapVersion = 1 | 2;\n\n/**\n * Surface the map is embedded in.\n *\n * - `PORTAL` — admin Center Map editor (`MapEditor`). Left rail is Map options\n * (Floors, Kiosks, Settings) plus Edit Map — never viewer chrome. Default\n * center is MapViewer (click-to-assign, no editor grid). Edit Map swaps\n * in the geometry canvas and grid.\n * - `PORTAL_ASSIGN` — admin editor default center (`MapViewer` for click-to-\n * assign). Floors + zoom only — no search / amenities.\n * - `WEBSITE` — public website / v1 WP_SITE (`MapViewer`). Floors + zoom only.\n * - `DISPLAY_APP` — kiosk (`MapViewer`).\n */\nexport type MapHost =\n | 'PORTAL'\n | 'PORTAL_ASSIGN'\n | 'WEBSITE'\n | 'DISPLAY_APP';\n\n/** Staff editor host. `PORTAL` always shows Map options inside the library. */\nexport type MapEditorHost = Extract<MapHost, 'PORTAL' | 'WEBSITE'>;\n\n/** Public / assign viewer. Never includes Map options. */\nexport type MapViewerHost = Extract<\n MapHost,\n 'WEBSITE' | 'DISPLAY_APP' | 'PORTAL_ASSIGN'\n>;\n\nexport type LevelKind = 'outdoor' | 'floor';\n\nexport type ShapeKind =\n | 'unit'\n | 'amenity'\n | 'kiosk_screen'\n | 'connector'\n | 'entrance'\n | 'walkable'\n | 'void'\n | 'wall'\n | 'boundary'\n | 'floorplate'\n | 'decor'\n | 'label'\n | 'zone'\n | 'parking_zone'\n | 'green_area'\n | 'water'\n | 'parking_icon';\n\nexport type AnchorKind = 'unit' | 'junction' | 'connector' | 'entrance';\n\nexport type EdgeKind = 'walk' | 'unit_link' | 'connector' | 'entrance_link';\n\nexport type ConnectorKind =\n | 'escalator'\n | 'elevator'\n | 'stairs'\n | 'ramp'\n | 'travelator';\n\nexport type ConnectorDirection = 'up' | 'down' | 'both';\n\nexport type UnitStatus =\n | 'occupied'\n | 'vacant'\n | 'coming_soon'\n | 'under_renovation';\n\nexport type AssignmentTargetType =\n | 'retailer'\n | 'amenity'\n | 'kiosk'\n | 'none';\n\n/** How a linked retailer / amenity / kiosk is drawn on the polygon (v1 layer_type). */\nexport type AssignmentLayerType =\n | 'retail_name'\n | 'retail_logo'\n | 'retail_text'\n | 'kiosk'\n | 'amenity'\n | 'connector'\n | 'custom_text'\n | 'custom_image';\n\n/** Center retailer for the PORTAL assign dropdown. */\nexport interface MapAssignRetailer {\n id: number;\n name: string;\n location?: string | null;\n logoUrl?: string | null;\n}\n\n/** Display-app kiosk row. Assign uses a Name; the numeric ID is owned by display_kiosks. */\nexport interface MapAssignKiosk {\n id: number;\n name: string;\n}\n\nexport type ShapeOrigin = 'import' | 'manual';\n\nexport type DeviceType = 'display_app' | 'desktop' | 'tablet' | 'mobile';\n\nexport type MapRenderMode = '2D' | '3D';\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Vec3 {\n x: number;\n y: number;\n z: number;\n}\n\nexport interface BBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface ViewBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Absolute SVG path subpath preserving Illustrator beziers. */\nexport interface PathSubpath {\n d: string;\n closed: boolean;\n}\n\nexport interface ShapeGeometry {\n /** Absolute path data (Illustrator-compatible). */\n paths: PathSubpath[];\n /** Cached polygon approximation for hit-testing / routing. */\n polygons: Vec2[][];\n}\n\nexport interface ShapeStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n extrudeHeight?: number;\n transparent?: boolean;\n}\n\nexport type LabelAlign = 'left' | 'center' | 'right';\n\nexport interface ShapeLabel {\n text?: string;\n imageKey?: string;\n size?: number;\n rotate?: number;\n offsetX?: number;\n offsetY?: number;\n color?: string;\n align?: LabelAlign;\n autoFit?: boolean;\n}\n\nexport interface LevelTransform {\n translateX: number;\n translateY: number;\n scale: number;\n rotate: number;\n}\n\nexport interface ThemeDefaults {\n MAP_STYLE: MapRenderMode;\n MAP_BACKGROUND_COLOR: string;\n ACCENT_COLOR: string;\n STORE_DEFAULT_COLOR: string;\n STORE_TEXT_COLOR: string;\n STORE_HEIGHT: number;\n /** Viewer-only corner radius for store (`unit`) polygons. Edit Map stays sharp. */\n STORE_RADIUS: number;\n WALL_COLOR: string;\n WALL_THICKNESS: number;\n BOUNDARY_COLOR: string;\n BOUNDARY_THICKNESS: number;\n BASE_COLOR: string;\n OVERLAY_COLOR: string;\n OVERLAY_OPACITY: number;\n PARKING_ZONE_COLOR: string;\n GREEN_AREA_COLOR: string;\n WATER_COLOR: string;\n WALKABLE_COLOR: string;\n PARKING_LANE_COLOR: string;\n PARKING_ICON_COLOR: string;\n KIOSK_SIZE: number;\n ZOOM_STEP: number;\n CAMERA_MAX_DISTANCE: number;\n CAMERA_MIN_DISTANCE: number;\n}\n\nexport const DEFAULT_THEME: ThemeDefaults = {\n MAP_STYLE: '2D',\n MAP_BACKGROUND_COLOR: '#FFFFFF',\n ACCENT_COLOR: '#2563eb',\n STORE_DEFAULT_COLOR: '#b6babe',\n STORE_TEXT_COLOR: '#1e293b',\n STORE_HEIGHT: 4,\n STORE_RADIUS: 0,\n WALL_COLOR: '#64748b',\n WALL_THICKNESS: 0.4,\n BOUNDARY_COLOR: '#334155',\n BOUNDARY_THICKNESS: 0.6,\n BASE_COLOR: '#ffffff',\n OVERLAY_COLOR: '#000000',\n OVERLAY_OPACITY: 0.15,\n PARKING_ZONE_COLOR: '#cbd5e1',\n ...staticLayerThemeDefaults(),\n KIOSK_SIZE: 12,\n ZOOM_STEP: 0.5,\n CAMERA_MAX_DISTANCE: 2000,\n CAMERA_MIN_DISTANCE: 50,\n};\n\n/** Early v2 default; same as canvas, so parking-lane #F6F6F6 disappeared. */\nconst LEGACY_V2_MAP_BACKGROUND = '#f5f5f5';\n\n/** Pre-house-color walkway fills — colder gray, then the beige guess. */\nconst LEGACY_WALKABLE_COLORS = new Set(['#f8fafc', '#f1efea']);\n\n/** Unused theme defaults from before outdoor colors were editable. */\nconst LEGACY_GREEN_AREA_COLOR = '#86efac';\nconst LEGACY_WATER_COLOR = '#7dd3fc';\n\n/** Unused slate store fill from before the house store color. */\nconst LEGACY_STORE_DEFAULT_COLOR = '#e2e8f0';\n\nconst MAX_STORE_RADIUS = 500;\n\n/** Non-negative store corner radius in SVG units. Invalid values become 0. */\nexport function clampStoreRadius(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(n) || n <= 0) return 0;\n return Math.min(n, MAX_STORE_RADIUS);\n}\n\nexport function mergeTheme(\n ...partials: Array<Partial<ThemeDefaults> | null | undefined>\n): ThemeDefaults {\n const theme = Object.assign({}, DEFAULT_THEME, ...partials.filter(Boolean));\n if (theme.MAP_BACKGROUND_COLOR.toLowerCase() === LEGACY_V2_MAP_BACKGROUND) {\n theme.MAP_BACKGROUND_COLOR = DEFAULT_THEME.MAP_BACKGROUND_COLOR;\n }\n if (LEGACY_WALKABLE_COLORS.has(theme.WALKABLE_COLOR.toLowerCase())) {\n theme.WALKABLE_COLOR = WALKING_PATH_COLOR;\n }\n if (theme.GREEN_AREA_COLOR.toLowerCase() === LEGACY_GREEN_AREA_COLOR) {\n theme.GREEN_AREA_COLOR = DEFAULT_THEME.GREEN_AREA_COLOR;\n }\n if (theme.WATER_COLOR.toLowerCase() === LEGACY_WATER_COLOR) {\n theme.WATER_COLOR = DEFAULT_THEME.WATER_COLOR;\n }\n if (theme.STORE_DEFAULT_COLOR.toLowerCase() === LEGACY_STORE_DEFAULT_COLOR) {\n theme.STORE_DEFAULT_COLOR = DEFAULT_THEME.STORE_DEFAULT_COLOR;\n }\n theme.STORE_RADIUS = clampStoreRadius(theme.STORE_RADIUS);\n return theme;\n}\n\nexport interface CmMap {\n id: number;\n centerId: number;\n baseSvgKey: string | null;\n baseViewbox: ViewBox | null;\n unitsPerMeter: number;\n theme: Partial<ThemeDefaults>;\n /** Current production document row in cm_revisions (overwritten in place). */\n publishedRevisionId: number | null;\n draftUpdatedAt: string | null;\n createdAt: string;\n}\n\nexport interface CmBuilding {\n id: number;\n mapId: number;\n name: string;\n ordering: number;\n}\n\nexport interface CmLevel {\n id: number;\n mapId: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgKey: string | null;\n /** Resolved CDN URL for editor preview (not persisted). */\n sourceSvgUrl?: string | null;\n sourceViewbox: ViewBox | null;\n transform: LevelTransform;\n isActive: boolean;\n}\n\nexport interface CmShape {\n id: number;\n levelId: number;\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n zIndex: number;\n style: ShapeStyle;\n label: ShapeLabel;\n sourceSvgId: string | null;\n origin: ShapeOrigin;\n /** When true, outdoor re-import never overwrites geometry/bbox. */\n geometryLocked?: boolean;\n /** Set when sourceSvgId disappeared from a re-upload; filtered from public docs. */\n orphanedAt?: string | null;\n}\n\nexport interface CmShapeAssignment {\n shapeId: number;\n targetType: AssignmentTargetType;\n retailerId: number | null;\n amenityId: number | null;\n kioskId: number | null;\n unitStatus: UnitStatus;\n unitNumber: string | null;\n customLabel: string | null;\n customImageKey: string | null;\n /** v1 `layer_type` — name, logo, custom text, amenity icon, etc. */\n layerType: AssignmentLayerType;\n size: number;\n rotate: number;\n offsetX: number;\n offsetY: number;\n bgColor: string | null;\n textColor: string | null;\n /** Baked onto `ShapeLabel.align` for custom text; not a DB column. */\n align?: LabelAlign;\n}\n\nexport interface CmAnchor {\n id: number;\n levelId: number;\n shapeId: number | null;\n kind: AnchorKind;\n x: number;\n y: number;\n connectorId: number | null;\n}\n\nexport interface CmRouteEdge {\n id: number;\n mapId: number;\n fromAnchorId: number;\n toAnchorId: number;\n weight: number | null;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface CmConnector {\n id: number;\n mapId: number;\n kind: ConnectorKind;\n name: string;\n direction: ConnectorDirection;\n accessible: boolean;\n}\n\nexport interface CmAmenityCatalogItem {\n id: number;\n centerId: number | null;\n code: string;\n name: string;\n iconKey: string | null;\n builtinIcon: string | null;\n ordering: number;\n isActive: boolean;\n}\n\nexport interface CmResponsiveOverride {\n id: number;\n mapId: number;\n levelId: number | null;\n device: DeviceType;\n camera: Vec3;\n controls: Vec3;\n}\n\nexport interface PublishedGraphNode {\n id: number;\n levelId: number;\n x: number;\n y: number;\n kind: AnchorKind;\n shapeId: number | null;\n connectorId: number | null;\n}\n\nexport interface PublishedGraphEdge {\n id: number;\n from: number;\n to: number;\n weight: number;\n directed: boolean;\n accessible: boolean;\n kind: EdgeKind;\n}\n\nexport interface PublishedLevel {\n id: number;\n buildingId: number | null;\n kind: LevelKind;\n name: string;\n levelIndex: number;\n ordering: number;\n sourceSvgUrl: string | null;\n viewbox: ViewBox | null;\n transform: LevelTransform;\n shapes: Array<CmShape & { assignment?: CmShapeAssignment | null }>;\n anchors: CmAnchor[];\n}\n\nexport interface PublishedDocument {\n version: 2;\n revisionId: number;\n revisionNumber: number;\n centerId: number;\n mapId: number;\n theme: ThemeDefaults;\n baseSvgUrl: string | null;\n baseViewbox: ViewBox | null;\n buildings: CmBuilding[];\n levels: PublishedLevel[];\n connectors: CmConnector[];\n amenities: CmAmenityCatalogItem[];\n graph: {\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n };\n responsiveOverrides: CmResponsiveOverride[];\n publishedAt: string;\n}\n\nexport interface ImportClassification {\n sourceSvgId: string;\n kind: ShapeKind | null;\n guessed: boolean;\n message?: string;\n}\n\nexport interface ImportReport {\n classified: ImportClassification[];\n unrecognized: string[];\n guessed: ImportClassification[];\n walkableCount: number;\n voidCount: number;\n unitCount: number;\n warnings: string[];\n}\n\nexport type DiffChangeType = 'added' | 'removed' | 'moved' | 'unchanged' | 'kind_changed';\n\nexport interface ImportDiffItem {\n sourceSvgId: string;\n change: DiffChangeType;\n existingShapeId?: number;\n newKind?: ShapeKind | null;\n existingKind?: ShapeKind | null;\n preserve?: {\n key?: string;\n assignment?: boolean;\n anchors?: boolean;\n };\n /** True when portal Edit Map owns this shape's geometry. */\n geometryLocked?: boolean;\n}\n\nexport interface ImportDiff {\n items: ImportDiffItem[];\n shapes: Array<{\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n sourceSvgId: string;\n style: ShapeStyle;\n }>;\n viewbox: ViewBox | null;\n}\n\nexport interface WeldResult {\n survivingAnchorId: number;\n removedAnchorIds: number[];\n rewiredEdgeIds: number[];\n}\n\nexport interface AutoConnectResult {\n unitAnchorId: number;\n junctionAnchor: { x: number; y: number; existingId?: number };\n edge: { fromAnchorId: number; toAnchorId?: number };\n}\n\nexport interface SkeletonSuggestion {\n anchors: Array<{ tempId: string; x: number; y: number; kind: AnchorKind }>;\n edges: Array<{ fromTempId: string; toTempId: string }>;\n}\n\nexport interface PathResult {\n anchorIds: number[];\n points: Array<Vec2 & { levelId: number }>;\n totalWeight: number;\n levelChanges: Array<{ fromLevelId: number; toLevelId: number; connectorId: number | null }>;\n}\n\nexport type BatchOp =\n | { op: 'upsert_shape'; shape: Partial<CmShape> & { levelId: number; key: string } }\n | { op: 'delete_shape'; shapeId: number }\n | { op: 'upsert_assignment'; assignment: CmShapeAssignment }\n | { op: 'delete_assignment'; shapeId: number }\n | { op: 'upsert_anchor'; anchor: Partial<CmAnchor> & { levelId: number; x: number; y: number; kind: AnchorKind } }\n | { op: 'delete_anchor'; anchorId: number }\n | { op: 'upsert_edge'; edge: Partial<CmRouteEdge> & { mapId: number; fromAnchorId: number; toAnchorId: number } }\n | { op: 'delete_edge'; edgeId: number }\n | { op: 'weld_anchors'; anchorIds: number[]; tolerance?: number }\n | { op: 'upsert_level'; level: Partial<CmLevel> & { mapId: number; name: string; kind: LevelKind } }\n | { op: 'delete_level'; levelId: number }\n | { op: 'upsert_building'; building: Partial<CmBuilding> & { mapId: number; name: string } }\n | { op: 'delete_building'; buildingId: number }\n | { op: 'update_theme'; theme: Partial<ThemeDefaults> }\n | { op: 'upsert_connector'; connector: Partial<CmConnector> & { mapId: number; kind: ConnectorKind; name: string } }\n | { op: 'delete_connector'; connectorId: number };\n\nexport const INTERACTIVE_SHAPE_KINDS: ShapeKind[] = [\n 'unit',\n 'amenity',\n 'kiosk_screen',\n 'connector',\n 'entrance',\n 'parking_zone',\n];\n\nexport const FLOOR_CHANGE_PENALTY = 10000;\n\nexport const DEFAULT_WELD_TOLERANCE = 2.5;\n","/** Built-in map marker — not a custom image URL. */\nexport const ENTRANCE_ICON_ID = 'entrance';\nexport const DEFAULT_ENTRANCE_SIZE = 36;\nexport const MIN_ENTRANCE_SIZE = 8;\n\nexport function isEntranceIcon(shape: {\n kind: string;\n label?: { imageKey?: string | null } | null;\n}): boolean {\n return shape.kind === 'entrance' && shape.label?.imageKey === ENTRANCE_ICON_ID;\n}\n\nexport function clampEntranceSize(size: number): number {\n return Math.max(MIN_ENTRANCE_SIZE, size);\n}\n","import type { BBox, LabelAlign } from './types';\n\nexport const LABEL_ALIGNS = ['left', 'center', 'right'] as const;\nexport const DEFAULT_LABEL_ALIGN: LabelAlign = 'center';\n\nexport function normalizeLabelAlign(value: unknown): LabelAlign {\n return value === 'left' || value === 'right' ? value : DEFAULT_LABEL_ALIGN;\n}\n\nexport function labelAlignX(box: BBox, align: LabelAlign): number {\n if (align === 'left') return box.minX;\n if (align === 'right') return box.maxX;\n return (box.minX + box.maxX) / 2;\n}\n\nexport function labelSvgTextAnchor(\n align: LabelAlign,\n): 'start' | 'middle' | 'end' {\n if (align === 'left') return 'start';\n if (align === 'right') return 'end';\n return 'middle';\n}\n","import type {\n AssignmentLayerType,\n AssignmentTargetType,\n CmShape,\n CmShapeAssignment,\n LabelAlign,\n MapAssignRetailer,\n ShapeKind,\n ShapeLabel,\n ShapeStyle,\n UnitStatus,\n} from './types';\nimport { isTransparentColor } from './color';\n\nexport const DEFAULT_ASSIGNMENT_SIZE = 12;\n/** Escalator / elevator icons use the same Size default as store names. */\nexport const CONNECTOR_ICON_SIZE = DEFAULT_ASSIGNMENT_SIZE;\n/** Retail logos read the same Size as retail names, then draw this many times larger. */\nexport const RETAIL_LOGO_RENDER_SCALE = 4;\n\nexport const ASSIGNMENT_LAYER_TYPES: AssignmentLayerType[] = [\n 'retail_name',\n 'retail_logo',\n 'retail_text',\n 'kiosk',\n 'amenity',\n 'connector',\n 'custom_text',\n 'custom_image',\n];\n\nconst LAYER_TYPES = new Set<string>(ASSIGNMENT_LAYER_TYPES);\n\nfunction asNumber(value: unknown, fallback: number): number {\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nconst INCOMPLETE_NUMBER = /^(?:|[+\\-]|[+\\-]?\\.(?:0*)?)$/;\n\n/**\n * Size / rotate / offset while typing. Empty or a lone minus is 0 for the\n * map; blur commits that 0 into the field.\n */\nexport function assignNumberFromDraft(raw: string): {\n render: number;\n complete: boolean;\n} {\n const text = raw.trim();\n if (INCOMPLETE_NUMBER.test(text)) {\n return { render: 0, complete: false };\n }\n const n = Number(text);\n if (!Number.isFinite(n)) return { render: 0, complete: false };\n return { render: n, complete: true };\n}\n\nexport function commitAssignNumberDraft(raw: string): {\n display: string;\n render: number;\n} {\n const parsed = assignNumberFromDraft(raw);\n if (!parsed.complete) return { display: '0', render: 0 };\n return { display: String(parsed.render), render: parsed.render };\n}\n\nfunction asNullableString(value: unknown): string | null {\n if (value == null) return null;\n const text = String(value).trim();\n return text ? text : null;\n}\n\n/** Keep spaces while typing (kiosk name, custom text). Empty string is unset. */\nfunction asNullableText(value: unknown): string | null {\n if (value == null) return null;\n const text = String(value);\n return text === '' ? null : text;\n}\n\nfunction asNullableId(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function isAssignmentLayerType(value: unknown): value is AssignmentLayerType {\n return typeof value === 'string' && LAYER_TYPES.has(value);\n}\n\nexport function defaultLayerTypeForKind(kind: ShapeKind): AssignmentLayerType {\n if (kind === 'amenity') return 'amenity';\n if (kind === 'kiosk_screen') return 'kiosk';\n if (kind === 'connector') return 'connector';\n return 'retail_name';\n}\n\nexport function defaultTargetTypeForKind(kind: ShapeKind): AssignmentTargetType {\n if (kind === 'amenity') return 'amenity';\n if (kind === 'kiosk_screen') return 'kiosk';\n if (kind === 'unit' || kind === 'parking_zone') return 'retailer';\n return 'none';\n}\n\nexport function emptyShapeAssignment(\n shapeId: number,\n kind: ShapeKind,\n): CmShapeAssignment {\n return {\n shapeId,\n targetType: 'none',\n retailerId: null,\n amenityId: null,\n kioskId: null,\n unitStatus: 'vacant',\n unitNumber: null,\n customLabel: null,\n customImageKey: null,\n layerType: defaultLayerTypeForKind(kind),\n size: DEFAULT_ASSIGNMENT_SIZE,\n rotate: 0,\n offsetX: 0,\n offsetY: 0,\n bgColor: null,\n textColor: null,\n };\n}\n\n/** Normalize a draft / API assignment row (camelCase or snake_case). */\nexport function parseShapeAssignment(\n raw: Record<string, unknown> | CmShapeAssignment,\n kind: ShapeKind = 'unit',\n): CmShapeAssignment {\n const layerRaw = raw.layerType ?? (raw as { layer_type?: unknown }).layer_type;\n const unitStatus = (raw.unitStatus ??\n (raw as { unit_status?: unknown }).unit_status ??\n 'vacant') as UnitStatus;\n return {\n shapeId: asNumber(\n raw.shapeId ?? (raw as { shape_id?: unknown }).shape_id,\n 0,\n ),\n targetType: (raw.targetType ??\n (raw as { target_type?: unknown }).target_type ??\n 'none') as AssignmentTargetType,\n retailerId: asNullableId(\n raw.retailerId ?? (raw as { retailer_id?: unknown }).retailer_id,\n ),\n amenityId: asNullableId(\n raw.amenityId ?? (raw as { amenity_id?: unknown }).amenity_id,\n ),\n kioskId: asNullableId(\n raw.kioskId ?? (raw as { kiosk_id?: unknown }).kiosk_id,\n ),\n unitStatus: unitStatus || 'vacant',\n unitNumber: asNullableString(\n raw.unitNumber ?? (raw as { unit_number?: unknown }).unit_number,\n ),\n customLabel: asNullableText(\n raw.customLabel ?? (raw as { custom_label?: unknown }).custom_label,\n ),\n customImageKey: asNullableString(\n raw.customImageKey ??\n (raw as { custom_image_key?: unknown }).custom_image_key,\n ),\n layerType: isAssignmentLayerType(layerRaw)\n ? layerRaw\n : defaultLayerTypeForKind(kind),\n size: asNumber(raw.size, DEFAULT_ASSIGNMENT_SIZE),\n rotate: asNumber(raw.rotate, 0),\n offsetX: asNumber(\n raw.offsetX ?? (raw as { offset_x?: unknown }).offset_x,\n 0,\n ),\n offsetY: asNumber(\n raw.offsetY ?? (raw as { offset_y?: unknown }).offset_y,\n 0,\n ),\n bgColor: asNullableString(\n raw.bgColor ?? (raw as { bg_color?: unknown }).bg_color,\n ),\n textColor: asNullableString(\n raw.textColor ?? (raw as { text_color?: unknown }).text_color,\n ),\n align: parseAssignmentAlign(raw.align),\n };\n}\n\nfunction parseAssignmentAlign(value: unknown): LabelAlign | undefined {\n if (value === 'left' || value === 'right' || value === 'center') return value;\n return undefined;\n}\n\nexport function retailerOptionLabel(\n retailer: MapAssignRetailer,\n duplicateName: boolean,\n): string {\n const location = (retailer.location ?? '').trim();\n if (duplicateName && location && location !== '-') {\n return `${retailer.name} (${location})`;\n }\n return retailer.name;\n}\n\n/** Per-store override, or the Settings store color when none is set. */\nexport function resolvedAssignmentBgColor(\n assignment: Pick<CmShapeAssignment, 'bgColor'> | null | undefined,\n storeColor: string,\n): string {\n const hex = assignment?.bgColor?.trim();\n if (isTransparentColor(hex)) return 'transparent';\n return hex || storeColor;\n}\n\n/** Per-store text override, or the theme store text color when none is set. */\nexport function resolvedAssignmentTextColor(\n assignment: Pick<CmShapeAssignment, 'textColor'> | null | undefined,\n textColor: string,\n): string {\n const hex = assignment?.textColor?.trim();\n if (isTransparentColor(hex)) return 'transparent';\n return hex || textColor;\n}\n\n/** Kiosk app ID typed in Map options — not chosen from a device list. */\nexport function parseKioskIdInput(raw: string): number | null {\n const text = raw.trim();\n if (!text || !/^\\d+$/.test(text)) return null;\n const id = Number(text);\n return Number.isSafeInteger(id) && id > 0 ? id : null;\n}\n\ntype AssignmentTargetFields = Pick<\n CmShapeAssignment,\n 'targetType' | 'retailerId' | 'amenityId' | 'kioskId'\n> & {\n customLabel?: string | null;\n};\n\n/** Staff-facing amenity name: catalog title, then the v1 type code. */\nexport function amenityAssignedName(\n assignment:\n | Pick<CmShapeAssignment, 'customLabel' | 'amenityId'>\n | null\n | undefined,\n catalogName?: string | null,\n): string | null {\n const catalog = catalogName?.trim();\n if (catalog) return catalog;\n const labeled = assignment?.customLabel?.trim();\n if (labeled) return labeled;\n if (assignment?.amenityId != null) return `Amenity ${assignment.amenityId}`;\n return null;\n}\n\n/** Staff-facing kiosk name: typed label, then catalog title, then a fallback. */\nexport function kioskAssignedName(\n assignment:\n | Pick<CmShapeAssignment, 'customLabel' | 'kioskId'>\n | null\n | undefined,\n catalogName?: string | null,\n): string | null {\n const named = assignment?.customLabel?.trim();\n if (named) return named;\n const catalog = catalogName?.trim();\n if (catalog) return catalog;\n if (assignment?.kioskId != null) return `Kiosk ${assignment.kioskId}`;\n return null;\n}\n\nexport function assignmentHasTarget(\n assignment: AssignmentTargetFields | null | undefined,\n): boolean {\n if (!assignment) return false;\n if (assignment.targetType === 'retailer') return assignment.retailerId != null;\n if (assignment.targetType === 'amenity') {\n return (\n assignment.amenityId != null || Boolean(assignment.customLabel?.trim())\n );\n }\n if (assignment.targetType === 'kiosk') {\n return (\n assignment.kioskId != null || Boolean(assignment.customLabel?.trim())\n );\n }\n return false;\n}\n\nconst ASSIGNMENT_OVERLAY_KINDS = new Set([\n 'unit',\n 'parking_zone',\n 'amenity',\n 'kiosk_screen',\n]);\n\n/** Drop leftover retailer/custom text when the polygon is not assigned. */\nexport function publishedShapeLabel(\n shape: Pick<CmShape, 'kind' | 'label' | 'style'>,\n assignment: CmShapeAssignment | null | undefined,\n retailer?: MapAssignRetailer | null,\n): ShapeLabel {\n if (shape.kind === 'label') return shape.label;\n if (shape.kind === 'entrance') return shape.label;\n if (shape.kind === 'connector' || assignment?.layerType === 'connector') {\n return assignment\n ? assignmentVisualPatch(\n { style: shape.style ?? {}, label: shape.label },\n assignment,\n retailer,\n ).label\n : shape.label;\n }\n if (!ASSIGNMENT_OVERLAY_KINDS.has(shape.kind)) {\n return shape.label;\n }\n if (!assignmentHasTarget(assignment)) {\n if (!shape.label?.text && !shape.label?.imageKey) return shape.label;\n return {\n ...shape.label,\n text: undefined,\n imageKey: undefined,\n };\n }\n return assignmentVisualPatch(\n { style: shape.style ?? {}, label: shape.label },\n assignment,\n retailer,\n ).label;\n}\n\nexport function assignmentDisplayText(\n assignment: CmShapeAssignment,\n retailer?: MapAssignRetailer | null,\n): string | undefined {\n if (!assignmentHasTarget(assignment)) return undefined;\n if (\n assignment.layerType === 'retail_text' ||\n assignment.layerType === 'custom_text'\n ) {\n return assignment.customLabel ?? undefined;\n }\n if (assignment.layerType === 'retail_name') {\n return retailer?.name ?? assignment.customLabel ?? undefined;\n }\n return undefined;\n}\n\n/**\n * Logo URL for retail_logo / custom_image — same lookup as v1 (retailer logo,\n * then the stored custom image, then a baked label.imageKey).\n * Amenity / kiosk icons are resolved at render time from the v1 SVG catalog.\n */\nexport function assignmentOverlayImageUrl(\n assignment?: CmShapeAssignment | null,\n retailer?: MapAssignRetailer | null,\n label?: ShapeLabel | null,\n): string | undefined {\n if (!assignmentHasTarget(assignment) || !assignment) return undefined;\n if (\n assignment.layerType !== 'retail_logo' &&\n assignment.layerType !== 'custom_image'\n ) {\n return undefined;\n }\n return (\n overlayImageKey(assignment, retailer) ??\n asNullableString(label?.imageKey) ??\n undefined\n );\n}\n\n/** Kiosk pin or amenity type code from the v1 `AllAmenities` list. */\nexport function assignmentSpecialIconId(\n assignment?: CmShapeAssignment | null,\n amenities?: Array<{ id: number; code: string }> | null,\n): 'kiosk' | string | undefined {\n if (!assignmentHasTarget(assignment) || !assignment) return undefined;\n if (assignment.layerType === 'kiosk') return 'kiosk';\n if (assignment.layerType === 'amenity') {\n return (\n amenities?.find((item) => item.id === assignment.amenityId)?.code ??\n assignment.customLabel?.trim() ??\n undefined\n );\n }\n return undefined;\n}\n\n/** Stored Size is shared; retail logos render larger than names. */\nexport function assignmentOverlayRenderSize(\n size: number,\n assignment?: Pick<CmShapeAssignment, 'layerType'> | null,\n): number {\n const n = Number.isFinite(size) && size > 0 ? size : DEFAULT_ASSIGNMENT_SIZE;\n if (assignment?.layerType === 'retail_logo') return n * RETAIL_LOGO_RENDER_SCALE;\n return n;\n}\n\n/** Size / rotate / offset / icon color for a linked escalator or elevator. */\nexport function connectorIconLayout(\n shape: {\n assignment?: Pick<\n CmShapeAssignment,\n 'size' | 'rotate' | 'offsetX' | 'offsetY' | 'textColor'\n > | null;\n label?: {\n size?: number;\n rotate?: number;\n offsetX?: number;\n offsetY?: number;\n color?: string;\n };\n },\n): {\n size: number;\n rotate: number;\n offsetX: number;\n offsetY: number;\n iconColor: string | null;\n} {\n const assignment = shape.assignment;\n const label = shape.label;\n return {\n size: assignmentOverlayRenderSize(\n assignment?.size ?? label?.size ?? CONNECTOR_ICON_SIZE,\n assignment,\n ),\n rotate: assignment?.rotate ?? label?.rotate ?? 0,\n offsetX: assignment?.offsetX ?? label?.offsetX ?? 0,\n offsetY: assignment?.offsetY ?? label?.offsetY ?? 0,\n iconColor: assignment?.textColor ?? label?.color ?? null,\n };\n}\n\n/** Assigned polygons can overlay name/custom text, a logo, or a v1 amenity/kiosk icon. */\nexport function assignmentOverlayVisible(\n assignment: CmShapeAssignment | null | undefined,\n label?: ShapeLabel | null,\n): boolean {\n if (!assignmentHasTarget(assignment)) return false;\n if (\n assignment?.layerType === 'kiosk' ||\n assignment?.layerType === 'amenity'\n ) {\n return true;\n }\n if (assignmentOverlayImageUrl(assignment, null, label)) return true;\n return Boolean(label?.text?.trim());\n}\n\nfunction overlayImageKey(\n assignment: CmShapeAssignment,\n retailer?: MapAssignRetailer | null,\n): string | undefined {\n if (!assignmentHasTarget(assignment)) return undefined;\n if (assignment.layerType === 'retail_logo') {\n return (\n asNullableString(retailer?.logoUrl) ??\n asNullableString(assignment.customImageKey) ??\n undefined\n );\n }\n if (assignment.layerType === 'custom_image') {\n return asNullableString(assignment.customImageKey) ?? undefined;\n }\n return undefined;\n}\n\n/** Fill / label overlay written onto the shape when staff assign on PORTAL. */\nexport type BulkAssignPatch = {\n size?: number;\n bgColor?: string | null;\n textColor?: string | null;\n};\n\nexport type BulkAssignFormState = {\n size: number | '';\n bgColor: string;\n textColor: string;\n bgColorMixed: boolean;\n textColorMixed: boolean;\n};\n\nfunction sameValue<T>(values: T[]): T | '' {\n if (values.length === 0) return '';\n const first = values[0];\n return values.every((item) => item === first) ? first : '';\n}\n\nfunction mixedColors(values: string[]): boolean {\n if (values.length === 0) return false;\n const first = values[0];\n return values.some((item) => item !== first);\n}\n\n/** Shared Size / colors for a multi-selection. Mixed values become blank. */\nexport function bulkAssignFormState(\n assignments: CmShapeAssignment[],\n): BulkAssignFormState {\n const bgColors = assignments.map((row) => row.bgColor ?? '');\n const textColors = assignments.map((row) => row.textColor ?? '');\n return {\n size: sameValue(assignments.map((row) => row.size)),\n bgColor: sameValue(bgColors),\n textColor: sameValue(textColors),\n bgColorMixed: mixedColors(bgColors),\n textColorMixed: mixedColors(textColors),\n };\n}\n\nexport function applyBulkAssignPatch(\n assignment: CmShapeAssignment,\n patch: BulkAssignPatch,\n): CmShapeAssignment {\n return {\n ...assignment,\n ...(patch.size != null ? { size: patch.size } : {}),\n ...(patch.bgColor !== undefined ? { bgColor: patch.bgColor } : {}),\n ...(patch.textColor !== undefined ? { textColor: patch.textColor } : {}),\n };\n}\n\nexport function assignmentVisualPatch(\n shape: Pick<CmShape, 'style' | 'label'>,\n assignment: CmShapeAssignment,\n retailer?: MapAssignRetailer | null,\n): { style: ShapeStyle; label: ShapeLabel } {\n const imageKey = assignmentOverlayImageUrl(assignment, retailer, shape.label);\n const text = assignmentHasTarget(assignment)\n ? imageKey\n ? undefined\n : assignmentDisplayText(assignment, retailer) ?? shape.label.text\n : undefined;\n return {\n style: {\n ...shape.style,\n fill: assignment.bgColor ?? undefined,\n },\n label: {\n ...shape.label,\n text,\n imageKey,\n size: Number.isFinite(assignment.size) ? assignment.size : 0,\n rotate: Number.isFinite(assignment.rotate) ? assignment.rotate : 0,\n offsetX: Number.isFinite(assignment.offsetX) ? assignment.offsetX : 0,\n offsetY: Number.isFinite(assignment.offsetY) ? assignment.offsetY : 0,\n color: assignment.textColor ?? undefined,\n ...(assignment.align ? { align: assignment.align } : {}),\n },\n };\n}\n","import type { MapHost, MapViewerHost } from './types';\n\n/** Which library surface a host should mount. `PORTAL` is the staff editor. */\nexport function mapSurface(host: MapHost): 'editor' | 'viewer' {\n return host === 'PORTAL' ? 'editor' : 'viewer';\n}\n\n/**\n * Viewer chrome. Public website (`WEBSITE` / v1 WP_SITE) is floors + zoom/\n * reset only — no search or amenity strip. Kiosk origin is DISPLAY_APP only.\n */\nexport interface ViewerChrome {\n search: boolean;\n amenities: boolean;\n floors: boolean;\n zoomReset: boolean;\n kioskOrigin: boolean;\n fetchDraft: boolean;\n}\n\n/** Floors + zoom/reset — public website and assign map. */\nconst FLOORS_ZOOM_CHROME: ViewerChrome = {\n search: false,\n amenities: false,\n floors: true,\n zoomReset: true,\n kioskOrigin: false,\n fetchDraft: false,\n};\n\nconst VIEWER_CHROME: Record<MapViewerHost, ViewerChrome> = {\n /** v1 WP_SITE / MapBox HOST WEBSITE. */\n WEBSITE: FLOORS_ZOOM_CHROME,\n /** Assign mode: click shapes, no public directory chrome. */\n PORTAL_ASSIGN: FLOORS_ZOOM_CHROME,\n DISPLAY_APP: {\n ...FLOORS_ZOOM_CHROME,\n kioskOrigin: true,\n },\n};\n\nexport function viewerChrome(host: MapViewerHost): ViewerChrome {\n return VIEWER_CHROME[host];\n}\n\nexport function isMapViewerHost(host: MapHost): host is MapViewerHost {\n return host !== 'PORTAL';\n}\n","/** Same contract as v1 `getMediaProxyUrl`: proxy base + encoded URL, no query key. */\nexport function resolveFetchUrl(url: string, imageProxyUrl?: string | null): string {\n if (!imageProxyUrl) return url;\n return imageProxyUrl + encodeURIComponent(url);\n}\n","import type { BBox, PathSubpath, ShapeGeometry, Vec2, ViewBox } from '../types';\n\n/**\n * Mirror points about the middle of a viewbox height.\n *\n * Never call this on stored geometry. Stored geometry keeps SVG user space\n * (Y down) so `paths`, `polygons`, anchors and the designer SVG all agree;\n * the viewer flips once at render. This helper exists only for render-side\n * and ad-hoc conversions.\n */\nexport function flipY(points: Vec2[], viewboxHeight: number): Vec2[] {\n return points.map((p) => ({ x: p.x, y: viewboxHeight - p.y }));\n}\n\nexport function distance(a: Vec2, b: Vec2): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.hypot(dx, dy);\n}\n\nexport function bboxOf(points: Vec2[]): BBox {\n if (points.length === 0) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 };\n }\n let minX = points[0].x;\n let minY = points[0].y;\n let maxX = points[0].x;\n let maxY = points[0].y;\n for (let i = 1; i < points.length; i++) {\n const p = points[i];\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport function bboxUnion(a: BBox, b: BBox): BBox {\n return {\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n };\n}\n\nexport function centroid(points: Vec2[]): Vec2 {\n if (points.length === 0) return { x: 0, y: 0 };\n let sx = 0;\n let sy = 0;\n for (const p of points) {\n sx += p.x;\n sy += p.y;\n }\n return { x: sx / points.length, y: sy / points.length };\n}\n\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x;\n const yi = polygon[i].y;\n const xj = polygon[j].x;\n const yj = polygon[j].y;\n const intersect =\n yi > point.y !== yj > point.y &&\n point.x < ((xj - xi) * (point.y - yi)) / (yj - yi + Number.EPSILON) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\nexport function pointInPolygons(point: Vec2, polygons: Vec2[][]): boolean {\n return polygons.some((poly) => pointInPolygon(point, poly));\n}\n\n/** Project point onto segment; returns closest point and t in [0,1]. */\nexport function projectOntoSegment(\n point: Vec2,\n a: Vec2,\n b: Vec2,\n): { point: Vec2; t: number; distance: number } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n return { point: { ...a }, t: 0, distance: distance(point, a) };\n }\n let t = ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n const proj = { x: a.x + t * dx, y: a.y + t * dy };\n return { point: proj, t, distance: distance(point, proj) };\n}\n\nexport function nearestPointOnPolyline(\n point: Vec2,\n polyline: Vec2[],\n): { point: Vec2; segmentIndex: number; distance: number } | null {\n if (polyline.length < 2) return null;\n let best: { point: Vec2; segmentIndex: number; distance: number } | null = null;\n for (let i = 0; i < polyline.length - 1; i++) {\n const proj = projectOntoSegment(point, polyline[i], polyline[i + 1]);\n if (!best || proj.distance < best.distance) {\n best = { point: proj.point, segmentIndex: i, distance: proj.distance };\n }\n }\n return best;\n}\n\n/**\n * Approximate a cubic bezier into line segments.\n */\nexport function approximateCubic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n segments = 8,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x:\n u * u * u * p0.x +\n 3 * u * u * t * p1.x +\n 3 * u * t * t * p2.x +\n t * t * t * p3.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * p1.y +\n 3 * u * t * t * p2.y +\n t * t * t * p3.y,\n });\n }\n return out;\n}\n\nexport function approximateQuadratic(\n p0: Vec2,\n p1: Vec2,\n p2: Vec2,\n segments = 6,\n): Vec2[] {\n const out: Vec2[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = i / segments;\n const u = 1 - t;\n out.push({\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n });\n }\n return out;\n}\n\n/**\n * A quarter turn is about the largest sweep a single cubic approximates well,\n * so an arc gets `approximateCubic`'s 8 segments per 90° of sweep. An arc and a\n * visually equivalent cubic therefore flatten to comparable point counts.\n */\nconst ARC_SEGMENTS_PER_QUADRANT = 8;\n\n/**\n * Flatten an SVG elliptical arc, using the endpoint-to-centre parameterisation\n * of SVG 1.1 appendix F.6.\n *\n * Returns `p0` first, like `approximateCubic`, so callers append `slice(1)`.\n */\nexport function approximateArc(\n p0: Vec2,\n rx: number,\n ry: number,\n xAxisRotationDeg: number,\n largeArc: boolean,\n sweep: boolean,\n p1: Vec2,\n): Vec2[] {\n // F.6.2: coincident endpoints drop the arc; a zero radius becomes a line.\n if (p0.x === p1.x && p0.y === p1.y) return [{ ...p0 }];\n let arx = Math.abs(rx);\n let ary = Math.abs(ry);\n if (arx === 0 || ary === 0 || !Number.isFinite(arx) || !Number.isFinite(ary)) {\n return [{ ...p0 }, { ...p1 }];\n }\n\n const phi = ((xAxisRotationDeg % 360) * Math.PI) / 180;\n const cosPhi = Math.cos(phi);\n const sinPhi = Math.sin(phi);\n\n // F.6.5.1 — half the chord, rotated into the ellipse's own frame.\n const dx2 = (p0.x - p1.x) / 2;\n const dy2 = (p0.y - p1.y) / 2;\n const x1p = cosPhi * dx2 + sinPhi * dy2;\n const y1p = -sinPhi * dx2 + cosPhi * dy2;\n\n // F.6.6.2 — radii too small to span the endpoints are scaled by sqrt(Λ).\n const lambda = (x1p * x1p) / (arx * arx) + (y1p * y1p) / (ary * ary);\n if (lambda > 1) {\n const scale = Math.sqrt(lambda);\n arx *= scale;\n ary *= scale;\n }\n\n // F.6.5.2 — centre in the ellipse frame.\n const rxSq = arx * arx;\n const rySq = ary * ary;\n const numerator = rxSq * rySq - rxSq * y1p * y1p - rySq * x1p * x1p;\n const denominator = rxSq * y1p * y1p + rySq * x1p * x1p;\n const factor =\n Math.sqrt(Math.max(0, numerator / denominator)) * (largeArc === sweep ? -1 : 1);\n const cxp = (factor * arx * y1p) / ary;\n const cyp = (-factor * ary * x1p) / arx;\n\n // F.6.5.3 — centre back in user space.\n const cx = cosPhi * cxp - sinPhi * cyp + (p0.x + p1.x) / 2;\n const cy = sinPhi * cxp + cosPhi * cyp + (p0.y + p1.y) / 2;\n\n // F.6.5.5 / F.6.5.6 — start angle and swept angle.\n const ux = (x1p - cxp) / arx;\n const uy = (y1p - cyp) / ary;\n const vx = (-x1p - cxp) / arx;\n const vy = (-y1p - cyp) / ary;\n const theta1 = Math.atan2(uy, ux);\n let deltaTheta = Math.atan2(ux * vy - uy * vx, ux * vx + uy * vy);\n if (!sweep && deltaTheta > 0) deltaTheta -= 2 * Math.PI;\n else if (sweep && deltaTheta < 0) deltaTheta += 2 * Math.PI;\n\n // Round rather than ceil the quadrant count. A chord that is almost exactly\n // the ellipse diameter is a near-degenerate half turn, so tiny coordinate\n // noise — a rewritten `d` rounded by the transform baker, say — swings the\n // sweep either side of pi. Rounding is stable at whole quadrants, which is\n // precisely where those degeneracies sit; ceil would flip a segment count\n // there and desynchronise `paths[].d` from `polygons`.\n const ideal = (Math.abs(deltaTheta) / (Math.PI / 2)) * ARC_SEGMENTS_PER_QUADRANT;\n const segments = Math.max(1, Math.round(ideal));\n\n const out: Vec2[] = [{ ...p0 }];\n for (let i = 1; i <= segments; i++) {\n const theta = theta1 + (deltaTheta * i) / segments;\n const cosT = Math.cos(theta);\n const sinT = Math.sin(theta);\n out.push({\n x: cx + arx * cosPhi * cosT - ary * sinPhi * sinT,\n y: cy + arx * sinPhi * cosT + ary * cosPhi * sinT,\n });\n }\n // Trig round-off must not leave a gap before the next command.\n out[out.length - 1] = { ...p1 };\n return out;\n}\n\nconst WHITESPACE_RE = /[\\s,]/;\n\n/**\n * Split path data into command letters and numbers.\n *\n * A plain number regex cannot do this: arc flags may be written without any\n * separator, so `a1 1 0 011 1` is legal and means flags `0` then `1` followed\n * by the coordinate `1`. Tracking the argument slot lets the two flag\n * positions of every `A`/`a` group consume exactly one character.\n */\nexport function tokenizePathData(d: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n let cmd = '';\n let argIndex = 0;\n\n while (i < d.length) {\n const ch = d[i];\n if (WHITESPACE_RE.test(ch)) {\n i++;\n continue;\n }\n if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {\n cmd = ch;\n argIndex = 0;\n tokens.push(ch);\n i++;\n continue;\n }\n\n // Slots 3 and 4 of each 7-argument arc group are single-character flags.\n const arcSlot = cmd === 'A' || cmd === 'a' ? argIndex % 7 : -1;\n if ((arcSlot === 3 || arcSlot === 4) && (ch === '0' || ch === '1')) {\n tokens.push(ch);\n i++;\n argIndex++;\n continue;\n }\n\n const start = i;\n let digits = 0;\n if (ch === '+' || ch === '-') i++;\n while (i < d.length && d[i] >= '0' && d[i] <= '9') {\n i++;\n digits++;\n }\n if (d[i] === '.') {\n i++;\n while (i < d.length && d[i] >= '0' && d[i] <= '9') {\n i++;\n digits++;\n }\n }\n if (digits > 0 && (d[i] === 'e' || d[i] === 'E')) {\n const beforeExponent = i;\n i++;\n if (d[i] === '+' || d[i] === '-') i++;\n if (i < d.length && d[i] >= '0' && d[i] <= '9') {\n while (i < d.length && d[i] >= '0' && d[i] <= '9') i++;\n } else {\n i = beforeExponent;\n }\n }\n if (digits === 0) {\n // Not a number at all — step over it rather than looping forever.\n i = start + 1;\n continue;\n }\n tokens.push(d.slice(start, i));\n argIndex++;\n }\n\n return tokens;\n}\n\n/**\n * Parse SVG path `d` into absolute polygon approximations.\n * Supports M/L/H/V/C/Q/S/T/A/Z (absolute and relative).\n *\n * Output stays in the input's coordinate space — deliberately no Y flip, so\n * `paths[].d`, `polygons`, anchors and route geometry never diverge. The\n * viewer applies the single flip at render time.\n */\nexport function pathToPolygons(d: string): Vec2[][] {\n const tokens = tokenizePathData(d);\n const polygons: Vec2[][] = [];\n let current: Vec2[] = [];\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n let lastCtrl: Vec2 | null = null;\n let i = 0;\n let cmd = '';\n\n const readNum = () => Number(tokens[i++]);\n\n while (i < tokens.length) {\n const t = tokens[i];\n if (/[a-zA-Z]/.test(t)) {\n cmd = t;\n i++;\n }\n\n switch (cmd) {\n case 'M':\n case 'm': {\n const isRel = cmd === 'm';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n if (current.length > 0) polygons.push(current);\n current = [{ x, y }];\n startX = x;\n startY = y;\n lastCtrl = null;\n cmd = isRel ? 'l' : 'L';\n break;\n }\n case 'L':\n case 'l': {\n const isRel = cmd === 'l';\n const nx = readNum();\n const ny = readNum();\n x = isRel ? x + nx : nx;\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'H':\n case 'h': {\n const isRel = cmd === 'h';\n const nx = readNum();\n x = isRel ? x + nx : nx;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'V':\n case 'v': {\n const isRel = cmd === 'v';\n const ny = readNum();\n y = isRel ? y + ny : ny;\n current.push({ x, y });\n lastCtrl = null;\n break;\n }\n case 'C':\n case 'c': {\n const isRel = cmd === 'c';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'Q':\n case 'q': {\n const isRel = cmd === 'q';\n const x1 = isRel ? x + readNum() : readNum();\n const y1 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: x1, y: y1 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x1, y: y1 };\n x = nx;\n y = ny;\n break;\n }\n case 'S':\n case 's': {\n const isRel = cmd === 's';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const x2 = isRel ? x + readNum() : readNum();\n const y2 = isRel ? y + readNum() : readNum();\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateCubic(\n { x, y },\n { x: cx, y: cy },\n { x: x2, y: y2 },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: x2, y: y2 };\n x = nx;\n y = ny;\n break;\n }\n case 'T':\n case 't': {\n const isRel = cmd === 't';\n const cx: number = lastCtrl ? 2 * x - lastCtrl.x : x;\n const cy: number = lastCtrl ? 2 * y - lastCtrl.y : y;\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateQuadratic(\n { x, y },\n { x: cx, y: cy },\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = { x: cx, y: cy };\n x = nx;\n y = ny;\n break;\n }\n case 'A':\n case 'a': {\n const isRel = cmd === 'a';\n const rx = readNum();\n const ry = readNum();\n const rot = readNum();\n const largeArc = readNum() !== 0;\n const sweep = readNum() !== 0;\n const nx = isRel ? x + readNum() : readNum();\n const ny = isRel ? y + readNum() : readNum();\n const approx = approximateArc(\n { x, y },\n rx,\n ry,\n rot,\n largeArc,\n sweep,\n { x: nx, y: ny },\n );\n current.push(...approx.slice(1));\n lastCtrl = null;\n x = nx;\n y = ny;\n break;\n }\n case 'Z':\n case 'z': {\n current.push({ x: startX, y: startY });\n polygons.push(current);\n current = [];\n x = startX;\n y = startY;\n lastCtrl = null;\n break;\n }\n default:\n // Unknown command — skip one token to avoid infinite loop\n i++;\n break;\n }\n }\n\n if (current.length > 0) polygons.push(current);\n\n return polygons;\n}\n\n/** First absolute `M` of a path, or null when the path does not start with one. */\nfunction firstMoveTo(d: string): Vec2 | null {\n const m = d.match(\n /^\\s*M\\s*(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)[\\s,]+(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/i,\n );\n if (!m) return null;\n const x = Number(m[1]);\n const y = Number(m[2]);\n return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;\n}\n\n/**\n * Rows written before the Y-flip removal hold `polygons` mirrored about the\n * viewbox while `paths[].d` stayed in SVG space, which renders the map upside\n * down. `paths` is authoritative, so rebuild `polygons` whenever the two\n * disagree. Comparing only the opening `M` keeps healthy geometry O(1).\n */\nexport function isGeometrySpaceStale(geometry: ShapeGeometry): boolean {\n const d = geometry.paths[0]?.d;\n if (!d) return false;\n if (geometry.polygons.length === 0) return false;\n const start = firstMoveTo(d);\n const first = geometry.polygons[0]?.[0];\n if (!start || !first) return false;\n return Math.abs(start.x - first.x) > 0.01 || Math.abs(start.y - first.y) > 0.01;\n}\n\n/** Return geometry with `polygons` rebuilt from `paths` when they disagree. */\nexport function normalizeGeometrySpace(geometry: ShapeGeometry): ShapeGeometry {\n if (!isGeometrySpaceStale(geometry)) return geometry;\n const polygons = geometry.paths.flatMap((p) => pathToPolygons(p.d));\n if (polygons.length === 0) return geometry;\n return { paths: geometry.paths, polygons };\n}\n\n/** `paths` keeps the original `d`; `polygons` must stay in the same space. */\nexport function buildGeometryFromPaths(pathDs: string[]): ShapeGeometry {\n const paths: PathSubpath[] = pathDs.map((d) => ({\n d,\n closed: /z/i.test(d),\n }));\n const polygons = pathDs.flatMap((d) => pathToPolygons(d));\n return { paths, polygons };\n}\n\nexport function geometryBBox(geometry: ShapeGeometry): BBox {\n const all = geometry.polygons.flat();\n return bboxOf(all);\n}\n\nexport function geometryCentroid(geometry: ShapeGeometry): Vec2 {\n return centroid(geometry.polygons.flat());\n}\n\n/**\n * Snap a delta angle to the nearest increment around a base angle.\n * baseDeg is the working orientation (e.g. from \"match this wall\").\n */\nexport function snapAngle(\n from: Vec2,\n to: Vec2,\n baseDeg = 0,\n increments: number[] = [15, 45, 90],\n): Vec2 {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const len = Math.hypot(dx, dy);\n if (len === 0) return { ...to };\n\n const rawDeg = (Math.atan2(dy, dx) * 180) / Math.PI;\n const relative = rawDeg - baseDeg;\n let best = relative;\n let bestDiff = Infinity;\n for (const step of increments) {\n const snapped = Math.round(relative / step) * step;\n const diff = Math.abs(relative - snapped);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = snapped;\n }\n }\n const finalDeg = ((best + baseDeg) * Math.PI) / 180;\n return {\n x: from.x + Math.cos(finalDeg) * len,\n y: from.y + Math.sin(finalDeg) * len,\n };\n}\n\n/** Derive working base angle from two wall points (degrees). */\nexport function angleFromWall(a: Vec2, b: Vec2): number {\n return (Math.atan2(b.y - a.y, b.x - a.x) * 180) / Math.PI;\n}\n\nexport function parseViewBox(raw: string | null | undefined): ViewBox | null {\n if (!raw) return null;\n const parts = raw.trim().split(/[\\s,]+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], width: parts[2], height: parts[3] };\n}\n","/**\n * Inline CSS class rules from `<style>` tags as SVG presentation attributes.\n * Works in Node (no DOM) so the SVG importer can resolve fills/strokes.\n * Mirrors v1 `inlineSvgStyles` behaviour for class→attribute mapping.\n */\n\nconst CSS_TO_SVG_ATTR: Record<string, string> = {\n fill: 'fill',\n 'fill-opacity': 'fill-opacity',\n stroke: 'stroke',\n 'stroke-width': 'stroke-width',\n 'stroke-opacity': 'stroke-opacity',\n opacity: 'opacity',\n};\n\nfunction parseCssDeclarations(block: string): Record<string, string> {\n const declarations: Record<string, string> = {};\n for (const declaration of block.split(';')) {\n const sep = declaration.indexOf(':');\n if (sep === -1) continue;\n const property = declaration.slice(0, sep).trim().toLowerCase();\n const value = declaration.slice(sep + 1).trim();\n if (property && value) declarations[property] = value;\n }\n return declarations;\n}\n\nfunction parseCssClassRules(cssText: string): Map<string, Record<string, string>> {\n const classStyles = new Map<string, Record<string, string>>();\n const normalizedCss = cssText.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n for (const match of normalizedCss.matchAll(/([^{]+)\\{([^}]*)\\}/g)) {\n const selectors = match[1].split(',').map((s) => s.trim());\n const declarations = parseCssDeclarations(match[2]);\n for (const selector of selectors) {\n const classMatch = selector.match(/^\\.([a-zA-Z0-9_-]+)$/);\n if (!classMatch) continue;\n const className = classMatch[1];\n classStyles.set(className, {\n ...(classStyles.get(className) || {}),\n ...declarations,\n });\n }\n }\n return classStyles;\n}\n\nfunction mergeClassStyles(\n classAttr: string,\n classStyles: Map<string, Record<string, string>>,\n): Record<string, string> {\n const merged: Record<string, string> = {};\n for (const name of classAttr.split(/\\s+/).map((c) => c.trim()).filter(Boolean)) {\n Object.assign(merged, classStyles.get(name) || {});\n }\n return merged;\n}\n\n/**\n * Rewrite SVG text so class-based fills/strokes become presentation attributes.\n * Safe to call in Node — pure string rewrite, no DOMParser.\n */\nexport function inlineSvgStyles(svgText: string): string {\n const styleBlocks: string[] = [];\n const withoutComments = svgText.replace(/<!--[\\s\\S]*?-->/g, '');\n for (const m of withoutComments.matchAll(/<style\\b[^>]*>([\\s\\S]*?)<\\/style>/gi)) {\n styleBlocks.push(m[1]);\n }\n if (styleBlocks.length === 0) return svgText;\n\n const classStyles = new Map<string, Record<string, string>>();\n for (const block of styleBlocks) {\n for (const [name, decls] of parseCssClassRules(block)) {\n classStyles.set(name, { ...(classStyles.get(name) || {}), ...decls });\n }\n }\n if (classStyles.size === 0) return svgText;\n\n return svgText.replace(\n /<(path|polygon|polyline|line|rect|g|circle|ellipse)\\b([^>]*)>/gi,\n (full, tag: string, attrs: string) => {\n // `[^>]*` swallows the `/` in `/>`, so strip it before rewriting attrs.\n const selfClosing = /\\/\\s*$/.test(attrs);\n const cleanAttrs = attrs.replace(/\\/\\s*$/, '');\n const classMatch = cleanAttrs.match(/\\bclass\\s*=\\s*[\"']([^\"']*)[\"']/i);\n if (!classMatch) return full;\n const merged = mergeClassStyles(classMatch[1], classStyles);\n let nextAttrs = cleanAttrs;\n for (const [cssProp, value] of Object.entries(merged)) {\n const svgAttr = CSS_TO_SVG_ATTR[cssProp];\n if (!svgAttr) continue;\n if (new RegExp(`\\\\b${svgAttr}\\\\s*=`, 'i').test(nextAttrs)) continue;\n nextAttrs += ` ${svgAttr}=\"${value}\"`;\n }\n return `<${tag}${nextAttrs}${selfClosing ? ' /' : ''}>`;\n },\n );\n}\n\nexport interface SvgPresentationStyle {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n}\n\n/** Read presentation attributes from an attribute string. */\nexport function readPresentationStyle(attrs: string): SvgPresentationStyle {\n const out: SvgPresentationStyle = {};\n const fill = attrs.match(/\\bfill\\s*=\\s*[\"']([^\"']*)[\"']/i)?.[1];\n const stroke = attrs.match(/\\bstroke\\s*=\\s*[\"']([^\"']*)[\"']/i)?.[1];\n const strokeWidth = attrs.match(/\\bstroke-width\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n const opacity = attrs.match(/\\bopacity\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n const fillOpacity = attrs.match(/\\bfill-opacity\\s*=\\s*[\"']?(-?[\\d.]+)/i)?.[1];\n if (fill && fill.toLowerCase() !== 'none') out.fill = fill;\n if (stroke && stroke.toLowerCase() !== 'none') out.stroke = stroke;\n if (strokeWidth != null && !Number.isNaN(Number(strokeWidth))) {\n out.strokeWidth = Number(strokeWidth);\n }\n if (opacity != null && !Number.isNaN(Number(opacity))) {\n out.opacity = Number(opacity);\n } else if (fillOpacity != null && !Number.isNaN(Number(fillOpacity))) {\n out.opacity = Number(fillOpacity);\n }\n return out;\n}\n\n/** Merge child over parent — child wins when set. */\nexport function mergePresentationStyle(\n parent: SvgPresentationStyle,\n child: SvgPresentationStyle,\n): SvgPresentationStyle {\n return {\n fill: child.fill ?? parent.fill,\n stroke: child.stroke ?? parent.stroke,\n strokeWidth: child.strokeWidth ?? parent.strokeWidth,\n opacity: child.opacity ?? parent.opacity,\n };\n}\n","/**\n * SVG `transform` attribute support for the importer.\n *\n * Pure string/matrix math — no DOM, so it runs in Node during server-side\n * import. Geometry stays in raw SVG user space (Y down); these helpers only\n * bake `transform` attributes into coordinates, they never flip axes.\n */\n\nimport type { Vec2 } from '../types';\nimport { tokenizePathData } from '../geometry';\n\n/**\n * 2D affine matrix in SVG order:\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n */\nexport interface Matrix2D {\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n}\n\nexport const IDENTITY_MATRIX: Matrix2D = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n\n/**\n * Matrix product `outer × inner`: the returned matrix applies `inner` first,\n * then `outer`. SVG composes `transform=\"A B\"` the same way — the rightmost\n * transform is applied to the geometry first, and an ancestor `<g>` transform\n * is the outer one relative to its descendants.\n */\nexport function multiplyMatrix(outer: Matrix2D, inner: Matrix2D): Matrix2D {\n return {\n a: outer.a * inner.a + outer.c * inner.b,\n b: outer.b * inner.a + outer.d * inner.b,\n c: outer.a * inner.c + outer.c * inner.d,\n d: outer.b * inner.c + outer.d * inner.d,\n e: outer.a * inner.e + outer.c * inner.f + outer.e,\n f: outer.b * inner.e + outer.d * inner.f + outer.f,\n };\n}\n\nexport function applyMatrix(m: Matrix2D, p: Vec2): Vec2 {\n return {\n x: m.a * p.x + m.c * p.y + m.e,\n y: m.b * p.x + m.d * p.y + m.f,\n };\n}\n\nexport function isIdentityMatrix(m: Matrix2D, epsilon = 1e-9): boolean {\n return (\n Math.abs(m.a - 1) < epsilon &&\n Math.abs(m.b) < epsilon &&\n Math.abs(m.c) < epsilon &&\n Math.abs(m.d - 1) < epsilon &&\n Math.abs(m.e) < epsilon &&\n Math.abs(m.f) < epsilon\n );\n}\n\nfunction translateMatrix(tx: number, ty: number): Matrix2D {\n return { a: 1, b: 0, c: 0, d: 1, e: tx, f: ty };\n}\n\nfunction rotateMatrix(deg: number): Matrix2D {\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n return { a: cos, b: sin, c: -sin, d: cos, e: 0, f: 0 };\n}\n\nfunction transformFunctionMatrix(name: string, args: number[]): Matrix2D | null {\n switch (name) {\n case 'matrix':\n if (args.length < 6) return null;\n return { a: args[0], b: args[1], c: args[2], d: args[3], e: args[4], f: args[5] };\n case 'translate':\n if (args.length < 1) return null;\n return translateMatrix(args[0], args[1] ?? 0);\n case 'scale': {\n if (args.length < 1) return null;\n const sx = args[0];\n const sy = args[1] ?? sx;\n return { a: sx, b: 0, c: 0, d: sy, e: 0, f: 0 };\n }\n case 'rotate': {\n if (args.length < 1) return null;\n const rot = rotateMatrix(args[0]);\n if (args.length < 3) return rot;\n const cx = args[1];\n const cy = args[2];\n return multiplyMatrix(\n multiplyMatrix(translateMatrix(cx, cy), rot),\n translateMatrix(-cx, -cy),\n );\n }\n case 'skewx':\n if (args.length < 1) return null;\n return { a: 1, b: 0, c: Math.tan((args[0] * Math.PI) / 180), d: 1, e: 0, f: 0 };\n case 'skewy':\n if (args.length < 1) return null;\n return { a: 1, b: Math.tan((args[0] * Math.PI) / 180), c: 0, d: 1, e: 0, f: 0 };\n default:\n return null;\n }\n}\n\nconst TRANSFORM_FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\n/**\n * Parse an SVG `transform` attribute into a single affine matrix.\n * Unknown functions are skipped. Returns identity for empty / unparseable input.\n */\nexport function parseTransform(raw: string | null | undefined): Matrix2D {\n if (!raw) return IDENTITY_MATRIX;\n let result = IDENTITY_MATRIX;\n TRANSFORM_FN_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = TRANSFORM_FN_RE.exec(raw)) !== null) {\n const name = match[1].toLowerCase();\n const args = match[2]\n .trim()\n .split(/[\\s,]+/)\n .filter(Boolean)\n .map(Number);\n if (args.some((n) => Number.isNaN(n))) continue;\n const next = transformFunctionMatrix(name, args);\n if (!next) continue;\n // Leftmost function is outermost: earlier entries apply last.\n result = multiplyMatrix(result, next);\n }\n return result;\n}\n\n/** Trim float noise so rewritten `d` strings stay readable and stable. */\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return '0';\n const rounded = Math.round(n * 1e4) / 1e4;\n return Object.is(rounded, -0) ? '0' : String(rounded);\n}\n\n/**\n * Re-express an elliptical arc under an affine map.\n * The ellipse basis is `A · R(phi) · diag(rx, ry)`; its singular values are the\n * new radii and the left rotation is the new x-axis-rotation.\n */\nfunction transformArc(\n m: Matrix2D,\n rx: number,\n ry: number,\n phiDeg: number,\n): { rx: number; ry: number; phiDeg: number } {\n const phi = (phiDeg * Math.PI) / 180;\n const cos = Math.cos(phi);\n const sin = Math.sin(phi);\n // Ellipse basis in user space, then the matrix linear part.\n const e11 = cos * rx;\n const e21 = sin * rx;\n const e12 = -sin * ry;\n const e22 = cos * ry;\n const m11 = m.a * e11 + m.c * e21;\n const m21 = m.b * e11 + m.d * e21;\n const m12 = m.a * e12 + m.c * e22;\n const m22 = m.b * e12 + m.d * e22;\n // Closed-form 2x2 SVD.\n const E = (m11 + m22) / 2;\n const F = (m11 - m22) / 2;\n const G = (m21 + m12) / 2;\n const H = (m21 - m12) / 2;\n const q = Math.hypot(E, H);\n const r = Math.hypot(F, G);\n const outRx = Math.abs(q + r);\n const outRy = Math.abs(q - r);\n const a1 = Math.atan2(G, F);\n const a2 = Math.atan2(H, E);\n const outPhi = ((a2 + a1) / 2) * (180 / Math.PI);\n return { rx: outRx, ry: outRy, phiDeg: outPhi };\n}\n\n/**\n * Bake an affine matrix into a path `d` string, emitting absolute commands.\n *\n * Flattening a bezier commutes with an affine map (control points transform\n * independently, sampling parameters do not change), so\n * `pathToPolygons(transformPathD(d, m))` equals `pathToPolygons(d)` mapped\n * through `m`. That is what keeps `geometry.paths[].d` and `geometry.polygons`\n * in the same coordinate space.\n *\n * Arcs commute exactly under a similarity (translate / rotate / uniform scale /\n * mirror), which covers Illustrator output. A shear or non-uniform scale maps\n * the same curve but reparameterises it, so individual sample points may shift\n * along the outline even though the outline itself is right.\n */\nexport function transformPathD(d: string, m: Matrix2D): string {\n if (!d || isIdentityMatrix(m)) return d;\n const tokens = tokenizePathData(d);\n const out: string[] = [];\n const flipsOrientation = m.a * m.d - m.b * m.c < 0;\n\n let i = 0;\n let cmd = '';\n // Current point / subpath start in *source* space.\n let x = 0;\n let y = 0;\n let startX = 0;\n let startY = 0;\n\n const readNum = () => {\n const n = Number(tokens[i++]);\n return Number.isNaN(n) ? 0 : n;\n };\n const emit = (letter: string, ...coords: number[]) => {\n out.push(letter + (coords.length ? ' ' + coords.map(fmt).join(' ') : ''));\n };\n const point = (px: number, py: number): [number, number] => {\n const p = applyMatrix(m, { x: px, y: py });\n return [p.x, p.y];\n };\n\n while (i < tokens.length) {\n const t = tokens[i];\n if (/[a-zA-Z]/.test(t)) {\n cmd = t;\n i++;\n }\n\n switch (cmd) {\n case 'M':\n case 'm': {\n const rel = cmd === 'm';\n const nx = readNum();\n const ny = readNum();\n x = rel ? x + nx : nx;\n y = rel ? y + ny : ny;\n startX = x;\n startY = y;\n emit('M', ...point(x, y));\n cmd = rel ? 'l' : 'L';\n break;\n }\n case 'L':\n case 'l': {\n const rel = cmd === 'l';\n const nx = readNum();\n const ny = readNum();\n x = rel ? x + nx : nx;\n y = rel ? y + ny : ny;\n emit('L', ...point(x, y));\n break;\n }\n case 'H':\n case 'h': {\n const rel = cmd === 'h';\n const nx = readNum();\n x = rel ? x + nx : nx;\n // A rotation or skew makes a horizontal run non-horizontal.\n emit('L', ...point(x, y));\n break;\n }\n case 'V':\n case 'v': {\n const rel = cmd === 'v';\n const ny = readNum();\n y = rel ? y + ny : ny;\n emit('L', ...point(x, y));\n break;\n }\n case 'C':\n case 'c': {\n const rel = cmd === 'c';\n const x1 = rel ? x + readNum() : readNum();\n const y1 = rel ? y + readNum() : readNum();\n const x2 = rel ? x + readNum() : readNum();\n const y2 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('C', ...point(x1, y1), ...point(x2, y2), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'S':\n case 's': {\n const rel = cmd === 's';\n const x2 = rel ? x + readNum() : readNum();\n const y2 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n // Reflection of the previous control point is affine-covariant.\n emit('S', ...point(x2, y2), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'Q':\n case 'q': {\n const rel = cmd === 'q';\n const x1 = rel ? x + readNum() : readNum();\n const y1 = rel ? y + readNum() : readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('Q', ...point(x1, y1), ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'T':\n case 't': {\n const rel = cmd === 't';\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n emit('T', ...point(nx, ny));\n x = nx;\n y = ny;\n break;\n }\n case 'A':\n case 'a': {\n const rel = cmd === 'a';\n const rx = readNum();\n const ry = readNum();\n const rot = readNum();\n const largeArc = readNum();\n const sweep = readNum();\n const nx = rel ? x + readNum() : readNum();\n const ny = rel ? y + readNum() : readNum();\n const arc = transformArc(m, rx, ry, rot);\n const [tx, ty] = point(nx, ny);\n out.push(\n `A ${fmt(arc.rx)} ${fmt(arc.ry)} ${fmt(arc.phiDeg)} ${largeArc ? 1 : 0} ` +\n `${(sweep ? 1 : 0) ^ (flipsOrientation ? 1 : 0)} ${fmt(tx)} ${fmt(ty)}`,\n );\n x = nx;\n y = ny;\n break;\n }\n case 'Z':\n case 'z': {\n out.push('Z');\n x = startX;\n y = startY;\n break;\n }\n default:\n // Unknown command — skip a token so we cannot loop forever.\n i++;\n break;\n }\n }\n\n return out.join(' ');\n}\n","import type {\n BBox,\n ImportClassification,\n ImportDiff,\n ImportDiffItem,\n ImportReport,\n ShapeGeometry,\n ShapeKind,\n ShapeStyle,\n ViewBox,\n} from '../types';\nimport { INTERACTIVE_SHAPE_KINDS } from '../types';\nimport {\n buildGeometryFromPaths,\n geometryBBox,\n geometryCentroid,\n parseViewBox,\n} from '../geometry';\nimport { resolveLayerStyle } from '../layerStyles';\nimport {\n inlineSvgStyles,\n mergePresentationStyle,\n readPresentationStyle,\n type SvgPresentationStyle,\n} from './svgStyle';\nimport {\n IDENTITY_MATRIX,\n multiplyMatrix,\n parseTransform,\n transformPathD,\n type Matrix2D,\n} from './svgTransform';\n\n/** Prefix → shape kind for floor SVGs. */\nconst FLOOR_PREFIXES: Array<{ prefix: string; kind: ShapeKind }> = [\n { prefix: 'walkable', kind: 'walkable' },\n { prefix: 'void', kind: 'void' },\n { prefix: 'unit', kind: 'unit' },\n { prefix: 'store', kind: 'unit' }, // v1 compatibility\n { prefix: 'wall', kind: 'wall' },\n { prefix: 'boundary', kind: 'boundary' },\n { prefix: 'outer-wall', kind: 'wall' },\n { prefix: 'amenity-', kind: 'amenity' },\n { prefix: 'kiosk-', kind: 'kiosk_screen' },\n { prefix: 'escalator-', kind: 'connector' },\n { prefix: 'elevator-', kind: 'connector' },\n { prefix: 'stairs-', kind: 'connector' },\n { prefix: 'entrance-', kind: 'entrance' },\n { prefix: 'zone-', kind: 'zone' },\n { prefix: 'label-', kind: 'label' },\n { prefix: 'floorplate', kind: 'floorplate' },\n { prefix: 'base', kind: 'floorplate' },\n { prefix: 'decor', kind: 'decor' },\n { prefix: 'special-shape', kind: 'decor' },\n { prefix: 'overlay', kind: 'decor' },\n { prefix: 'green-area', kind: 'green_area' },\n { prefix: 'parking-lane', kind: 'parking_zone' },\n { prefix: 'parking-line', kind: 'decor' },\n { prefix: 'parking-icon', kind: 'parking_icon' },\n { prefix: 'walking-path', kind: 'walkable' },\n { prefix: 'water', kind: 'water' },\n];\n\n/** Prefix → shape kind for outdoor / base layer. */\nconst BASE_PREFIXES: Array<{ prefix: string; kind: ShapeKind }> = [\n { prefix: 'parking-zone', kind: 'parking_zone' },\n { prefix: 'parking-lane', kind: 'parking_zone' },\n { prefix: 'parking-line', kind: 'decor' },\n { prefix: 'parking-icon', kind: 'parking_icon' },\n { prefix: 'green-area', kind: 'green_area' },\n { prefix: 'water', kind: 'water' },\n { prefix: 'walking-path', kind: 'walkable' },\n { prefix: 'decor', kind: 'decor' },\n { prefix: 'entrance-', kind: 'entrance' },\n { prefix: 'unit', kind: 'unit' },\n { prefix: 'store', kind: 'unit' },\n { prefix: 'interactive-', kind: 'unit' },\n { prefix: 'walkable', kind: 'walkable' },\n { prefix: 'void', kind: 'void' },\n { prefix: 'amenity-', kind: 'amenity' },\n { prefix: 'kiosk-', kind: 'kiosk_screen' },\n // Connectors also appear in outdoor artboards (car-park decks, ramps).\n { prefix: 'escalator-', kind: 'connector' },\n { prefix: 'elevator-', kind: 'connector' },\n { prefix: 'stairs-', kind: 'connector' },\n];\n\n/** v1 / Illustrator walking-path ids (`route-path`, `route-path-12`). */\nexport function isRoutePathLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return n === 'route path' || n.startsWith('route path ');\n}\n\n/** Folder that holds walking paths (`ROUTES`, `route-path`, `WAYFINDING`). */\nexport function isRouteFolderLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return (\n n === 'routes' ||\n n === 'route' ||\n n === 'wayfinding' ||\n n === 'wayfinding routes' ||\n isRoutePathLabel(label)\n );\n}\n\n/**\n * Outdoor / base imports only persist interactive polygons (+ walkable/void for\n * autoroute). Decoration stays in the live SVG renderer.\n */\nexport const IMPORT_PERSISTED_KINDS: readonly ShapeKind[] = [\n ...INTERACTIVE_SHAPE_KINDS,\n 'walkable',\n 'void',\n];\n\n/** Centroid shift (world units) above which a matched shape is flagged `moved`. */\nexport const IMPORT_DRIFT_THRESHOLD = 8;\n\nexport interface RawSvgElement {\n id: string;\n tag: string;\n d?: string;\n points?: string;\n x1?: number;\n y1?: number;\n x2?: number;\n y2?: number;\n /** True when data-interactive is set or the element is inside an INTERACTIVE group. */\n interactive?: boolean;\n /** Resolved fill/stroke after group inheritance + CSS class inlining. */\n style?: SvgPresentationStyle;\n}\n\ninterface GroupFrame {\n id: string | null;\n /** Named INTERACTIVE* group (not NON_INTERACTIVE*). Children are assignable units. */\n interactiveContainer: boolean;\n /** Named NON_INTERACTIVE* group. Children keep prefix classification only. */\n nonInteractiveContainer: boolean;\n /** STORES / UNITS / store-layer — Illustrator folder, never a shape. */\n storeFolder: boolean;\n /** This group or an INTERACTIVE/STORES ancestor applies (unless a closer NON_INTERACTIVE wins). */\n inInteractive: boolean;\n collectedPaths: string[];\n style: SvgPresentationStyle;\n /** Own `transform` composed with every ancestor `<g>` transform. */\n matrix: Matrix2D;\n /** A descendant carried its own `id` — this group behaves like a folder. */\n hasNamedChild: boolean;\n /** ROUTES / route-path folder — unnamed children are walking paths. */\n routeContainer: boolean;\n}\n\nexport interface ParsedSvg {\n viewbox: ViewBox | null;\n elements: RawSvgElement[];\n routePathDs: string[];\n /** Structural problems worth surfacing in the import report. */\n warnings: string[];\n}\n\nexport function classifyId(\n id: string,\n mode: 'floor' | 'base' = 'floor',\n): { kind: ShapeKind | null; guessed: boolean } {\n // Layer folders first — `store` prefix must not claim `STORES`.\n if (isLayerContainerLabel(id)) {\n return { kind: null, guessed: false };\n }\n const lower = id.toLowerCase();\n const table = mode === 'base' ? BASE_PREFIXES : FLOOR_PREFIXES;\n for (const { prefix, kind } of table) {\n if (lower === prefix || lower.startsWith(prefix)) {\n return { kind, guessed: false };\n }\n }\n // interactive-* or data-interactive attribute handled by caller\n if (lower.startsWith('interactive')) {\n return { kind: 'unit', guessed: true };\n }\n return { kind: null, guessed: false };\n}\n\n/** Collapse Illustrator id / data-name punctuation so labels compare as words. */\nexport function normalizeLayerLabel(label: string): string {\n return label\n .toLowerCase()\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Illustrator / designer NON_INTERACTIVE, NON-INTERACTIVE, \"NON INTERACTIVE ITEMS\". */\nexport function isNonInteractiveGroupLabel(label: string): boolean {\n return /non[-_ ]?interactive/i.test(label);\n}\n\n/**\n * INTERACTIVE, INTERACTIVE_ITEMS, INTERACTIVE-2, data-name=\"INTERACTIVE ITEMS\".\n * Excludes NON_INTERACTIVE* and generated ids like interactive-anon-1.\n */\nexport function isInteractiveGroupLabel(label: string): boolean {\n if (isNonInteractiveGroupLabel(label)) return false;\n return /^interactive( items)?( \\d+)?$/.test(normalizeLayerLabel(label));\n}\n\n/**\n * STORES, store-layer, UNITS — folder names only.\n * Does not match store-46 / unit-12 (those are leaf stores).\n */\nexport function isStoreFolderLabel(label: string): boolean {\n const n = normalizeLayerLabel(label);\n return n === 'stores' || n === 'store layer' || n === 'units' || n === 'unit layer';\n}\n\n/**\n * Illustrator layer / folder: never emit as a shape, never join descendants into one `d`.\n */\nexport function isLayerContainerLabel(label: string): boolean {\n return (\n isInteractiveGroupLabel(label) ||\n isNonInteractiveGroupLabel(label) ||\n isStoreFolderLabel(label) ||\n isRouteFolderLabel(label)\n );\n}\n\nfunction isContainerFrame(frame: GroupFrame): boolean {\n return frame.interactiveContainer || frame.nonInteractiveContainer || frame.storeFolder;\n}\n\nfunction attrValue(attrs: string, name: string): string | null {\n const m = attrs.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`, 'i'));\n return m ? m[1] : null;\n}\n\nfunction numAttr(attrs: string, name: string): number {\n const m = attrs.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']?(-?[\\\\d.]+)`, 'i'));\n return m ? Number(m[1]) : 0;\n}\n\nfunction hasDataInteractive(attrs: string): boolean {\n return /\\bdata-interactive\\s*=\\s*[\"']?(true|1|yes)/i.test(attrs);\n}\n\nfunction labelsFromAttrs(attrs: string): string[] {\n return [attrValue(attrs, 'id'), attrValue(attrs, 'data-name')].filter(\n (s): s is string => Boolean(s),\n );\n}\n\nfunction groupKindFromLabels(labels: string[]): {\n interactiveContainer: boolean;\n nonInteractiveContainer: boolean;\n storeFolder: boolean;\n} {\n if (labels.some(isNonInteractiveGroupLabel)) {\n return { interactiveContainer: false, nonInteractiveContainer: true, storeFolder: false };\n }\n if (labels.some(isInteractiveGroupLabel)) {\n return { interactiveContainer: true, nonInteractiveContainer: false, storeFolder: false };\n }\n if (labels.some(isStoreFolderLabel)) {\n return { interactiveContainer: false, nonInteractiveContainer: false, storeFolder: true };\n }\n return { interactiveContainer: false, nonInteractiveContainer: false, storeFolder: false };\n}\n\nfunction pointsToPath(points: string): string {\n const nums = points.trim().split(/[\\s,]+/).map(Number);\n if (nums.length < 4) return '';\n let d = `M ${nums[0]} ${nums[1]}`;\n for (let i = 2; i < nums.length; i += 2) {\n d += ` L ${nums[i]} ${nums[i + 1]}`;\n }\n d += ' Z';\n return d;\n}\n\nfunction lineToPath(x1: number, y1: number, x2: number, y2: number): string {\n return `M ${x1} ${y1} L ${x2} ${y2}`;\n}\n\nfunction geometryFromTag(tag: string, attrs: string): string | undefined {\n if (tag === 'path') {\n return attrValue(attrs, 'd') ?? undefined;\n }\n if (tag === 'polygon' || tag === 'polyline') {\n const points = attrValue(attrs, 'points');\n return points ? pointsToPath(points) : undefined;\n }\n if (tag === 'line') {\n return lineToPath(\n numAttr(attrs, 'x1'),\n numAttr(attrs, 'y1'),\n numAttr(attrs, 'x2'),\n numAttr(attrs, 'y2'),\n );\n }\n if (tag === 'rect') {\n const x = numAttr(attrs, 'x');\n const y = numAttr(attrs, 'y');\n const w = numAttr(attrs, 'width');\n const h = numAttr(attrs, 'height');\n return `M ${x} ${y} L ${x + w} ${y} L ${x + w} ${y + h} L ${x} ${y + h} Z`;\n }\n return undefined;\n}\n\n/**\n * Lightweight SVG string parser — no DOM required (works in Node).\n * Scans tags sequentially and tracks `<g>` ancestry so Illustrator folders\n * (INTERACTIVE, STORES, NON_INTERACTIVE*) are never joined into one shape.\n */\nexport function parseSvgString(svg: string): ParsedSvg {\n const stripped = inlineSvgStyles(svg).replace(/<!--[\\s\\S]*?-->/g, '');\n const viewboxMatch = stripped.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n const viewbox = parseViewBox(viewboxMatch?.[1]);\n\n const elements: RawSvgElement[] = [];\n const routePathDs: string[] = [];\n const warnings: string[] = [];\n const stack: GroupFrame[] = [];\n let anon = 0;\n\n const inRouteContainer = (): boolean =>\n stack.some((frame) => frame.routeContainer);\n\n const parentStyle = (): SvgPresentationStyle => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const s = stack[i].style;\n if (s.fill || s.stroke || s.strokeWidth != null || s.opacity != null) {\n // Merge from root → leaf\n break;\n }\n }\n let merged: SvgPresentationStyle = {};\n for (const frame of stack) {\n merged = mergePresentationStyle(merged, frame.style);\n }\n return merged;\n };\n\n const inInteractive = (): boolean => {\n for (let i = stack.length - 1; i >= 0; i--) {\n if (stack[i].nonInteractiveContainer) return false;\n if (stack[i].interactiveContainer || stack[i].storeFolder) return true;\n }\n return false;\n };\n\n /** Accumulated `<g>` transform for the element currently being read. */\n const parentMatrix = (): Matrix2D =>\n stack.length > 0 ? stack[stack.length - 1].matrix : IDENTITY_MATRIX;\n\n const markNamedChild = () => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (isContainerFrame(frame)) continue;\n if (frame.id) {\n frame.hasNamedChild = true;\n return;\n }\n }\n };\n\n const findCollector = (): GroupFrame | null => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (isContainerFrame(frame)) continue;\n if (frame.id) return frame;\n }\n return null;\n };\n\n const closeGroup = (frame: GroupFrame) => {\n if (frame.routeContainer) {\n for (const collected of frame.collectedPaths) emitRoute('path', collected);\n return;\n }\n if (isContainerFrame(frame)) return;\n if (!frame.id || frame.collectedPaths.length === 0) return;\n if (frame.hasNamedChild) {\n // A folder-like group (KIOSK, ESCALATORS, …) that also holds a stray\n // unnamed path: the stray silently merges into one shape keyed after\n // the group. Classification is unchanged — the designer gets a warning.\n warnings.push(\n `Group ${frame.id} mixes named children with ${frame.collectedPaths.length} unnamed path(s); ` +\n `the unnamed paths were merged into a single shape \"${frame.id}\" — give them ids if they are separate shapes`,\n );\n }\n elements.push({\n id: frame.id,\n tag: 'g',\n d: frame.collectedPaths.join(' '),\n interactive: frame.inInteractive,\n style: mergePresentationStyle(parentStyle(), frame.style),\n });\n };\n\n const emitRoute = (tag: string, d: string | undefined) => {\n if (!d) return;\n const open =\n tag === 'polyline' || tag === 'polygon' || tag === 'path'\n ? d.replace(/\\s*Z\\s*$/i, '')\n : d;\n if (routePathDs.includes(open)) return;\n routePathDs.push(open);\n };\n\n const tokenRe = /<(\\/?)(path|polygon|polyline|line|rect|g)\\b([^>]*)(\\/?)>/gi;\n let match: RegExpExecArray | null;\n while ((match = tokenRe.exec(stripped)) !== null) {\n const closing = match[1] === '/';\n const tag = match[2].toLowerCase();\n const attrs = match[3] ?? '';\n const selfClosing = match[4] === '/' || /\\/\\s*$/.test(attrs);\n\n if (closing) {\n if (tag === 'g') {\n const frame = stack.pop();\n if (frame) closeGroup(frame);\n }\n continue;\n }\n\n if (tag === 'g') {\n const id = attrValue(attrs, 'id');\n const labels = labelsFromAttrs(attrs);\n const { interactiveContainer, nonInteractiveContainer, storeFolder } =\n groupKindFromLabels(labels);\n const parentInteractive = inInteractive();\n if (id) markNamedChild();\n const frame: GroupFrame = {\n id,\n interactiveContainer,\n nonInteractiveContainer,\n storeFolder,\n inInteractive:\n interactiveContainer ||\n storeFolder ||\n hasDataInteractive(attrs) ||\n (parentInteractive && !nonInteractiveContainer),\n collectedPaths: [],\n style: readPresentationStyle(attrs),\n matrix: multiplyMatrix(parentMatrix(), parseTransform(attrValue(attrs, 'transform'))),\n hasNamedChild: false,\n routeContainer:\n labels.some(isRouteFolderLabel) || inRouteContainer(),\n };\n if (!selfClosing) stack.push(frame);\n continue;\n }\n\n const id = attrValue(attrs, 'id');\n const raw = geometryFromTag(tag, attrs);\n // Bake own + inherited group transforms so every emitted `d` is in root\n // user space, matching the polygons derived from it later.\n const matrix = multiplyMatrix(parentMatrix(), parseTransform(attrValue(attrs, 'transform')));\n const d = raw ? transformPathD(raw, matrix) : raw;\n const interactive = hasDataInteractive(attrs) || inInteractive();\n const style = mergePresentationStyle(parentStyle(), readPresentationStyle(attrs));\n\n const dataName = attrValue(attrs, 'data-name');\n const routeNamed =\n (id != null && isRoutePathLabel(id)) ||\n (dataName != null && isRoutePathLabel(dataName));\n if (routeNamed || (!id && inRouteContainer())) {\n emitRoute(tag, d);\n continue;\n }\n\n if (id) {\n markNamedChild();\n if (d) {\n elements.push({ id, tag, d, interactive, style });\n }\n continue;\n }\n\n if (!d) continue;\n\n const collector = findCollector();\n if (collector) {\n collector.collectedPaths.push(d);\n // Prefer first child style onto the collector when empty\n if (!collector.style.fill && style.fill) collector.style = style;\n } else if (interactive) {\n anon += 1;\n elements.push({\n id: `interactive-anon-${anon}`,\n tag,\n d,\n interactive: true,\n style,\n });\n }\n }\n\n while (stack.length > 0) {\n closeGroup(stack.pop()!);\n }\n\n return { viewbox, elements, routePathDs, warnings };\n}\n\nexport interface ImportedShapeDraft {\n key: string;\n kind: ShapeKind;\n geometry: ShapeGeometry;\n bbox: BBox;\n sourceSvgId: string;\n style: ShapeStyle;\n}\n\nfunction slugKey(id: string): string {\n return id\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 80);\n}\n\nfunction styleFromElement(\n el: RawSvgElement,\n sourceSvgId: string,\n): ShapeStyle {\n const layer = resolveLayerStyle(sourceSvgId);\n const style: ShapeStyle = {};\n if (layer?.fill) style.fill = layer.fill;\n else if (el.style?.fill) style.fill = el.style.fill;\n if (layer?.stroke) style.stroke = layer.stroke;\n else if (el.style?.stroke) style.stroke = el.style.stroke;\n if (layer?.strokeWidth != null) style.strokeWidth = layer.strokeWidth;\n else if (el.style?.strokeWidth != null) style.strokeWidth = el.style.strokeWidth;\n if (el.style?.opacity != null) style.opacity = el.style.opacity;\n if (layer?.extrudeHeight != null) style.extrudeHeight = layer.extrudeHeight;\n return style;\n}\n\nfunction viewBoxesEqual(a: ViewBox | null, b: ViewBox | null): boolean {\n if (a == null && b == null) return true;\n if (a == null || b == null) return false;\n return (\n Math.abs(a.x - b.x) < 0.01 &&\n Math.abs(a.y - b.y) < 0.01 &&\n Math.abs(a.width - b.width) < 0.01 &&\n Math.abs(a.height - b.height) < 0.01\n );\n}\n\nexport interface ImportSvgOptions {\n /** Previous level viewBox — used to detect artboard changes on re-upload. */\n previousViewbox?: ViewBox | null;\n}\n\nexport function importSvg(\n svg: string,\n mode: 'floor' | 'base' = 'floor',\n options: ImportSvgOptions = {},\n): {\n report: ImportReport;\n shapes: ImportedShapeDraft[];\n viewbox: ViewBox | null;\n routePathDs: string[];\n viewBoxChanged: boolean;\n} {\n const parsed = parseSvgString(svg);\n const classified: ImportClassification[] = [];\n const unrecognized: string[] = [];\n const guessed: ImportClassification[] = [];\n const warnings: string[] = [...parsed.warnings];\n const shapes: ImportedShapeDraft[] = [];\n\n let walkableCount = 0;\n let voidCount = 0;\n let unitCount = 0;\n\n const viewBoxChanged =\n options.previousViewbox != null &&\n parsed.viewbox != null &&\n !viewBoxesEqual(options.previousViewbox, parsed.viewbox);\n\n if (viewBoxChanged) {\n warnings.push(\n 'SVG viewBox differs from the stored artboard — re-upload blocked until the designer restores the original viewBox',\n );\n }\n\n for (const el of parsed.elements) {\n if (isLayerContainerLabel(el.id)) continue;\n let { kind, guessed: isGuessed } = classifyId(el.id, mode);\n if (el.interactive && !kind) {\n kind = 'unit';\n isGuessed = true;\n }\n\n const entry: ImportClassification = {\n sourceSvgId: el.id,\n kind,\n guessed: isGuessed,\n };\n\n // Floor mode: keep unrecognized as decor so discarding the SVG loses nothing.\n // Outdoor / base mode: skip unrecognized — live SVG renderer draws them.\n if (!kind) {\n unrecognized.push(el.id);\n if (mode === 'floor') {\n kind = 'decor';\n entry.kind = 'decor';\n entry.message = 'No matching prefix; imported as decor (floor mode)';\n } else {\n entry.message = 'No matching prefix; skipped (outdoor decor stays in SVG)';\n classified.push(entry);\n continue;\n }\n }\n\n if (!el.d) {\n warnings.push(`Element ${el.id} has no drawable geometry`);\n continue;\n }\n\n // Outdoor: only persist interactive (+ walkable/void). Decoration stays in SVG.\n // Static house-style layers (green-area, parking-lane, …) are never rows.\n if (mode === 'base') {\n const isStaticDecor = resolveLayerStyle(el.id) != null;\n const shouldPersist =\n !isStaticDecor &&\n (IMPORT_PERSISTED_KINDS.includes(kind) || Boolean(el.interactive));\n if (!shouldPersist) {\n classified.push({\n ...entry,\n message: isStaticDecor\n ? 'Static decoration — rendered from outdoor SVG'\n : 'Decoration — not persisted; rendered from outdoor SVG',\n });\n continue;\n }\n }\n\n if (isGuessed) {\n guessed.push(entry);\n entry.message = entry.message ?? 'Guessed kind from interactive/fallback rule';\n }\n classified.push(entry);\n\n if (kind === 'walkable') walkableCount++;\n if (kind === 'void') voidCount++;\n if (kind === 'unit') unitCount++;\n\n const geometry = buildGeometryFromPaths([el.d]);\n const bbox = geometryBBox(geometry);\n\n shapes.push({\n key: slugKey(el.id),\n kind,\n geometry,\n bbox,\n sourceSvgId: el.id,\n style: styleFromElement(el, el.id),\n });\n }\n\n if (mode === 'floor' && walkableCount === 0) {\n warnings.push(\n 'No walkable layer found — auto-skeleton will be unavailable for this level',\n );\n }\n\n return {\n report: {\n classified,\n unrecognized,\n guessed,\n walkableCount,\n voidCount,\n unitCount,\n warnings,\n },\n shapes,\n viewbox: parsed.viewbox,\n routePathDs: parsed.routePathDs,\n viewBoxChanged,\n };\n}\n\nexport interface ExistingShapeRef {\n id: number;\n sourceSvgId: string | null;\n kind: ShapeKind;\n key: string;\n /** When set, centroid drift is measured against the new draft. */\n bbox?: BBox | null;\n geometryLocked?: boolean;\n}\n\n/**\n * Diff newly imported shapes against existing level shapes by source_svg_id.\n * Emits `moved` when a matched id's centroid drifts past IMPORT_DRIFT_THRESHOLD.\n */\nexport function diffImport(\n imported: ImportedShapeDraft[],\n existing: ExistingShapeRef[],\n viewbox: ViewBox | null,\n options: { driftThreshold?: number } = {},\n): ImportDiff {\n const driftThreshold = options.driftThreshold ?? IMPORT_DRIFT_THRESHOLD;\n const existingBySource = new Map(\n existing\n .filter((e) => e.sourceSvgId)\n .map((e) => [e.sourceSvgId as string, e]),\n );\n const seen = new Set<string>();\n const items: ImportDiffItem[] = [];\n\n for (const shape of imported) {\n const prev = existingBySource.get(shape.sourceSvgId);\n seen.add(shape.sourceSvgId);\n if (!prev) {\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change: 'added',\n newKind: shape.kind,\n });\n } else if (prev.kind !== shape.kind) {\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change: 'kind_changed',\n existingShapeId: prev.id,\n existingKind: prev.kind,\n newKind: shape.kind,\n preserve: { key: prev.key, assignment: true, anchors: true },\n geometryLocked: prev.geometryLocked,\n });\n } else {\n let change: ImportDiffItem['change'] = 'unchanged';\n if (prev.bbox) {\n const prevCx = (prev.bbox.minX + prev.bbox.maxX) / 2;\n const prevCy = (prev.bbox.minY + prev.bbox.maxY) / 2;\n const next = geometryCentroid(shape.geometry);\n const drift = Math.hypot(next.x - prevCx, next.y - prevCy);\n if (drift > driftThreshold) change = 'moved';\n }\n items.push({\n sourceSvgId: shape.sourceSvgId,\n change,\n existingShapeId: prev.id,\n existingKind: prev.kind,\n newKind: shape.kind,\n preserve: { key: prev.key, assignment: true, anchors: true },\n geometryLocked: prev.geometryLocked,\n });\n }\n }\n\n for (const prev of existing) {\n if (prev.sourceSvgId && !seen.has(prev.sourceSvgId)) {\n items.push({\n sourceSvgId: prev.sourceSvgId,\n change: 'removed',\n existingShapeId: prev.id,\n existingKind: prev.kind,\n geometryLocked: prev.geometryLocked,\n });\n }\n }\n\n return {\n items,\n shapes: imported,\n viewbox,\n };\n}\n\nexport {\n inlineSvgStyles,\n readPresentationStyle,\n mergePresentationStyle,\n} from './svgStyle';\n\nexport {\n IDENTITY_MATRIX,\n applyMatrix,\n isIdentityMatrix,\n multiplyMatrix,\n parseTransform,\n transformPathD,\n type Matrix2D,\n} from './svgTransform';\n","import { distance } from './geometry';\nimport { clampStoreRadius, type Vec2 } from './types';\n\nconst EPS = 1e-6;\n/** Illustrator-style: only corner anchors, not smooth wall wobble. */\nconst MIN_CORNER_TURN = (15 * Math.PI) / 180;\nconst EDGE_GAP = 1e-3;\nconst TWO_PI = Math.PI * 2;\n\nfunction almostSame(a: Vec2, b: Vec2): boolean {\n return Math.abs(a.x - b.x) < EPS && Math.abs(a.y - b.y) < EPS;\n}\n\nfunction add(a: Vec2, b: Vec2): Vec2 {\n return { x: a.x + b.x, y: a.y + b.y };\n}\n\nfunction sub(a: Vec2, b: Vec2): Vec2 {\n return { x: a.x - b.x, y: a.y - b.y };\n}\n\nfunction scale(a: Vec2, s: number): Vec2 {\n return { x: a.x * s, y: a.y * s };\n}\n\nfunction pointOnCircle(center: Vec2, radius: number, angle: number): Vec2 {\n return {\n x: center.x + Math.cos(angle) * radius,\n y: center.y + Math.sin(angle) * radius,\n };\n}\n\n/** Drop duplicate consecutive points and a repeated closing vertex. */\nexport function uniqueClosedRing(points: Vec2[]): Vec2[] {\n const ring: Vec2[] = [];\n for (const point of points) {\n const last = ring[ring.length - 1];\n if (last && almostSame(last, point)) continue;\n ring.push(point);\n }\n if (ring.length >= 2 && almostSame(ring[0], ring[ring.length - 1])) ring.pop();\n return ring;\n}\n\n/**\n * Illustrator Round Corners: replace each real corner with a circular arc\n * tangent to both walls. The arc stays at the corner (never the long way\n * through the store). Shallow wall bends are left alone.\n */\nexport function filletPolygon(points: Vec2[], radius: number): Vec2[] {\n const r = clampStoreRadius(radius);\n const ring = uniqueClosedRing(points);\n if (ring.length < 3 || r <= 0) return points;\n\n const n = ring.length;\n const inN: Vec2[] = new Array(n);\n const outN: Vec2[] = new Array(n);\n const outLen: number[] = new Array(n);\n const turn: number[] = new Array(n);\n const inD = new Array(n).fill(0);\n const outD = new Array(n).fill(0);\n const fillet = new Array(n).fill(false);\n\n for (let i = 0; i < n; i++) {\n const prev = ring[(i - 1 + n) % n];\n const curr = ring[i];\n const next = ring[(i + 1) % n];\n const incoming = distance(prev, curr);\n const outgoing = distance(curr, next);\n outLen[i] = outgoing;\n if (incoming < EPS || outgoing < EPS) {\n inN[i] = { x: 1, y: 0 };\n outN[i] = { x: 1, y: 0 };\n turn[i] = 0;\n continue;\n }\n inN[i] = scale(sub(curr, prev), 1 / incoming);\n outN[i] = scale(sub(next, curr), 1 / outgoing);\n const cross = inN[i].x * outN[i].y - inN[i].y * outN[i].x;\n const dot = inN[i].x * outN[i].x + inN[i].y * outN[i].y;\n turn[i] = Math.atan2(cross, dot);\n const absTurn = Math.abs(turn[i]);\n if (absTurn < MIN_CORNER_TURN) continue;\n // Illustrator uses the same offset for convex and concave:\n // d = r / tan((π − |turn|)/2). Splitting those cases made\n // store-40's inner notch bulge instead of a tight inner radius.\n const wedge = Math.PI - absTurn;\n const tanHalf = Math.tan(wedge / 2);\n if (tanHalf < EPS || wedge <= EPS || wedge >= Math.PI - EPS) continue;\n const desired = r / tanHalf;\n inD[i] = desired;\n outD[i] = desired;\n fillet[i] = true;\n }\n\n for (let i = 0; i < n; i++) {\n const j = (i + 1) % n;\n const need = outD[i] + inD[j];\n const available = Math.max(0, outLen[i] - EDGE_GAP);\n if (need <= available || need <= EPS) continue;\n const scaleDown = available / need;\n outD[i] *= scaleDown;\n inD[j] *= scaleDown;\n }\n\n const out: Vec2[] = [];\n for (let i = 0; i < n; i++) {\n const curr = ring[i];\n const d = Math.min(inD[i], outD[i]);\n const absTurn = Math.abs(turn[i]);\n const wedge = Math.PI - absTurn;\n const actualR = d * Math.tan(wedge / 2);\n if (!fillet[i] || actualR < EPS || d < EPS) {\n out.push({ ...curr });\n continue;\n }\n\n const start = add(curr, scale(inN[i], -d));\n const end = add(curr, scale(outN[i], d));\n const sign = turn[i] > 0 ? 1 : -1;\n const center = add(start, {\n x: -inN[i].y * sign * actualR,\n y: inN[i].x * sign * actualR,\n });\n const a0 = Math.atan2(start.y - center.y, start.x - center.x);\n const a1 = Math.atan2(end.y - center.y, end.x - center.x);\n const sweepCCW = (a1 - a0 + TWO_PI) % TWO_PI;\n const sweepCW = (a0 - a1 + TWO_PI) % TWO_PI;\n const midCCW = pointOnCircle(center, actualR, a0 + sweepCCW / 2);\n const midCW = pointOnCircle(center, actualR, a0 - sweepCW / 2);\n const useCCW = distance(midCCW, curr) <= distance(midCW, curr);\n const sweep = useCCW ? sweepCCW : sweepCW;\n const steps = Math.max(8, Math.min(28, Math.ceil((sweep * actualR) / 2)));\n\n for (let s = 0; s <= steps; s++) {\n const t = s / steps;\n const ang = useCCW ? a0 + sweep * t : a0 - sweep * t;\n out.push(pointOnCircle(center, actualR, ang));\n }\n }\n\n return out;\n}\n","import createGraph, { type Graph } from 'ngraph.graph';\nimport path from 'ngraph.path';\nimport type {\n CmAnchor,\n CmConnector,\n CmRouteEdge,\n PathResult,\n PublishedGraphEdge,\n PublishedGraphNode,\n} from '../types';\nimport { FLOOR_CHANGE_PENALTY } from '../types';\nimport { distance } from '../geometry';\n\nexport interface CompiledGraph {\n graph: Graph;\n nodes: PublishedGraphNode[];\n edges: PublishedGraphEdge[];\n anchorById: Map<number, CmAnchor>;\n}\n\nexport function compileGraph(\n anchors: CmAnchor[],\n edges: CmRouteEdge[],\n connectors: CmConnector[] = [],\n): CompiledGraph {\n const graph = createGraph();\n const anchorById = new Map(anchors.map((a) => [a.id, a]));\n const connectorById = new Map(connectors.map((c) => [c.id, c]));\n\n const nodes: PublishedGraphNode[] = anchors.map((a) => ({\n id: a.id,\n levelId: a.levelId,\n x: a.x,\n y: a.y,\n kind: a.kind,\n shapeId: a.shapeId,\n connectorId: a.connectorId,\n }));\n\n for (const n of nodes) {\n graph.addNode(n.id, n);\n }\n\n const publishedEdges: PublishedGraphEdge[] = [];\n\n for (const e of edges) {\n const from = anchorById.get(e.fromAnchorId);\n const to = anchorById.get(e.toAnchorId);\n if (!from || !to) continue;\n\n let weight = e.weight;\n if (weight == null) {\n weight = distance(from, to);\n if (from.levelId !== to.levelId) {\n weight += FLOOR_CHANGE_PENALTY;\n }\n }\n\n // Accessibility: connector edges inherit connector.accessible\n let accessible = e.accessible;\n if (e.kind === 'connector' && from.connectorId != null) {\n const conn = connectorById.get(from.connectorId);\n if (conn) accessible = conn.accessible;\n }\n\n const pub: PublishedGraphEdge = {\n id: e.id,\n from: e.fromAnchorId,\n to: e.toAnchorId,\n weight,\n directed: e.directed,\n accessible,\n kind: e.kind,\n };\n publishedEdges.push(pub);\n\n graph.addLink(e.fromAnchorId, e.toAnchorId, pub);\n if (!e.directed) {\n graph.addLink(e.toAnchorId, e.fromAnchorId, pub);\n }\n }\n\n return { graph, nodes, edges: publishedEdges, anchorById };\n}\n\nexport interface FindPathOptions {\n accessibleOnly?: boolean;\n}\n\n/**\n * NBA* pathfinding over the compiled graph.\n * Returns null if no path exists.\n */\nexport function findPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n toAnchorId: number,\n options: FindPathOptions = {},\n): PathResult | null {\n const { graph, anchorById } = compiled;\n if (!anchorById.has(fromAnchorId) || !anchorById.has(toAnchorId)) {\n return null;\n }\n\n const finder = path.nba(graph, {\n oriented: true,\n distance(fromNode, toNode, link) {\n const data = link.data as PublishedGraphEdge | undefined;\n if (options.accessibleOnly && data && !data.accessible) {\n return Number.POSITIVE_INFINITY;\n }\n return data?.weight ?? 1;\n },\n heuristic(fromNode, toNode) {\n const a = anchorById.get(fromNode.id as number);\n const b = anchorById.get(toNode.id as number);\n if (!a || !b) return 0;\n let d = distance(a, b);\n if (a.levelId !== b.levelId) d += FLOOR_CHANGE_PENALTY;\n return d;\n },\n });\n\n const raw = finder.find(fromAnchorId, toAnchorId);\n if (!raw || raw.length === 0) return null;\n\n // ngraph returns destination → start; reverse\n const nodes = raw.reverse();\n const anchorIds = nodes.map((n) => n.id as number);\n const points: PathResult['points'] = [];\n const levelChanges: PathResult['levelChanges'] = [];\n let totalWeight = 0;\n\n for (let i = 0; i < anchorIds.length; i++) {\n const a = anchorById.get(anchorIds[i])!;\n points.push({ x: a.x, y: a.y, levelId: a.levelId });\n if (i > 0) {\n const prev = anchorById.get(anchorIds[i - 1])!;\n totalWeight += distance(prev, a);\n if (prev.levelId !== a.levelId) {\n totalWeight += FLOOR_CHANGE_PENALTY;\n levelChanges.push({\n fromLevelId: prev.levelId,\n toLevelId: a.levelId,\n connectorId: a.connectorId ?? prev.connectorId,\n });\n }\n }\n }\n\n return { anchorIds, points, totalWeight, levelChanges };\n}\n\n/**\n * Find the nearest matching amenity shape anchor from a start point.\n */\nexport function findNearestAmenityPath(\n compiled: CompiledGraph,\n fromAnchorId: number,\n amenityAnchorIds: number[],\n options: FindPathOptions = {},\n): PathResult | null {\n let best: PathResult | null = null;\n for (const targetId of amenityAnchorIds) {\n const result = findPath(compiled, fromAnchorId, targetId, options);\n if (!result) continue;\n if (!best || result.totalWeight < best.totalWeight) {\n best = result;\n }\n }\n return best;\n}\n","import type {\n CmAmenityCatalogItem,\n CmAnchor,\n CmBuilding,\n CmConnector,\n CmLevel,\n CmResponsiveOverride,\n CmRouteEdge,\n CmShape,\n CmShapeAssignment,\n MapAssignRetailer,\n PublishedDocument,\n ThemeDefaults,\n ViewBox,\n} from '../types';\nimport { mergeTheme } from '../types';\nimport { compileGraph } from '../routing/pathfinding';\nimport { publishedShapeLabel } from '../assignment';\nimport { geometryBBox, normalizeGeometrySpace } from '../geometry';\n\nexport interface PublishInput {\n revisionId: number;\n revisionNumber: number;\n centerId: number;\n mapId: number;\n theme: Partial<ThemeDefaults>;\n baseSvgUrl: string | null;\n baseViewbox: ViewBox | null;\n buildings: CmBuilding[];\n levels: CmLevel[];\n shapes: CmShape[];\n assignments: CmShapeAssignment[];\n anchors: CmAnchor[];\n edges: CmRouteEdge[];\n connectors: CmConnector[];\n amenities: CmAmenityCatalogItem[];\n responsiveOverrides: CmResponsiveOverride[];\n /** Center retailers — used to bake retail_logo URLs the way v1 looks them up at draw time. */\n retailers?: MapAssignRetailer[];\n /** Resolve S3 key → CDN URL for level source SVGs. */\n resolveSvgUrl?: (key: string | null) => string | null;\n publishedAt?: string;\n}\n\n/**\n * Compile live cm_* rows into the current production document.\n * Used by Save Changes (overwrite-in-place) and draft preview (?draft=1).\n */\nexport function compileDocument(input: PublishInput): PublishedDocument {\n const theme: ThemeDefaults = mergeTheme(input.theme);\n const assignmentByShape = new Map(\n input.assignments.map((a) => [a.shapeId, a]),\n );\n const retailerById = new Map(\n (input.retailers ?? []).map((item) => [item.id, item]),\n );\n const resolve = input.resolveSvgUrl ?? ((k: string | null) => k);\n\n const levels = input.levels\n .filter((l) => l.isActive)\n .sort((a, b) => a.ordering - b.ordering)\n .map((level) => {\n const levelShapes = input.shapes\n .filter((s) => s.levelId === level.id)\n .map((s) => {\n // Heals rows imported before the Y-flip removal without a re-import.\n const geometry = normalizeGeometrySpace(s.geometry);\n const assignment = assignmentByShape.get(s.id) ?? null;\n const retailer =\n assignment?.retailerId != null\n ? retailerById.get(assignment.retailerId) ?? null\n : null;\n return {\n ...s,\n geometry,\n bbox: geometry === s.geometry ? s.bbox : geometryBBox(geometry),\n assignment,\n label: publishedShapeLabel(s, assignment, retailer),\n };\n });\n const levelAnchors = input.anchors.filter((a) => a.levelId === level.id);\n return {\n id: level.id,\n buildingId: level.buildingId,\n kind: level.kind,\n name: level.name,\n levelIndex: level.levelIndex,\n ordering: level.ordering,\n sourceSvgUrl: resolve(level.sourceSvgKey) ?? level.sourceSvgUrl ?? null,\n viewbox: level.sourceViewbox,\n transform: level.transform,\n shapes: levelShapes,\n anchors: levelAnchors,\n };\n });\n\n const { nodes, edges } = compileGraph(\n input.anchors,\n input.edges,\n input.connectors,\n );\n\n return {\n version: 2,\n revisionId: input.revisionId,\n revisionNumber: input.revisionNumber,\n centerId: input.centerId,\n mapId: input.mapId,\n theme,\n baseSvgUrl: input.baseSvgUrl,\n baseViewbox: input.baseViewbox,\n buildings: input.buildings,\n levels,\n connectors: input.connectors,\n amenities: input.amenities.filter((a) => a.isActive),\n graph: { nodes, edges },\n responsiveOverrides: input.responsiveOverrides,\n publishedAt: input.publishedAt ?? new Date().toISOString(),\n };\n}\n\n/**\n * Heal a document that was compiled before the Y-flip removal, and drop\n * leftover store names on unassigned polygons. Viewer hosts load\n * `cm_revisions` JSON as-is (they never re-run `compileDocument`).\n */\nexport function normalizePublishedDocument(\n doc: PublishedDocument,\n): PublishedDocument {\n let changed = false;\n const levels = doc.levels.map((level) => {\n let levelChanged = false;\n const shapes = level.shapes.map((shape) => {\n const geometry = normalizeGeometrySpace(shape.geometry);\n const label = publishedShapeLabel(shape, shape.assignment);\n const geometryChanged = geometry !== shape.geometry;\n const labelChanged = label !== shape.label;\n if (!geometryChanged && !labelChanged) return shape;\n levelChanged = true;\n return {\n ...shape,\n geometry,\n bbox: geometryChanged ? geometryBBox(geometry) : shape.bbox,\n label,\n };\n });\n if (!levelChanged) return level;\n changed = true;\n return { ...level, shapes };\n });\n return changed ? { ...doc, levels } : doc;\n}\n","import type { ShapeKind, Vec2 } from './types';\n\n/** Large fills that would otherwise cover an atrium. */\nexport const SLAB_SHAPE_KINDS: ShapeKind[] = [\n 'floorplate',\n 'walkable',\n 'decor',\n 'zone',\n 'green_area',\n 'water',\n 'parking_zone',\n];\n\nexport function isVoidKind(kind: string): boolean {\n return kind === 'void';\n}\n\nexport function isSlabShapeKind(kind: string): boolean {\n return SLAB_SHAPE_KINDS.includes(kind as ShapeKind);\n}\n\ntype VoidishShape = {\n kind: string;\n orphanedAt?: string | null;\n geometry?: { polygons?: Vec2[][] };\n};\n\nexport function isActiveVoidShape(shape: VoidishShape): boolean {\n return isVoidKind(shape.kind) && !shape.orphanedAt;\n}\n\nexport function levelHasVoids(level: { shapes?: VoidishShape[] | null }): boolean {\n return (level.shapes ?? []).some(isActiveVoidShape);\n}\n\n/** Cached polygons for every opening on a level. */\nexport function voidPolygonsOnLevel(level: {\n shapes?: VoidishShape[] | null;\n}): Vec2[][] {\n const out: Vec2[][] = [];\n for (const shape of level.shapes ?? []) {\n if (!isActiveVoidShape(shape)) continue;\n for (const poly of shape.geometry?.polygons ?? []) {\n if (poly.length >= 3) out.push(poly);\n }\n }\n return out;\n}\n\nexport function polygonSignedArea(points: Vec2[]): number {\n let area = 0;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n area += points[j].x * points[i].y - points[i].x * points[j].y;\n }\n return area / 2;\n}\n\n/** Opposite winding so Three.js / SVG treat the ring as a hole. */\nexport function reversedRing(points: Vec2[]): Vec2[] {\n return points.slice().reverse();\n}\n\nexport function holeRingForOuter(outer: Vec2[], hole: Vec2[]): Vec2[] {\n const outerArea = polygonSignedArea(outer);\n const holeArea = polygonSignedArea(hole);\n if (outerArea === 0 || holeArea === 0) return hole;\n return Math.sign(outerArea) === Math.sign(holeArea) ? reversedRing(hole) : hole;\n}\n\nexport function polygonBBox(points: Vec2[]): {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n} {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const p of points) {\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n return { minX, minY, maxX, maxY };\n}\n\nexport function polygonsOverlap(a: Vec2[], b: Vec2[]): boolean {\n const aa = polygonBBox(a);\n const bb = polygonBBox(b);\n return aa.minX <= bb.maxX && aa.maxX >= bb.minX && aa.minY <= bb.maxY && aa.maxY >= bb.minY;\n}\n\nexport function holesOverlappingOuter(outer: Vec2[], holes: Vec2[][]): Vec2[][] {\n return holes\n .filter((hole) => hole.length >= 3 && polygonsOverlap(outer, hole))\n .map((hole) => holeRingForOuter(outer, hole));\n}\n\n/**\n * Default / public map: dashed outline and an X through the void —\n * the usual open-to-below mark. Edit Map is unchanged.\n */\nexport const OPENING_VOID_FILL = '#e8eef4';\nexport const OPENING_VOID_STROKE = '#64748b';\nexport const OPENING_VOID_MARK = '#475569';\n","import type { BBox, LevelKind, LevelTransform, PublishedLevel, ViewBox } from './types';\nimport { levelHasVoids } from './voids';\n\nexport interface StackLevel {\n id: number;\n kind: LevelKind;\n ordering: number;\n levelIndex: number;\n}\n\n/** Same comparator as admin FloorsPanel `buildingFloors`. */\nexport function compareBuildingFloors(\n a: { ordering: number; levelIndex: number },\n b: { ordering: number; levelIndex: number },\n): number {\n return a.ordering - b.ordering || a.levelIndex - b.levelIndex;\n}\n\nexport interface SceneBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n cx: number;\n cy: number;\n size: number;\n}\n\nexport function isOutdoorLevel(level: { kind: string }): boolean {\n return level.kind === 'outdoor';\n}\n\n/**\n * Persistent base + optional building-floor overlay.\n * Outdoor/base is never dropped when a floor is selected.\n * Selecting Outdoor hides building floors (base stays).\n * Only one building floor is shown at a time.\n */\nexport function viewerLevelStack<\n T extends StackLevel & { shapes?: Array<{ kind: string; orphanedAt?: string | null }> },\n>(levels: T[], activeLevelId: number | null): T[] {\n const outdoor = levels.filter(isOutdoorLevel);\n const active =\n activeLevelId == null\n ? null\n : (levels.find((level) => level.id === activeLevelId) ?? null);\n\n if (!active || isOutdoorLevel(active)) {\n return outdoor;\n }\n\n if (outdoor.some((level) => level.id === active.id)) {\n return outdoor;\n }\n\n return [...outdoor, active];\n}\n\n/**\n * Building floors visible through openings on `active`, lowest first.\n * Each step requires the floor above it to have at least one opening, so a\n * three-storey atrium keeps looking down until a solid deck stops it.\n */\nexport function revealedBuildingFloors<\n T extends StackLevel & { shapes?: Array<{ kind: string; orphanedAt?: string | null }> },\n>(levels: T[], activeLevelId: number | null): T[] {\n if (activeLevelId == null) return [];\n const floors = floorSwitcherLevels(levels);\n const start = floors.findIndex((level) => level.id === activeLevelId);\n if (start < 0) return [];\n\n const chain: T[] = [];\n let current = floors[start];\n for (let i = start; i < floors.length - 1; i++) {\n if (!levelHasVoids(current)) break;\n const lower = floors[i + 1];\n if (!lower) break;\n chain.unshift(lower);\n current = lower;\n }\n return chain;\n}\n\n/** Floor immediately below the active building floor, if an opening looks through. */\nexport function nextLowerBuildingFloor<\n T extends StackLevel & { shapes?: Array<{ kind: string; orphanedAt?: string | null }> },\n>(levels: T[], activeLevelId: number | null): T | null {\n return revealedBuildingFloors(levels, activeLevelId).at(-1) ?? null;\n}\n\n/**\n * Clicking an outdoor shape must not switch the viewer off the current\n * building floor. Outdoor is already stacked under every floor on the\n * default assign map, so changing `activeLevelId` to Outdoor hides the\n * floor the staff were managing.\n */\nexport function viewerLevelIdAfterShapeSelect(\n levels: Array<{\n id: number;\n kind: string;\n ordering: number;\n levelIndex: number;\n }>,\n currentLevelId: number | null,\n clickedLevelId: number,\n): number {\n const clicked = levels.find((level) => level.id === clickedLevelId);\n if (!clicked || !isOutdoorLevel(clicked)) return clickedLevelId;\n const current =\n currentLevelId == null\n ? null\n : (levels.find((level) => level.id === currentLevelId) ?? null);\n if (current && !isOutdoorLevel(current)) return current.id;\n return defaultViewerLevelId(levels) ?? clickedLevelId;\n}\n\n/** Building floors only, same order as the admin Floors list. */\nexport function floorSwitcherLevels<T extends StackLevel>(levels: T[]): T[] {\n return levels\n .filter((level) => level.kind === 'floor')\n .slice()\n .sort(compareBuildingFloors);\n}\n\n/**\n * Switcher buttons top-to-bottom — same order as the admin Floors list.\n * Do not reverse: staff order the list (upper level at the top) and the map\n * must match that.\n */\nexport function floorSwitcherDisplayLevels<T extends StackLevel>(levels: T[]): T[] {\n return floorSwitcherLevels(levels);\n}\n\n/** Hide the map floor list when there is only one building floor. */\nexport function shouldShowFloorSwitcher<T extends StackLevel>(levels: T[]): boolean {\n return floorSwitcherLevels(levels).length > 1;\n}\n\n/** Building floors only — Outdoor does not count. */\nexport function hasBuildingFloors(levels: Array<{ kind: string }>): boolean {\n return levels.some((level) => level.kind === 'floor');\n}\n\nexport const MAP_NO_FLOORS_MESSAGE = 'This map doesn’t have any floors yet.';\n\n/**\n * Prefer the last building floor in admin Floors order (bottom of the list).\n * The list stays upper-to-ground top-to-bottom; visitors should land on ground.\n */\nexport function defaultViewerLevelId(\n levels: Array<{ id: number; kind: string; ordering: number; levelIndex: number }>,\n): number | null {\n return floorSwitcherLevels(levels as StackLevel[]).at(-1)?.id ?? levels[0]?.id ?? null;\n}\n\nexport function viewBoxToBounds(viewbox: ViewBox): SceneBounds {\n return {\n minX: viewbox.x,\n minY: viewbox.y,\n maxX: viewbox.x + viewbox.width,\n maxY: viewbox.y + viewbox.height,\n cx: viewbox.x + viewbox.width / 2,\n cy: viewbox.y + viewbox.height / 2,\n size: Math.max(viewbox.width, viewbox.height, 100),\n };\n}\n\n/** Match three.js group compose: scale, then rotate about origin, then translate. */\nexport function applyLevelTransform(\n point: { x: number; y: number },\n transform: LevelTransform,\n): { x: number; y: number } {\n const scale = transform.scale || 1;\n const rad = ((transform.rotate || 0) * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const x = point.x * scale;\n const y = point.y * scale;\n return {\n x: x * cos - y * sin + (transform.translateX || 0),\n y: x * sin + y * cos + (transform.translateY || 0),\n };\n}\n\nexport function sceneBoundsFromBBox(\n bbox: BBox,\n transform?: LevelTransform | null,\n): SceneBounds {\n const corners = [\n { x: bbox.minX, y: bbox.minY },\n { x: bbox.maxX, y: bbox.minY },\n { x: bbox.minX, y: bbox.maxY },\n { x: bbox.maxX, y: bbox.maxY },\n ].map((point) => (transform ? applyLevelTransform(point, transform) : point));\n const minX = Math.min(\n corners[0].x,\n corners[1].x,\n corners[2].x,\n corners[3].x,\n );\n const minY = Math.min(\n corners[0].y,\n corners[1].y,\n corners[2].y,\n corners[3].y,\n );\n const maxX = Math.max(\n corners[0].x,\n corners[1].x,\n corners[2].x,\n corners[3].x,\n );\n const maxY = Math.max(\n corners[0].y,\n corners[1].y,\n corners[2].y,\n corners[3].y,\n );\n return {\n minX,\n minY,\n maxX,\n maxY,\n cx: (minX + maxX) / 2,\n cy: (minY + maxY) / 2,\n size: Math.max(maxX - minX, maxY - minY, 100),\n };\n}\n\nexport function expandBounds(target: SceneBounds, next: SceneBounds): SceneBounds {\n const minX = Math.min(target.minX, next.minX);\n const minY = Math.min(target.minY, next.minY);\n const maxX = Math.max(target.maxX, next.maxX);\n const maxY = Math.max(target.maxY, next.maxY);\n return {\n minX,\n minY,\n maxX,\n maxY,\n cx: (minX + maxX) / 2,\n cy: (minY + maxY) / 2,\n size: Math.max(maxX - minX, maxY - minY, 100),\n };\n}\n\nexport function boundsFromStackedLevels(\n levels: PublishedLevel[],\n activeLevelId: number | null,\n baseViewbox?: ViewBox | null,\n): SceneBounds {\n let bounds: SceneBounds | null = baseViewbox ? viewBoxToBounds(baseViewbox) : null;\n\n for (const level of viewerLevelStack(levels, activeLevelId)) {\n if (level.viewbox) {\n const vb = viewBoxToBounds(level.viewbox);\n bounds = bounds ? expandBounds(bounds, vb) : vb;\n }\n for (const shape of level.shapes) {\n const shapeBounds = sceneBoundsFromBBox(shape.bbox);\n bounds = bounds ? expandBounds(bounds, shapeBounds) : shapeBounds;\n }\n }\n\n return bounds ?? { minX: 0, minY: 0, maxX: 500, maxY: 500, cx: 250, cy: 250, size: 500 };\n}\n\nexport function unionViewBox(\n primary: ViewBox | null | undefined,\n secondary: ViewBox | null | undefined,\n): ViewBox {\n if (!primary && !secondary) return { x: 0, y: 0, width: 1000, height: 800 };\n if (!primary) return secondary!;\n if (!secondary) return primary;\n const minX = Math.min(primary.x, secondary.x);\n const minY = Math.min(primary.y, secondary.y);\n const maxX = Math.max(primary.x + primary.width, secondary.x + secondary.width);\n const maxY = Math.max(primary.y + primary.height, secondary.y + secondary.height);\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n"],"names":["TRANSPARENT_COLOR","isTransparentColor","value","text","WALKING_PATH_COLOR","STATIC_LAYER_KEYS","STATIC_LAYER_THEME_KEYS","STATIC_LAYER_STYLES","staticLayerHouseColor","key","style","staticLayerThemeDefaults","normalizeLayerName","label","namesMatchLayer","normalized","keyNorm","resolveStaticLayerKey","layerName","keys","a","b","applyLayerTheme","theme","field","override","resolveLayerStyle","svgIdsOwnedByShapes","shapes","options","omitStatic","ids","shape","id","outdoorSvgSuppressIds","levels","level","DEFAULT_THEME","LEGACY_V2_MAP_BACKGROUND","LEGACY_WALKABLE_COLORS","LEGACY_GREEN_AREA_COLOR","LEGACY_WATER_COLOR","LEGACY_STORE_DEFAULT_COLOR","MAX_STORE_RADIUS","clampStoreRadius","n","mergeTheme","partials","INTERACTIVE_SHAPE_KINDS","FLOOR_CHANGE_PENALTY","DEFAULT_WELD_TOLERANCE","ENTRANCE_ICON_ID","DEFAULT_ENTRANCE_SIZE","MIN_ENTRANCE_SIZE","isEntranceIcon","_a","clampEntranceSize","size","LABEL_ALIGNS","DEFAULT_LABEL_ALIGN","normalizeLabelAlign","labelAlignX","box","align","labelSvgTextAnchor","DEFAULT_ASSIGNMENT_SIZE","CONNECTOR_ICON_SIZE","RETAIL_LOGO_RENDER_SCALE","ASSIGNMENT_LAYER_TYPES","LAYER_TYPES","asNumber","fallback","INCOMPLETE_NUMBER","assignNumberFromDraft","raw","commitAssignNumberDraft","parsed","asNullableString","asNullableText","asNullableId","isAssignmentLayerType","defaultLayerTypeForKind","kind","defaultTargetTypeForKind","emptyShapeAssignment","shapeId","parseShapeAssignment","layerRaw","unitStatus","parseAssignmentAlign","retailerOptionLabel","retailer","duplicateName","location","resolvedAssignmentBgColor","assignment","storeColor","hex","resolvedAssignmentTextColor","textColor","parseKioskIdInput","amenityAssignedName","catalogName","catalog","labeled","kioskAssignedName","named","assignmentHasTarget","_b","ASSIGNMENT_OVERLAY_KINDS","publishedShapeLabel","assignmentVisualPatch","assignmentDisplayText","assignmentOverlayImageUrl","overlayImageKey","assignmentSpecialIconId","amenities","item","assignmentOverlayRenderSize","connectorIconLayout","assignmentOverlayVisible","sameValue","values","first","mixedColors","bulkAssignFormState","assignments","bgColors","row","textColors","applyBulkAssignPatch","patch","imageKey","mapSurface","host","FLOORS_ZOOM_CHROME","VIEWER_CHROME","viewerChrome","isMapViewerHost","resolveFetchUrl","url","imageProxyUrl","flipY","points","viewboxHeight","p","distance","dx","dy","bboxOf","minX","minY","maxX","maxY","i","bboxUnion","centroid","sx","sy","pointInPolygon","point","polygon","inside","j","xi","yi","xj","yj","pointInPolygons","polygons","poly","projectOntoSegment","lenSq","t","proj","nearestPointOnPolyline","polyline","best","approximateCubic","p0","p1","p2","p3","segments","out","u","approximateQuadratic","ARC_SEGMENTS_PER_QUADRANT","approximateArc","rx","ry","xAxisRotationDeg","largeArc","sweep","arx","ary","phi","cosPhi","sinPhi","dx2","dy2","x1p","y1p","lambda","scale","rxSq","rySq","numerator","denominator","factor","cxp","cyp","cx","cy","ux","uy","vx","vy","theta1","deltaTheta","ideal","theta","cosT","sinT","WHITESPACE_RE","tokenizePathData","d","tokens","cmd","argIndex","ch","arcSlot","start","digits","beforeExponent","pathToPolygons","current","x","y","startX","startY","lastCtrl","readNum","isRel","nx","ny","x1","y1","x2","y2","approx","rot","firstMoveTo","m","isGeometrySpaceStale","geometry","normalizeGeometrySpace","buildGeometryFromPaths","pathDs","paths","geometryBBox","all","geometryCentroid","snapAngle","from","to","baseDeg","increments","len","relative","bestDiff","step","snapped","diff","finalDeg","angleFromWall","parseViewBox","parts","CSS_TO_SVG_ATTR","parseCssDeclarations","block","declarations","declaration","sep","property","parseCssClassRules","cssText","classStyles","normalizedCss","match","selectors","s","selector","classMatch","className","mergeClassStyles","classAttr","merged","name","c","inlineSvgStyles","svgText","styleBlocks","withoutComments","decls","full","tag","attrs","selfClosing","cleanAttrs","nextAttrs","cssProp","svgAttr","readPresentationStyle","fill","stroke","strokeWidth","_c","opacity","_d","fillOpacity","_e","mergePresentationStyle","parent","child","IDENTITY_MATRIX","multiplyMatrix","outer","inner","applyMatrix","isIdentityMatrix","epsilon","translateMatrix","tx","ty","rotateMatrix","deg","rad","cos","sin","transformFunctionMatrix","args","TRANSFORM_FN_RE","parseTransform","result","next","fmt","rounded","transformArc","phiDeg","e11","e21","e12","e22","m11","m21","m12","m22","E","F","G","H","q","r","outRx","outRy","a1","outPhi","transformPathD","flipsOrientation","emit","letter","coords","px","py","rel","arc","FLOOR_PREFIXES","BASE_PREFIXES","isRoutePathLabel","normalizeLayerLabel","isRouteFolderLabel","IMPORT_PERSISTED_KINDS","IMPORT_DRIFT_THRESHOLD","classifyId","mode","isLayerContainerLabel","lower","table","prefix","isNonInteractiveGroupLabel","isInteractiveGroupLabel","isStoreFolderLabel","isContainerFrame","frame","attrValue","numAttr","hasDataInteractive","labelsFromAttrs","groupKindFromLabels","labels","pointsToPath","nums","lineToPath","geometryFromTag","w","h","parseSvgString","svg","stripped","viewboxMatch","viewbox","elements","routePathDs","warnings","stack","anon","inRouteContainer","parentStyle","inInteractive","parentMatrix","markNamedChild","findCollector","closeGroup","collected","emitRoute","open","tokenRe","closing","interactiveContainer","nonInteractiveContainer","storeFolder","parentInteractive","matrix","interactive","dataName","collector","slugKey","styleFromElement","el","sourceSvgId","layer","viewBoxesEqual","importSvg","classified","unrecognized","guessed","walkableCount","voidCount","unitCount","viewBoxChanged","isGuessed","entry","isStaticDecor","bbox","diffImport","imported","existing","driftThreshold","existingBySource","e","seen","items","prev","change","prevCx","prevCy","EPS","MIN_CORNER_TURN","EDGE_GAP","TWO_PI","almostSame","add","sub","pointOnCircle","center","radius","angle","uniqueClosedRing","ring","last","filletPolygon","inN","outN","outLen","turn","inD","outD","fillet","curr","incoming","outgoing","cross","dot","absTurn","wedge","tanHalf","desired","need","available","scaleDown","actualR","end","sign","a0","sweepCCW","sweepCW","midCCW","midCW","useCCW","steps","ang","compileGraph","anchors","edges","connectors","graph","createGraph","anchorById","connectorById","nodes","publishedEdges","weight","accessible","conn","pub","findPath","compiled","fromAnchorId","toAnchorId","path","fromNode","toNode","link","data","anchorIds","levelChanges","totalWeight","findNearestAmenityPath","amenityAnchorIds","targetId","compileDocument","input","assignmentByShape","retailerById","resolve","k","l","levelShapes","levelAnchors","normalizePublishedDocument","doc","changed","levelChanged","geometryChanged","labelChanged","SLAB_SHAPE_KINDS","isVoidKind","isSlabShapeKind","isActiveVoidShape","levelHasVoids","voidPolygonsOnLevel","polygonSignedArea","area","reversedRing","holeRingForOuter","hole","outerArea","holeArea","polygonBBox","polygonsOverlap","aa","bb","holesOverlappingOuter","holes","OPENING_VOID_FILL","OPENING_VOID_STROKE","OPENING_VOID_MARK","compareBuildingFloors","isOutdoorLevel","viewerLevelStack","activeLevelId","outdoor","active","revealedBuildingFloors","floors","floorSwitcherLevels","chain","nextLowerBuildingFloor","viewerLevelIdAfterShapeSelect","currentLevelId","clickedLevelId","clicked","defaultViewerLevelId","floorSwitcherDisplayLevels","shouldShowFloorSwitcher","hasBuildingFloors","MAP_NO_FLOORS_MESSAGE","viewBoxToBounds","applyLevelTransform","transform","sceneBoundsFromBBox","corners","expandBounds","target","boundsFromStackedLevels","baseViewbox","bounds","vb","shapeBounds","unionViewBox","primary","secondary"],"mappings":"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"}