becomap-v2 2.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +119 -0
- package/dist/becomap.umd.js +329 -0
- package/dist/becomap.umd.js.map +1 -0
- package/dist/index.d.ts +603 -0
- package/dist/index.js +6970 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/beco-map.ts","../src/events.ts","../src/options.ts","../src/render/venue-renderer.ts","../src/render/coords.ts","../src/render/geometry.ts","../src/render/labels.ts","../src/render/markers.ts","../src/render/models.ts","../src/render/polygon-theme.ts","../src/render/render-layer.ts","../src/render/route-ribbon.ts","../src/lod/floor-manager.ts","../src/ui/floor-switcher.ts","../src/interact/hit-test.ts","../src/search/index.ts","../src/routing/astar.ts","../src/routing/route-service.ts","../src/data/venue-model.ts","../src/routing/segments.ts","../src/routing/navigation.ts","../src/ui/route-bar.ts","../src/facades/index.ts","../src/data/mock-provider.ts","../src/data/gen/becomap-proto.js","../src/data/http.ts","../src/data/rest-provider.ts"],"sourcesContent":["import maplibregl from 'maplibre-gl';\r\nimport { Emitter, type BecoMapEvents, type Listener } from './events.js';\r\nimport { assertContainer, type BecoMapOptions } from './options.js';\r\nimport { VenueRenderer } from './render/venue-renderer.js';\r\nimport { resolvePolygonTheme, type PolygonThemeName } from './render/polygon-theme.js';\r\nimport type { FrameStats } from './render/render-layer.js';\r\nimport type { Venue } from './data/venue-model.js';\r\nimport { pointInRing, polygonCentroid, ringToMeters, toLngLat, createFrame } from './render/coords.js';\r\nimport { storeHeight } from './render/geometry.js';\r\nimport { FloorManager, type ViewChange } from './lod/floor-manager.js';\r\nimport { createFloorSwitcher, type FloorSwitcher } from './ui/floor-switcher.js';\r\nimport { resolveClick } from './interact/hit-test.js';\r\nimport { SearchIndex } from './search/index.js';\r\nimport { RouteService } from './routing/route-service.js';\r\nimport { buildRoute } from './routing/segments.js';\r\nimport { NavigationController } from './routing/navigation.js';\r\nimport { createRouteBar, type RouteBar } from './ui/route-bar.js';\r\nimport type { VenueLocation } from './data/types.js';\r\nimport {\r\n createCameraFacade,\r\n createFloorsFacade,\r\n createRoutingFacade,\r\n createSearchFacade,\r\n createVenueFacade,\r\n type CameraFacade,\r\n type FloorsFacade,\r\n type RoutingFacade,\r\n type SearchFacade,\r\n type VenueFacade,\r\n} from './facades/index.js';\r\n\r\n/**\r\n * The public handle returned by {@link createMap}. Everything a consumer can\r\n * do goes through this interface — the implementing class is internal.\r\n */\r\nexport interface BecoMap {\r\n /** Subscribe to an SDK event. Subscribing to `load` after the map has loaded fires immediately. */\r\n on<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void;\r\n /** Unsubscribe a listener previously passed to {@link BecoMap.on}. */\r\n off<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void;\r\n /** Tear down the map, its WebGL context, and all listeners. */\r\n destroy(): void;\r\n /** Debug: last frame's draw calls/triangles from the unified 3D layer. */\r\n getFrameStats(): FrameStats;\r\n /** The underlying MapLibre GL map, for advanced camera/interaction control. */\r\n getMapLibreMap(): maplibregl.Map;\r\n /**\r\n * Switch the store-polygon colour theme at runtime: `ivory` (the default\r\n * warm directory panels) or `data` (the venue's real editor / category\r\n * colours). `neutral` is a back-compat alias for `ivory`.\r\n */\r\n setPolygonTheme(theme: PolygonThemeName): void;\r\n /** Select a location programmatically (highlight + popup + `select` event). */\r\n selectLocation(locationId: string): void;\r\n /** Clear the current selection (no event; deselect event may come later). */\r\n clearSelection(): void;\r\n /** Venue data access (Phase 2). */\r\n readonly venue: VenueFacade;\r\n /** Floor selection and LOD views (Phase 4). */\r\n readonly floors: FloorsFacade;\r\n /** Location search (Phase 5). */\r\n readonly search: SearchFacade;\r\n /** Routing and navigation (Phase 6). */\r\n readonly routing: RoutingFacade;\r\n /** Camera helpers. */\r\n readonly camera: CameraFacade;\r\n}\r\n\r\n/** Inject the minimal \"name chip\" popup styling once (no box, no tail, no X). */\r\nfunction ensureChipStyle(): void {\r\n if (typeof document === 'undefined' || document.getElementById('bc-chip-style')) return;\r\n const s = document.createElement('style');\r\n s.id = 'bc-chip-style';\r\n const CHIP = '#1b1f2a';\r\n s.textContent =\r\n '.maplibregl-popup.bc-chip .maplibregl-popup-content{' +\r\n `background:${CHIP};color:#fff;padding:5px 12px;border-radius:8px;` +\r\n \"font:600 13px/1.2 system-ui,-apple-system,'Segoe UI',sans-serif;\" +\r\n 'box-shadow:0 4px 14px rgba(16,19,28,.32);white-space:nowrap;}' +\r\n '.maplibregl-popup.bc-chip .maplibregl-popup-close-button{display:none;}' +\r\n // colour the tail to match the chip, for whichever side it anchors from\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-bottom .maplibregl-popup-tip,` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip{border-top-color:${CHIP};}` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-top .maplibregl-popup-tip,` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-top-left .maplibregl-popup-tip,` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-top-right .maplibregl-popup-tip{border-bottom-color:${CHIP};}` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-left .maplibregl-popup-tip{border-right-color:${CHIP};}` +\r\n `.maplibregl-popup.bc-chip.maplibregl-popup-anchor-right .maplibregl-popup-tip{border-left-color:${CHIP};}`;\r\n document.head.appendChild(s);\r\n}\r\n\r\n/** Overlay card for floor-connection instructions (the reference look: dark\r\n * rounded card, bold title, arrow + connection glyph). App-restylable via\r\n * the bc-transition-* class names; injected once. */\r\nfunction ensureTransitionStyle(): void {\r\n if (typeof document === 'undefined' || document.getElementById('bc-transition-style')) return;\r\n const s = document.createElement('style');\r\n s.id = 'bc-transition-style';\r\n s.textContent =\r\n '.bc-transition-card{position:absolute;top:14%;left:50%;transform:translateX(-50%);' +\r\n 'z-index:30;background:rgba(8,8,10,.94);color:#fff;padding:22px 30px;border-radius:14px;' +\r\n \"font:700 20px/1.3 system-ui,-apple-system,'Segoe UI',sans-serif;text-align:center;\" +\r\n 'box-shadow:0 10px 34px rgba(0,0,0,.4);pointer-events:none;}' +\r\n '.bc-transition-icons{display:flex;gap:30px;justify-content:center;margin-top:16px;}' +\r\n '.bc-transition-icons svg{width:38px;height:38px;stroke:#fff;fill:none;' +\r\n 'stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;}';\r\n document.head.appendChild(s);\r\n}\r\n\r\nfunction transitionArrowSvg(direction: 'up' | 'down'): string {\r\n return direction === 'up'\r\n ? '<svg viewBox=\"0 0 24 24\"><path d=\"M12 20V5M6 11l6-6 6 6\"/></svg>'\r\n : '<svg viewBox=\"0 0 24 24\"><path d=\"M12 4v15M6 13l6 6 6-6\"/></svg>';\r\n}\r\n\r\nfunction transitionKindSvg(kind: string): string {\r\n const k = kind.toLowerCase();\r\n if (k.includes('elevator') || k.includes('lift')) {\r\n return '<svg viewBox=\"0 0 24 24\"><rect x=\"5\" y=\"4\" width=\"14\" height=\"17\" rx=\"1.5\"/><path d=\"M9.5 10l2.5-3 2.5 3M9.5 15l2.5 3 2.5-3\"/></svg>';\r\n }\r\n if (k.includes('stair')) {\r\n return '<svg viewBox=\"0 0 24 24\"><path d=\"M4 20h4v-4h4v-4h4V8h4\"/></svg>';\r\n }\r\n // escalator (default): diagonal rail with steps\r\n return '<svg viewBox=\"0 0 24 24\"><path d=\"M4 19h3l10-11h3M7 19l10-11M10 19l7.5-8.2\"/></svg>';\r\n}\r\n\r\n/** Internal implementation — instance-scoped state only, no singletons. */\r\nclass BecoMapImpl implements BecoMap {\r\n #map: maplibregl.Map;\r\n #emitter = new Emitter<BecoMapEvents>();\r\n #loaded = false;\r\n #abort = new AbortController();\r\n #container: HTMLElement;\r\n #uiFloorSwitcher: boolean;\r\n #polygonTheme: PolygonThemeName;\r\n\r\n readonly venue: ReturnType<typeof createVenueFacade>;\r\n readonly floors: FloorsFacade;\r\n readonly search = createSearchFacade({\r\n query: async (text) => (this.#searchIndex ? this.#searchIndex.query(text) : Promise.resolve([])),\r\n byCategory: (categoryId) => this.#searchIndex?.byCategory(categoryId) ?? [],\r\n });\r\n readonly routing = createRoutingFacade({\r\n route: (from, to, options) => this.#route(from, to, options),\r\n clear: () => {\r\n this.#clearRoute();\r\n },\r\n preview: () => {\r\n this.#nav?.preview();\r\n },\r\n next: () => {\r\n this.#nav?.next();\r\n },\r\n previous: () => {\r\n this.#nav?.previous();\r\n },\r\n stepInfo: () => this.#nav?.stepInfo() ?? null,\r\n active: () => this.#nav?.active ?? false,\r\n });\r\n readonly camera = createCameraFacade({\r\n focusVenue: (options) => {\r\n this.#venueRenderer?.focusVenue(options);\r\n },\r\n focusTo: (locationId) => {\r\n this.#focusTo(locationId);\r\n },\r\n });\r\n\r\n #venueRenderer: VenueRenderer | null = null;\r\n #floorManager: FloorManager | null = null;\r\n #floorSwitcher: FloorSwitcher | null = null;\r\n #venue: Venue | null = null;\r\n #searchIndex: SearchIndex | null = null;\r\n #selected: { location: VenueLocation; floorId: string; popup: maplibregl.Popup } | null = null;\r\n #popupFollow: (() => void) | null = null;\r\n #hoveredId: string | null = null;\r\n #suppressPopupClose = false;\r\n #routeService: RouteService | null = null;\r\n #nav: NavigationController | null = null;\r\n #startMarkerMove: (() => void) | null = null;\r\n #transitionCard: HTMLElement | null = null;\r\n #transitionTimer: ReturnType<typeof setTimeout> | null = null;\r\n #uiTransitionCard = true;\r\n #routeBar: RouteBar | null = null;\r\n #uiRouteBar = true;\r\n\r\n constructor(container: HTMLElement, options: BecoMapOptions) {\r\n this.#container = container;\r\n this.#uiFloorSwitcher = options.ui?.floorSwitcher !== false;\r\n this.#uiRouteBar = options.ui?.routeBar !== false;\r\n this.#uiTransitionCard = options.ui?.transitionCard !== false;\r\n this.#polygonTheme = options.polygonTheme ?? 'ivory';\r\n this.venue = createVenueFacade({\r\n ...(options.venue?.provider ? { provider: options.venue.provider } : {}),\r\n emitter: this.#emitter,\r\n signal: this.#abort.signal,\r\n onLoaded: (venue) => {\r\n this.#attachRenderer(venue);\r\n },\r\n });\r\n this.floors = createFloorsFacade({\r\n select: (floorId) => {\r\n this.#applyChanges(this.#floorManager?.selectFloor(floorId) ?? []);\r\n },\r\n focusedBuildingId: () => this.#floorManager?.focusedBuildingId() ?? null,\r\n viewOf: (buildingId) => this.#floorManager?.viewOf(buildingId),\r\n });\r\n this.#map = new maplibregl.Map({\r\n container,\r\n center: options.center ?? [0, 0],\r\n zoom: options.zoom ?? 15,\r\n pitch: options.pitch ?? 0,\r\n bearing: options.bearing ?? 0,\r\n antialias: true,\r\n attributionControl: false,\r\n // the original beCoMap basemap (same style v1 ships), instead of a flat\r\n // colour — streets/context render underneath the venue again.\r\n style: 'https://beco-lightning-backend.s3.ap-southeast-1.amazonaws.com/styles/style.json',\r\n });\r\n this.#map.on('load', () => {\r\n // dim the whole basemap slightly so the venue reads as the subject; the\r\n // custom 3D layer is added later and therefore stays above this veil.\r\n if (!this.#map.getLayer('bc-dim')) {\r\n this.#map.addLayer({\r\n id: 'bc-dim',\r\n type: 'background',\r\n paint: { 'background-color': '#000000', 'background-opacity': 0.08 },\r\n });\r\n }\r\n this.#loaded = true;\r\n this.#emitter.emit('load', undefined);\r\n });\r\n this.#map.on('error', (e) => {\r\n const cause: unknown = (e as { error?: unknown }).error;\r\n const message = cause instanceof Error ? cause.message : 'map error';\r\n this.#emitter.emit('error', { message, cause });\r\n });\r\n }\r\n\r\n on<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void {\r\n this.#emitter.on(event, listener);\r\n // Late subscribers to `load` still get the event (research Open Q3).\r\n if (event === 'load' && this.#loaded) {\r\n (listener as Listener<BecoMapEvents['load']>)(undefined);\r\n }\r\n }\r\n\r\n off<K extends keyof BecoMapEvents>(event: K, listener: Listener<BecoMapEvents[K]>): void {\r\n this.#emitter.off(event, listener);\r\n }\r\n\r\n destroy(): void {\r\n this.#abort.abort();\r\n this.#nav?.dispose();\r\n this.#nav = null;\r\n this.#routeBar?.dispose();\r\n this.#routeBar = null;\r\n this.#routeService?.dispose();\r\n this.#routeService = null;\r\n this.#floorSwitcher?.dispose();\r\n this.#floorSwitcher = null;\r\n this.#venueRenderer?.dispose();\r\n this.#venueRenderer = null;\r\n this.#map.remove();\r\n this.#emitter.removeAll();\r\n }\r\n\r\n getFrameStats(): FrameStats {\r\n return this.#venueRenderer?.getFrameStats() ?? { drawCalls: 0, triangles: 0 };\r\n }\r\n\r\n getMapLibreMap(): maplibregl.Map {\r\n return this.#map;\r\n }\r\n\r\n setPolygonTheme(theme: PolygonThemeName): void {\r\n this.#polygonTheme = theme;\r\n this.#venueRenderer?.setTheme(theme);\r\n // only meaningful when running on a flat-colour style; the basemap style\r\n // has no 'bg' layer, so the theme backdrop is a no-op there.\r\n if (this.#map.getLayer('bg')) {\r\n this.#map.setPaintProperty('bg', 'background-color', resolvePolygonTheme(theme).background);\r\n }\r\n }\r\n\r\n /** Attach the unified 3D layer, LOD manager, and floor switcher. */\r\n #attachRenderer(venue: Venue): void {\r\n this.#venueRenderer?.dispose();\r\n this.#venue = venue;\r\n const attach = (): void => {\r\n this.#venueRenderer = new VenueRenderer(this.#map, venue, this.#polygonTheme);\r\n this.#floorManager = new FloorManager(venue);\r\n this.#searchIndex = new SearchIndex(venue);\r\n this.#routeService = new RouteService(venue);\r\n if (this.#uiFloorSwitcher) {\r\n this.#floorSwitcher = createFloorSwitcher(this.#container, (floorId) => {\r\n this.floors.select(floorId);\r\n });\r\n }\r\n // initial views from the current zoom (typically all sealed)\r\n this.#applyChanges(this.#floorManager.update(this.#map.getZoom()));\r\n this.#refreshSwitcher();\r\n this.#venueRenderer.focusVenue();\r\n\r\n this.#map.on('zoom', () => {\r\n this.#applyChanges(this.#floorManager?.update(this.#map.getZoom()) ?? []);\r\n });\r\n this.#map.on('zoomend', () => {\r\n this.#applyChanges(this.#floorManager?.onZoomEnd(this.#map.getZoom()) ?? []);\r\n });\r\n this.#map.on('click', (e) => {\r\n this.#handleClick(e.point.x, e.point.y, e.lngLat.lng, e.lngLat.lat);\r\n });\r\n this.#map.on('mousemove', (e) => {\r\n this.#handleHover(e.point.x, e.point.y, e.lngLat.lng, e.lngLat.lat);\r\n });\r\n this.#map.getCanvas().addEventListener('mouseleave', () => {\r\n this.#hoveredId = null;\r\n this.#venueRenderer?.setHover(null);\r\n });\r\n };\r\n if (this.#loaded) attach();\r\n else this.#map.on('load', attach);\r\n }\r\n\r\n /** Fly to a location, opening its building/floor, and select it. */\r\n #focusTo(locationId: string): void {\r\n const location = this.#venue?.getLocation(locationId);\r\n if (!location?.floorId || !this.#venue) return;\r\n this.selectLocation(locationId);\r\n let anchor: [number, number] | null = null;\r\n if (location.nodeId) {\r\n const node = this.#venue.getNode(location.nodeId);\r\n if (node) anchor = [node.lng, node.lat];\r\n }\r\n if (!anchor && location.shapeId) {\r\n const geom = this.#venue.getShape(location.shapeId)?.geometry;\r\n const ring = geom?.type === 'Polygon' ? geom.coordinates[0] : undefined;\r\n if (ring && ring.length >= 3) {\r\n const frame = createFrame(this.#venue.center);\r\n const [cx, cy] = polygonCentroid(ringToMeters(frame, ring));\r\n anchor = toLngLat(frame, cx, cy);\r\n }\r\n }\r\n if (anchor) {\r\n this.#map.easeTo({ center: anchor, zoom: 18, pitch: 45, duration: 900 });\r\n }\r\n }\r\n\r\n /**\r\n * Resolve what's under a CSS-pixel point in TRUE 3D: cast the pick ray and\r\n * test every visible store's TOP face; the nearest hit wins. Falls back to\r\n * MapLibre's ground-plane lngLat — which also catches side-face clicks,\r\n * because a ray through a store's side exits through its footprint. Without\r\n * this, extruded stores were only clickable at their label (the ground\r\n * point at pitch lands BEHIND the extrusion).\r\n */\r\n #resolveAt(px: number, py: number, lng: number, lat: number): ReturnType<typeof resolveClick> {\r\n if (!this.#venue || !this.#floorManager) return { kind: 'outdoor' };\r\n const ground = resolveClick(this.#venue, (id) => this.#floorManager?.viewOf(id), lng, lat);\r\n const ray = this.#venueRenderer?.pickRay(px, py);\r\n if (!ray || Math.abs(ray.dir.z) < 1e-9) return ground;\r\n const theme = resolvePolygonTheme(this.#polygonTheme);\r\n const frame = createFrame(this.#venue.center);\r\n let best: { t: number; target: ReturnType<typeof resolveClick> } | null = null;\r\n for (const building of this.#venue.buildings) {\r\n const view = this.#floorManager.viewOf(building.id);\r\n if (!view?.open) continue;\r\n const floor = building.floors.find((f) => f.id === view.floorId);\r\n if (!floor) continue;\r\n const locByShape = new Map(\r\n floor.locations.filter((l) => l.shapeId && !l.hidden).map((l) => [l.shapeId, l]),\r\n );\r\n for (const shape of floor.shapes) {\r\n if (shape.geometry.type !== 'Polygon') continue;\r\n const location = locByShape.get(shape.id);\r\n if (!location) continue;\r\n const h = theme.panel?.uniformHeight ?? shape.style?.height ?? storeHeight(shape.id);\r\n if (h <= 0.2) continue; // flat zones: the ground pass already resolves them\r\n const topZ = 0.6 + h;\r\n const t = (topZ - ray.origin.z) / ray.dir.z;\r\n if (t <= 0) continue;\r\n const hx = ray.origin.x + ray.dir.x * t;\r\n const hy = ray.origin.y + ray.dir.y * t;\r\n const [hLng, hLat] = toLngLat(frame, hx, hy);\r\n const ring = shape.geometry.coordinates[0];\r\n if (ring && ring.length >= 3 && pointInRing(ring, hLng, hLat)) {\r\n if (!best || t < best.t) {\r\n best = {\r\n t,\r\n target: { kind: 'store', buildingId: building.id, floorId: floor.id, location, shape },\r\n };\r\n }\r\n }\r\n }\r\n }\r\n return best ? best.target : ground;\r\n }\r\n\r\n /** POC click rules: sealed→open+fly · store→select · corridor→focus · outdoor→clear. */\r\n #handleClick(px: number, py: number, lng: number, lat: number): void {\r\n if (!this.#venue || !this.#floorManager) return;\r\n const target = this.#resolveAt(px, py, lng, lat);\r\n switch (target.kind) {\r\n case 'sealed': {\r\n this.#applyChanges(this.#floorManager.clickOpen(target.buildingId));\r\n this.#refreshSwitcher();\r\n let cx = 0;\r\n let cy = 0;\r\n for (const p of target.ring) {\r\n cx += p[0];\r\n cy += p[1];\r\n }\r\n this.#map.flyTo({\r\n center: [cx / target.ring.length, cy / target.ring.length],\r\n zoom: 17,\r\n pitch: 55,\r\n duration: 1400,\r\n });\r\n break;\r\n }\r\n case 'store':\r\n if (this.#nav?.active) break; // ROUT-07: inert while navigating\r\n this.#select(target.location);\r\n this.#floorManager.focusBuilding(target.buildingId);\r\n this.#refreshSwitcher();\r\n break;\r\n case 'corridor':\r\n // focus without clearing the selection (POC rule)\r\n this.#floorManager.focusBuilding(target.buildingId);\r\n this.#refreshSwitcher();\r\n break;\r\n case 'outdoor':\r\n if (!this.#nav?.active) this.clearSelection();\r\n break;\r\n }\r\n }\r\n\r\n /** Hover: cursor + a light glaze over the store under the pointer. */\r\n #handleHover(px: number, py: number, lng: number, lat: number): void {\r\n if (!this.#venue || !this.#floorManager) return;\r\n const target = this.#resolveAt(px, py, lng, lat);\r\n this.#map.getCanvas().style.cursor =\r\n target.kind === 'sealed' || target.kind === 'store' ? 'pointer' : '';\r\n // the selected store already wears the selection glaze — no hover on top\r\n const hovered =\r\n target.kind === 'store' &&\r\n !this.#nav?.active &&\r\n target.location.id !== this.#selected?.location.id\r\n ? target.location\r\n : null;\r\n if ((hovered?.id ?? null) === this.#hoveredId) return;\r\n this.#hoveredId = hovered?.id ?? null;\r\n if (hovered?.shapeId) {\r\n const shape = this.#venue.getShape(hovered.shapeId);\r\n const ring = shape?.geometry.type === 'Polygon' ? shape.geometry.coordinates[0] : undefined;\r\n if (shape && ring && ring.length >= 3) {\r\n this.#venueRenderer?.setHover(ring, shape.style?.height ?? storeHeight(shape.id));\r\n return;\r\n }\r\n }\r\n this.#venueRenderer?.setHover(null);\r\n }\r\n\r\n selectLocation(locationId: string): void {\r\n const location = this.#venue?.getLocation(locationId);\r\n if (!location) return;\r\n if (location.floorId) {\r\n this.#applyChanges(this.#floorManager?.selectFloor(location.floorId) ?? []);\r\n }\r\n this.#select(location);\r\n this.#refreshSwitcher();\r\n }\r\n\r\n clearSelection(): void {\r\n this.#popupFollow?.();\r\n this.#popupFollow = null;\r\n if (!this.#selected) return;\r\n this.#selected.popup.remove();\r\n this.#selected = null;\r\n this.#venueRenderer?.setHighlight(null);\r\n }\r\n\r\n /** Select a location: highlight from its real polygon + popup + event. */\r\n #select(location: VenueLocation): void {\r\n if (!this.#venue || !location.floorId) return;\r\n this.clearSelection();\r\n const shape = location.shapeId ? this.#venue.getShape(location.shapeId) : undefined;\r\n let anchor: [number, number] | null = null;\r\n // the chip is pinned ABOVE the polygon: track the ROOF point (build-frame\r\n // meters + top height) and reproject it on every camera move, so the chip\r\n // stays fixed over the store instead of drifting to its ground shadow.\r\n let roof: { x: number; y: number; z: number } | null = null;\r\n if (shape && shape.geometry.type === 'Polygon') {\r\n const ring = shape.geometry.coordinates[0];\r\n if (ring && ring.length >= 3) {\r\n const height = shape.style?.height ?? storeHeight(shape.id);\r\n this.#venueRenderer?.setHighlight(ring, height);\r\n const frame = createFrame(this.#venue.center);\r\n const [cx, cy] = polygonCentroid(ringToMeters(frame, ring));\r\n anchor = toLngLat(frame, cx, cy);\r\n const theme = resolvePolygonTheme(this.#polygonTheme);\r\n const eff = theme.panel?.uniformHeight ?? height;\r\n roof = { x: cx, y: cy, z: 0.6 + Math.max(0.2, eff) + 0.1 };\r\n }\r\n }\r\n if (!anchor && location.nodeId) {\r\n const node = this.#venue.getNode(location.nodeId);\r\n if (node) anchor = [node.lng, node.lat];\r\n }\r\n if (!anchor) return;\r\n ensureChipStyle();\r\n const popup = new maplibregl.Popup({\r\n closeOnClick: false,\r\n closeButton: false,\r\n offset: 10,\r\n className: 'bc-chip',\r\n })\r\n .setLngLat(anchor)\r\n .setText(location.name)\r\n .addTo(this.#map);\r\n if (roof) {\r\n // 'render' fires AFTER the custom layer drew with the current camera, so\r\n // the projection matrix is fresh ('move' fires before and lags a frame).\r\n let lastX = NaN;\r\n let lastY = NaN;\r\n const follow = (): void => {\r\n const scr = this.#venueRenderer?.projectPoint(roof.x, roof.y, roof.z);\r\n if (!scr) return;\r\n if (Math.abs(scr.x - lastX) < 0.5 && Math.abs(scr.y - lastY) < 0.5) return;\r\n lastX = scr.x;\r\n lastY = scr.y;\r\n popup.setLngLat(this.#map.unproject([scr.x, scr.y]));\r\n };\r\n this.#map.on('render', follow);\r\n this.#popupFollow = () => {\r\n this.#map.off('render', follow);\r\n };\r\n this.#map.triggerRepaint(); // ensure a frame renders for initial placement\r\n }\r\n popup.on('close', () => {\r\n // user hit the X: clear the whole selection (programmatic hides are suppressed)\r\n if (!this.#suppressPopupClose && this.#selected?.popup === popup) {\r\n this.#popupFollow?.();\r\n this.#popupFollow = null;\r\n this.#selected = null;\r\n this.#venueRenderer?.setHighlight(null);\r\n }\r\n });\r\n this.#selected = { location, floorId: location.floorId, popup };\r\n this.#emitter.emit('select', { locationId: location.id });\r\n this.#refreshSelectionVisibility();\r\n }\r\n\r\n /** ROUT: compute, render, preview, and hand over to step navigation. */\r\n async #route(\r\n fromLocationId: string,\r\n toLocationId: string,\r\n options: { accessibleOnly?: boolean } = {},\r\n ): Promise<import('./facades/index.js').RouteInfo> {\r\n if (!this.#venue || !this.#routeService || !this.#venueRenderer || !this.#floorManager) {\r\n throw new Error('becomap: load a venue before routing');\r\n }\r\n const from = this.#venue.getLocation(fromLocationId);\r\n const to = this.#venue.getLocation(toLocationId);\r\n if (!from?.nodeId || !to?.nodeId) {\r\n throw new Error('becomap: both locations must exist and have graph nodes');\r\n }\r\n const result = await this.#routeService.findPath(from.nodeId, to.nodeId, options);\r\n if (!result) throw new Error('becomap: no route found');\r\n const built = buildRoute(this.#venue, result.path, {\r\n origin: from.name,\r\n destination: to.name,\r\n });\r\n if (!built) throw new Error('becomap: route could not be built');\r\n\r\n this.#clearRoute(false);\r\n const ribbon = this.#venueRenderer.routeRibbon();\r\n ribbon.setRoute(built.segments);\r\n // pre-build EVERY floor the route touches now, behind the camera glide —\r\n // later floor switches become pure visibility flips (no build, no texture\r\n // pop-in), which is what made mid-preview switching look glitchy.\r\n for (const seg of built.segments) {\r\n if (seg.buildingId) this.#venueRenderer.prepareFloor(seg.floorId);\r\n }\r\n ribbon.updateVisibility((floorId, buildingId) => {\r\n const view = buildingId ? this.#floorManager?.viewOf(buildingId) : undefined;\r\n return view?.open === true && view.floorId === floorId;\r\n });\r\n // start pin: v1's source artwork as a camera-billboarded quad inside the\r\n // 3D scene — constant on-screen size, but depth-tested against the venue.\r\n // The ribbon planted it in setRoute; here we feed it the map camera on\r\n // every move so it stays facing the viewer at a fixed pixel height.\r\n const startSeg = built.segments[0];\r\n const startPt2 = startSeg?.points[0];\r\n let startZ = 0.75; // just above the slab\r\n let startXY: [number, number] | null = null;\r\n if (startSeg && startPt2) {\r\n // if the start point sits inside an extruded store, stand the pin on\r\n // that store's rendered roof (a floor-level pin would be swallowed by\r\n // the store's own walls under depth testing)\r\n const startFloor = this.#venue.getFloor(startSeg.floorId);\r\n const theme = resolvePolygonTheme(this.#polygonTheme);\r\n for (const shape of startFloor?.shapes ?? []) {\r\n if (shape.geometry.type !== 'Polygon') continue;\r\n const ring = shape.geometry.coordinates[0];\r\n if (!ring || ring.length < 3 || !pointInRing(ring, startPt2[0], startPt2[1])) continue;\r\n const h = theme.panel?.uniformHeight ?? shape.style?.height ?? storeHeight(shape.id);\r\n startZ = Math.max(startZ, 0.6 + Math.max(0.2, h) + 0.05);\r\n }\r\n ribbon.setStartMarkerAltitude(startZ);\r\n const frame = createFrame(this.#venue.center);\r\n startXY = ringToMeters(frame, [startPt2])[0] ?? null;\r\n }\r\n const startLat = built.segments[0]?.points[0]?.[1] ?? 0;\r\n const cosLat = Math.cos((startLat * Math.PI) / 180);\r\n const applyStartView = (): void => {\r\n const bearing = this.#map.getBearing();\r\n const pitch = this.#map.getPitch();\r\n // metres-per-pixel MEASURED from the live projection: project two points\r\n // one metre apart along the pin's own tilted up-axis and invert the\r\n // pixel distance. Exact at any zoom/pitch/latitude — the analytic\r\n // zoom formula drifted noticeably from maplibre's actual camera.\r\n let mpp = (cosLat * 40075016.686) / (512 * Math.pow(2, this.#map.getZoom()));\r\n if (startXY) {\r\n const b = (bearing * Math.PI) / 180;\r\n const pr = (pitch * Math.PI) / 180;\r\n const dir = [Math.sin(b) * Math.cos(pr), Math.cos(b) * Math.cos(pr), Math.sin(pr)];\r\n const base = this.#venueRenderer?.projectPoint(startXY[0], startXY[1], startZ);\r\n const tip = this.#venueRenderer?.projectPoint(\r\n startXY[0] + (dir[0] ?? 0),\r\n startXY[1] + (dir[1] ?? 0),\r\n startZ + (dir[2] ?? 0),\r\n );\r\n if (base && tip) {\r\n const pxPerM = Math.hypot(tip.x - base.x, tip.y - base.y);\r\n if (pxPerM > 1e-3) mpp = 1 / pxPerM;\r\n }\r\n }\r\n ribbon.setStartMarkerView(bearing, pitch, mpp);\r\n };\r\n applyStartView();\r\n this.#startMarkerMove = applyStartView;\r\n this.#map.on('move', applyStartView);\r\n this.#map.on('render', applyStartView);\r\n if (this.#uiRouteBar) {\r\n this.#routeBar = createRouteBar(this.#container, {\r\n onPrev: () => {\r\n this.#nav?.previous();\r\n },\r\n onNext: () => {\r\n this.#nav?.next();\r\n },\r\n onClear: () => {\r\n this.#clearRoute();\r\n },\r\n });\r\n }\r\n this.#nav = new NavigationController({\r\n map: this.#map,\r\n ribbon,\r\n segments: built.segments,\r\n steps: built.steps,\r\n showFloor: (floorId) => {\r\n this.#applyChanges(this.#floorManager?.selectFloor(floorId) ?? []);\r\n },\r\n onStep: (info) => {\r\n this.#routeBar?.update(info);\r\n this.#emitter.emit('step', info);\r\n },\r\n onTransition: (t) => {\r\n this.#showTransitionCard(t);\r\n },\r\n repaint: () => {\r\n this.#venueRenderer?.repaint();\r\n },\r\n });\r\n this.#nav.start();\r\n // Stores keep full 3D height during navigation. The route stays visible\r\n // via the ribbon's ghost/x-ray pass (drawn through walls) — no flatten.\r\n this.#emitter.emit('routeChange', { routeId: `${fromLocationId}->${toLocationId}` });\r\n return { distanceMeters: Math.round(built.totalMeters), stepCount: built.steps.length };\r\n }\r\n\r\n /**\r\n * Floor-connection instruction: emits the structured `transition` event\r\n * (apps can render their own HTML from it) and, unless disabled via\r\n * `ui.transitionCard: false`, shows the built-in overlay card — plain DOM\r\n * with stable class names (`bc-transition-card`, `-title`, `-icons`) so the\r\n * app side can restyle it with CSS.\r\n */\r\n #showTransitionCard(t: { kind: string; toFloorId: string } | null): void {\r\n if (this.#transitionTimer) {\r\n clearTimeout(this.#transitionTimer);\r\n this.#transitionTimer = null;\r\n }\r\n this.#transitionCard?.remove();\r\n this.#transitionCard = null;\r\n if (!t) {\r\n this.#emitter.emit('transition', null);\r\n return;\r\n }\r\n const toFloor = this.#venue?.getFloor(t.toFloorId);\r\n const fromFloor = this.#selectedFloorLevelForTransition(t.toFloorId);\r\n const direction: 'up' | 'down' = (toFloor?.level ?? 0) >= fromFloor ? 'up' : 'down';\r\n const kindLabel = t.kind.charAt(0).toUpperCase() + t.kind.slice(1);\r\n const floorName = toFloor?.name ?? t.toFloorId;\r\n const label = `Take the ${kindLabel} to ${floorName}`;\r\n this.#emitter.emit('transition', {\r\n kind: t.kind,\r\n toFloorId: t.toFloorId,\r\n toFloorName: floorName,\r\n direction,\r\n label,\r\n });\r\n // pre-build the destination floor WHILE the card is up, so the switch\r\n // right after is a pure visibility flip instead of a build stutter\r\n this.#venueRenderer?.prepareFloor(t.toFloorId);\r\n if (!this.#uiTransitionCard) return;\r\n ensureTransitionStyle();\r\n const card = document.createElement('div');\r\n card.className = 'bc-transition-card';\r\n const arrow = transitionArrowSvg(direction);\r\n card.innerHTML =\r\n `<div class=\"bc-transition-title\"></div>` +\r\n `<div class=\"bc-transition-icons\">${arrow}${transitionKindSvg(t.kind)}${arrow}</div>`;\r\n const title = card.querySelector('.bc-transition-title');\r\n if (title) title.textContent = label; // textContent — names are venue data\r\n this.#container.appendChild(card);\r\n this.#transitionCard = card;\r\n this.#transitionTimer = setTimeout(() => {\r\n this.#showTransitionCard(null);\r\n }, 1600);\r\n }\r\n\r\n /** Level of the floor the runner is LEAVING (falls back below the target). */\r\n #selectedFloorLevelForTransition(toFloorId: string): number {\r\n const building = this.#venue?.getFloor(toFloorId)?.buildingId;\r\n const view = building ? this.#floorManager?.viewOf(building) : undefined;\r\n const current = view?.floorId ? this.#venue?.getFloor(view.floorId) : undefined;\r\n return current?.level ?? (this.#venue?.getFloor(toFloorId)?.level ?? 1) - 1;\r\n }\r\n\r\n #clearRoute(emit = true): void {\r\n const hadRoute = this.#nav !== null;\r\n this.#nav?.dispose();\r\n this.#nav = null;\r\n this.#routeBar?.dispose();\r\n this.#routeBar = null;\r\n this.#venueRenderer?.routeRibbon().clear();\r\n if (this.#startMarkerMove) {\r\n this.#map.off('move', this.#startMarkerMove);\r\n this.#map.off('render', this.#startMarkerMove);\r\n this.#startMarkerMove = null;\r\n }\r\n this.#venueRenderer?.repaint();\r\n if (emit && hadRoute) {\r\n this.#emitter.emit('step', null);\r\n this.#emitter.emit('routeChange', { routeId: null });\r\n }\r\n }\r\n\r\n /** INT-02: highlight/popup show only while the store's floor is visible. */\r\n #refreshSelectionVisibility(): void {\r\n if (!this.#selected || !this.#venue || !this.#floorManager) return;\r\n const floor = this.#venue.getFloor(this.#selected.floorId);\r\n const view = floor ? this.#floorManager.viewOf(floor.buildingId) : undefined;\r\n const visible = view?.open === true && view.floorId === this.#selected.floorId;\r\n this.#venueRenderer?.setHighlightVisible(visible);\r\n const popupOnMap = this.#selected.popup.isOpen();\r\n if (visible && !popupOnMap) this.#selected.popup.addTo(this.#map);\r\n if (!visible && popupOnMap) {\r\n // hide WITHOUT treating it as a user close\r\n this.#suppressPopupClose = true;\r\n this.#selected.popup.remove();\r\n this.#suppressPopupClose = false;\r\n }\r\n }\r\n\r\n #applyChanges(changes: ViewChange[]): void {\r\n if (!this.#venueRenderer || changes.length === 0) {\r\n if (changes.length > 0) return;\r\n this.#refreshSwitcher();\r\n return;\r\n }\r\n for (const change of changes) {\r\n this.#venueRenderer.applyView(change.buildingId, change.view);\r\n if (change.view.open) {\r\n this.#emitter.emit('floorChange', { floorId: change.view.floorId });\r\n }\r\n }\r\n this.#refreshSelectionVisibility();\r\n this.#refreshSwitcher();\r\n }\r\n\r\n #refreshSwitcher(): void {\r\n if (!this.#floorSwitcher || !this.#venue || !this.#floorManager) return;\r\n const focusedId = this.#floorManager.focusedBuildingId();\r\n const building = focusedId ? (this.#venue.getBuilding(focusedId) ?? null) : null;\r\n this.#floorSwitcher.update(building, focusedId ? this.#floorManager.viewOf(focusedId) : undefined);\r\n }\r\n}\r\n\r\n/**\r\n * Create a beCoMap instance inside the given container element.\r\n *\r\n * @example\r\n * ```ts\r\n * import { createMap } from 'becomap';\r\n * const map = createMap(document.getElementById('map')!, { zoom: 16 });\r\n * map.on('load', () => console.log('ready'));\r\n * ```\r\n */\r\nexport function createMap(container: HTMLElement, options: BecoMapOptions = {}): BecoMap {\r\n assertContainer(container);\r\n return new BecoMapImpl(container, options);\r\n}\r\n","import type { StepAction, StepDirection } from './routing/segments.js';\r\n\r\n/**\r\n * All events a {@link BecoMap} instance can emit, with their payload types.\r\n * Payload shapes are placeholders in the foundation phase and are refined as\r\n * features land (venue selection in Phase 5, routing in Phase 6).\r\n */\r\nexport interface BecoMapEvents {\r\n /** Fired once the underlying map has loaded and the SDK is ready. */\r\n load: undefined;\r\n /** Fired when a location is selected. */\r\n select: { locationId: string };\r\n /** Fired when the visible floor of a building changes. */\r\n floorChange: { floorId: string };\r\n /** Fired when the active route changes (null = route cleared). */\r\n routeChange: { routeId: string | null };\r\n /**\r\n * Fired when the route preview reaches a floor connection (null = card\r\n * should hide). Apps can consume this to render their OWN instruction UI —\r\n * the built-in card can be disabled via `ui.transitionCard: false`.\r\n */\r\n transition: {\r\n kind: string;\r\n toFloorId: string;\r\n toFloorName: string;\r\n direction: 'up' | 'down';\r\n label: string;\r\n } | null;\r\n /**\r\n * Fired whenever the active turn-by-turn step changes (null = route\r\n * cleared). Carries STRUCTURED data — `action`, `direction`, `distanceMeters`\r\n * — so apps can localise the instruction or render their own nav UI instead\r\n * of parsing `label`.\r\n */\r\n step: {\r\n index: number;\r\n total: number;\r\n label: string;\r\n action: StepAction;\r\n direction: StepDirection;\r\n distanceMeters: number;\r\n floorId: string;\r\n landmark: string | null;\r\n isFirst: boolean;\r\n isLast: boolean;\r\n } | null;\r\n /** Fired on recoverable SDK errors. */\r\n error: { message: string; cause?: unknown };\r\n}\r\n\r\n/** A listener for a single event's payload. */\r\nexport type Listener<T> = (payload: T) => void;\r\n\r\n/**\r\n * Instance-scoped typed event emitter. Deliberately tiny: no Node `events`,\r\n * no dependencies, and never a singleton — every {@link BecoMap} owns one.\r\n */\r\nexport class Emitter<TEvents extends object> {\r\n #listeners = new Map<keyof TEvents, Set<Listener<never>>>();\r\n\r\n on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): void {\r\n let set = this.#listeners.get(event);\r\n if (!set) {\r\n set = new Set();\r\n this.#listeners.set(event, set);\r\n }\r\n set.add(listener);\r\n }\r\n\r\n off<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): void {\r\n this.#listeners.get(event)?.delete(listener);\r\n }\r\n\r\n /** Internal — not exposed on the public BecoMap interface. */\r\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\r\n const set = this.#listeners.get(event);\r\n if (!set) return;\r\n for (const listener of [...set]) (listener as Listener<TEvents[K]>)(payload);\r\n }\r\n\r\n removeAll(): void {\r\n this.#listeners.clear();\r\n }\r\n}\r\n","import type { VenueProvider } from './data/provider.js';\r\nimport type { PolygonThemeName } from './render/polygon-theme.js';\r\n\r\n/** Options accepted by {@link createMap}. All fields are optional. */\r\nexport interface BecoMapOptions {\r\n /**\r\n * Store-polygon colour theme. `ivory` (default) is the warm directory-panel\r\n * look; `data` uses the venue's real editor / category colours. `neutral`\r\n * is a back-compat alias for `ivory`.\r\n */\r\n polygonTheme?: PolygonThemeName;\r\n /** Initial map center as [lng, lat]. Defaults to [0, 0] until venue data provides one. */\r\n center?: [number, number];\r\n /** Initial zoom level. Defaults to 15. */\r\n zoom?: number;\r\n /** Initial pitch in degrees. Defaults to 0. */\r\n pitch?: number;\r\n /** Initial bearing in degrees. Defaults to 0. */\r\n bearing?: number;\r\n /** Venue data source. Without it, `map.venue.load()` rejects. */\r\n venue?: {\r\n provider: VenueProvider;\r\n };\r\n /** Built-in UI controls. */\r\n ui?: {\r\n /** Floor switcher control (default true). */\r\n floorSwitcher?: boolean;\r\n /** Route navigation bar (default true). */\r\n routeBar?: boolean;\r\n /** Built-in floor-connection instruction card (default true). Disable to\r\n * render your own HTML from the `transition` event. */\r\n transitionCard?: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Validates the container argument early with a clear error, instead of\r\n * letting MapLibre fail obscurely later.\r\n */\r\nexport function assertContainer(container: unknown): asserts container is HTMLElement {\r\n if (typeof HTMLElement === 'undefined' || !(container instanceof HTMLElement)) {\r\n throw new TypeError('becomap: createMap(container, …) requires an HTMLElement container');\r\n }\r\n}\r\n","import * as THREE from 'three';\r\nimport maplibregl from 'maplibre-gl';\r\nimport type { Building, Floor } from '../data/types.js';\r\nimport type { Venue } from '../data/venue-model.js';\r\nimport type { BuildingView } from '../lod/floor-manager.js';\r\nimport { createFrame, polygonCentroid, ringToMeters, type VenueFrame } from './coords.js';\r\nimport { addOutlineWalls, buildFloorGeometry, hashId, polygonLabelAngle } from './geometry.js';\r\nimport {\r\n createFloorLabels,\r\n createSingleLabel,\r\n labelFlipState,\r\n type FloorLabels,\r\n type SingleLabel,\r\n} from './labels.js';\r\nimport { createAmenityMarkers, type AmenityMarkers } from './markers.js';\r\nimport { loadFloorModels } from './models.js';\r\nimport { resolvePolygonTheme, type PolygonTheme, type PolygonThemeName } from './polygon-theme.js';\r\nimport { RenderLayer, type FrameStats } from './render-layer.js';\r\nimport { RouteRibbon } from './route-ribbon.js';\r\n\r\ninterface FloorEntry {\r\n group: THREE.Group;\r\n labels: FloorLabels | null;\r\n markers: AmenityMarkers | null;\r\n built: boolean;\r\n}\r\n\r\ninterface ShellEntry {\r\n group: THREE.Group;\r\n label: SingleLabel | null;\r\n}\r\n\r\n/** Map-object GLBs (escalators, travelators). Toggle to hide them venue-wide. */\r\nconst SHOW_MAP_OBJECT_MODELS = true;\r\n\r\nconst SHELL_STOREY_M = 5;\r\nconst SHELL_ROOF_PALETTE = ['#c7d2e8', '#cfe0d8', '#e8d8cd', '#d8cfe8', '#e8e0c8'];\r\n// extrusion z-scale while navigating: 4m store → ~0.5m, clears the ~0.95m ribbon\r\nconst FLATTEN_SCALE = 0.13;\r\n\r\n/**\r\n * Owns the unified 3D scene for one venue: lazy per-floor geometry (built on\r\n * first show — LOD-04 groundwork), floor visibility, label readability flip,\r\n * and lifecycle. Instance-scoped; disposed with the map.\r\n */\r\nexport class VenueRenderer {\r\n #venue: Venue;\r\n #frame: VenueFrame;\r\n #map: maplibregl.Map;\r\n #layer: RenderLayer;\r\n #root = new THREE.Group();\r\n #floors = new Map<string, FloorEntry>();\r\n #shells = new Map<string, ShellEntry>();\r\n #capMat: THREE.MeshBasicMaterial;\r\n #shellWallMat: THREE.MeshLambertMaterial;\r\n #theme: PolygonTheme;\r\n #translucentMat = new THREE.MeshLambertMaterial({\r\n vertexColors: true,\r\n transparent: true,\r\n opacity: 0.7,\r\n side: THREE.DoubleSide,\r\n });\r\n #borderMat = new THREE.LineBasicMaterial({ color: '#5a5852' });\r\n // Selection: a translucent dark glaze over the store — the selected panel reads\r\n // as a darker shade of its own colour. Unlit + depthWrite:false + polygonOffset\r\n // so it never z-fights the panel (no flicker).\r\n #highlightMat = new THREE.MeshBasicMaterial({\r\n color: '#10131c',\r\n transparent: true,\r\n opacity: 0.34,\r\n side: THREE.DoubleSide,\r\n depthWrite: false,\r\n polygonOffset: true,\r\n polygonOffsetFactor: -2,\r\n polygonOffsetUnits: -2,\r\n });\r\n #highlight: THREE.Group | null = null;\r\n // Hover: a light glaze over the store under the pointer — subtler than the\r\n // selection glaze so the two read as different states.\r\n #hoverMat = new THREE.MeshBasicMaterial({\r\n color: '#ffffff',\r\n transparent: true,\r\n opacity: 0.24,\r\n side: THREE.DoubleSide,\r\n depthWrite: false,\r\n polygonOffset: true,\r\n polygonOffsetFactor: -1,\r\n polygonOffsetUnits: -1,\r\n });\r\n #hover: THREE.Group | null = null;\r\n #routeRibbon: RouteRibbon | null = null;\r\n #labelsFlipped = false;\r\n #onCameraMove: () => void;\r\n #onRotate: () => void;\r\n // navigation flatten: 3D extrusions collapse toward a floor-plan while a\r\n // route is active so nothing occludes the path (Mappedin-style wayfinding).\r\n #floorScaleZ = 1;\r\n #floorScaleTarget = 1;\r\n #flattenRaf = 0;\r\n\r\n constructor(map: maplibregl.Map, venue: Venue, theme?: PolygonThemeName) {\r\n this.#map = map;\r\n this.#venue = venue;\r\n this.#frame = createFrame(venue.center);\r\n this.#theme = resolvePolygonTheme(theme);\r\n // UNLIT (MeshBasic) so panel tops/walls render their exact colours — a clean\r\n // flat-shaded stylised look. Lit shading muddied the bright top to grey and\r\n // washed out the top-vs-wall contrast; the wall gradient is baked into the\r\n // vertex colours instead, so we get a bright panel in a dark frame.\r\n this.#capMat = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide });\r\n this.#shellWallMat = new THREE.MeshLambertMaterial({ color: '#f7f8fb', side: THREE.DoubleSide });\r\n\r\n this.#root.add(new THREE.HemisphereLight(0xffffff, 0xdde8dd, 1.15));\r\n const sun = new THREE.DirectionalLight(0xffffff, 0.8);\r\n sun.position.set(-300, -400, 600);\r\n this.#root.add(sun);\r\n this.#root.rotation.x = -Math.PI / 2; // z-up build frame → y-up map frame\r\n\r\n this.#layer = new RenderLayer(this.#root, venue.center);\r\n map.addLayer(this.#layer);\r\n\r\n // Labels are fixed to the map (rotate with it); only flip 180 degrees past\r\n // the upside-down threshold so they stay readable.\r\n this.#onRotate = () => {\r\n const flip = labelFlipState(this.#map.getBearing(), this.#labelsFlipped);\r\n if (flip === this.#labelsFlipped) return;\r\n this.#labelsFlipped = flip;\r\n for (const entry of this.#floors.values()) {\r\n entry.labels?.setFlip(flip);\r\n entry.markers?.setFlip(flip);\r\n }\r\n for (const shell of this.#shells.values()) shell.label?.setFlip(flip);\r\n this.#layer.repaint();\r\n };\r\n map.on('rotate', this.#onRotate);\r\n // floating connection pins billboard toward the viewer: they need the\r\n // camera on EVERY move (pitch counts too), not just past a flip threshold\r\n this.#onCameraMove = () => {\r\n const bearing = this.#map.getBearing();\r\n const pitch = this.#map.getPitch();\r\n for (const entry of this.#floors.values()) entry.markers?.setCameraView(bearing, pitch);\r\n };\r\n map.on('move', this.#onCameraMove);\r\n this.#labelsFlipped = labelFlipState(map.getBearing(), false);\r\n }\r\n\r\n /**\r\n * Highlight a store by its real polygon outline: extruded outline walls +\r\n * cap, teal, one reusable slot. Pass null to clear.\r\n */\r\n setHighlight(outlineLngLat: [number, number][] | null, storeHeightM = 4): void {\r\n if (this.#highlight) {\r\n this.#root.remove(this.#highlight);\r\n this.#highlight.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) (obj.geometry as THREE.BufferGeometry).dispose();\r\n });\r\n this.#highlight = null;\r\n }\r\n if (outlineLngLat) {\r\n const outline = ringToMeters(this.#frame, outlineLngLat);\r\n const group = new THREE.Group();\r\n const buf = { pos: [], nrm: [], uv: [], idx: [] } as {\r\n pos: number[];\r\n nrm: number[];\r\n uv: number[];\r\n idx: number[];\r\n };\r\n // hug the top so the glaze covers the whole panel — under a uniform-height\r\n // theme the data height is ignored, so the overlay must ignore it too\r\n const hEff = this.#theme.panel?.uniformHeight ?? storeHeightM;\r\n const z1 = 0.6 + hEff + 0.05;\r\n addOutlineWalls(buf, outline, 0.55, z1);\r\n const walls = new THREE.BufferGeometry();\r\n walls.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buf.pos), 3));\r\n walls.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buf.nrm), 3));\r\n walls.setIndex(buf.idx);\r\n group.add(new THREE.Mesh(walls, this.#highlightMat));\r\n const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));\r\n const cap = new THREE.ShapeGeometry(shape);\r\n cap.translate(0, 0, z1);\r\n group.add(new THREE.Mesh(cap, this.#highlightMat));\r\n this.#root.add(group);\r\n this.#highlight = group;\r\n }\r\n this.#layer.repaint();\r\n }\r\n\r\n /** Hover glaze over a store's real outline; null clears. Same construction\r\n * as the selection highlight, separate slot + subtler material. */\r\n setHover(outlineLngLat: [number, number][] | null, storeHeightM = 4): void {\r\n if (this.#hover) {\r\n this.#root.remove(this.#hover);\r\n this.#hover.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) (obj.geometry as THREE.BufferGeometry).dispose();\r\n });\r\n this.#hover = null;\r\n }\r\n if (outlineLngLat) {\r\n const outline = ringToMeters(this.#frame, outlineLngLat);\r\n const group = new THREE.Group();\r\n const buf = { pos: [], nrm: [], uv: [], idx: [] } as {\r\n pos: number[];\r\n nrm: number[];\r\n uv: number[];\r\n idx: number[];\r\n };\r\n const hEff = this.#theme.panel?.uniformHeight ?? storeHeightM;\r\n const z1 = 0.6 + hEff + 0.05;\r\n addOutlineWalls(buf, outline, 0.55, z1);\r\n const walls = new THREE.BufferGeometry();\r\n walls.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buf.pos), 3));\r\n walls.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buf.nrm), 3));\r\n walls.setIndex(buf.idx);\r\n group.add(new THREE.Mesh(walls, this.#hoverMat));\r\n const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));\r\n const cap = new THREE.ShapeGeometry(shape);\r\n cap.translate(0, 0, z1);\r\n group.add(new THREE.Mesh(cap, this.#hoverMat));\r\n this.#root.add(group);\r\n this.#hover = group;\r\n }\r\n this.#layer.repaint();\r\n }\r\n\r\n setHighlightVisible(visible: boolean): void {\r\n if (this.#highlight) {\r\n this.#highlight.visible = visible;\r\n this.#layer.repaint();\r\n }\r\n }\r\n\r\n /** Route ribbon lives in the same scene (correct occlusion, lazy init). */\r\n routeRibbon(): RouteRibbon {\r\n this.#routeRibbon ??= new RouteRibbon(this.#root, this.#frame, () => {\r\n this.#layer.repaint();\r\n });\r\n return this.#routeRibbon;\r\n }\r\n\r\n repaint(): void {\r\n this.#layer.repaint();\r\n }\r\n\r\n /**\r\n * Collapse floor extrusions toward a flat plan (flat=true) while navigating,\r\n * so tall stores can't occlude the low route ribbon; restore full 3D on\r\n * clear. Smoothly tweened.\r\n */\r\n setFlattened(flat: boolean): void {\r\n this.#floorScaleTarget = flat ? FLATTEN_SCALE : 1;\r\n if (this.#flattenRaf) return; // tween already running\r\n const tick = (): void => {\r\n const diff = this.#floorScaleTarget - this.#floorScaleZ;\r\n this.#floorScaleZ += diff * 0.18;\r\n if (Math.abs(diff) < 0.005) this.#floorScaleZ = this.#floorScaleTarget;\r\n for (const entry of this.#floors.values()) entry.group.scale.z = this.#floorScaleZ;\r\n this.#layer.repaint();\r\n if (this.#floorScaleZ !== this.#floorScaleTarget) {\r\n this.#flattenRaf = requestAnimationFrame(tick);\r\n } else {\r\n this.#flattenRaf = 0;\r\n }\r\n };\r\n this.#flattenRaf = requestAnimationFrame(tick);\r\n }\r\n\r\n #refreshRouteVisibility(): void {\r\n this.#routeRibbon?.updateVisibility(\r\n (floorId) => this.#floors.get(floorId)?.group.visible ?? false,\r\n );\r\n }\r\n\r\n /**\r\n * Apply an LOD view: sealed → shell visible, all floors hidden;\r\n * open → shell hidden, exactly the selected floor visible (built lazily).\r\n */\r\n applyView(buildingId: string, view: BuildingView): void {\r\n const building = this.#venue.getBuilding(buildingId);\r\n if (!building) return;\r\n const shell = this.#ensureShell(building);\r\n if (shell) shell.group.visible = !view.open;\r\n for (const floor of building.floors) {\r\n if (view.open && floor.id === view.floorId) {\r\n this.showFloor(floor.id);\r\n } else {\r\n this.hideFloor(floor.id);\r\n }\r\n }\r\n this.#refreshRouteVisibility();\r\n this.#layer.repaint();\r\n }\r\n\r\n /**\r\n * Pre-build a floor's geometry WITHOUT showing it — warms the cache so a\r\n * later showFloor is an instant visibility flip. Used while the floor-change\r\n * card is up, so the switch that follows never stutters.\r\n */\r\n prepareFloor(floorId: string): void {\r\n const wasVisible = this.#floors.get(floorId)?.group.visible ?? false;\r\n const entry = this.#ensureFloor(floorId);\r\n if (entry && !wasVisible) entry.group.visible = false;\r\n }\r\n\r\n /** Build (once) and show a floor. */\r\n showFloor(floorId: string): void {\r\n const entry = this.#ensureFloor(floorId);\r\n if (entry) entry.group.visible = true;\r\n this.#layer.repaint();\r\n }\r\n\r\n hideFloor(floorId: string): void {\r\n const entry = this.#floors.get(floorId);\r\n if (entry) entry.group.visible = false;\r\n this.#layer.repaint();\r\n }\r\n\r\n visibleFloorIds(): string[] {\r\n return [...this.#floors.entries()].filter(([, e]) => e.group.visible).map(([id]) => id);\r\n }\r\n\r\n /**\r\n * Switch the polygon colour theme. Colours are baked into geometry, so built\r\n * floors are disposed and the visible ones rebuilt under the new theme.\r\n */\r\n setTheme(name: PolygonThemeName): void {\r\n const theme = resolvePolygonTheme(name);\r\n if (theme.name === this.#theme.name) return;\r\n this.#theme = theme;\r\n const visible = this.visibleFloorIds();\r\n for (const [id, entry] of [...this.#floors.entries()]) {\r\n entry.labels?.dispose();\r\n entry.markers?.dispose();\r\n entry.group.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) (obj.geometry as THREE.BufferGeometry).dispose();\r\n });\r\n this.#root.remove(entry.group);\r\n this.#floors.delete(id);\r\n }\r\n for (const id of visible) this.showFloor(id);\r\n this.#refreshRouteVisibility();\r\n this.#layer.repaint();\r\n }\r\n\r\n /** True once a floor's geometry has been built (lazy-loading observability). */\r\n isFloorBuilt(floorId: string): boolean {\r\n return this.#floors.get(floorId)?.built ?? false;\r\n }\r\n\r\n /** Screen position of a build-frame point (see RenderLayer.projectPoint). */\r\n projectPoint(x: number, y: number, z: number): { x: number; y: number } | null {\r\n return this.#layer.projectPoint(x, y, z);\r\n }\r\n\r\n /** Build-frame pick ray for a CSS-pixel point (see RenderLayer.pickRay). */\r\n pickRay(px: number, py: number): { origin: THREE.Vector3; dir: THREE.Vector3 } | null {\r\n return this.#layer.pickRay(px, py);\r\n }\r\n\r\n getFrameStats(): FrameStats {\r\n return this.#layer.getFrameStats();\r\n }\r\n\r\n /** Fit the camera to the venue's building extents. */\r\n focusVenue(options: { pitch?: number; duration?: number } = {}): void {\r\n const bounds = new maplibregl.LngLatBounds();\r\n let any = false;\r\n for (const building of this.#venue.buildings) {\r\n for (const floor of building.floors) {\r\n for (const shape of floor.shapes) {\r\n if (shape.geometry.type !== 'Polygon') continue;\r\n for (const pos of shape.geometry.coordinates[0] ?? []) {\r\n bounds.extend(pos);\r\n any = true;\r\n }\r\n }\r\n }\r\n }\r\n if (!any) return;\r\n this.#map.fitBounds(bounds, {\r\n padding: 60,\r\n pitch: options.pitch ?? 45,\r\n duration: options.duration ?? 800,\r\n });\r\n }\r\n\r\n dispose(): void {\r\n cancelAnimationFrame(this.#flattenRaf);\r\n this.#map.off('rotate', this.#onRotate);\r\n this.#map.off('move', this.#onCameraMove);\r\n for (const entry of this.#floors.values()) {\r\n entry.labels?.dispose();\r\n entry.markers?.dispose();\r\n entry.group.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) (obj.geometry as THREE.BufferGeometry).dispose();\r\n });\r\n }\r\n for (const shell of this.#shells.values()) {\r\n shell.label?.dispose();\r\n shell.group.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) (obj.geometry as THREE.BufferGeometry).dispose();\r\n });\r\n }\r\n this.#routeRibbon?.dispose();\r\n if (this.#map.getLayer(this.#layer.id)) this.#map.removeLayer(this.#layer.id);\r\n this.#capMat.dispose();\r\n this.#shellWallMat.dispose();\r\n this.#translucentMat.dispose();\r\n this.#borderMat.dispose();\r\n this.#highlightMat.dispose();\r\n this.#hoverMat.dispose();\r\n }\r\n\r\n /** Sealed-building shell: plain walls + hash-colored roof + name label. */\r\n #ensureShell(building: Building): ShellEntry | undefined {\r\n let shell = this.#shells.get(building.id);\r\n if (shell) return shell;\r\n const ground = building.floors[0];\r\n const footprint = ground?.shapes.find(\r\n (s) => (s.layerId === 'footprint' || s.type.toUpperCase() === 'WALL') && s.geometry.type === 'Polygon',\r\n );\r\n const ring = footprint?.geometry.type === 'Polygon' ? footprint.geometry.coordinates[0] : undefined;\r\n if (!ring || ring.length < 3) return undefined;\r\n const outline = ringToMeters(this.#frame, ring);\r\n const height = building.floors.length * SHELL_STOREY_M + 2;\r\n\r\n const group = new THREE.Group();\r\n const buf = { pos: [], nrm: [], uv: [], idx: [] } as {\r\n pos: number[];\r\n nrm: number[];\r\n uv: number[];\r\n idx: number[];\r\n };\r\n addOutlineWalls(buf, outline, 0, height);\r\n const walls = new THREE.BufferGeometry();\r\n walls.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buf.pos), 3));\r\n walls.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buf.nrm), 3));\r\n walls.setIndex(buf.idx);\r\n group.add(new THREE.Mesh(walls, this.#shellWallMat));\r\n\r\n const roofColor = new THREE.Color(\r\n SHELL_ROOF_PALETTE[hashId(building.id) % SHELL_ROOF_PALETTE.length],\r\n );\r\n const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));\r\n const roof = new THREE.ShapeGeometry(shape);\r\n const count = roof.attributes.position?.count ?? 0;\r\n const colors = new Float32Array(count * 3);\r\n for (let i = 0; i < count; i++) {\r\n colors[i * 3] = roofColor.r;\r\n colors[i * 3 + 1] = roofColor.g;\r\n colors[i * 3 + 2] = roofColor.b;\r\n }\r\n roof.setAttribute('color', new THREE.BufferAttribute(colors, 3));\r\n roof.translate(0, 0, height);\r\n group.add(new THREE.Mesh(roof, this.#capMat));\r\n\r\n const [cx, cy] = polygonCentroid(outline);\r\n const label = createSingleLabel(\r\n {\r\n text: building.name,\r\n x: cx,\r\n y: cy,\r\n z: height + 0.4,\r\n fontSize: 15,\r\n baseRotation: polygonLabelAngle(outline), // aligned to the building itself\r\n color: this.#theme.labelColor,\r\n },\r\n () => {\r\n this.#layer.repaint();\r\n },\r\n );\r\n label.setFlip(this.#labelsFlipped);\r\n group.add(label.object);\r\n\r\n group.visible = false;\r\n this.#root.add(group);\r\n shell = { group, label };\r\n this.#shells.set(building.id, shell);\r\n return shell;\r\n }\r\n\r\n #ensureFloor(floorId: string): FloorEntry | undefined {\r\n let entry = this.#floors.get(floorId);\r\n if (entry?.built) return entry;\r\n const floor = this.#venue.getFloor(floorId);\r\n if (!floor) return undefined;\r\n entry = { group: new THREE.Group(), labels: null, markers: null, built: false };\r\n this.#buildFloor(entry, floor);\r\n entry.built = true;\r\n entry.group.scale.z = this.#floorScaleZ; // adopt current flatten state\r\n this.#floors.set(floorId, entry);\r\n this.#root.add(entry.group);\r\n return entry;\r\n }\r\n\r\n #buildFloor(entry: FloorEntry, floor: Floor): void {\r\n const geo = buildFloorGeometry(this.#frame, floor, this.#theme);\r\n if (geo.solid) entry.group.add(new THREE.Mesh(geo.solid, this.#capMat));\r\n if (geo.translucent) entry.group.add(new THREE.Mesh(geo.translucent, this.#translucentMat));\r\n // Polygon outlines removed — the white-model look reads cleaner without them.\r\n if (geo.labelSpecs.length) {\r\n entry.labels = createFloorLabels(geo.labelSpecs, this.#theme.labelColor, () => {\r\n this.#layer.repaint();\r\n });\r\n entry.labels.setFlip(this.#labelsFlipped);\r\n entry.group.add(entry.labels.object);\r\n }\r\n // amenity markers — badges with the venue's real category/amenity icons\r\n entry.markers = createAmenityMarkers(this.#frame, floor, this.#venue.iconset, () => {\r\n this.#layer.repaint();\r\n });\r\n if (entry.markers) {\r\n entry.markers.setFlip(this.#labelsFlipped);\r\n entry.markers.setCameraView(this.#map.getBearing(), this.#map.getPitch());\r\n entry.group.add(entry.markers.object);\r\n }\r\n // GLB map objects (instanced per model URL), loaded async — never blocks.\r\n void loadFloorModels(this.#frame, this.#venue, floor.id).then((models) => {\r\n if (models) {\r\n models.visible = SHOW_MAP_OBJECT_MODELS;\r\n entry.group.add(models);\r\n this.#layer.repaint();\r\n }\r\n });\r\n }\r\n}\r\n","import type { LngLat } from '../data/types.js';\n\n/**\n * Venue-local coordinate frame: meters east/north of the venue center.\n * Geometry is built in this frame (z-up) and the render layer maps it into\n * MapLibre's mercator space each frame.\n */\nexport interface VenueFrame {\n center: LngLat;\n metersPerDegLat: number;\n metersPerDegLng: number;\n}\n\nconst M_PER_DEG_LAT = 111_320;\n\nexport function createFrame(center: LngLat): VenueFrame {\n return {\n center,\n metersPerDegLat: M_PER_DEG_LAT,\n metersPerDegLng: M_PER_DEG_LAT * Math.cos((center[1] * Math.PI) / 180),\n };\n}\n\n/** [lng, lat] → venue-local meters [xEast, yNorth]. */\nexport function toMeters(frame: VenueFrame, lngLat: LngLat): [number, number] {\n return [\n (lngLat[0] - frame.center[0]) * frame.metersPerDegLng,\n (lngLat[1] - frame.center[1]) * frame.metersPerDegLat,\n ];\n}\n\n/** Venue-local meters → [lng, lat]. */\nexport function toLngLat(frame: VenueFrame, x: number, y: number): LngLat {\n return [frame.center[0] + x / frame.metersPerDegLng, frame.center[1] + y / frame.metersPerDegLat];\n}\n\n/** Ring of [lng,lat] positions → local meters, dropping a closing duplicate. */\nexport function ringToMeters(frame: VenueFrame, ring: LngLat[]): [number, number][] {\n const pts = ring.map((p) => toMeters(frame, p));\n const first = pts[0];\n const last = pts[pts.length - 1];\n if (pts.length > 1 && first && last && Math.hypot(first[0] - last[0], first[1] - last[1]) < 0.01) {\n pts.pop();\n }\n return pts;\n}\n\n/** Area centroid (shoelace) — keeps labels inside irregular outlines. */\nexport function polygonCentroid(pts: [number, number][]): [number, number] {\n let a = 0;\n let cx = 0;\n let cy = 0;\n for (let i = 0; i < pts.length; i++) {\n const p0 = pts[i];\n const p1 = pts[(i + 1) % pts.length];\n if (!p0 || !p1) continue;\n const cross = p0[0] * p1[1] - p1[0] * p0[1];\n a += cross;\n cx += (p0[0] + p1[0]) * cross;\n cy += (p0[1] + p1[1]) * cross;\n }\n if (Math.abs(a) < 1e-9) return pts[0] ?? [0, 0];\n a *= 0.5;\n return [cx / (6 * a), cy / (6 * a)];\n}\n\n/** Point-in-ring test directly on [lng, lat] positions (raycast). */\nexport function pointInRing(ring: LngLat[], lng: number, lat: number): boolean {\n let inside = false;\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n const pi = ring[i];\n const pj = ring[j];\n if (!pi || !pj) continue;\n const [xi, yi] = pi;\n const [xj, yj] = pj;\n if (yi > lat !== yj > lat && lng < ((xj - xi) * (lat - yi)) / (yj - yi) + xi) inside = !inside;\n }\n return inside;\n}\n\n/** Absolute polygon area in m² (local meters ring). */\nexport function polygonArea(pts: [number, number][]): number {\n let a = 0;\n for (let i = 0; i < pts.length; i++) {\n const p0 = pts[i];\n const p1 = pts[(i + 1) % pts.length];\n if (!p0 || !p1) continue;\n a += p0[0] * p1[1] - p1[0] * p0[1];\n }\n return Math.abs(a / 2);\n}\n","import * as THREE from 'three';\r\nimport { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';\r\nimport type { Floor, Shape, VenueLocation } from '../data/types.js';\r\nimport { polygonCentroid, ringToMeters, toMeters, type VenueFrame } from './coords.js';\r\nimport type { PolygonTheme } from './polygon-theme.js';\r\n\r\n/** Theme constants (a venue style config in a later milestone). */\r\nexport const SLAB_HEIGHT = 0.6;\r\nexport const STORE_HEIGHT_MIN = 3.2;\r\nexport const STORE_HEIGHT_RANGE = 1.8;\r\nexport const WINDOW_SPACING_M = 3.6;\r\n\r\nconst FALLBACK_PALETTE = ['#93b7d4', '#f2a65e', '#f7d488', '#e8968a', '#9ccfc3'];\r\nconst SLAB_TOP = new THREE.Color('#aab3d0');\r\n\r\n/** Deterministic per-id hash for stable pseudo-random heights/colors. */\r\nexport function hashId(id: string): number {\r\n let h = 2166136261;\r\n for (let i = 0; i < id.length; i++) {\r\n h ^= id.charCodeAt(i);\r\n h = Math.imul(h, 16777619);\r\n }\r\n return h >>> 0;\r\n}\r\n\r\nexport function storeHeight(id: string): number {\r\n return STORE_HEIGHT_MIN + (hashId(id) % 1000) * (STORE_HEIGHT_RANGE / 1000);\r\n}\r\n\r\nexport function roofColorFor(location: VenueLocation | undefined, shapeId: string): THREE.Color {\r\n const hex = location?.categories[0]?.colorHex;\r\n if (hex) return new THREE.Color(hex);\r\n return new THREE.Color(FALLBACK_PALETTE[hashId(shapeId) % FALLBACK_PALETTE.length]);\r\n}\r\n\r\ninterface WallBuffers {\r\n pos: number[];\r\n nrm: number[];\r\n uv: number[];\r\n idx: number[];\r\n}\r\n\r\n/**\r\n * Walls along an arbitrary polygon outline: one quad per segment, with u\r\n * accumulating by real length so the facade tiles continuously around\r\n * corners and curves (POC-validated technique).\r\n */\r\nexport function addOutlineWalls(\r\n buf: WallBuffers,\r\n outline: [number, number][],\r\n z0: number,\r\n z1: number,\r\n): void {\r\n let u = 0;\r\n for (let i = 0; i < outline.length; i++) {\r\n const p0 = outline[i];\r\n const p1 = outline[(i + 1) % outline.length];\r\n if (!p0 || !p1) continue;\r\n const len = Math.hypot(p1[0] - p0[0], p1[1] - p0[1]);\r\n if (len < 0.05) continue;\r\n const nx = (p1[1] - p0[1]) / len;\r\n const ny = -(p1[0] - p0[0]) / len;\r\n const base = buf.pos.length / 3;\r\n buf.pos.push(p0[0], p0[1], z0, p1[0], p1[1], z0, p1[0], p1[1], z1, p0[0], p0[1], z1);\r\n buf.nrm.push(nx, ny, 0, nx, ny, 0, nx, ny, 0, nx, ny, 0);\r\n const u1 = u + len / WINDOW_SPACING_M;\r\n buf.uv.push(u, 0, u1, 0, u1, 1, u, 1);\r\n buf.idx.push(base, base + 1, base + 2, base, base + 2, base + 3);\r\n u = u1;\r\n }\r\n}\r\n\r\nfunction wallBuffersToGeometry(buf: WallBuffers): THREE.BufferGeometry {\r\n const geo = new THREE.BufferGeometry();\r\n geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buf.pos), 3));\r\n geo.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buf.nrm), 3));\r\n geo.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(buf.uv), 2));\r\n geo.setIndex(buf.idx);\r\n return geo;\r\n}\r\n\r\nexport interface FloorGeometry {\r\n /** Everything vertex-colored & opaque (base caps/skirts, walls, roofs) — ONE draw call. */\r\n solid: THREE.BufferGeometry | null;\r\n /** Vertex-colored translucent shapes (editor opacity < 0.95) — ONE draw call. */\r\n translucent: THREE.BufferGeometry | null;\r\n /** Dark outline segments around every polygon roof — ONE draw call (LineSegments). */\r\n borders: THREE.BufferGeometry | null;\r\n /** Per-shape label anchor data for the label builder. */\r\n labelSpecs: LabelSpec[];\r\n}\r\n\r\nexport interface LabelSpec {\r\n text: string;\r\n x: number;\r\n y: number;\r\n z: number;\r\n fontSize: number;\r\n /** Base yaw (radians) aligning the text to the polygon's dominant edge. */\r\n baseRotation: number;\r\n locationId: string;\r\n /** Brand logo (PNG url from the venue data) drawn instead of the name. */\r\n logoUrl?: string;\r\n /** Box (m) the logo may fill, row-sampled so it stays INSIDE the polygon. */\r\n logoBoxW?: number;\r\n logoBoxH?: number;\r\n}\r\n\r\nexport type ShapeRole = 'base' | 'boundary' | 'partition' | 'unit';\r\n\r\n/**\r\n * What a shape IS, derived from editor type + geometry + authored height:\r\n * - WALL (Polygon outline) → 'boundary': flat floor plate (fillColor) +\r\n * perimeter wall band (color, height)\r\n * - INNER_WALL (LineString) → 'partition': centerline buffered into a\r\n * wall band (v1 buffers by ~0.8m)\r\n * - POLYGON height ≤ 0.2 → 'base': flat fill zone\r\n * - POLYGON → 'unit': extruded store\r\n */\r\nexport function shapeRole(shape: Shape): ShapeRole {\r\n if (shape.layerId === 'footprint') return 'base'; // mock convention\r\n const t = shape.type.toUpperCase();\r\n if (t === 'WALL') return 'boundary';\r\n if (t === 'INNER_WALL' || shape.geometry.type === 'LineString') return 'partition';\r\n // Editor data (style present): ONLY an explicit height > 0.2 extrudes —\r\n // missing height renders flat, exactly like v1's ['get','height'] → 0.\r\n // Mock shapes (no style) keep the legacy hashed heights.\r\n if (shape.style) {\r\n const h = shape.style.height;\r\n return h !== undefined && h > 0.2 ? 'unit' : 'base';\r\n }\r\n return 'unit';\r\n}\r\n\r\n/** Editor-authored extrusion height, with sensible per-role defaults. */\r\nexport function shapeHeight(shape: Shape, role: ShapeRole): number {\r\n const h = shape.style?.height;\r\n if (role === 'boundary' || role === 'partition') return h !== undefined && h > 0 ? h : 3;\r\n if (role === 'unit') return h ?? storeHeight(shape.id); // hash only for style-less mock shapes\r\n return 0;\r\n}\r\n\r\n/**\r\n * Top/fill color for POLYGON shapes. The editor stores the polygon fill in\r\n * `color` (NOT fillColor — that's the WALL floor plate); fall back to the\r\n * linked location's category color, then the palette.\r\n */\r\nexport function polygonTopColor(shape: Shape, location: VenueLocation | undefined): THREE.Color {\r\n if (shape.style?.color) return new THREE.Color(shape.style.color);\r\n if (shape.style?.fillColor) return new THREE.Color(shape.style.fillColor);\r\n return roofColorFor(location, shape.id);\r\n}\r\n\r\n/** v1 buffers wall centerlines by 0.0005 miles ≈ 0.8m (band ≈ 1.6m wide). */\r\nexport const WALL_BAND_HALF_WIDTH_M = 0.8;\r\n\r\n/**\r\n * A wall band along a polyline: one thin oriented box per segment (sides +\r\n * top), vertex-colored. Corners overlap slightly — same visual result as\r\n * v1's turf.buffer at these widths, without the dependency.\r\n */\r\nexport function lineBandGeometries(\r\n points: [number, number][],\r\n closed: boolean,\r\n z0: number,\r\n z1: number,\r\n half: number,\r\n color: THREE.Color,\r\n): THREE.BufferGeometry[] {\r\n const out: THREE.BufferGeometry[] = [];\r\n const count = closed ? points.length : points.length - 1;\r\n for (let i = 0; i < count; i++) {\r\n const a = points[i];\r\n const b = points[(i + 1) % points.length];\r\n if (!a || !b) continue;\r\n const dx = b[0] - a[0];\r\n const dy = b[1] - a[1];\r\n const len = Math.hypot(dx, dy);\r\n if (len < 0.05) continue;\r\n const nx = (-dy / len) * half;\r\n const ny = (dx / len) * half;\r\n // slightly extend segment ends so corners meet\r\n const ex = (dx / len) * half;\r\n const ey = (dy / len) * half;\r\n const ring: [number, number][] = [\r\n [a[0] - ex + nx, a[1] - ey + ny],\r\n [b[0] + ex + nx, b[1] + ey + ny],\r\n [b[0] + ex - nx, b[1] + ey - ny],\r\n [a[0] - ex - nx, a[1] - ey - ny],\r\n ];\r\n out.push(coloredSides([ring], z0, z1, color));\r\n out.push(capWithHoles([ring], z1, color));\r\n }\r\n return out;\r\n}\r\n\r\nconst DEFAULT_WALL_SIDE = new THREE.Color('#e7e6e1');\r\n\r\nconst LABEL_MIN_SIZE = 0.4;\r\nconst LABEL_MAX_SIZE = 2.6;\r\nconst CHAR_ADVANCE = 0.62; // troika bold advance width per char, in em\r\n\r\n/** Soft contact tone under each slab so it sits on the floor instead of floating. */\r\nconst CONTACT_SHADOW = new THREE.Color('#d9dadd');\r\nconst CONTACT_SHADOW_SPREAD_M = 0.35;\r\nconst WIDTH_FILL = 0.72; // full name should span ~72% of the store's length\r\nconst HEIGHT_FILL = 0.4; // one line of text should be ~40% of the store's thickness\r\n\r\n/**\r\n * Chord of `ring` through the point (px, py) along direction `angle`: the\r\n * distance between the two ring crossings that bracket the point. This is the\r\n * ACTUAL room a centred label has at its anchor — a bounding box lies about it\r\n * for L-shaped, diagonal, or off-centre shapes, which is exactly how long\r\n * names end up poking outside their polygons. Returns null if the point isn't\r\n * bracketed (e.g. a centroid outside a concave ring).\r\n */\r\nfunction chordSpan(\r\n ring: [number, number][],\r\n px: number,\r\n py: number,\r\n angle: number,\r\n): [number, number] | null {\r\n const dx = Math.cos(angle);\r\n const dy = Math.sin(angle);\r\n const ts: number[] = [];\r\n for (let i = 0; i < ring.length; i++) {\r\n const a = ring[i];\r\n const b = ring[(i + 1) % ring.length];\r\n if (!a || !b) continue;\r\n const ex = b[0] - a[0];\r\n const ey = b[1] - a[1];\r\n const det = ex * dy - ey * dx;\r\n if (Math.abs(det) < 1e-9) continue; // parallel\r\n const u = (dx * (a[1] - py) - dy * (a[0] - px)) / det;\r\n if (u < 0 || u > 1) continue;\r\n const t = Math.abs(dx) > Math.abs(dy) ? (a[0] + u * ex - px) / dx : (a[1] + u * ey - py) / dy;\r\n ts.push(t);\r\n }\r\n if (ts.length < 2) return null;\r\n ts.sort((p, q) => p - q);\r\n for (let i = 0; i < ts.length - 1; i++) {\r\n const t0 = ts[i];\r\n const t1 = ts[i + 1];\r\n if (t0 !== undefined && t1 !== undefined && t0 <= 0 && t1 >= 0) return [t0, t1];\r\n }\r\n return null;\r\n}\r\n\r\nfunction chordThrough(ring: [number, number][], px: number, py: number, angle: number): number | null {\r\n const span = chordSpan(ring, px, py, angle);\r\n return span ? span[1] - span[0] : null;\r\n}\r\n\r\n/**\r\n * SYMMETRIC room around the anchor: twice the distance to the NEARER edge.\r\n * A box centred on the anchor fits inside the shape only within this span —\r\n * the full chord lies about it whenever the anchor sits off-centre, which is\r\n * exactly how a centred logo pokes past the near edge of a big store.\r\n */\r\nfunction chordAround(ring: [number, number][], px: number, py: number, angle: number): number | null {\r\n const span = chordSpan(ring, px, py, angle);\r\n return span ? 2 * Math.min(-span[0], span[1]) : null;\r\n}\r\n\r\n/** Font growth per metre of the polygon's length — sizes come from the SHAPE. */\r\nconst ALONG_FILL = 0.14;\r\n\r\n/** Space index splitting `text` into two most-balanced lines, or -1. */\r\nfunction bestSplit(text: string): number {\r\n let best = -1;\r\n let bestDiff = Infinity;\r\n for (let i = 0; i < text.length; i++) {\r\n if (text[i] !== ' ') continue;\r\n const diff = Math.abs(i - (text.length - 1 - i));\r\n if (diff < bestDiff) {\r\n bestDiff = diff;\r\n best = i;\r\n }\r\n }\r\n return best;\r\n}\r\n\r\ninterface LabelFitResult {\r\n text: string;\r\n fontSize: number;\r\n rotation: number;\r\n /** The chords actually measured at the anchor — logo sizing uses these. */\r\n alongM: number;\r\n acrossM: number;\r\n}\r\n\r\n/** Fit `name` inside `ring` with text running at `angle`. Size comes from the\r\n * polygon (chords at the anchor); wrap + last-resort shrink keep it inside,\r\n * and wrapped labels re-measure the shape at each line's own row so tapering\r\n * polygons can't push a line outside. */\r\nfunction fitAtAngle(\r\n ring: [number, number][],\r\n name: string,\r\n cx: number,\r\n cy: number,\r\n angle: number,\r\n): LabelFitResult {\r\n const cos = Math.cos(-angle);\r\n const sin = Math.sin(-angle);\r\n let minU = Infinity;\r\n let maxU = -Infinity;\r\n let minV = Infinity;\r\n let maxV = -Infinity;\r\n for (const p of ring) {\r\n const u = p[0] * cos - p[1] * sin;\r\n const v = p[0] * sin + p[1] * cos;\r\n if (u < minU) minU = u;\r\n if (u > maxU) maxU = u;\r\n if (v < minV) minV = v;\r\n if (v > maxV) maxV = v;\r\n }\r\n const along = chordThrough(ring, cx, cy, angle) ?? maxU - minU;\r\n const across = chordThrough(ring, cx, cy, angle + Math.PI / 2) ?? maxV - minV;\r\n // the font size IS the polygon size, clamped to the legible band\r\n const fontSize = Math.max(\r\n LABEL_MIN_SIZE,\r\n Math.min(LABEL_MAX_SIZE, along * ALONG_FILL, across * HEIGHT_FILL),\r\n );\r\n if (name.length * CHAR_ADVANCE * fontSize <= along * WIDTH_FILL) {\r\n return { text: name, fontSize, rotation: angle, alongM: along, acrossM: across };\r\n }\r\n // One line overflows at the ceiling. Two candidates compete:\r\n // a) ONE line, shrunk just enough to fill the polygon's width\r\n // b) TWO balanced lines at up to the ceiling (row-sampled for tapers)\r\n // Wrap ONLY when it earns meaningfully bigger text — two cramped lines in a\r\n // wide strip read worse than one slightly smaller line that fills it.\r\n const oneLine = Math.max(\r\n LABEL_MIN_SIZE,\r\n Math.min(fontSize, (along * WIDTH_FILL) / (name.length * CHAR_ADVANCE)),\r\n );\r\n const split = bestSplit(name);\r\n if (split > 0) {\r\n const l1 = name.slice(0, split);\r\n const l2 = name.slice(split + 1);\r\n const maxChars = Math.max(1, l1.length, l2.length);\r\n const heightCap = (across * HEIGHT_FILL) / 2; // two lines need twice the room\r\n let twoLine = Math.max(\r\n LABEL_MIN_SIZE,\r\n Math.min(fontSize, (along * WIDTH_FILL) / (maxChars * CHAR_ADVANCE), heightCap),\r\n );\r\n // each line sits OFF the centroid, where a tapering shape may be narrower —\r\n // measure the chord at both line rows and refit against the tightest one\r\n const px = -Math.sin(angle);\r\n const py = Math.cos(angle);\r\n const off = 0.66 * twoLine; // line centres at ±~0.6 line heights\r\n const rowA = chordThrough(ring, cx + px * off, cy + py * off, angle) ?? along;\r\n const rowB = chordThrough(ring, cx - px * off, cy - py * off, angle) ?? along;\r\n const rowMin = Math.min(along, rowA, rowB);\r\n twoLine = Math.max(\r\n LABEL_MIN_SIZE,\r\n Math.min(twoLine, (rowMin * WIDTH_FILL) / (maxChars * CHAR_ADVANCE)),\r\n );\r\n if (twoLine > oneLine * 1.15) {\r\n return {\r\n text: `${l1}\r\n${l2}`,\r\n fontSize: twoLine,\r\n rotation: angle,\r\n alongM: along,\r\n acrossM: across,\r\n };\r\n }\r\n }\r\n // one line wins (or nothing to wrap): fill the width at the size that fits\r\n return { text: name, fontSize: oneLine, rotation: angle, alongM: along, acrossM: across };\r\n}\r\n\r\n/** A level-axis label at or above this size is kept without trying the other axis. */\r\nconst HORIZONTAL_OK = 0.85;\r\n\r\n/** Normalise an angle to (-PI/2, PI/2] so text never starts upside-down. */\r\nfunction normalizeTextAngle(a: number): number {\r\n while (a > Math.PI / 2) a -= Math.PI;\r\n while (a <= -Math.PI / 2) a += Math.PI;\r\n return a;\r\n}\r\n\r\n/**\r\n * Orientation is STRAIGHT BASED ON THE POLYGON: a label may only run along one\r\n * of its own store's two axes (the dominant-edge direction or its\r\n * perpendicular) — never any angle that isn't the store's own. Horizontal-\r\n * first between those two: prefer the axis closer to level, and use the\r\n * store's cross axis only when the text can't fit legibly the level way.\r\n * Labels are fixed to the venue and rotate with the map.\r\n */\r\nfunction labelFit(ring: [number, number][], text: string, cx: number, cy: number): LabelFitResult {\r\n const name = text.trim();\r\n const axisA = polygonLabelAngle(ring); // dominant edge, already in (-PI/2, PI/2]\r\n const axisB = normalizeTextAngle(axisA + Math.PI / 2); // the store's other axis\r\n // the store's \"horizontal\": whichever of its own axes is closer to level\r\n const levelAxis = Math.abs(axisA) <= Math.abs(axisB) ? axisA : axisB;\r\n const crossAxis = levelAxis === axisA ? axisB : axisA;\r\n const level = fitAtAngle(ring, name, cx, cy, levelAxis);\r\n if (level.fontSize >= HORIZONTAL_OK) return level;\r\n const cross = fitAtAngle(ring, name, cx, cy, crossAxis);\r\n return cross.fontSize > level.fontSize * 1.15 ? cross : level;\r\n}\r\n\r\n/** Fraction of the store's room a logo may fill. */\r\nconst LOGO_ALONG_FILL = 0.65;\r\nconst LOGO_ACROSS_FILL = 0.5;\r\n\r\n/**\r\n * The box a logo may occupy, centred at the anchor along the label axis. The\r\n * centroid chord alone is not enough: a concave store (notches, L-shapes) can\r\n * be wide at the centroid line yet much narrower at the logo's upper and lower\r\n * rows — so the box is row-sampled across its own height and shrunk until\r\n * every row genuinely fits inside the polygon.\r\n */\r\nfunction logoFitBox(\r\n ring: [number, number][],\r\n cx: number,\r\n cy: number,\r\n angle: number,\r\n alongM: number,\r\n acrossM: number,\r\n): { logoBoxW: number; logoBoxH: number } {\r\n // symmetric room around the anchor — a centred box must not cross the NEAR edge\r\n const cAlong = chordAround(ring, cx, cy, angle);\r\n const cAcross = chordAround(ring, cx, cy, angle + Math.PI / 2);\r\n let availW = LOGO_ALONG_FILL * (cAlong ?? alongM * 0.5);\r\n let availH = LOGO_ACROSS_FILL * (cAcross ?? acrossM * 0.5);\r\n const px = -Math.sin(angle);\r\n const py = Math.cos(angle);\r\n for (let i = 0; i < 3; i++) {\r\n const off = 0.45 * availH;\r\n const rowA = chordAround(ring, cx + px * off, cy + py * off, angle);\r\n const rowB = chordAround(ring, cx - px * off, cy - py * off, angle);\r\n if (rowA === null || rowB === null) {\r\n // a row falls outside the polygon (notch / concavity) — pull the box in\r\n availH *= 0.6;\r\n continue;\r\n }\r\n availW = Math.min(availW, LOGO_ALONG_FILL * Math.min(rowA, rowB));\r\n break;\r\n }\r\n return { logoBoxW: availW, logoBoxH: availH };\r\n}\r\n\r\n/**\r\n * Orientation (radians) of a polygon's dominant (longest) edge, normalised to\r\n * [-PI/2, PI/2] so text starts upright. Aligns the label to the polygon's own\r\n * edges — computed purely from geometry, no external rotation value — so it\r\n * reads parallel to the store instead of the world axes.\r\n */\r\nexport function polygonLabelAngle(ring: [number, number][]): number {\r\n let maxDistSq = 0;\r\n let angle = 0;\r\n for (let i = 0; i < ring.length - 1; i++) {\r\n const a = ring[i];\r\n const b = ring[i + 1];\r\n if (!a || !b) continue;\r\n const dx = b[0] - a[0];\r\n const dy = b[1] - a[1];\r\n const distSq = dx * dx + dy * dy;\r\n if (distSq > maxDistSq) {\r\n maxDistSq = distSq;\r\n angle = Math.atan2(dy, dx);\r\n }\r\n }\r\n while (angle <= -Math.PI / 2) angle += Math.PI;\r\n while (angle > Math.PI / 2) angle -= Math.PI;\r\n return angle;\r\n}\r\n\r\n/** All rings of a Polygon shape in local meters (outer + holes), with faceted\r\n * curves smoothed while sharp corners are preserved. */\r\nfunction shapeRings(frame: VenueFrame, shape: Shape): [number, number][][] {\r\n if (shape.geometry.type !== 'Polygon') return [];\r\n return shape.geometry.coordinates\r\n .map((ring) => smoothRing(ringToMeters(frame, ring)))\r\n .filter((r) => r.length >= 3);\r\n}\r\n\r\n/** Flat cap honoring holes, vertex-colored, with the uv attribute kept for merging. */\r\nfunction capWithHoles(rings: [number, number][][], z: number, color: THREE.Color): THREE.BufferGeometry {\r\n const outer = rings[0] ?? [];\r\n const shape = new THREE.Shape(outer.map(([x, y]) => new THREE.Vector2(x, y)));\r\n for (const hole of rings.slice(1)) {\r\n shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));\r\n }\r\n const geo = new THREE.ShapeGeometry(shape);\r\n const count = geo.attributes.position?.count ?? 0;\r\n const colors = new Float32Array(count * 3);\r\n for (let i = 0; i < count; i++) {\r\n colors[i * 3] = color.r;\r\n colors[i * 3 + 1] = color.g;\r\n colors[i * 3 + 2] = color.b;\r\n }\r\n geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));\r\n geo.translate(0, 0, z);\r\n return geo;\r\n}\r\n\r\n/**\r\n * Fake directional light for vertical faces, BAKED into the vertex colours.\r\n * The scene renders unlit (MeshBasicMaterial keeps bright colours true), but\r\n * uniformly-coloured extrusions read as flat paper — the reference maps look\r\n * \"solid\" because every side face catches a different amount of light. N·L\r\n * against a fixed sun direction gives each face a stable tone at zero runtime\r\n * cost; caps stay at full colour, exactly like a lit scene under a high sun.\r\n */\r\nconst SUN_X = -0.55; // sun from the north-west, matching the abuzz venues\r\nconst SUN_Y = 0.835;\r\n// Keep the shading SUBTLE: on curved outlines the per-face N·L snaps between\r\n// facets, and anything stronger than a few percent reads as a dirty patch on\r\n// the side of the panel (seen on the live venue) rather than as lighting.\r\nconst SIDE_AMBIENT = 0.9; // faces away from the sun keep 90% of their colour\r\nconst SIDE_DIFFUSE = 0.1;\r\nfunction sideShade(nx: number, ny: number): number {\r\n return SIDE_AMBIENT + SIDE_DIFFUSE * Math.max(0, nx * SUN_X + ny * SUN_Y);\r\n}\r\n\r\n/** Extruded side walls for all rings, vertex-colored (for the solid bucket). */\r\nfunction coloredSides(\r\n rings: [number, number][][],\r\n z0: number,\r\n z1: number,\r\n color: THREE.Color,\r\n): THREE.BufferGeometry {\r\n const buf: WallBuffers = { pos: [], nrm: [], uv: [], idx: [] };\r\n for (const ring of rings) addOutlineWalls(buf, ring, z0, z1);\r\n const geo = wallBuffersToGeometry(buf);\r\n const count = geo.attributes.position?.count ?? 0;\r\n const nrm = geo.attributes.normal;\r\n const colors = new Float32Array(count * 3);\r\n for (let i = 0; i < count; i++) {\r\n const s = nrm ? sideShade(nrm.getX(i), nrm.getY(i)) : 1;\r\n colors[i * 3] = color.r * s;\r\n colors[i * 3 + 1] = color.g * s;\r\n colors[i * 3 + 2] = color.b * s;\r\n }\r\n geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));\r\n return geo;\r\n}\r\n\r\n/**\r\n * Extruded side walls, vertex-coloured with a vertical gradient: `topColor` at\r\n * the roof line fading to the darker `baseColor` at the floor. This fakes\r\n * ambient occlusion at the base so a unit reads as a solid matte block — the\r\n * modern indoor-map look (Mappedin / Visioglobe), replacing the window facade.\r\n */\r\nfunction gradientSides(\r\n rings: [number, number][][],\r\n z0: number,\r\n z1: number,\r\n topColor: THREE.Color,\r\n baseColor: THREE.Color,\r\n): THREE.BufferGeometry {\r\n const buf: WallBuffers = { pos: [], nrm: [], uv: [], idx: [] };\r\n for (const ring of rings) addOutlineWalls(buf, ring, z0, z1);\r\n const geo = wallBuffersToGeometry(buf);\r\n const count = geo.attributes.position?.count ?? 0;\r\n const colors = new Float32Array(count * 3);\r\n const nrm = geo.attributes.normal;\r\n // addOutlineWalls emits each quad as [p0@z0, p1@z0, p1@z1, p0@z1]: within\r\n // every group of four vertices the first two sit at the base, the last two\r\n // at the top — so the gradient runs cleanly from baseColor up to topColor.\r\n // The same baked sun as coloredSides keeps every vertical face consistent.\r\n for (let i = 0; i < count; i++) {\r\n const c = i % 4 >= 2 ? topColor : baseColor;\r\n const s = nrm ? sideShade(nrm.getX(i), nrm.getY(i)) : 1;\r\n colors[i * 3] = c.r * s;\r\n colors[i * 3 + 1] = c.g * s;\r\n colors[i * 3 + 2] = c.b * s;\r\n }\r\n geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));\r\n return geo;\r\n}\r\n\r\n/** Signed area (shoelace) of a ring — positive is CCW in the build frame. */\r\nfunction ringArea(ring: [number, number][]): number {\r\n let a = 0;\r\n for (let i = 0; i < ring.length; i++) {\r\n const p = ring[i];\r\n const q = ring[(i + 1) % ring.length];\r\n if (p && q) a += p[0] * q[1] - q[0] * p[1];\r\n }\r\n return a / 2;\r\n}\r\n\r\n/** Perimeter of a ring (metres). */\r\nfunction ringPerimeter(ring: [number, number][]): number {\r\n let p = 0;\r\n for (let i = 0; i < ring.length; i++) {\r\n const a = ring[i];\r\n const b = ring[(i + 1) % ring.length];\r\n if (a && b) p += Math.hypot(b[0] - a[0], b[1] - a[1]);\r\n }\r\n return p;\r\n}\r\n\r\n/**\r\n * Average \"thickness\" of a polygon (2·area / perimeter). A wide store is a few\r\n * metres; a divider/rail strip is well under a metre. Below this we treat the\r\n * shape as a thin strip and render it flat rather than extruding a tall bar.\r\n */\r\nconst THIN_STRIP_M = 1.0;\r\n\r\n/** Inset (m) applied to flat zone caps so adjacent zones read as separate. */\r\nconst FLAT_ZONE_GAP_M = 0.2;\r\n\r\n/** Ray-cast point-in-ring test. */\r\nfunction pointInRing(x: number, y: number, ring: [number, number][]): boolean {\r\n let inside = false;\r\n const n = ring.length;\r\n for (let i = 0, j = n - 1; i < n; j = i++) {\r\n const a = ring[i];\r\n const b = ring[j];\r\n if (!a || !b) continue;\r\n if (a[1] > y !== b[1] > y && x < ((b[0] - a[0]) * (y - a[1])) / (b[1] - a[1]) + a[0]) {\r\n inside = !inside;\r\n }\r\n }\r\n return inside;\r\n}\r\n\r\n/**\r\n * Inset a ring inward by a constant perpendicular `offset` (metres): each edge\r\n * is shifted inward by `offset` and consecutive shifted edges are intersected.\r\n * This is correct for concave shapes (unlike a vertex-bisector miter, which\r\n * spikes / escapes the polygon at reflex corners). If the result self-intersects\r\n * or leaves the polygon (thin/complex shapes), we fall back to NO inset so the\r\n * top face can never spill outside its footprint.\r\n */\r\nfunction insetRing(ring: [number, number][], offset: number): [number, number][] {\r\n const n = ring.length;\r\n if (n < 3) return ring;\r\n const area = ringArea(ring);\r\n if (Math.abs(area) < 1e-6) return ring;\r\n const s = area > 0 ? 1 : -1; // inward-normal sign for this winding\r\n\r\n // one inward-shifted line per edge: point (px,py) + direction (ux,uy)\r\n const lx: number[] = [];\r\n const ly: number[] = [];\r\n const ux: number[] = [];\r\n const uy: number[] = [];\r\n for (let i = 0; i < n; i++) {\r\n const a = ring[i];\r\n const b = ring[(i + 1) % n];\r\n if (!a || !b) {\r\n lx.push(0);\r\n ly.push(0);\r\n ux.push(1);\r\n uy.push(0);\r\n continue;\r\n }\r\n let ex = b[0] - a[0];\r\n let ey = b[1] - a[1];\r\n const len = Math.hypot(ex, ey) || 1;\r\n ex /= len;\r\n ey /= len;\r\n lx.push(a[0] + -ey * s * offset);\r\n ly.push(a[1] + ex * s * offset);\r\n ux.push(ex);\r\n uy.push(ey);\r\n }\r\n\r\n // new vertex i = intersection of edge-line (i-1) and edge-line (i)\r\n const out: [number, number][] = [];\r\n for (let i = 0; i < n; i++) {\r\n const j = (i - 1 + n) % n;\r\n const uxi = ux[i] ?? 1;\r\n const uyi = uy[i] ?? 0;\r\n const uxj = ux[j] ?? 1;\r\n const uyj = uy[j] ?? 0;\r\n const lxi = lx[i] ?? 0;\r\n const lyi = ly[i] ?? 0;\r\n const lxj = lx[j] ?? 0;\r\n const lyj = ly[j] ?? 0;\r\n const denom = uxj * uyi - uyj * uxi;\r\n if (Math.abs(denom) < 1e-9) {\r\n out.push([lxi, lyi]); // parallel edges — take the shifted start point\r\n continue;\r\n }\r\n const t = ((lxi - lxj) * uyi - (lyi - lyj) * uxi) / denom;\r\n out.push([lxj + t * uxj, lyj + t * uyj]);\r\n }\r\n\r\n // validity: same winding, not collapsed, and every vertex inside the original\r\n const ia = ringArea(out);\r\n if (Math.sign(ia) !== Math.sign(area) || Math.abs(ia) < Math.abs(area) * 0.2) return ring;\r\n for (const p of out) {\r\n if (!pointInRing(p[0], p[1], ring)) return ring;\r\n }\r\n return out;\r\n}\r\n\r\n// Curve smoothing tunables. Kept conservative: aggressive smoothing self-\r\n// intersects on rounded/complex shapes and corrupts the caps. The guard below\r\n// falls back to the original outline whenever a smoothed ring would fold.\r\nconst CURVE_SMOOTH_ITERATIONS = 2;\r\nconst CURVE_KEEP_ANGLE_DEG = 40;\r\n\r\n/** True if any two non-adjacent edges of the ring cross (a folded/bad polygon). */\r\nfunction ringSelfIntersects(ring: [number, number][]): boolean {\r\n const n = ring.length;\r\n const cross = (\r\n a1: [number, number],\r\n a2: [number, number],\r\n b1: [number, number],\r\n b2: [number, number],\r\n ): boolean => {\r\n const d = (a2[0] - a1[0]) * (b2[1] - b1[1]) - (a2[1] - a1[1]) * (b2[0] - b1[0]);\r\n if (Math.abs(d) < 1e-12) return false;\r\n const t = ((b1[0] - a1[0]) * (b2[1] - b1[1]) - (b1[1] - a1[1]) * (b2[0] - b1[0])) / d;\r\n const u = ((b1[0] - a1[0]) * (a2[1] - a1[1]) - (b1[1] - a1[1]) * (a2[0] - a1[0])) / d;\r\n return t > 1e-6 && t < 1 - 1e-6 && u > 1e-6 && u < 1 - 1e-6;\r\n };\r\n for (let i = 0; i < n; i++) {\r\n const a1 = ring[i];\r\n const a2 = ring[(i + 1) % n];\r\n if (!a1 || !a2) continue;\r\n for (let j = i + 2; j < n; j++) {\r\n if (i === 0 && j === n - 1) continue; // skip the wrap-adjacent pair\r\n const b1 = ring[j];\r\n const b2 = ring[(j + 1) % n];\r\n if (!b1 || !b2) continue;\r\n if (cross(a1, a2, b1, b2)) return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Corner-preserving Chaikin smoothing: rounds shallow \"curve\" joints (where the\r\n * outline turns gently, from a faceted arc) while keeping sharp store corners\r\n * intact. Makes curved edges read smooth instead of segmented.\r\n */\r\nfunction smoothRing(\r\n ring: [number, number][],\r\n iterations = CURVE_SMOOTH_ITERATIONS,\r\n keepAngleDeg = CURVE_KEEP_ANGLE_DEG,\r\n): [number, number][] {\r\n const cosKeep = Math.cos((keepAngleDeg * Math.PI) / 180);\r\n let pts = ring;\r\n for (let it = 0; it < iterations; it++) {\r\n const n = pts.length;\r\n if (n < 4) break;\r\n const out: [number, number][] = [];\r\n for (let i = 0; i < n; i++) {\r\n const prev = pts[(i - 1 + n) % n];\r\n const cur = pts[i];\r\n const next = pts[(i + 1) % n];\r\n if (!prev || !cur || !next) {\r\n if (cur) out.push([cur[0], cur[1]]);\r\n continue;\r\n }\r\n const d1x = cur[0] - prev[0];\r\n const d1y = cur[1] - prev[1];\r\n const d2x = next[0] - cur[0];\r\n const d2y = next[1] - cur[1];\r\n const l1 = Math.hypot(d1x, d1y) || 1;\r\n const l2 = Math.hypot(d2x, d2y) || 1;\r\n const dot = (d1x * d2x + d1y * d2y) / (l1 * l2); // cos(turn angle)\r\n if (dot <= cosKeep) {\r\n out.push([cur[0], cur[1]]); // sharp corner — keep\r\n } else {\r\n out.push([cur[0] - 0.25 * d1x, cur[1] - 0.25 * d1y]); // cut the shallow joint\r\n out.push([cur[0] + 0.25 * d2x, cur[1] + 0.25 * d2y]);\r\n }\r\n }\r\n pts = out;\r\n }\r\n // guard: never emit a folded outline — fall back to the original faceted ring\r\n return ringSelfIntersects(pts) ? ring : pts;\r\n}\r\n\r\n/**\r\n * Build one floor's merged geometry, DATA-DRIVEN from the editor's shape\r\n * types and per-shape `shapeProperties` (heights, colors, opacity):\r\n * - base (height ≤ 0.2 or mock `footprint`) → flat cap at slab height + skirt\r\n * - WALL / INNER_WALL → extruded colored walls with top caps (no windows)\r\n * - POLYGON units → matte shaded walls (vertical gradient) + lit roof + label\r\n * Merges to ≤3 draw calls per floor (textured, solid, translucent).\r\n */\r\nexport function buildFloorGeometry(\r\n frame: VenueFrame,\r\n floor: Floor,\r\n theme: PolygonTheme,\r\n): FloorGeometry {\r\n const solid: THREE.BufferGeometry[] = [];\r\n const glass: THREE.BufferGeometry[] = [];\r\n const labelSpecs: LabelSpec[] = [];\r\n // dark outline segments around every polygon roof (separation between\r\n // neighbours) — LineSegments = consecutive vertex pairs. One draw call.\r\n const borderPos: number[] = [];\r\n const pushBorder = (rings: [number, number][][], z: number): void => {\r\n for (const ring of rings) {\r\n for (let i = 0; i < ring.length; i++) {\r\n const a = ring[i];\r\n const b = ring[(i + 1) % ring.length];\r\n if (a && b) borderPos.push(a[0], a[1], z, b[0], b[1], z);\r\n }\r\n }\r\n };\r\n\r\n const locationByShapeId = new Map<string, VenueLocation>();\r\n for (const loc of floor.locations) {\r\n if (loc.shapeId) locationByShapeId.set(loc.shapeId, loc);\r\n }\r\n\r\n for (const shape of floor.shapes) {\r\n const role = shapeRole(shape);\r\n const style = shape.style;\r\n // Editor opacity DISABLED for now (user call): translucent blending over\r\n // overlapping editor polygons produced banding artifacts. Everything goes\r\n // to the opaque bucket. Re-enable per-shape opacity once blending is sorted.\r\n const bucket = solid;\r\n const height = shapeHeight(shape, role);\r\n // Overlapping neighbor polygons share identical editor heights (e.g. 4m)\r\n // → coplanar roofs → z-fighting. A deterministic ≤4.5cm per-shape offset\r\n // keeps every roof on its own plane, imperceptibly.\r\n const antiCoplanar = (hashId(shape.id) % 16) * 0.003;\r\n const z1 = SLAB_HEIGHT + height + antiCoplanar;\r\n\r\n // INNER_WALL: centerline → wall band (v1 buffers ~0.8m each side)\r\n if (role === 'partition') {\r\n const pts =\r\n shape.geometry.type === 'LineString'\r\n ? shape.geometry.coordinates.map((p) => toMeters(frame, p))\r\n : shapeRings(frame, shape)[0];\r\n // panel theme forces a constant reduced wall height + colour; otherwise\r\n // a zero editor height means \"no wall\".\r\n if (!pts || pts.length < 2 || (!theme.panel && height <= 0)) continue;\r\n const P = theme.panel;\r\n const wallZ1 = P ? SLAB_HEIGHT + P.wallHeight : z1;\r\n // INNER_WALL carries only ONE colour in the editor data (`color`, no\r\n // fillColor). A panel theme replaces it with the fixed partition colour\r\n // unless `wallFromData` (data theme) asks for the editor's own value.\r\n const innerHex = P\r\n ? P.wallFromData\r\n ? (style?.color ?? P.innerWall)\r\n : P.innerWall\r\n : (style?.color ?? DEFAULT_WALL_SIDE.getStyle());\r\n bucket.push(\r\n ...lineBandGeometries(pts, false, SLAB_HEIGHT, wallZ1, WALL_BAND_HALF_WIDTH_M, new THREE.Color(innerHex)),\r\n );\r\n continue;\r\n }\r\n\r\n const rings = shapeRings(frame, shape);\r\n const outer = rings[0];\r\n if (!outer) continue;\r\n\r\n if (role === 'base') {\r\n const location0 = locationByShapeId.get(shape.id);\r\n if (shape.layerId === 'footprint') {\r\n // mock slab: cap + skirt\r\n bucket.push(capWithHoles(rings, SLAB_HEIGHT, new THREE.Color(style?.fillColor ?? SLAB_TOP.getStyle())));\r\n bucket.push(coloredSides(rings, 0, SLAB_HEIGHT, new THREE.Color('#f2f2f5')));\r\n } else {\r\n // editor flat zone/carpet: stacked slightly above the floor plate to\r\n // avoid z-fighting (carpets with height 0.1 sit a hair higher)\r\n const z = SLAB_HEIGHT + 0.03 + ((style?.height ?? 0) > 0 ? 0.03 : 0) + (hashId(shape.id) % 8) * 0.002;\r\n // panel theme paints the corridor floor a light neutral so the map stays\r\n // bright — the data theme (`topUpperFromData`) keeps the editor's own\r\n // zone colour exactly as authored.\r\n const baseColor =\r\n theme.panel && !theme.panel.topUpperFromData\r\n ? new THREE.Color(theme.panel.floor)\r\n : polygonTopColor(shape, location0);\r\n // inset the cap slightly so adjacent flat zones get a visible seam of\r\n // the underlying plate between them instead of blending edge-to-edge\r\n // (insetRing falls back to the original ring for slivers it would break)\r\n const insetFlat = rings.map((r) => insetRing(r, FLAT_ZONE_GAP_M));\r\n bucket.push(capWithHoles(insetFlat, z, baseColor));\r\n pushBorder(insetFlat, z + 0.02);\r\n if (location0 && !location0.hidden && !location0.amenity) {\r\n const [cx0, cy0] = polygonCentroid(outer);\r\n const fit0 = labelFit(outer, location0.name, cx0, cy0);\r\n labelSpecs.push({\r\n text: fit0.text,\r\n x: cx0,\r\n y: cy0,\r\n z: z + 0.05,\r\n fontSize: fit0.fontSize,\r\n baseRotation: fit0.rotation,\r\n locationId: location0.id,\r\n ...(location0.logoUrl\r\n ? { logoUrl: location0.logoUrl, ...logoFitBox(outer, cx0, cy0, fit0.rotation, fit0.alongM, fit0.acrossM) }\r\n : {}),\r\n });\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n // WALL carries TWO colours in the editor data — `fillColor` for the flat\r\n // floor plate (the base layer) and `color` for the perimeter wall band. A\r\n // panel theme replaces both with fixed colours (`wallBase` / `wall`).\r\n // NO lid over the interior (that lid was the \"grey plate\" bug).\r\n if (role === 'boundary') {\r\n const P = theme.panel;\r\n // `wallFromData` (data theme) keeps the editor's own two colours, falling\r\n // back to the fixed ones for the floors that omit `fillColor` entirely.\r\n const plateHex = P\r\n ? P.wallFromData\r\n ? (style?.fillColor ?? P.wallBase)\r\n : P.wallBase\r\n : (style?.fillColor ?? '#c9c9c9');\r\n solid.push(capWithHoles(rings, SLAB_HEIGHT, new THREE.Color(plateHex)));\r\n solid.push(coloredSides(rings, 0, SLAB_HEIGHT, new THREE.Color('#f2f2f5')));\r\n // panel theme forces a constant reduced wall height + colour\r\n const wallZ1 = P ? SLAB_HEIGHT + P.wallHeight : z1;\r\n const wallHex = P\r\n ? P.wallFromData\r\n ? (style?.color ?? P.wall)\r\n : P.wall\r\n : (style?.color ?? '#f7f7f7');\r\n bucket.push(\r\n ...lineBandGeometries(outer, true, SLAB_HEIGHT, wallZ1, WALL_BAND_HALF_WIDTH_M, new THREE.Color(wallHex)),\r\n );\r\n continue;\r\n }\r\n\r\n const location = locationByShapeId.get(shape.id);\r\n\r\n // Thin divider/rail strips (mistyped as POLYGON, ~0.5m wide) would extrude\r\n // into tall bars — render them as a low flat strip on the floor instead.\r\n const perim = ringPerimeter(outer);\r\n const thickness = perim > 0 ? (2 * Math.abs(ringArea(outer))) / perim : 0;\r\n if (thickness < THIN_STRIP_M) {\r\n const dz = SLAB_HEIGHT + 0.12;\r\n const dividerCol = new THREE.Color('#adadb6');\r\n bucket.push(gradientSides(rings, SLAB_HEIGHT, dz, dividerCol, dividerCol));\r\n bucket.push(capWithHoles(rings, dz, dividerCol));\r\n continue;\r\n }\r\n\r\n // Panel theme: fixed-colour multi-tier directory panel (base band → constant\r\n // -height wall → lower-layer rim → inset upper face with the label).\r\n if (theme.panel) {\r\n const P = theme.panel;\r\n // glass theme → translucent bucket; the top face can take the store's own\r\n // editor/category colour (data theme) instead of the fixed panel colour.\r\n const panelBucket = theme.translucent ? glass : bucket;\r\n // uniformHeight (Visioglobe policy) flattens every unit to one calm\r\n // roofline; otherwise the store keeps its data height. Top section =\r\n // topFraction of the height, the base/wall gets the rest.\r\n const hEff = P.uniformHeight ?? height;\r\n const topZ = SLAB_HEIGHT + hEff + antiCoplanar;\r\n const wallTopZ = topZ - hEff * P.topFraction; // rim level\r\n const upperCol = P.topUpperFromData\r\n ? polygonTopColor(shape, location) // the EXACT editor colour, untouched\r\n : new THREE.Color(P.topUpper);\r\n // Data theme: ONLY the raised top layer — its face and its side walls —\r\n // takes the store's data colour. The rim ledge, the tall sides, and the\r\n // base band all stay theme-neutral.\r\n const baseCol = new THREE.Color(P.base);\r\n const edgeCol = new THREE.Color(P.edge);\r\n const lowerCol = new THREE.Color(P.topLower);\r\n // soft contact tone spreading past the footprint so the slab sits on the\r\n // floor instead of floating\r\n panelBucket.push(\r\n capWithHoles(\r\n rings.map((r) => insetRing(r, -CONTACT_SHADOW_SPREAD_M)),\r\n SLAB_HEIGHT + 0.015,\r\n CONTACT_SHADOW,\r\n ),\r\n );\r\n // No hard seam between the base layer and the side above it — but the\r\n // fade stays SHORT: only the bottom stretch blends base → edge, and the\r\n // side is solid edge colour above that, so it still reads bright.\r\n const blendTop = SLAB_HEIGHT + Math.min(0.6, Math.max(0.2, (wallTopZ - SLAB_HEIGHT) * 0.3));\r\n panelBucket.push(gradientSides(rings, SLAB_HEIGHT, blendTop, edgeCol, baseCol)); // short fade\r\n panelBucket.push(gradientSides(rings, blendTop, wallTopZ, edgeCol, edgeCol)); // solid above\r\n panelBucket.push(capWithHoles(rings, wallTopZ, lowerCol)); // top lower layer / rim\r\n const insetR = rings.map((r) => insetRing(r, P.rimWidth));\r\n // The raised top's little side walls take the bevel colour (own slot, so\r\n // the tall lower side can differ) — that bright ring around a darker top\r\n // face is the signature of the reference maps; matching sides erase it.\r\n const bevelCol = P.topUpperFromData ? upperCol : new THREE.Color(P.bevel ?? P.edge);\r\n panelBucket.push(gradientSides(insetR, wallTopZ, topZ, bevelCol, bevelCol)); // bevel\r\n panelBucket.push(capWithHoles(insetR, topZ, upperCol)); // inset top upper face\r\n pushBorder(rings, wallTopZ + 0.02); // panel outline (separates neighbours)\r\n if (location && !location.hidden && !location.amenity) {\r\n const [cx, cy] = polygonCentroid(outer);\r\n const fit = labelFit(outer, location.name, cx, cy);\r\n labelSpecs.push({\r\n text: fit.text,\r\n x: cx,\r\n y: cy,\r\n z: topZ + 0.05,\r\n fontSize: fit.fontSize,\r\n baseRotation: fit.rotation,\r\n locationId: location.id,\r\n ...(location.logoUrl\r\n ? { logoUrl: location.logoUrl, ...logoFitBox(outer, cx, cy, fit.rotation, fit.alongM, fit.acrossM) }\r\n : {}),\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n // unit: themed block — roof + vertical-gradient walls. Glass themes render\r\n // translucent (their own bucket/material); everything else is opaque.\r\n const base = polygonTopColor(shape, location);\r\n const unitBucket = theme.translucent ? glass : bucket;\r\n unitBucket.push(gradientSides(rings, SLAB_HEIGHT, z1, theme.wallTop(base), theme.wallBase(base)));\r\n unitBucket.push(capWithHoles(rings, z1, theme.roof(base)));\r\n pushBorder(rings, z1 + 0.02);\r\n\r\n if (location && !location.hidden && !location.amenity) {\r\n const [cx, cy] = polygonCentroid(outer);\r\n const fit = labelFit(outer, location.name, cx, cy);\r\n labelSpecs.push({\r\n text: fit.text,\r\n x: cx,\r\n y: cy,\r\n z: z1 + 0.08,\r\n fontSize: fit.fontSize,\r\n baseRotation: fit.rotation,\r\n locationId: location.id,\r\n ...(location.logoUrl\r\n ? { logoUrl: location.logoUrl, ...logoFitBox(outer, cx, cy, fit.rotation, fit.alongM, fit.acrossM) }\r\n : {}),\r\n });\r\n }\r\n }\r\n\r\n let borders: THREE.BufferGeometry | null = null;\r\n if (borderPos.length) {\r\n borders = new THREE.BufferGeometry();\r\n borders.setAttribute('position', new THREE.BufferAttribute(new Float32Array(borderPos), 3));\r\n }\r\n\r\n return {\r\n solid: solid.length ? mergeGeometries(solid, false) : null,\r\n translucent: glass.length ? mergeGeometries(glass, false) : null,\r\n borders,\r\n labelSpecs,\r\n };\r\n}\r\n","import * as THREE from 'three';\r\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n// @ts-ignore troika-three-text ships no types\r\nimport { BatchedText, Text } from 'troika-three-text';\r\nimport type { LabelSpec } from './geometry.js';\r\n\r\n/**\r\n * Floor labels via troika BatchedText: one draw call per floor batch.\r\n * Labels are part of the MAP: aligned to their own store's axes and fixed to\r\n * the venue, rotating with it. `setFlip` turns all of them 180 degrees once\r\n * the bearing passes +-90 so text never reads upside-down (hysteresis in caller).\r\n */\r\nexport interface FloorLabels {\r\n object: THREE.Object3D;\r\n /** Flip all labels 180 degrees (true) or back upright (false). */\r\n setFlip(flipped: boolean): void;\r\n dispose(): void;\r\n}\r\n\r\ninterface TroikaText extends THREE.Object3D {\r\n text: string;\r\n fontSize: number;\r\n color: number;\r\n anchorX: string;\r\n anchorY: string;\r\n outlineWidth: string | number;\r\n outlineColor: number;\r\n outlineBlur: string | number;\r\n fontWeight: string | number;\r\n textAlign: string;\r\n sync(cb?: () => void): void;\r\n dispose(): void;\r\n}\r\n\r\n/** Flat ink, no halo — clean text sitting directly on the panel top. The\r\n * colour comes from the theme (black on light tops, white on data colours). */\r\nfunction styleLabel(t: TroikaText, color: number): void {\r\n t.color = color;\r\n t.fontWeight = 'bold';\r\n t.outlineWidth = 0; // no halo\r\n t.anchorX = 'center';\r\n t.anchorY = 'middle';\r\n t.textAlign = 'center'; // wrapped two-line names centre on each other\r\n}\r\n\r\n/** A single standalone label (building names on sealed shells). */\r\nexport interface SingleLabel {\r\n object: THREE.Object3D;\r\n setFlip(flipped: boolean): void;\r\n dispose(): void;\r\n}\r\n\r\nexport function createSingleLabel(\r\n spec: { text: string; x: number; y: number; z: number; fontSize: number; baseRotation?: number; color?: number },\r\n onReady?: () => void,\r\n): SingleLabel {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment\r\n const t = new Text() as TroikaText;\r\n t.text = spec.text;\r\n t.fontSize = spec.fontSize;\r\n styleLabel(t, spec.color ?? 0x000000);\r\n t.position.set(spec.x, spec.y, spec.z);\r\n const base = spec.baseRotation ?? 0;\r\n t.rotation.z = base;\r\n t.sync(onReady);\r\n return {\r\n object: t,\r\n // world-fixed: keep the polygon-aligned base yaw, add 180 only when flipping.\r\n setFlip(flipped: boolean): void {\r\n t.rotation.z = base + (flipped ? Math.PI : 0);\r\n },\r\n dispose(): void {\r\n t.dispose();\r\n },\r\n };\r\n}\r\n\r\n// A location with a logo shows ONLY the logo — the name renders otherwise.\r\n// The box a logo may fill is computed by the geometry layer (row-sampled so\r\n// the logo stays inside even concave stores); this module just fits into it.\r\n\r\ninterface LogoEntry {\r\n mesh: THREE.Mesh;\r\n x: number;\r\n y: number;\r\n z: number;\r\n base: number;\r\n off: number;\r\n}\r\n\r\n/** Position a logo above its label along the label's own \"up\", honouring flip. */\r\nfunction placeLogo(e: LogoEntry, extra: number): void {\r\n const rot = e.base + extra;\r\n const ux = -Math.sin(rot);\r\n const uy = Math.cos(rot);\r\n e.mesh.position.set(e.x + ux * e.off, e.y + uy * e.off, e.z);\r\n e.mesh.rotation.z = rot;\r\n}\r\n\r\nexport function createFloorLabels(specs: LabelSpec[], color: number, onReady?: () => void): FloorLabels {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment\r\n const batched = new BatchedText() as TroikaText & { addText?: unknown };\r\n const members: { text: TroikaText; base: number }[] = [];\r\n for (const spec of specs) {\r\n if (spec.logoUrl) continue; // the logo replaces the name entirely\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment\r\n const t = new Text() as TroikaText;\r\n t.text = spec.text;\r\n t.fontSize = spec.fontSize;\r\n styleLabel(t, color);\r\n t.position.set(spec.x, spec.y, spec.z);\r\n t.rotation.z = spec.baseRotation; // align to the polygon's dominant edge\r\n (batched as unknown as THREE.Object3D).add(t);\r\n members.push({ text: t, base: spec.baseRotation });\r\n }\r\n batched.sync(onReady);\r\n\r\n // Brand logos from the venue data, drawn IN PLACE of the name: a location\r\n // with a logo gets only its logo, sized from the same polygon-driven fit.\r\n // Loaded lazily; a failed load (missing file / CORS) leaves the store bare.\r\n const group = new THREE.Group();\r\n group.add(batched);\r\n const logos: LogoEntry[] = [];\r\n const loader = new THREE.TextureLoader();\r\n loader.setCrossOrigin('anonymous');\r\n for (const spec of specs) {\r\n if (!spec.logoUrl) continue;\r\n // the box the geometry layer measured INSIDE the polygon for this logo\r\n const availW = spec.logoBoxW ?? 5 * spec.fontSize;\r\n const availH = spec.logoBoxH ?? 1.5 * spec.fontSize;\r\n const off = 0; // centred exactly where the name would have been\r\n const mat = new THREE.MeshBasicMaterial({ transparent: true, opacity: 0, depthWrite: false });\r\n const mesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), mat);\r\n const entry: LogoEntry = { mesh, x: spec.x, y: spec.y, z: spec.z + 0.03, base: spec.baseRotation, off };\r\n placeLogo(entry, 0);\r\n loader.load(\r\n spec.logoUrl,\r\n (tex) => {\r\n tex.colorSpace = THREE.SRGBColorSpace;\r\n const img = tex.image as { width?: number; height?: number };\r\n const aspect = Math.max(0.05, (img.width ?? 1) / Math.max(1, img.height ?? 1));\r\n // largest size that fits the store's box at the logo's own aspect\r\n const h = Math.min(availH, availW / aspect);\r\n mesh.scale.set(h * aspect, h, 1);\r\n mat.map = tex;\r\n mat.opacity = 1;\r\n mat.needsUpdate = true;\r\n onReady?.();\r\n },\r\n undefined,\r\n () => undefined, // logo unavailable → store stays bare, silently\r\n );\r\n group.add(mesh);\r\n logos.push(entry);\r\n }\r\n\r\n return {\r\n object: group,\r\n // each label keeps its own polygon-aligned base yaw; flip adds 180 on top,\r\n // and logos flip in place so they stay upright on screen.\r\n setFlip(flipped: boolean): void {\r\n const extra = flipped ? Math.PI : 0;\r\n for (const { text, base } of members) text.rotation.z = base + extra;\r\n for (const e of logos) placeLogo(e, extra);\r\n },\r\n dispose(): void {\r\n batched.dispose();\r\n for (const { mesh } of logos) {\r\n mesh.geometry.dispose();\r\n const m = mesh.material as THREE.MeshBasicMaterial;\r\n m.map?.dispose();\r\n m.dispose();\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Bearing→flip policy with hysteresis (flip past 95°, unflip under 85°) —\r\n * pure so it's unit-testable.\r\n */\r\nexport function labelFlipState(bearingDeg: number, currentlyFlipped: boolean): boolean {\r\n let b = bearingDeg % 360;\r\n if (b > 180) b -= 360;\r\n if (b <= -180) b += 360;\r\n return currentlyFlipped ? Math.abs(b) > 85 : Math.abs(b) > 95;\r\n}\r\n","import * as THREE from 'three';\r\nimport type { Floor } from '../data/types.js';\r\nimport { polygonCentroid, toMeters, type VenueFrame } from './coords.js';\r\nimport { SLAB_HEIGHT, polygonLabelAngle, shapeHeight, shapeRole } from './geometry.js';\r\n\r\n/** Mirror of geometry's thin-strip rule: strips this narrow render FLAT. */\r\nconst THIN_STRIP_M = 1.0;\r\n\r\nfunction ringThickness(ring: [number, number][]): number {\r\n let area = 0;\r\n let perim = 0;\r\n for (let i = 0; i < ring.length; i++) {\r\n const p = ring[i];\r\n const q = ring[(i + 1) % ring.length];\r\n if (!p || !q) continue;\r\n area += p[0] * q[1] - q[0] * p[1];\r\n perim += Math.hypot(q[0] - p[0], q[1] - p[1]);\r\n }\r\n // |shoelace sum| / perimeter ≡ 2·area/perimeter — geometry's exact metric\r\n return perim > 0 ? Math.abs(area) / perim : 0;\r\n}\r\n\r\n/** The polygon's \"level\" axis — same horizontal-first pick the labels use. */\r\nfunction levelAxis(ring: [number, number][]): number {\r\n const a = polygonLabelAngle(ring);\r\n let b = a + Math.PI / 2;\r\n while (b > Math.PI / 2) b -= Math.PI;\r\n while (b <= -Math.PI / 2) b += Math.PI;\r\n return Math.abs(a) <= Math.abs(b) ? a : b;\r\n}\r\n\r\n/**\r\n * Amenity markers: flat circular badges lying on the map at each amenity's\r\n * node — escalators, stairs, lifts, restrooms, info desks. They REPLACE the\r\n * text label for amenity locations, are drawn as built-in vector glyphs (no\r\n * network dependency), and flip with the labels so they stay readable.\r\n */\r\nexport interface AmenityMarkers {\r\n object: THREE.Object3D;\r\n setFlip(flipped: boolean): void;\r\n /** Orient the FLOATING connection pins toward the viewer (map bearing/pitch). */\r\n setCameraView(bearingDeg: number, pitchDeg: number): void;\r\n dispose(): void;\r\n}\r\n\r\nconst MARKER_DIAMETER_M = 2.6;\r\n// Floating connection pins: the badge hovers just above the floor, upright and\r\n// turned toward the camera, so escalators/stairs/lifts stay legible instead of\r\n// foreshortening to an ellipse under pitch.\r\nconst FLOAT_DIAMETER_M = 2.2;\r\nconst FLOAT_HEIGHT_M = 2.6;\r\nconst BADGE_FILL = '#5b6470'; // slate — visible on light floors, never loud\r\nconst GLYPH_INK = '#ffffff';\r\n\r\ntype Glyph = 'escalator' | 'stairs' | 'elevator' | 'restroom' | 'info' | 'default';\r\n\r\n/** Vertical circulation — the amenities that MOVE you between floors. */\r\nfunction isConnection(amenity: string): boolean {\r\n const a = amenity.toLowerCase();\r\n return (\r\n a.includes('escalator') ||\r\n a.includes('stair') ||\r\n a.includes('elevator') ||\r\n a.includes('lift') ||\r\n a.includes('travelator') ||\r\n a.includes('walkway') ||\r\n a.includes('ramp')\r\n );\r\n}\r\n\r\nfunction glyphFor(amenity: string): Glyph {\r\n const a = amenity.toLowerCase();\r\n if (a.includes('escalator')) return 'escalator';\r\n if (a.includes('stair')) return 'stairs';\r\n if (a.includes('elevator') || a.includes('lift')) return 'elevator';\r\n if (a.includes('restroom') || a.includes('washroom') || a.includes('toilet')) return 'restroom';\r\n if (a.includes('information')) return 'info';\r\n return 'default';\r\n}\r\n\r\n/** Step polyline shared by the stairs and escalator glyphs. */\r\nfunction drawSteps(ctx: CanvasRenderingContext2D): void {\r\n ctx.beginPath();\r\n ctx.moveTo(36, 90);\r\n ctx.lineTo(52, 90);\r\n ctx.lineTo(52, 74);\r\n ctx.lineTo(68, 74);\r\n ctx.lineTo(68, 58);\r\n ctx.lineTo(84, 58);\r\n ctx.lineTo(84, 42);\r\n ctx.lineTo(94, 42);\r\n ctx.stroke();\r\n}\r\n\r\nconst textureCache = new Map<Glyph, THREE.CanvasTexture>();\r\n\r\nfunction badgeTexture(glyph: Glyph): THREE.CanvasTexture {\r\n const cached = textureCache.get(glyph);\r\n if (cached) return cached;\r\n const c = document.createElement('canvas');\r\n c.width = 128;\r\n c.height = 128;\r\n const ctx = c.getContext('2d');\r\n if (ctx) {\r\n // badge circle with a soft white ring so it reads on any floor colour\r\n ctx.beginPath();\r\n ctx.arc(64, 64, 56, 0, Math.PI * 2);\r\n ctx.fillStyle = BADGE_FILL;\r\n ctx.fill();\r\n ctx.lineWidth = 7;\r\n ctx.strokeStyle = 'rgba(255,255,255,0.95)';\r\n ctx.stroke();\r\n ctx.strokeStyle = GLYPH_INK;\r\n ctx.fillStyle = GLYPH_INK;\r\n ctx.lineWidth = 9;\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n ctx.textAlign = 'center';\r\n ctx.textBaseline = 'middle';\r\n switch (glyph) {\r\n case 'stairs':\r\n drawSteps(ctx);\r\n break;\r\n case 'escalator': {\r\n drawSteps(ctx);\r\n // diagonal rail with an up arrowhead — distinguishes it from stairs\r\n ctx.beginPath();\r\n ctx.moveTo(40, 62);\r\n ctx.lineTo(74, 28);\r\n ctx.stroke();\r\n ctx.beginPath();\r\n ctx.moveTo(58, 26);\r\n ctx.lineTo(78, 24);\r\n ctx.lineTo(76, 44);\r\n ctx.closePath();\r\n ctx.fill();\r\n break;\r\n }\r\n case 'elevator': {\r\n ctx.lineWidth = 8;\r\n ctx.strokeRect(38, 34, 52, 60);\r\n ctx.beginPath(); // up triangle\r\n ctx.moveTo(64, 44);\r\n ctx.lineTo(52, 58);\r\n ctx.lineTo(76, 58);\r\n ctx.closePath();\r\n ctx.fill();\r\n ctx.beginPath(); // down triangle\r\n ctx.moveTo(64, 84);\r\n ctx.lineTo(52, 70);\r\n ctx.lineTo(76, 70);\r\n ctx.closePath();\r\n ctx.fill();\r\n break;\r\n }\r\n case 'restroom':\r\n ctx.font = 'bold 44px system-ui, sans-serif';\r\n ctx.fillText('WC', 64, 66);\r\n break;\r\n case 'info':\r\n ctx.font = 'bold italic 72px Georgia, serif';\r\n ctx.fillText('i', 64, 66);\r\n break;\r\n default:\r\n ctx.beginPath();\r\n ctx.arc(64, 64, 14, 0, Math.PI * 2);\r\n ctx.fill();\r\n }\r\n }\r\n const tex = new THREE.CanvasTexture(c);\r\n tex.colorSpace = THREE.SRGBColorSpace;\r\n tex.anisotropy = 4;\r\n textureCache.set(glyph, tex);\r\n return tex;\r\n}\r\n\r\n/**\r\n * Badge with a REAL icon from the venue's default icon set (CDN SVG), drawn\r\n * onto the circle once it loads; until then (or if it fails) the badge shows\r\n * the built-in vector glyph. Textures cached per url+colour.\r\n */\r\nconst iconTextureCache = new Map<string, THREE.CanvasTexture>();\r\n\r\nfunction iconBadgeTexture(\r\n iconUrl: string,\r\n fill: string,\r\n fallback: Glyph,\r\n onLoad?: () => void,\r\n): THREE.CanvasTexture {\r\n const key = `${iconUrl}|${fill}`;\r\n const cached = iconTextureCache.get(key);\r\n if (cached) return cached;\r\n const c = document.createElement('canvas');\r\n c.width = 128;\r\n c.height = 128;\r\n const ctx = c.getContext('2d');\r\n const tex = new THREE.CanvasTexture(c);\r\n tex.colorSpace = THREE.SRGBColorSpace;\r\n tex.anisotropy = 4;\r\n const drawCircle = (): void => {\r\n if (!ctx) return;\r\n ctx.clearRect(0, 0, 128, 128);\r\n ctx.beginPath();\r\n ctx.arc(64, 64, 56, 0, Math.PI * 2);\r\n ctx.fillStyle = fill;\r\n ctx.fill();\r\n ctx.lineWidth = 7;\r\n ctx.strokeStyle = 'rgba(255,255,255,0.95)';\r\n ctx.stroke();\r\n };\r\n drawCircle();\r\n const img = new Image();\r\n img.crossOrigin = 'anonymous';\r\n img.onload = () => {\r\n if (!ctx) return;\r\n drawCircle();\r\n ctx.drawImage(img, 32, 32, 64, 64); // icon centred inside the circle\r\n tex.needsUpdate = true;\r\n onLoad?.();\r\n };\r\n img.onerror = () => {\r\n // icon unavailable → fall back to the built-in glyph badge\r\n const glyphCanvas = badgeTexture(fallback).image as HTMLCanvasElement;\r\n if (ctx) ctx.drawImage(glyphCanvas, 0, 0);\r\n tex.needsUpdate = true;\r\n onLoad?.();\r\n };\r\n img.src = iconUrl;\r\n iconTextureCache.set(key, tex);\r\n return tex;\r\n}\r\n\r\n/**\r\n * Build the amenity markers for one floor; null when the floor has none.\r\n * Every amenity gets a badge — connections (escalators, stairs, lifts)\r\n * included, at their node. An amenity WITH a polygon gets its badge centred\r\n * ON TOP of that polygon at its extruded height; shapeless amenities sit at\r\n * their node at floor level. Icons resolve exactly like v1: the location's\r\n * CATEGORY icon first, then the amenity key through the venue's default icon\r\n * set, then the built-in glyph.\r\n */\r\nexport function createAmenityMarkers(\r\n frame: VenueFrame,\r\n floor: Floor,\r\n iconset: Record<string, string> = {},\r\n onIconLoad?: () => void,\r\n): AmenityMarkers | null {\r\n const nodesById = new Map(floor.nodes.map((n) => [n.id, n]));\r\n const shapesById = new Map(floor.shapes.map((s) => [s.id, s]));\r\n const group = new THREE.Group();\r\n const entries: { mesh: THREE.Mesh; base: number }[] = [];\r\n const floating: THREE.Mesh[] = [];\r\n const geo = new THREE.PlaneGeometry(1, 1);\r\n const floatGeo = new THREE.PlaneGeometry(1, 1);\r\n for (const loc of floor.locations) {\r\n if (!loc.amenity || loc.hidden) continue;\r\n let x: number | undefined;\r\n let y: number | undefined;\r\n let z = SLAB_HEIGHT + 0.16; // shapeless fallback: node at floor level\r\n let base = 0;\r\n const shape = loc.shapeId ? shapesById.get(loc.shapeId) : undefined;\r\n if (shape && shape.geometry.type === 'Polygon' && shape.geometry.coordinates[0]) {\r\n // EXACTLY on top of the polygon, aligned like labels/logos: centred at\r\n // the centroid, rotated to the shape's level axis, and sitting on the\r\n // RENDERED top — which for thin strips is the flattened slab, not the\r\n // editor height (that mismatch is what left the badge floating mid-air).\r\n const ring = shape.geometry.coordinates[0].map((p) => toMeters(frame, p));\r\n [x, y] = polygonCentroid(ring);\r\n base = levelAxis(ring);\r\n const role = shapeRole(shape);\r\n let renderedH = 0.1; // flat zones cap just above the slab\r\n if (role === 'unit') {\r\n renderedH = ringThickness(ring) < THIN_STRIP_M ? 0.12 : shapeHeight(shape, role);\r\n }\r\n z = SLAB_HEIGHT + renderedH + 0.12;\r\n } else if (loc.nodeId) {\r\n const node = nodesById.get(loc.nodeId);\r\n if (node) [x, y] = toMeters(frame, [node.lng, node.lat]);\r\n }\r\n if (x === undefined || y === undefined) continue;\r\n // icon resolution, v1 order: category icon → amenity key in the venue's\r\n // default icon set → built-in glyph\r\n const category = loc.categories[0];\r\n const iconUrl = category?.icon ?? iconset[loc.amenity.toUpperCase()];\r\n const fill = category?.colorHex ?? BADGE_FILL;\r\n const glyph = glyphFor(loc.amenity);\r\n const mat = new THREE.MeshBasicMaterial({\r\n map: iconUrl ? iconBadgeTexture(iconUrl, fill, glyph, onIconLoad) : badgeTexture(glyph),\r\n transparent: true,\r\n depthWrite: false,\r\n });\r\n if (isConnection(loc.amenity)) {\r\n // FLOATING pin: badge hovers above the anchor, standing upright and\r\n // turned toward the camera — never a flat ellipse.\r\n const badge = new THREE.Mesh(floatGeo, mat);\r\n badge.scale.set(FLOAT_DIAMETER_M, FLOAT_DIAMETER_M, 1);\r\n badge.position.set(x, y, z + FLOAT_HEIGHT_M);\r\n badge.renderOrder = 6;\r\n badge.frustumCulled = false;\r\n group.add(badge);\r\n floating.push(badge);\r\n continue;\r\n }\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.scale.set(MARKER_DIAMETER_M, MARKER_DIAMETER_M, 1);\r\n mesh.position.set(x, y, z);\r\n mesh.rotation.z = base;\r\n group.add(mesh);\r\n entries.push({ mesh, base });\r\n }\r\n if (!entries.length && !floating.length) {\r\n geo.dispose();\r\n floatGeo.dispose();\r\n return null;\r\n }\r\n return {\r\n object: group,\r\n // FLAT markers keep their polygon-aligned base yaw and flip with the labels\r\n // so WC / i glyphs never read upside-down\r\n setFlip(flipped: boolean): void {\r\n const extra = flipped ? Math.PI : 0;\r\n for (const e of entries) e.mesh.rotation.z = e.base + extra;\r\n },\r\n // FLOATING pins billboard instead: the camera's view matrix is folded into\r\n // one combined projection matrix here, so a THREE.Sprite can't face the\r\n // viewer — build the facing from the map's own bearing + pitch.\r\n setCameraView(bearingDeg: number, pitchDeg: number): void {\r\n const rx = (pitchDeg * Math.PI) / 180;\r\n const rz = (-bearingDeg * Math.PI) / 180;\r\n for (const badge of floating) badge.rotation.set(rx, 0, rz, 'ZXY');\r\n },\r\n dispose(): void {\r\n geo.dispose();\r\n floatGeo.dispose();\r\n for (const e of entries) (e.mesh.material as THREE.Material).dispose();\r\n for (const b of floating) (b.material as THREE.Material).dispose();\r\n // badge textures stay cached — shared across floors and rebuilds\r\n },\r\n };\r\n}\r\n","import * as THREE from 'three';\r\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\r\nimport type { MapObjectDef } from '../data/types.js';\r\nimport type { Venue } from '../data/venue-model.js';\r\nimport { toMeters, type VenueFrame } from './coords.js';\r\nimport { SLAB_HEIGHT } from './geometry.js';\r\n\r\nexport interface ModelInstance {\r\n url: string;\r\n matrix: THREE.Matrix4;\r\n}\r\n\r\n/**\r\n * Group map objects by model URL and compute per-instance transforms in the\r\n * venue-local frame (pure — unit-testable without a loader or WebGL).\r\n * Repeated models render via InstancedMesh: one draw call per mesh per URL.\r\n */\r\nexport function computeModelInstances(\r\n frame: VenueFrame,\r\n venue: Venue,\r\n floorId: string,\r\n): Map<string, THREE.Matrix4[]> {\r\n const byUrl = new Map<string, THREE.Matrix4[]>();\r\n const dummy = new THREE.Object3D();\r\n for (const def of venue.mapObjects) {\r\n const node = venue.getNode(def.nodeId);\r\n if (!node || node.floorId !== floorId || !def.modelUrl) continue;\r\n const [x, y] = toMeters(frame, [node.lng, node.lat]);\r\n // altitude is relative to the WALKING surface — the slab top — not world\r\n // zero; placing at raw altitude (0 in this venue) sank models into the slab\r\n dummy.position.set(x, y, SLAB_HEIGHT + def.altitude);\r\n // The editor's rotation value is NOT degrees: v1 decodes yaw as PI/value\r\n // (e.g. 1.6 → 112.5°, 0.88 → 204.5° — verified against the live venue,\r\n // matching the mall's building grid). Treating it as degrees left every\r\n // model unrotated. X = 90° maps the GLB's y-up into our z-up frame; the\r\n // yaw then lands on the (new) local Y, which is world up.\r\n const yaw = def.rotation !== 0 ? Math.PI / def.rotation : 0;\r\n dummy.rotation.set(Math.PI / 2, yaw, 0);\r\n dummy.scale.setScalar(def.scale || 1);\r\n dummy.updateMatrix();\r\n const list = byUrl.get(def.modelUrl) ?? [];\r\n list.push(dummy.matrix.clone());\r\n byUrl.set(def.modelUrl, list);\r\n }\r\n return byUrl;\r\n}\r\n\r\n/**\r\n * Load a floor's GLB models and return a group of InstancedMeshes (one per\r\n * mesh per distinct URL). Browser-only (GLTFLoader). Failed loads are\r\n * skipped with a console warning — a missing tree never blocks the map.\r\n */\r\nexport async function loadFloorModels(\r\n frame: VenueFrame,\r\n venue: Venue,\r\n floorId: string,\r\n defs?: MapObjectDef[],\r\n): Promise<THREE.Group | null> {\r\n void defs;\r\n const byUrl = computeModelInstances(frame, venue, floorId);\r\n if (byUrl.size === 0) return null;\r\n const loader = new GLTFLoader();\r\n const group = new THREE.Group();\r\n await Promise.all(\r\n [...byUrl.entries()].map(async ([url, matrices]) => {\r\n try {\r\n const gltf = await loader.loadAsync(url);\r\n gltf.scene.traverse((obj) => {\r\n if (!(obj instanceof THREE.Mesh)) return;\r\n const mesh = obj as THREE.Mesh<THREE.BufferGeometry, THREE.Material>;\r\n const instanced = new THREE.InstancedMesh(mesh.geometry, mesh.material, matrices.length);\r\n matrices.forEach((m, i) => {\r\n instanced.setMatrixAt(i, new THREE.Matrix4().multiplyMatrices(m, mesh.matrixWorld));\r\n });\r\n instanced.instanceMatrix.needsUpdate = true;\r\n group.add(instanced);\r\n });\r\n } catch (err) {\r\n console.warn(`becomap: failed to load model ${url}`, err);\r\n }\r\n }),\r\n );\r\n return group;\r\n}\r\n","import * as THREE from 'three';\r\n\r\n/**\r\n * Named colour themes for store polygons.\r\n *\r\n * The palettes follow what the market leaders actually ship (values read from\r\n * Mappedin's own `styles.json` and Place Vendôme's abuzz scene): a very TIGHT,\r\n * HIGH-KEY value range — whites and near-whites within a few percent of each\r\n * other — with structure carried by soft tonal steps and one or two desaturated\r\n * accents, never by dark grey. Mappedin's walls are `#ffffff`, its rooms\r\n * `#f5f5f5`, its hallways `#FCFCFC`; the only saturated notes are a pale blue\r\n * (`#E6F4FB`) and a warm cream (`#F5EFE0`). Heavy mid-greys are what made the\r\n * earlier themes read as muddy, so nothing here goes below ~75% lightness.\r\n *\r\n * Every palette stays in a WARM hue family. A cool blue-grey of the same\r\n * lightness reads as an untextured CAD default rather than a material: the\r\n * leaders' only saturated notes are warm ones (Mappedin's `#F5EFE0` desks,\r\n * Place Vendôme's `#34230e` wood), because a map surface has to suggest\r\n * plaster, stone or timber to look designed rather than unfinished.\r\n *\r\n * - `ivory` — the DEFAULT: warm greige directory panels\r\n * - `data` — the venue's real editor colours for tops, walls and inner walls\r\n */\r\nexport type PolygonThemeName = 'ivory' | 'data' | 'neutral';\r\n\r\n/**\r\n * A multi-tier \"directory panel\" unit: a base band, a constant-height wall, and\r\n * a two-layer top (a lower rim with an inset upper face that holds the label).\r\n * When a theme sets this, units render as these fixed-colour panels instead of\r\n * the data-driven gradient block.\r\n */\r\nexport interface PanelStyle {\r\n /** Structural WALL / INNER_WALL height (m), constant — NOT from editor data. */\r\n wallHeight: number;\r\n /** Top section (rim + inset top face) as a FRACTION of the store's data\r\n * height; the base/wall gets the rest. Stores keep their original height. */\r\n topFraction: number;\r\n /** Width (m) of the rim between the panel edge and the inset upper face. */\r\n rimWidth: number;\r\n /**\r\n * When set, EVERY unit renders at this height (m) instead of its data\r\n * height — flush tops, one calm roofline (the Visioglobe look). The data\r\n * height still drives nothing but the selection overlay.\r\n */\r\n uniformHeight?: number;\r\n floor: string; // corridor / base-zone ground colour (keeps the map light)\r\n base: string; // store panel base-layer band at the floor\r\n edge: string; // store panel vertical edges\r\n /** WALL base layer — the flat floor plate (editor `fillColor`). */\r\n wallBase: string;\r\n /** WALL body — the actual perimeter wall band (editor `color`). */\r\n wall: string;\r\n /** INNER_WALL band — partitions carry a single colour in the data. */\r\n innerWall: string;\r\n topLower: string; // store panel top lower layer / rim\r\n topUpper: string; // store panel top upper face — inset, holds the label\r\n /** Sides of the raised top block (the bevel ring). Defaults to `edge`. */\r\n bevel?: string;\r\n /** Use each store's data/category colour for the top face instead of `topUpper`. */\r\n topUpperFromData?: boolean;\r\n /**\r\n * Use each WALL / INNER_WALL's own editor colours instead of the fixed ones:\r\n * the WALL's `fillColor` for the base layer and `color` for the wall band,\r\n * the INNER_WALL's `color` for partitions. Shapes missing a colour in the\r\n * data fall back to `wallBase` / `wall` / `innerWall`.\r\n */\r\n wallFromData?: boolean;\r\n}\r\n\r\nexport interface PolygonTheme {\r\n readonly name: PolygonThemeName;\r\n /** Store units render translucent (glass) rather than opaque. */\r\n readonly translucent: boolean;\r\n /**\r\n * Map background behind the venue. Kept in the same hue family as the panels —\r\n * a cool grey under warm ivory panels is the single fastest way to make an\r\n * otherwise good palette look cheap.\r\n */\r\n readonly background: string;\r\n /** Roof / top-face colour for a unit, given its data-driven base colour. */\r\n roof(base: THREE.Color): THREE.Color;\r\n /** Wall colour at the roof line. */\r\n wallTop(base: THREE.Color): THREE.Color;\r\n /** Wall colour at the floor — darker, to fake ambient occlusion. */\r\n wallBase(base: THREE.Color): THREE.Color;\r\n /** When set, units render as fixed-colour multi-tier panels (see PanelStyle). */\r\n panel?: PanelStyle;\r\n /** Label ink — black on light tops (ivory), white on data-coloured tops. */\r\n readonly labelColor: number;\r\n}\r\n\r\nconst WHITE = new THREE.Color(1, 1, 1);\r\nconst lighten = (c: THREE.Color, f: number): THREE.Color => c.clone().lerp(WHITE, f);\r\nconst darken = (c: THREE.Color, f: number): THREE.Color => c.clone().multiplyScalar(1 - f);\r\n/** Fixed colour, ignoring the data base — for the monochrome themes. */\r\nconst fixed = (hex: string) => (): THREE.Color => new THREE.Color(hex);\r\n\r\n/** Panel proportions — identical across themes; only the colours change. */\r\nconst PANEL_SHAPE = {\r\n wallHeight: 1.5, // structural walls, constant (~half of the old ~3m)\r\n topFraction: 0.3, // top section = 30% of the store's data height; base ≈ 70%\r\n rimWidth: 0.25, // narrow rim between the panel edge and the top face\r\n};\r\n\r\n/** The eight colours a panel palette needs, in draw order from ground to label. */\r\ninterface PanelPalette {\r\n floor: string;\r\n base: string;\r\n edge: string;\r\n wallBase: string;\r\n wall: string;\r\n innerWall: string;\r\n topLower: string;\r\n topUpper: string;\r\n bevel?: string;\r\n}\r\n\r\nconst panel = (p: PanelPalette): PanelStyle => ({ ...PANEL_SHAPE, ...p });\r\n\r\n/**\r\n * Warm ivory / greige. The tonal steps are deliberately small (each tier ~4-6%\r\n * darker than the one above) so the panel reads as one carved object catching\r\n * light, not as stacked slabs — and the top face stays near-white so the black\r\n * label keeps maximum contrast.\r\n */\r\nconst IVORY_PALETTE: PanelPalette = {\r\n floor: '#f2efe9', // warm ground — lighter than the panels sitting on it\r\n base: '#ded7cb', // greige plinth, the darkest note; grounds the panel\r\n edge: '#ece5d9', // panel sides, catching light\r\n wallBase: '#efe9df', // WALL floor plate — warm near-white\r\n wall: '#cfc7b8', // soft taupe wall: visible structure, never heavy\r\n innerWall: '#ded7ca', // partitions a step lighter than perimeter walls\r\n topLower: '#d5cdbf', // rim, deep enough to separate the top face\r\n topUpper: '#fffdf8', // warm white top face — holds the label\r\n bevel: '#fffdf8', // top layer's side walls — same colour as its top face\r\n};\r\n\r\n/** The default aesthetic look — warm, opaque ivory panels. */\r\nconst IVORY: PolygonTheme = {\r\n name: 'ivory',\r\n translucent: false,\r\n background: '#ffffff', // white map backdrop\r\n labelColor: 0x000000, // black ink on the near-white tops\r\n roof: fixed(IVORY_PALETTE.topUpper),\r\n wallTop: fixed(IVORY_PALETTE.edge),\r\n wallBase: fixed(IVORY_PALETTE.base),\r\n panel: panel(IVORY_PALETTE),\r\n};\r\n\r\n/**\r\n * The same panel, but everything colourable takes its real editor value: the\r\n * store top face, the WALL's floor plate (`fillColor`) and wall band (`color`),\r\n * and the INNER_WALL partitions (`color`). Ivory supplies the fallbacks for\r\n * shapes the editor left uncoloured.\r\n */\r\nconst DATA: PolygonTheme = {\r\n name: 'data',\r\n translucent: false,\r\n background: '#ffffff', // white map backdrop, same as ivory\r\n labelColor: 0xffffff, // white ink on the data-coloured tops (the MOQ/DFCM way)\r\n roof: (base) => lighten(base, 0.12),\r\n wallTop: (base) => darken(base, 0.05),\r\n wallBase: (base) => darken(base, 0.34),\r\n panel: {\r\n ...panel(IVORY_PALETTE),\r\n // Visioglobe policy: a WHITE slab body under a colour top, on a single\r\n // quiet cool-grey ground. Structure (walls/partitions) is nearly invisible\r\n // light grey — the coloured stores are the only thing with visual weight.\r\n floor: '#e8e9eb',\r\n base: '#ffffff',\r\n edge: '#ffffff',\r\n // the exposed top surface of the lower block — darker than the white\r\n // sides, so the ledge reads as its own layer and separates neighbours\r\n topLower: '#eaeaf4',\r\n wallBase: '#ededef',\r\n wall: '#e3e4e6',\r\n innerWall: '#e3e4e6',\r\n rimWidth: 0.3, // wide visible ledge around the coloured top — clear separation\r\n topUpperFromData: true,\r\n // NOTE: wallFromData intentionally off — raw editor wall colours break the\r\n // calm-ground rule that makes this look work.\r\n },\r\n};\r\n\r\nconst THEMES: Record<PolygonThemeName, PolygonTheme> = {\r\n ivory: IVORY,\r\n data: DATA,\r\n neutral: IVORY, // back-compat alias for the old default\r\n};\r\n\r\n/** Resolve a theme name (or undefined) to its preset — defaults to `ivory`. */\r\nexport function resolvePolygonTheme(name: PolygonThemeName | undefined): PolygonTheme {\r\n return THEMES[name ?? 'ivory'];\r\n}\r\n","import * as THREE from 'three';\r\nimport maplibregl from 'maplibre-gl';\r\nimport type { LngLat } from '../data/types.js';\r\n\r\nexport interface FrameStats {\r\n drawCalls: number;\r\n triangles: number;\r\n}\r\n\r\n/**\r\n * The ONE custom layer owning the ONE Three.js scene (extrusions, labels,\r\n * models — a single depth buffer so occlusion is always correct). MapLibre\r\n * 4.x CustomLayerInterface (`render(gl, matrix)` signature — v5 changed it;\r\n * see Phase 1 research for the version pin rationale).\r\n */\r\nexport class RenderLayer implements maplibregl.CustomLayerInterface {\r\n readonly id = 'becomap-3d';\r\n readonly type = 'custom' as const;\r\n readonly renderingMode = '3d' as const;\r\n\r\n #root: THREE.Object3D;\r\n #origin: LngLat;\r\n #camera = new THREE.Camera();\r\n #scene = new THREE.Scene();\r\n #renderer: THREE.WebGLRenderer | null = null;\r\n #originMatrix = new THREE.Matrix4();\r\n #map: maplibregl.Map | null = null;\r\n #stats: FrameStats = { drawCalls: 0, triangles: 0 };\r\n #lastMatrix = new THREE.Matrix4();\r\n #hasMatrix = false;\r\n\r\n constructor(root: THREE.Object3D, origin: LngLat) {\r\n this.#root = root;\r\n this.#origin = origin;\r\n }\r\n\r\n onAdd(map: maplibregl.Map, gl: WebGLRenderingContext | WebGL2RenderingContext): void {\r\n this.#map = map;\r\n this.#scene.add(this.#root);\r\n const mc = maplibregl.MercatorCoordinate.fromLngLat(\r\n { lng: this.#origin[0], lat: this.#origin[1] },\r\n 0,\r\n );\r\n const scale = mc.meterInMercatorCoordinateUnits();\r\n // meters (y-up after the root's rotX(-π/2)) → mercator; same construction\r\n // as the POC / official MapLibre three.js example\r\n this.#originMatrix = new THREE.Matrix4()\r\n .makeTranslation(mc.x, mc.y, mc.z)\r\n .scale(new THREE.Vector3(scale, -scale, scale))\r\n .multiply(new THREE.Matrix4().makeRotationX(Math.PI / 2));\r\n this.#renderer = new THREE.WebGLRenderer({\r\n canvas: map.getCanvas(),\r\n context: gl,\r\n antialias: true,\r\n });\r\n this.#renderer.autoClear = false;\r\n }\r\n\r\n // property (not method) to satisfy maplibre's strictly-typed interface;\r\n // matrix arrives as gl-matrix mat4 (array-like of 16 numbers)\r\n render: maplibregl.CustomRenderMethod = (_gl, matrix) => {\r\n if (!this.#renderer) return;\r\n this.#camera.projectionMatrix = new THREE.Matrix4()\r\n .fromArray(Array.from(matrix as ArrayLike<number>))\r\n .multiply(this.#originMatrix);\r\n this.#lastMatrix.copy(this.#camera.projectionMatrix);\r\n this.#hasMatrix = true;\r\n this.#renderer.resetState();\r\n this.#renderer.render(this.#scene, this.#camera);\r\n this.#stats = {\r\n drawCalls: this.#renderer.info.render.calls,\r\n triangles: this.#renderer.info.render.triangles,\r\n };\r\n };\r\n\r\n onRemove(): void {\r\n this.#scene.remove(this.#root);\r\n this.#renderer?.dispose();\r\n this.#renderer = null;\r\n this.#map = null;\r\n }\r\n\r\n repaint(): void {\r\n this.#map?.triggerRepaint();\r\n }\r\n\r\n getFrameStats(): FrameStats {\r\n return this.#stats;\r\n }\r\n\r\n /** Debug/diagnostics access to the live scene graph (not part of the public API). */\r\n debugScene(): THREE.Scene {\r\n return this.#scene;\r\n }\r\n\r\n /** Debug: the last frame's full projection matrix (clip = M · rootTransform · v). */\r\n debugMatrix(): number[] | null {\r\n return this.#hasMatrix ? this.#lastMatrix.toArray() : null;\r\n }\r\n\r\n /**\r\n * Unproject a CSS-pixel point into a RAY in the build frame (venue-local\r\n * meters, z-up) using the projection matrix of the last rendered frame.\r\n * This is what makes extruded stores clickable on their whole 3D body:\r\n * MapLibre's lngLat is the GROUND intersection, which at pitch lands behind\r\n * a tall store when the user clicks its roof or side.\r\n */\r\n /** Project a build-frame point (venue meters, z-up) to CSS-pixel screen\r\n * coordinates using the last rendered frame's matrix. Null offscreen/unready. */\r\n projectPoint(x: number, y: number, z: number): { x: number; y: number } | null {\r\n if (!this.#hasMatrix || !this.#map) return null;\r\n const canvas = this.#map.getCanvas();\r\n const w = canvas.clientWidth;\r\n const h = canvas.clientHeight;\r\n if (!w || !h) return null;\r\n const full = new THREE.Matrix4().multiplyMatrices(\r\n this.#lastMatrix,\r\n new THREE.Matrix4().makeRotationX(-Math.PI / 2),\r\n );\r\n const v = new THREE.Vector4(x, y, z, 1).applyMatrix4(full);\r\n if (v.w <= 0) return null; // behind the camera\r\n return { x: ((v.x / v.w + 1) / 2) * w, y: ((1 - v.y / v.w) / 2) * h };\r\n }\r\n\r\n pickRay(px: number, py: number): { origin: THREE.Vector3; dir: THREE.Vector3 } | null {\r\n if (!this.#hasMatrix || !this.#map) return null;\r\n const canvas = this.#map.getCanvas();\r\n const w = canvas.clientWidth;\r\n const h = canvas.clientHeight;\r\n if (!w || !h) return null;\r\n const ndcX = (px / w) * 2 - 1;\r\n const ndcY = 1 - (py / h) * 2;\r\n // clip = P · rotX(-π/2) · v_build → invert the full chain\r\n const full = new THREE.Matrix4().multiplyMatrices(\r\n this.#lastMatrix,\r\n new THREE.Matrix4().makeRotationX(-Math.PI / 2),\r\n );\r\n const inv = full.invert();\r\n const a4 = new THREE.Vector4(ndcX, ndcY, -1, 1).applyMatrix4(inv);\r\n const b4 = new THREE.Vector4(ndcX, ndcY, 1, 1).applyMatrix4(inv);\r\n if (!a4.w || !b4.w) return null;\r\n const origin = new THREE.Vector3(a4.x / a4.w, a4.y / a4.w, a4.z / a4.w);\r\n const far = new THREE.Vector3(b4.x / b4.w, b4.y / b4.w, b4.z / b4.w);\r\n const dir = far.sub(origin).normalize();\r\n return { origin, dir };\r\n }\r\n}\r\n","import * as THREE from 'three';\r\nimport type { RouteSegment } from '../routing/segments.js';\r\nimport { ringToMeters, type VenueFrame } from './coords.js';\r\nimport { SLAB_HEIGHT } from './geometry.js';\r\n\r\nconst RIBBON_WIDTH = 1.6;\r\n// start-of-route marker: the SDK's classic source pin artwork\r\nconst START_MARKER_URL =\r\n 'https://backend-lightning-prod.s3.ap-southeast-1.amazonaws.com/assets/source.svg';\r\nconst START_MARKER_PX = 54; // constant on-screen height — prominent but not overpowering\r\nconst Z_INDOOR = SLAB_HEIGHT + 0.35;\r\nconst Z_OUTDOOR = 0.35;\r\n\r\nconst RIBBON_VERTEX = /* glsl */ `\r\n varying vec2 vUv;\r\n void main() {\r\n vUv = uv;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n }\r\n`;\r\n\r\n// uGhost=0 → solid pass (real depth); uGhost=1 → faint x-ray pass drawn\r\n// through walls so the occluded part of the path is never lost.\r\nconst RIBBON_FRAGMENT = /* glsl */ `\r\n uniform float uProgress;\r\n uniform float uVisited;\r\n uniform float uTime;\r\n uniform float uGhost;\r\n varying vec2 vUv; // x = arc length in meters, y = 0..1 across the ribbon\r\n void main() {\r\n float u = vUv.x;\r\n if (u > uProgress) discard;\r\n float v = abs(vUv.y - 0.5);\r\n float p = fract(u / 7.0 - uTime * 0.45);\r\n float a = 0.42 - v;\r\n float arrow = step(a * 0.55, p) * step(p, a * 0.55 + 0.16) * step(v, 0.42);\r\n float visited = 1.0 - step(uVisited, u);\r\n vec3 base = mix(vec3(0.18, 0.50, 0.93), vec3(0.66, 0.69, 0.75), visited);\r\n float arrowStrength = mix(0.95, 0.25, visited);\r\n vec3 col = mix(base, vec3(1.0), arrow * arrowStrength);\r\n // ghost: lighten toward pale blue and cut alpha so it reads as \"behind glass\"\r\n col = mix(col, vec3(0.60, 0.76, 0.98), uGhost * 0.6);\r\n float edge = smoothstep(0.5, 0.40, v);\r\n gl_FragColor = vec4(col, edge * mix(1.0, 0.30, uGhost));\r\n }\r\n`;\r\n\r\nfunction makeRibbonMaterial(ghost: boolean): THREE.ShaderMaterial {\r\n return new THREE.ShaderMaterial({\r\n transparent: true,\r\n depthWrite: false,\r\n // solid pass keeps REAL depth: the path is occluded by near walls and\r\n // reads as sitting IN the 3D world (not a flat 2D overlay). ghost pass\r\n // ignores depth to show the hidden portion faintly through walls.\r\n depthTest: !ghost,\r\n side: THREE.DoubleSide,\r\n uniforms: {\r\n uProgress: { value: 0 },\r\n uVisited: { value: 0 },\r\n uTime: { value: 0 },\r\n uGhost: { value: ghost ? 1 : 0 },\r\n },\r\n vertexShader: RIBBON_VERTEX,\r\n fragmentShader: RIBBON_FRAGMENT,\r\n });\r\n}\r\n\r\n/**\r\n * Animated route ribbon with a two-pass x-ray occlusion technique (grounded\r\n * in occlusion-reduced 3D-routing research + Google patent EP3186591A1):\r\n * - SOLID pass: normal depth test, so the path is correctly occluded by walls\r\n * in front of it and reads as a real 3D object on the floor.\r\n * - GHOST pass: depth test off + faint/pale, so wherever a wall hides the\r\n * path you still see a dim x-ray of it (obstacles stay as landmarks).\r\n * Both passes share reveal (uProgress), visited dimming (uVisited), and\r\n * flowing chevrons (uTime). Two draw calls per segment.\r\n */\r\nexport class RouteRibbon {\r\n #material = makeRibbonMaterial(false);\r\n #ghostMaterial = makeRibbonMaterial(true);\r\n #meshes: {\r\n solid: THREE.Mesh;\r\n ghost: THREE.Mesh;\r\n segment: RouteSegment;\r\n start: number;\r\n end: number;\r\n /** Spaced samples + their GLOBAL arc metres — the runner interpolates these. */\r\n pts: THREE.Vector3[];\r\n arcs: number[];\r\n }[] = [];\r\n #runner: THREE.Group | null = null;\r\n #startMarker: THREE.Mesh | null = null;\r\n #startTex: THREE.CanvasTexture | null = null;\r\n #startAspect = 0.8;\r\n #startView = { bearing: 0, pitch: 0, mpp: 0.05 };\r\n #parent: THREE.Object3D;\r\n #frame: VenueFrame;\r\n #totalLength = 0;\r\n #repaint: () => void;\r\n\r\n constructor(parent: THREE.Object3D, frame: VenueFrame, repaint: () => void = () => undefined) {\r\n this.#parent = parent;\r\n this.#frame = frame;\r\n this.#repaint = repaint;\r\n }\r\n\r\n /** Build ribbon meshes for the segments. Returns total ribbon arc length. */\r\n setRoute(segments: RouteSegment[]): number {\r\n this.clear();\r\n let offset = 0;\r\n for (const segment of segments) {\r\n const localPts = ringToMeters(this.#frame, segment.points);\r\n if (localPts.length < 2) continue;\r\n const z = segment.buildingId ? Z_INDOOR : Z_OUTDOOR;\r\n const curve = new THREE.CatmullRomCurve3(\r\n localPts.map(([x, y]) => new THREE.Vector3(x, y, z)),\r\n false,\r\n 'catmullrom',\r\n 0.05,\r\n );\r\n const length = curve.getLength();\r\n const n = Math.max(2, Math.ceil(length / 1.2));\r\n const pts = curve.getSpacedPoints(n);\r\n const pos = new Float32Array((n + 1) * 2 * 3);\r\n const uvs = new Float32Array((n + 1) * 2 * 2);\r\n const idx: number[] = [];\r\n const tan = new THREE.Vector3();\r\n let acc = offset;\r\n const arcs: number[] = [];\r\n for (let i = 0; i <= n; i++) {\r\n const p = pts[i];\r\n const prev = pts[i - 1];\r\n const next = pts[i + 1];\r\n if (!p) continue;\r\n if (i > 0 && prev) acc += p.distanceTo(prev);\r\n arcs.push(acc);\r\n if (i === 0 && next) tan.subVectors(next, p);\r\n else if (i === n && prev) tan.subVectors(p, prev);\r\n else if (prev && next) tan.subVectors(next, prev);\r\n tan.z = 0;\r\n tan.normalize();\r\n const nx = -tan.y * RIBBON_WIDTH * 0.5;\r\n const ny = tan.x * RIBBON_WIDTH * 0.5;\r\n pos.set([p.x + nx, p.y + ny, p.z, p.x - nx, p.y - ny, p.z], i * 6);\r\n uvs.set([acc, 0, acc, 1], i * 4);\r\n if (i < n) {\r\n const a = i * 2;\r\n idx.push(a, a + 1, a + 2, a + 1, a + 3, a + 2);\r\n }\r\n }\r\n const geo = new THREE.BufferGeometry();\r\n geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\r\n geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));\r\n geo.setIndex(idx);\r\n // ghost first (behind), then solid on top where it's genuinely visible\r\n const ghost = new THREE.Mesh(geo, this.#ghostMaterial);\r\n ghost.renderOrder = 9;\r\n const solid = new THREE.Mesh(geo, this.#material);\r\n solid.renderOrder = 11;\r\n this.#parent.add(ghost, solid);\r\n this.#meshes.push({ solid, ghost, segment, start: offset, end: acc, pts, arcs });\r\n offset = acc;\r\n }\r\n this.#totalLength = offset;\r\n // plant the start pin on the route's first point\r\n const first = this.#meshes[0];\r\n const start = first?.pts[0];\r\n if (first && start) {\r\n const marker = this.#ensureStartMarker();\r\n marker.position.set(start.x, start.y, start.z + 0.05);\r\n marker.visible = true;\r\n this.#applyStartMarkerView();\r\n }\r\n return offset;\r\n }\r\n\r\n get totalLength(): number {\r\n return this.#totalLength;\r\n }\r\n\r\n get active(): boolean {\r\n return this.#meshes.length > 0;\r\n }\r\n\r\n /** Per-segment visibility (outdoor always; indoor per visible floor). */\r\n updateVisibility(isFloorVisible: (floorId: string, buildingId: string | null) => boolean): void {\r\n for (const entry of this.#meshes) {\r\n const visible =\r\n entry.segment.buildingId === null\r\n ? true\r\n : isFloorVisible(entry.segment.floorId, entry.segment.buildingId);\r\n entry.solid.visible = visible;\r\n entry.ghost.visible = visible;\r\n }\r\n // the start pin lives on the START segment's floor\r\n const first = this.#meshes[0];\r\n if (this.#startMarker && first) {\r\n this.#startMarker.visible =\r\n first.segment.buildingId === null\r\n ? true\r\n : isFloorVisible(first.segment.floorId, first.segment.buildingId);\r\n }\r\n }\r\n\r\n /** The segment END (arc metres) closest to `meters` — the true boundary the\r\n * runner must park BEFORE while a floor-change card is showing. Step\r\n * distances and ribbon arcs differ slightly (the ribbon resamples through a\r\n * curve), so callers must use the ribbon's own boundary, not the step's. */\r\n nearestBoundary(meters: number): number | null {\r\n let best: number | null = null;\r\n for (const entry of this.#meshes) {\r\n if (best === null || Math.abs(entry.end - meters) < Math.abs(best - meters)) best = entry.end;\r\n }\r\n return best;\r\n }\r\n\r\n /** Segment whose arc range contains the given progress (for floor-follow). */\r\n segmentAt(progressMeters: number): RouteSegment | undefined {\r\n return this.#meshes.find((m) => progressMeters >= m.start && progressMeters < m.end)?.segment;\r\n }\r\n\r\n #setUniform(name: 'uProgress' | 'uVisited' | 'uTime', value: number): void {\r\n const a = this.#material.uniforms[name];\r\n const b = this.#ghostMaterial.uniforms[name];\r\n if (a) a.value = value;\r\n if (b) b.value = value;\r\n }\r\n setProgress(meters: number): void {\r\n this.#setUniform('uProgress', meters);\r\n }\r\n setVisited(meters: number): void {\r\n this.#setUniform('uVisited', meters);\r\n }\r\n getVisited(): number {\r\n return (this.#material.uniforms.uVisited?.value as number | undefined) ?? 0;\r\n }\r\n setTime(seconds: number): void {\r\n this.#setUniform('uTime', seconds);\r\n }\r\n\r\n /**\r\n * Start-of-route marker: the source pin artwork on a textured quad INSIDE\r\n * the 3D scene. A THREE.Sprite cannot billboard here (the camera's view\r\n * matrix is folded into one combined projection matrix, so sprite-space\r\n * axes are not screen axes) — instead the quad is oriented every camera\r\n * move from the map's own bearing + pitch and rescaled from metres-per-\r\n * pixel to hold a constant on-screen height. Unlike a DOM marker it is\r\n * depth-tested against the venue, so walls in front genuinely occlude it.\r\n */\r\n #ensureStartMarker(): THREE.Mesh {\r\n if (this.#startMarker) return this.#startMarker;\r\n // Transparent until the artwork arrives — the texture is built ONLY once\r\n // the image is in hand. A CanvasTexture must never be resized after its\r\n // first upload: three allocates immutable GPU storage from that first\r\n // size, so a later, larger redraw silently fails to upload and the pin\r\n // renders as nothing at all.\r\n const mat = new THREE.MeshBasicMaterial({\r\n transparent: true,\r\n depthWrite: false,\r\n depthTest: false,\r\n opacity: 0,\r\n });\r\n const img = new Image();\r\n img.crossOrigin = 'anonymous';\r\n img.onload = () => {\r\n const h = 256;\r\n const w = Math.max(2, Math.round((img.width / img.height) * h) || h);\r\n const canvas = document.createElement('canvas');\r\n canvas.width = w;\r\n canvas.height = h;\r\n canvas.getContext('2d')?.drawImage(img, 0, 0, w, h);\r\n const tex = new THREE.CanvasTexture(canvas);\r\n tex.colorSpace = THREE.SRGBColorSpace;\r\n tex.anisotropy = 4;\r\n tex.generateMipmaps = false; // level 0 only: sharper, and no mip surprises\r\n tex.minFilter = THREE.LinearFilter;\r\n this.#startTex?.dispose();\r\n this.#startTex = tex;\r\n mat.map = tex;\r\n mat.opacity = 1;\r\n mat.needsUpdate = true;\r\n this.#startAspect = w / h;\r\n this.#applyStartMarkerView();\r\n this.#repaint();\r\n };\r\n img.src = START_MARKER_URL;\r\n const geo = new THREE.PlaneGeometry(1, 1);\r\n geo.translate(0, 0.5, 0); // bottom-anchored: the pin tip sits ON the point\r\n // drawn OVER the venue (no depth test), the way Visioglobe presents its\r\n // route pins: standing on the roof but never swallowed by other buildings\r\n const mesh = new THREE.Mesh(geo, mat);\r\n mesh.renderOrder = 30;\r\n mesh.frustumCulled = false;\r\n mesh.visible = false;\r\n this.#parent.add(mesh);\r\n this.#startMarker = mesh;\r\n return mesh;\r\n }\r\n\r\n /** Stand the start pin's tip at this build-frame altitude. Routes start at\r\n * a store's node INSIDE its extruded volume, where a depth-tested pin\r\n * would be swallowed by the store's own walls — the caller lifts it onto\r\n * the store's rendered roof instead (amenity-badge style). */\r\n setStartMarkerAltitude(z: number): void {\r\n const m = this.#startMarker;\r\n if (m) m.position.z = z;\r\n }\r\n\r\n /** Feed the map camera in: bearing/pitch orient the start pin toward the\r\n * viewer, metres-per-pixel holds it at a constant on-screen height. */\r\n setStartMarkerView(bearingDeg: number, pitchDeg: number, metersPerPixel: number): void {\r\n this.#startView = { bearing: bearingDeg, pitch: pitchDeg, mpp: metersPerPixel };\r\n this.#applyStartMarkerView();\r\n }\r\n\r\n #applyStartMarkerView(): void {\r\n const m = this.#startMarker;\r\n if (!m) return;\r\n const { bearing, pitch, mpp } = this.#startView;\r\n const h = START_MARKER_PX * mpp;\r\n m.scale.set(h * this.#startAspect, h, 1);\r\n // yaw to the screen's up direction, then tip back by the camera pitch:\r\n // a billboard built from map camera parameters\r\n m.rotation.set((pitch * Math.PI) / 180, 0, (-bearing * Math.PI) / 180, 'ZXY');\r\n }\r\n\r\n /**\r\n * Lazily built 3D marker that travels the route in preview: a classic pin —\r\n * a lit cone standing tip-down on the path with a sphere head — so it reads\r\n * as a real object in the scene, not a flat decal. Route-blue, always\r\n * upright; sized ~3m so it's visible at venue zoom.\r\n */\r\n #ensureRunner(): THREE.Group {\r\n if (this.#runner) return this.#runner;\r\n const group = new THREE.Group();\r\n const mat = new THREE.MeshLambertMaterial({ color: '#2e80ee' });\r\n const cone = new THREE.ConeGeometry(0.7, 2.0, 24);\r\n cone.rotateX(-Math.PI / 2); // apex points DOWN (-z) — the pin's tip\r\n const tip = new THREE.Mesh(cone, mat);\r\n tip.position.z = 1.0; // tip touches the group origin (the path)\r\n const head = new THREE.Mesh(new THREE.SphereGeometry(0.85, 24, 18), mat);\r\n head.position.z = 2.4;\r\n group.add(tip, head);\r\n // the mercator-scale projection can misjudge tiny bounding spheres —\r\n // never let the marker be frustum-culled away\r\n group.traverse((o) => (o.frustumCulled = false));\r\n group.renderOrder = 20;\r\n group.visible = false;\r\n this.#parent.add(group);\r\n this.#runner = group;\r\n return group;\r\n }\r\n\r\n showRunner(): void {\r\n this.#ensureRunner().visible = true;\r\n }\r\n\r\n hideRunner(): void {\r\n if (this.#runner) this.#runner.visible = false;\r\n }\r\n\r\n /** Place the 3D pin at `meters` along the route (tip on the path). */\r\n setRunner(meters: number): void {\r\n const entry = this.#meshes.find((m) => meters >= m.start && meters <= m.end) ?? this.#meshes[0];\r\n if (!entry) return;\r\n const runner = this.#ensureRunner();\r\n const { pts, arcs } = entry;\r\n let i = 0;\r\n while (i < arcs.length - 1 && (arcs[i + 1] ?? Infinity) < meters) i++;\r\n const a = pts[i];\r\n const b = pts[Math.min(i + 1, pts.length - 1)];\r\n const a0 = arcs[i] ?? 0;\r\n const a1 = arcs[Math.min(i + 1, arcs.length - 1)] ?? a0;\r\n if (!a || !b) return;\r\n const t = a1 > a0 ? Math.min(1, Math.max(0, (meters - a0) / (a1 - a0))) : 0;\r\n runner.position.set(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + 0.05);\r\n }\r\n\r\n clear(): void {\r\n for (const entry of this.#meshes) {\r\n this.#parent.remove(entry.solid, entry.ghost);\r\n entry.solid.geometry.dispose(); // shared geometry — dispose once\r\n }\r\n this.#meshes = [];\r\n this.#totalLength = 0;\r\n this.hideRunner();\r\n if (this.#startMarker) this.#startMarker.visible = false;\r\n this.setProgress(0);\r\n this.setVisited(0);\r\n }\r\n\r\n dispose(): void {\r\n this.clear();\r\n if (this.#runner) {\r\n this.#parent.remove(this.#runner);\r\n this.#runner.traverse((obj) => {\r\n if (obj instanceof THREE.Mesh) {\r\n (obj.geometry as THREE.BufferGeometry).dispose();\r\n (obj.material as THREE.Material).dispose();\r\n }\r\n });\r\n this.#runner = null;\r\n }\r\n if (this.#startMarker) {\r\n this.#parent.remove(this.#startMarker);\r\n this.#startMarker.geometry.dispose();\r\n (this.#startMarker.material as THREE.Material).dispose();\r\n this.#startMarker = null;\r\n }\r\n this.#startTex?.dispose();\r\n this.#startTex = null;\r\n this.#material.dispose();\r\n this.#ghostMaterial.dispose();\r\n }\r\n}\r\n","import type { Venue } from '../data/venue-model.js';\n\n/** Zoom at/after which buildings open automatically. */\nexport const OPEN_ZOOM = 16.2;\n/** Below this zoom, click-opened buildings reset (hysteresis). */\nexport const CLOSE_ZOOM = 15.4;\n\nexport interface BuildingView {\n open: boolean;\n floorId: string;\n}\n\nexport interface ViewChange {\n buildingId: string;\n view: BuildingView;\n}\n\n/**\n * Pure LOD/floor state machine: derives per-building views (sealed shell vs\n * one visible floor) from the zoom level, click-opens, and floor selection.\n * The renderer applies the returned changes; no three.js/maplibre in here.\n */\nexport class FloorManager {\n #venue: Venue;\n #openZoom: number;\n #closeZoom: number;\n #zoom = 0;\n #selected = new Map<string, string>(); // buildingId -> floorId\n #manualOpen = new Set<string>();\n #focusedBuildingId: string | null = null;\n #lastViews = new Map<string, BuildingView>();\n\n constructor(venue: Venue, options: { openZoom?: number; closeZoom?: number } = {}) {\n this.#venue = venue;\n this.#openZoom = options.openZoom ?? OPEN_ZOOM;\n this.#closeZoom = options.closeZoom ?? CLOSE_ZOOM;\n for (const b of venue.buildings) {\n const ground = b.floors[0];\n if (ground) this.#selected.set(b.id, ground.id);\n }\n this.#focusedBuildingId = venue.buildings[0]?.id ?? null;\n }\n\n focusedBuildingId(): string | null {\n return this.#focusedBuildingId;\n }\n\n focusBuilding(buildingId: string): void {\n if (this.#venue.getBuilding(buildingId)) this.#focusedBuildingId = buildingId;\n }\n\n viewOf(buildingId: string): BuildingView | undefined {\n return this.#computeView(buildingId);\n }\n\n views(): Map<string, BuildingView> {\n const out = new Map<string, BuildingView>();\n for (const b of this.#venue.buildings) {\n const v = this.#computeView(b.id);\n if (v) out.set(b.id, v);\n }\n return out;\n }\n\n /** Zoom moved (continuous). Returns the views that changed. */\n update(zoom: number): ViewChange[] {\n this.#zoom = zoom;\n return this.#diff();\n }\n\n /** Zoom settled. Below the close threshold, manual opens reset. */\n onZoomEnd(zoom: number): ViewChange[] {\n this.#zoom = zoom;\n if (zoom < this.#closeZoom && this.#manualOpen.size > 0) this.#manualOpen.clear();\n return this.#diff();\n }\n\n /** Click on a sealed building: open it (persists until reseal). */\n clickOpen(buildingId: string): ViewChange[] {\n if (!this.#venue.getBuilding(buildingId)) return [];\n this.#manualOpen.add(buildingId);\n this.#focusedBuildingId = buildingId;\n return this.#diff();\n }\n\n /**\n * Select a floor by id. Focuses its building; selecting a floor of a\n * sealed building opens it (POC behavior).\n */\n selectFloor(floorId: string): ViewChange[] {\n const floor = this.#venue.getFloor(floorId);\n if (!floor) return [];\n this.#selected.set(floor.buildingId, floorId);\n this.#focusedBuildingId = floor.buildingId;\n const view = this.#computeView(floor.buildingId);\n if (view && !view.open) this.#manualOpen.add(floor.buildingId);\n return this.#diff();\n }\n\n #isOpen(buildingId: string): boolean {\n return this.#zoom >= this.#openZoom || this.#manualOpen.has(buildingId);\n }\n\n #computeView(buildingId: string): BuildingView | undefined {\n const floorId = this.#selected.get(buildingId);\n if (floorId === undefined) return undefined;\n return { open: this.#isOpen(buildingId), floorId };\n }\n\n #diff(): ViewChange[] {\n const changes: ViewChange[] = [];\n for (const b of this.#venue.buildings) {\n const next = this.#computeView(b.id);\n if (!next) continue;\n const prev = this.#lastViews.get(b.id);\n if (!prev || prev.open !== next.open || prev.floorId !== next.floorId) {\n changes.push({ buildingId: b.id, view: next });\n this.#lastViews.set(b.id, next);\n }\n }\n return changes;\n }\n}\n","import type { Building } from '../data/types.js';\nimport type { BuildingView } from '../lod/floor-manager.js';\n\n/**\n * Built-in floor switcher control (top-right): shows the focused building's\n * name and one button per floor, bottom-up like an elevator panel. Selecting\n * a floor of a sealed building opens it. Inline-styled — no CSS import\n * required by consumers. Disable via `createMap(..., { ui: { floorSwitcher:\n * false } })`.\n */\nexport interface FloorSwitcher {\n update(building: Building | null, view: BuildingView | undefined): void;\n dispose(): void;\n}\n\nexport function createFloorSwitcher(\n container: HTMLElement,\n onSelect: (floorId: string) => void,\n): FloorSwitcher {\n const el = document.createElement('div');\n el.style.cssText =\n 'position:absolute;top:12px;right:12px;z-index:10;background:rgba(255,255,255,.92);' +\n 'border-radius:10px;padding:10px 12px;font-family:system-ui,sans-serif;font-size:12px;' +\n 'color:#1f2937;box-shadow:0 2px 12px rgba(0,0,0,.12);text-align:center;display:none';\n const name = document.createElement('div');\n name.style.cssText = 'font-weight:600;margin-bottom:6px;max-width:110px';\n const buttons = document.createElement('div');\n buttons.style.cssText = 'display:flex;flex-direction:column-reverse;gap:4px';\n el.append(name, buttons);\n container.appendChild(el);\n\n return {\n update(building, view): void {\n if (!building) {\n el.style.display = 'none';\n return;\n }\n el.style.display = 'block';\n name.textContent = building.name;\n buttons.replaceChildren();\n for (const floor of building.floors) {\n const btn = document.createElement('button');\n btn.textContent = floor.name;\n const active = view?.open === true && view.floorId === floor.id;\n btn.style.cssText =\n 'width:44px;height:32px;margin:0 auto;border:1px solid #d1d5db;border-radius:8px;' +\n 'font-size:13px;font-weight:600;cursor:pointer;' +\n (active ? 'background:#0d9488;border-color:#0d9488;color:#fff' : 'background:#fff;color:#1f2937');\n btn.onclick = () => {\n onSelect(floor.id);\n };\n buttons.appendChild(btn);\n }\n },\n dispose(): void {\n el.remove();\n },\n };\n}\n","import type { Venue } from '../data/venue-model.js';\r\nimport type { BuildingView } from '../lod/floor-manager.js';\r\nimport { pointInRing } from '../render/coords.js';\r\nimport type { LngLat, Shape, VenueLocation } from '../data/types.js';\r\n\r\nexport type ClickTarget =\r\n | { kind: 'sealed'; buildingId: string; ring: LngLat[] }\r\n | {\r\n kind: 'store';\r\n buildingId: string;\r\n floorId: string;\r\n location: VenueLocation;\r\n shape: Shape;\r\n }\r\n | { kind: 'corridor'; buildingId: string }\r\n | { kind: 'outdoor' };\r\n\r\n/**\r\n * Pure click resolution against the venue model + current LOD views:\r\n * - inside a sealed building's footprint → 'sealed'\r\n * - inside an open building: on a unit shape of the VISIBLE floor with a\r\n * linked location → 'store'; otherwise → 'corridor'\r\n * - anywhere else → 'outdoor'\r\n */\r\nexport function resolveClick(\r\n venue: Venue,\r\n viewOf: (buildingId: string) => BuildingView | undefined,\r\n lng: number,\r\n lat: number,\r\n): ClickTarget {\r\n for (const building of venue.buildings) {\r\n const view = viewOf(building.id);\r\n if (!view) continue;\r\n const footprint = building.floors[0]?.shapes.find(\r\n (s) => (s.layerId === 'footprint' || s.type.toUpperCase() === 'WALL') && s.geometry.type === 'Polygon',\r\n );\r\n const ring = footprint?.geometry.type === 'Polygon' ? footprint.geometry.coordinates[0] : undefined;\r\n if (!ring || !pointInRing(ring, lng, lat)) continue;\r\n\r\n if (!view.open) return { kind: 'sealed', buildingId: building.id, ring };\r\n\r\n const floor = building.floors.find((f) => f.id === view.floorId);\r\n if (floor) {\r\n const locationByShapeId = new Map<string, VenueLocation>();\r\n for (const loc of floor.locations) {\r\n if (loc.shapeId) locationByShapeId.set(loc.shapeId, loc);\r\n }\r\n for (const shape of floor.shapes) {\r\n if (shape.layerId === 'footprint' || shape.geometry.type !== 'Polygon') continue;\r\n const shapeRing = shape.geometry.coordinates[0];\r\n if (!shapeRing || !pointInRing(shapeRing, lng, lat)) continue;\r\n const location = locationByShapeId.get(shape.id);\r\n if (location && !location.hidden) {\r\n return { kind: 'store', buildingId: building.id, floorId: floor.id, location, shape };\r\n }\r\n }\r\n }\r\n return { kind: 'corridor', buildingId: building.id };\r\n }\r\n return { kind: 'outdoor' };\r\n}\r\n","import type { Venue } from '../data/venue-model.js';\nimport type { VenueLocation } from '../data/types.js';\n\nexport interface SearchResult {\n location: VenueLocation;\n /** Higher is better: matched tokens + full-prefix bonuses. */\n score: number;\n}\n\ninterface IndexEntry {\n location: VenueLocation;\n nameTokens: string[];\n categoryTokens: string[];\n}\n\n/** Lowercase + strip diacritics (NFD) + split on non-alphanumerics. */\nexport function tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 0);\n}\n\n/**\n * Search index over venue locations: built once at load, queried with\n * diacritic-insensitive token-prefix matching (every query token must\n * prefix-match a name or category token). Queries yield to the event loop\n * every CHUNK entries so even stress-scale venues never block input.\n */\nexport class SearchIndex {\n static CHUNK = 500;\n #entries: IndexEntry[] = [];\n\n constructor(venue: Venue) {\n for (const location of venue.locations) {\n if (location.hidden) continue;\n this.#entries.push({\n location,\n nameTokens: tokenize(location.name),\n categoryTokens: location.categories.flatMap((c) => tokenize(c.name)),\n });\n }\n }\n\n get size(): number {\n return this.#entries.length;\n }\n\n async query(text: string): Promise<SearchResult[]> {\n const queryTokens = tokenize(text);\n if (queryTokens.length === 0) return [];\n const results: SearchResult[] = [];\n for (let i = 0; i < this.#entries.length; i++) {\n if (i > 0 && i % SearchIndex.CHUNK === 0) {\n await new Promise((resolve) => setTimeout(resolve, 0)); // yield\n }\n const entry = this.#entries[i];\n if (!entry) continue;\n const score = scoreEntry(entry, queryTokens);\n if (score > 0) results.push({ location: entry.location, score });\n }\n results.sort(\n (a, b) => b.score - a.score || a.location.sortOrder - b.location.sortOrder,\n );\n return results;\n }\n\n byCategory(categoryId: string): VenueLocation[] {\n return this.#entries\n .filter((e) => e.location.categories.some((c) => c.id === categoryId))\n .map((e) => e.location)\n .sort((a, b) => a.sortOrder - b.sortOrder);\n }\n}\n\nfunction scoreEntry(entry: IndexEntry, queryTokens: string[]): number {\n let score = 0;\n const candidates = [...entry.nameTokens, ...entry.categoryTokens];\n const used = new Set<number>();\n for (const q of queryTokens) {\n let matched = -1;\n for (let i = 0; i < candidates.length; i++) {\n if (used.has(i)) continue;\n const c = candidates[i];\n if (c !== undefined && c.startsWith(q)) {\n matched = i;\n break;\n }\n }\n if (matched === -1) return 0; // every query token must match\n used.add(matched);\n score += 1 + (candidates[matched] === q ? 0.5 : 0); // exact-token bonus\n }\n return score;\n}\n","/**\n * A* over the venue routing graph.\n *\n * IMPORTANT: `runAStar` must remain fully self-contained (no imports, no\n * closure captures) — it is stringified into a Blob worker by the route\n * service, so everything it needs lives inside the function body. The same\n * function runs inline as the no-Worker fallback and in unit tests.\n */\n\nexport interface SerializedGraphNode {\n lng: number;\n lat: number;\n edges: { to: string; cost: number; accessible: boolean }[];\n}\n\nexport type SerializedGraph = Record<string, SerializedGraphNode>;\n\nexport interface AStarResult {\n path: string[];\n cost: number;\n}\n\nexport function runAStar(\n graph: SerializedGraph,\n fromId: string,\n toId: string,\n accessibleOnly: boolean,\n): AStarResult | null {\n const start = graph[fromId];\n const goal = graph[toId];\n if (!start || !goal) return null;\n\n const R = 6371000;\n const toRad = Math.PI / 180;\n const heuristic = (a: { lng: number; lat: number }, b: { lng: number; lat: number }): number => {\n const dLat = (b.lat - a.lat) * toRad;\n const dLng = (b.lng - a.lng) * toRad;\n const s =\n Math.sin(dLat / 2) ** 2 +\n Math.cos(a.lat * toRad) * Math.cos(b.lat * toRad) * Math.sin(dLng / 2) ** 2;\n return 2 * R * Math.asin(Math.sqrt(s));\n };\n\n // binary min-heap keyed by fScore\n const heapIds: string[] = [];\n const heapF: number[] = [];\n const push = (id: string, f: number): void => {\n heapIds.push(id);\n heapF.push(f);\n let i = heapIds.length - 1;\n while (i > 0) {\n const p = (i - 1) >> 1;\n const hf = heapF[p];\n const cf = heapF[i];\n if (hf === undefined || cf === undefined || hf <= cf) break;\n [heapF[p], heapF[i]] = [cf, hf];\n const pid = heapIds[p];\n const cid = heapIds[i];\n if (pid !== undefined && cid !== undefined) {\n heapIds[p] = cid;\n heapIds[i] = pid;\n }\n i = p;\n }\n };\n const pop = (): string | undefined => {\n if (heapIds.length === 0) return undefined;\n const top = heapIds[0];\n const lastId = heapIds.pop();\n const lastF = heapF.pop();\n if (heapIds.length > 0 && lastId !== undefined && lastF !== undefined) {\n heapIds[0] = lastId;\n heapF[0] = lastF;\n let i = 0;\n for (;;) {\n const l = i * 2 + 1;\n const r = l + 1;\n let smallest = i;\n const fi = heapF[i] ?? Infinity;\n const fl = heapF[l] ?? Infinity;\n const fr = heapF[r] ?? Infinity;\n if (l < heapF.length && fl < fi) smallest = l;\n if (r < heapF.length && fr < (heapF[smallest] ?? Infinity)) smallest = r;\n if (smallest === i) break;\n const si = heapIds[smallest];\n const ii = heapIds[i];\n const sf = heapF[smallest];\n const iff = heapF[i];\n if (si === undefined || ii === undefined || sf === undefined || iff === undefined) break;\n heapIds[i] = si;\n heapIds[smallest] = ii;\n heapF[i] = sf;\n heapF[smallest] = iff;\n i = smallest;\n }\n }\n return top;\n };\n\n const gScore = new Map<string, number>();\n const cameFrom = new Map<string, string>();\n const closed = new Set<string>();\n gScore.set(fromId, 0);\n push(fromId, heuristic(start, goal));\n\n for (;;) {\n const current = pop();\n if (current === undefined) return null;\n if (current === toId) break;\n if (closed.has(current)) continue;\n closed.add(current);\n const node = graph[current];\n if (!node) continue;\n const g = gScore.get(current) ?? Infinity;\n for (const edge of node.edges) {\n if (accessibleOnly && !edge.accessible) continue;\n const neighbor = graph[edge.to];\n if (!neighbor || closed.has(edge.to)) continue;\n const tentative = g + edge.cost;\n if (tentative < (gScore.get(edge.to) ?? Infinity)) {\n gScore.set(edge.to, tentative);\n cameFrom.set(edge.to, current);\n push(edge.to, tentative + heuristic(neighbor, goal));\n }\n }\n }\n\n const path: string[] = [toId];\n let cursor = toId;\n while (cursor !== fromId) {\n const prev = cameFrom.get(cursor);\n if (prev === undefined) return null;\n path.push(prev);\n cursor = prev;\n }\n path.reverse();\n return { path, cost: gScore.get(toId) ?? 0 };\n}\n","import { runAStar, type AStarResult, type SerializedGraph } from './astar.js';\nimport type { Venue } from '../data/venue-model.js';\n\n/**\n * Main-thread routing entry: LRU-cached A* executed in a Blob Web Worker\n * (never blocking input), with a synchronous inline fallback where Workers\n * don't exist (tests/SSR). The worker source is generated by stringifying\n * the self-contained `runAStar` — no bundler worker plumbing required in\n * either the SDK build or consumer builds.\n */\nexport class RouteService {\n #graph: SerializedGraph;\n #worker: Worker | null = null;\n #pending = new Map<number, (result: AStarResult | null) => void>();\n #nextId = 1;\n #cache = new Map<string, AStarResult | null>();\n static CACHE_MAX = 100;\n\n constructor(venue: Venue) {\n this.#graph = serializeGraph(venue);\n if (typeof Worker !== 'undefined' && typeof URL.createObjectURL === 'function') {\n try {\n const source =\n `const runAStar = ${runAStar.toString()};\\n` +\n `let graph = null;\\n` +\n `self.onmessage = (e) => {\\n` +\n ` const msg = e.data;\\n` +\n ` if (msg.type === 'init') { graph = msg.graph; return; }\\n` +\n ` const result = graph ? runAStar(graph, msg.from, msg.to, msg.accessibleOnly) : null;\\n` +\n ` self.postMessage({ id: msg.id, result });\\n` +\n `};`;\n const url = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));\n this.#worker = new Worker(url);\n URL.revokeObjectURL(url);\n this.#worker.onmessage = (e: MessageEvent<{ id: number; result: AStarResult | null }>) => {\n const resolve = this.#pending.get(e.data.id);\n if (resolve) {\n this.#pending.delete(e.data.id);\n resolve(e.data.result);\n }\n };\n this.#worker.postMessage({ type: 'init', graph: this.#graph });\n } catch {\n this.#worker = null; // CSP or worker failure → inline fallback\n }\n }\n }\n\n get usingWorker(): boolean {\n return this.#worker !== null;\n }\n\n async findPath(\n fromNodeId: string,\n toNodeId: string,\n options: { accessibleOnly?: boolean } = {},\n ): Promise<AStarResult | null> {\n const accessibleOnly = options.accessibleOnly ?? false;\n const key = `${fromNodeId}|${toNodeId}|${String(accessibleOnly)}`;\n const cached = this.#cache.get(key);\n if (cached !== undefined) {\n // refresh LRU position\n this.#cache.delete(key);\n this.#cache.set(key, cached);\n return cached;\n }\n const result = this.#worker\n ? await new Promise<AStarResult | null>((resolve) => {\n const id = this.#nextId++;\n this.#pending.set(id, resolve);\n this.#worker?.postMessage({ id, from: fromNodeId, to: toNodeId, accessibleOnly });\n })\n : runAStar(this.#graph, fromNodeId, toNodeId, accessibleOnly);\n if (this.#cache.size >= RouteService.CACHE_MAX) {\n const oldest = this.#cache.keys().next().value;\n if (oldest !== undefined) this.#cache.delete(oldest);\n }\n this.#cache.set(key, result);\n return result;\n }\n\n dispose(): void {\n this.#worker?.terminate();\n this.#worker = null;\n this.#pending.clear();\n this.#cache.clear();\n }\n}\n\nfunction serializeGraph(venue: Venue): SerializedGraph {\n const graph: SerializedGraph = {};\n for (const node of venue.nodes) {\n graph[node.id] = {\n lng: node.lng,\n lat: node.lat,\n edges: node.edges.map((e) => ({ to: e.toNodeId, cost: e.cost, accessible: e.accessible })),\n };\n }\n return graph;\n}\n","import type {\r\n Building,\r\n Category,\r\n Floor,\r\n FloorConnectionKind,\r\n GraphNode,\r\n MapObjectDef,\r\n Shape,\r\n VenueData,\r\n VenueLocation,\r\n VenueStats,\r\n} from './types.js';\r\n\r\n/** Great-circle distance in meters (sufficient accuracy at venue scale). */\r\nexport function haversineMeters(lng1: number, lat1: number, lng2: number, lat2: number): number {\r\n const R = 6371000;\r\n const toRad = Math.PI / 180;\r\n const dLat = (lat2 - lat1) * toRad;\r\n const dLng = (lng2 - lng1) * toRad;\r\n const a =\r\n Math.sin(dLat / 2) ** 2 + Math.cos(lat1 * toRad) * Math.cos(lat2 * toRad) * Math.sin(dLng / 2) ** 2;\r\n return 2 * R * Math.asin(Math.sqrt(a));\r\n}\r\n\r\n/**\r\n * The built, indexed venue model. Instance-scoped (never a singleton),\r\n * immutable by convention after {@link buildVenue} returns.\r\n */\r\nexport class Venue {\r\n readonly id: string;\r\n readonly name: string;\r\n readonly center: [number, number];\r\n readonly buildings: Building[];\r\n readonly categories: Category[];\r\n readonly mapObjects: MapObjectDef[];\r\n /** Default icon set (key -> SVG url) — markers resolve amenity icons here. */\r\n readonly iconset: Record<string, string>;\r\n\r\n readonly #buildingsById = new Map<string, Building>();\r\n readonly #floorsById = new Map<string, Floor>();\r\n readonly #locationsById = new Map<string, VenueLocation>();\r\n readonly #shapesById = new Map<string, Shape>();\r\n readonly #nodesById = new Map<string, GraphNode>();\r\n readonly #categoriesById = new Map<string, Category>();\r\n #edgeCount = 0;\r\n\r\n constructor(data: {\r\n id: string;\r\n name: string;\r\n center: [number, number];\r\n buildings: Building[];\r\n categories: Category[];\r\n mapObjects: MapObjectDef[];\r\n iconset?: Record<string, string>;\r\n nodes: GraphNode[];\r\n shapes: Shape[];\r\n locations: VenueLocation[];\r\n edgeCount: number;\r\n }) {\r\n this.id = data.id;\r\n this.name = data.name;\r\n this.center = data.center;\r\n this.buildings = data.buildings;\r\n this.categories = data.categories;\r\n this.mapObjects = data.mapObjects;\r\n this.iconset = data.iconset ?? {};\r\n this.#edgeCount = data.edgeCount;\r\n for (const b of data.buildings) {\r\n this.#buildingsById.set(b.id, b);\r\n for (const f of b.floors) this.#floorsById.set(f.id, f);\r\n }\r\n for (const c of data.categories) this.#categoriesById.set(c.id, c);\r\n for (const n of data.nodes) this.#nodesById.set(n.id, n);\r\n for (const s of data.shapes) this.#shapesById.set(s.id, s);\r\n for (const l of data.locations) this.#locationsById.set(l.id, l);\r\n }\r\n\r\n getBuilding(id: string): Building | undefined {\r\n return this.#buildingsById.get(id);\r\n }\r\n getFloor(id: string): Floor | undefined {\r\n return this.#floorsById.get(id);\r\n }\r\n getLocation(id: string): VenueLocation | undefined {\r\n return this.#locationsById.get(id);\r\n }\r\n getShape(id: string): Shape | undefined {\r\n return this.#shapesById.get(id);\r\n }\r\n getNode(id: string): GraphNode | undefined {\r\n return this.#nodesById.get(id);\r\n }\r\n getCategory(id: string): Category | undefined {\r\n return this.#categoriesById.get(id);\r\n }\r\n\r\n get locations(): IterableIterator<VenueLocation> {\r\n return this.#locationsById.values();\r\n }\r\n get nodes(): IterableIterator<GraphNode> {\r\n return this.#nodesById.values();\r\n }\r\n\r\n stats(): VenueStats {\r\n return {\r\n buildings: this.buildings.length,\r\n floors: this.#floorsById.size,\r\n locations: this.#locationsById.size,\r\n shapes: this.#shapesById.size,\r\n nodes: this.#nodesById.size,\r\n edges: this.#edgeCount,\r\n categories: this.#categoriesById.size,\r\n mapObjects: this.mapObjects.length,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Build the indexed venue model from raw provider data: derive location\r\n * floors, group entities per floor, and assemble the routing graph (sibling\r\n * edges with haversine costs; cross-floor edges from floor connections with\r\n * kind penalties).\r\n */\r\nexport function buildVenue(data: VenueData): Venue {\r\n // --- graph nodes ---------------------------------------------------------\r\n const nodes = new Map<string, GraphNode>();\r\n for (const rn of data.nodes) {\r\n nodes.set(rn.id, {\r\n id: rn.id,\r\n lng: rn.lng,\r\n lat: rn.lat,\r\n floorId: rn.floorId,\r\n accessible: rn.accessible,\r\n privateNode: rn.privateNode,\r\n edges: [],\r\n });\r\n }\r\n let edgeCount = 0;\r\n const addEdge = (\r\n from: GraphNode,\r\n to: GraphNode,\r\n cost: number,\r\n accessible: boolean,\r\n kind?: FloorConnectionKind,\r\n ): void => {\r\n if (from.edges.some((e) => e.toNodeId === to.id)) return;\r\n from.edges.push(\r\n kind\r\n ? { toNodeId: to.id, cost, accessible, connectionKind: kind }\r\n : { toNodeId: to.id, cost, accessible },\r\n );\r\n edgeCount++;\r\n };\r\n // Sibling edges: directed as listed (editor data lists both directions;\r\n // the mock generator does too). Cost = geodesic meters.\r\n for (const rn of data.nodes) {\r\n const from = nodes.get(rn.id);\r\n if (!from) continue;\r\n for (const sib of rn.siblings) {\r\n const to = nodes.get(sib);\r\n if (!to) continue;\r\n addEdge(from, to, haversineMeters(from.lng, from.lat, to.lng, to.lat), true);\r\n }\r\n }\r\n // Connection edges: editor cost rule, per-direction (v1 #processConnections).\r\n for (const fc of data.floorConnections) {\r\n const start = nodes.get(fc.startNodeId);\r\n const end = nodes.get(fc.endNodeId);\r\n if (!start || !end) continue; // v1 skips connections referencing unknown nodes\r\n const cost = (fc.weight > 0 ? fc.weight : 100) * (fc.multiplier || 1);\r\n if (fc.direction === 'startToEnd' || fc.direction === 'both') {\r\n addEdge(start, end, cost, fc.accessible, fc.kind);\r\n }\r\n if (fc.direction === 'endToStart' || fc.direction === 'both') {\r\n addEdge(end, start, cost, fc.accessible, fc.kind);\r\n }\r\n }\r\n\r\n // --- categories -----------------------------------------------------------\r\n const categories = new Map<string, Category>();\r\n for (const rc of data.categories) {\r\n const cat: Category = { id: rc.id, name: rc.name, sortOrder: rc.sortOrder };\r\n if (rc.icon !== undefined) cat.icon = rc.icon;\r\n if (rc.colorHex !== undefined) cat.colorHex = rc.colorHex;\r\n categories.set(rc.id, cat);\r\n }\r\n\r\n // --- shapes ---------------------------------------------------------------\r\n const shapes = new Map<string, Shape>();\r\n for (const rs of data.shapes) {\r\n const shape: Shape = {\r\n id: rs.id,\r\n floorId: rs.floorId,\r\n layerId: rs.layerId,\r\n type: rs.type,\r\n geometry: rs.geometry,\r\n };\r\n if (rs.style) shape.style = rs.style;\r\n shapes.set(rs.id, shape);\r\n }\r\n\r\n // --- locations (derive floor from node, else shape) -----------------------\r\n const locations = new Map<string, VenueLocation>();\r\n for (const rl of data.locations) {\r\n const nodeFloor = rl.nodeId ? nodes.get(rl.nodeId)?.floorId : undefined;\r\n const shapeFloor = rl.shapeId ? shapes.get(rl.shapeId)?.floorId : undefined;\r\n const floorId = nodeFloor ?? shapeFloor;\r\n const loc: VenueLocation = {\r\n id: rl.id,\r\n name: rl.name,\r\n type: rl.type,\r\n categories: rl.categoryIds\r\n .map((id) => categories.get(id))\r\n .filter((c): c is Category => c !== undefined),\r\n hidden: rl.hidden,\r\n sortOrder: rl.sortOrder,\r\n };\r\n if (rl.description !== undefined) loc.description = rl.description;\r\n if (rl.nodeId !== undefined) loc.nodeId = rl.nodeId;\r\n if (rl.shapeId !== undefined) loc.shapeId = rl.shapeId;\r\n if (floorId !== undefined) loc.floorId = floorId;\r\n if (rl.amenity !== undefined) loc.amenity = rl.amenity;\r\n if (rl.logoUrl !== undefined) loc.logoUrl = rl.logoUrl;\r\n locations.set(rl.id, loc);\r\n }\r\n\r\n // v1 synthesizes a selectable location at each connection endpoint that\r\n // lacks one (type 'connection', amenity = kind) so elevators/escalators are\r\n // addressable in search/selection.\r\n const locationByNodeId = new Map<string, VenueLocation>();\r\n for (const loc of locations.values()) {\r\n if (loc.nodeId) locationByNodeId.set(loc.nodeId, loc);\r\n }\r\n for (const fc of data.floorConnections) {\r\n for (const nid of [fc.startNodeId, fc.endNodeId]) {\r\n const node = nodes.get(nid);\r\n if (!node || locationByNodeId.has(nid)) continue;\r\n const loc: VenueLocation = {\r\n id: `conn-${fc.id}-${nid}`,\r\n name: fc.name ?? fc.kind,\r\n type: 'connection',\r\n nodeId: nid,\r\n floorId: node.floorId,\r\n amenity: fc.kind,\r\n categories: [],\r\n hidden: false,\r\n sortOrder: 0,\r\n };\r\n locations.set(loc.id, loc);\r\n locationByNodeId.set(nid, loc);\r\n }\r\n }\r\n\r\n // --- buildings & floors, with per-floor groupings --------------------------\r\n const floorLocations = new Map<string, VenueLocation[]>();\r\n for (const loc of locations.values()) {\r\n if (!loc.floorId) continue;\r\n const list = floorLocations.get(loc.floorId) ?? [];\r\n list.push(loc);\r\n floorLocations.set(loc.floorId, list);\r\n }\r\n const floorShapes = new Map<string, Shape[]>();\r\n for (const s of shapes.values()) {\r\n const list = floorShapes.get(s.floorId) ?? [];\r\n list.push(s);\r\n floorShapes.set(s.floorId, list);\r\n }\r\n const floorNodes = new Map<string, GraphNode[]>();\r\n for (const n of nodes.values()) {\r\n const list = floorNodes.get(n.floorId) ?? [];\r\n list.push(n);\r\n floorNodes.set(n.floorId, list);\r\n }\r\n\r\n const buildings: Building[] = data.buildings.map((rb) => ({\r\n id: rb.id,\r\n name: rb.name,\r\n floors: [...rb.floors]\r\n .sort((a, b) => a.level - b.level)\r\n .map((rf) => ({\r\n id: rf.id,\r\n name: rf.name,\r\n level: rf.level,\r\n buildingId: rf.buildingId,\r\n locations: floorLocations.get(rf.id) ?? [],\r\n shapes: floorShapes.get(rf.id) ?? [],\r\n nodes: floorNodes.get(rf.id) ?? [],\r\n })),\r\n }));\r\n\r\n const mapObjects: MapObjectDef[] = data.mapObjects.map((m) => ({ ...m }));\r\n\r\n return new Venue({\r\n id: data.site.id,\r\n name: data.site.name,\r\n center: data.site.center,\r\n buildings,\r\n categories: [...categories.values()].sort((a, b) => a.sortOrder - b.sortOrder),\r\n mapObjects,\r\n nodes: [...nodes.values()],\r\n shapes: [...shapes.values()],\r\n locations: [...locations.values()],\r\n edgeCount,\r\n ...(data.iconset ? { iconset: data.iconset } : {}),\r\n });\r\n}\r\n","import type { Venue } from '../data/venue-model.js';\r\nimport type { FloorConnectionKind, LngLat } from '../data/types.js';\r\nimport { haversineMeters } from '../data/venue-model.js';\r\n\r\nexport interface RouteSegment {\r\n /** Floor the segment lives on ('outdoor' pseudo-floors have buildingId null). */\r\n floorId: string;\r\n buildingId: string | null;\r\n points: LngLat[];\r\n /** Connection used to LEAVE this segment (elevator/escalator/...), if any. */\r\n exitKind?: FloorConnectionKind;\r\n /** Graph node id per point — keeps landmarks resolvable from a step. */\r\n nodeIds: string[];\r\n}\r\n\r\n/** What happens AT a step. Mirrors the v1 SDK's step-action semantics. */\r\nexport type StepAction =\r\n | 'depart'\r\n | 'turn'\r\n | 'continue'\r\n | 'floorChange'\r\n | 'exitBuilding'\r\n | 'enterBuilding'\r\n | 'arrive';\r\n\r\n/** Which way to go at a step. `up`/`down` accompany a floor change. */\r\nexport type StepDirection =\r\n | 'none'\r\n | 'straight'\r\n | 'slightLeft'\r\n | 'left'\r\n | 'uTurnLeft'\r\n | 'slightRight'\r\n | 'right'\r\n | 'uTurnRight'\r\n | 'up'\r\n | 'down';\r\n\r\nexport interface RouteStep {\r\n lng: number;\r\n lat: number;\r\n floorId: string;\r\n buildingId: string | null;\r\n segmentIndex: number;\r\n /** Cumulative meters from the route start (matches ribbon arc length). */\r\n cumMeters: number;\r\n /** Ready-to-show English instruction, built from the fields below. */\r\n label: string;\r\n /** Structured action, so hosts can localise or draw their own UI. */\r\n action: StepAction;\r\n /** Structured direction — the turn this step calls for. */\r\n direction: StepDirection;\r\n /** Meters covered from THIS step to the next (0 at the destination). */\r\n distanceMeters: number;\r\n /** Graph node this step sits on. */\r\n nodeId: string;\r\n /** Named location at this step, for \"turn right at Zara\" (null when none). */\r\n landmark: string | null;\r\n}\r\n\r\nexport interface BuiltRoute {\r\n segments: RouteSegment[];\r\n steps: RouteStep[];\r\n totalMeters: number;\r\n}\r\n\r\nfunction buildingIdForFloor(venue: Venue, floorId: string): string | null {\r\n return venue.getFloor(floorId)?.buildingId ?? null;\r\n}\r\n\r\n/**\r\n * Compass bearing a→b in degrees. Longitude is scaled by cos(lat) so the angle\r\n * is a TRUE bearing — without it, turn angles are stretched by the latitude\r\n * factor and a slight bend can be classified as a full turn.\r\n */\r\nfunction bearingDeg(a: LngLat, b: LngLat): number {\r\n const cosLat = Math.cos((((a[1] + b[1]) / 2) * Math.PI) / 180);\r\n return (Math.atan2((b[0] - a[0]) * cosLat, b[1] - a[1]) * 180) / Math.PI;\r\n}\r\n\r\n/** Signed bearing change in (-180, 180]: positive = right, negative = left. */\r\nfunction bearingDelta(from: number, to: number): number {\r\n return ((to - from + 540) % 360) - 180;\r\n}\r\n\r\n/** Bucket a bearing change into a named turn (v1's thresholds). */\r\nfunction turnFor(delta: number): StepDirection {\r\n if (delta >= -10 && delta <= 10) return 'straight';\r\n if (delta > 135) return 'uTurnRight';\r\n if (delta > 45) return 'right';\r\n if (delta > 10) return 'slightRight';\r\n if (delta < -135) return 'uTurnLeft';\r\n if (delta < -45) return 'left';\r\n return 'slightLeft';\r\n}\r\n\r\n/** Below this the bend is path noise, not an instruction worth a step. */\r\nconst TURN_MIN_DEG = 25;\r\n\r\n/**\r\n * Longest leg a single instruction may cover. A straight run of 87 m told as\r\n * one step (\"walk 87 m\") is useless to follow — beyond this the run is broken\r\n * into even legs so the walker gets a fresh confirmation every ~30 m.\r\n */\r\nconst MAX_LEG_M = 35;\r\n\r\n/** How far a leg break may shift to land on a real node (and keep a landmark). */\r\nconst SNAP_M = 2;\r\n\r\nconst TURN_PHRASE: Record<string, string> = {\r\n slightRight: 'Slight right',\r\n right: 'Turn right',\r\n uTurnRight: 'Make a U-turn',\r\n slightLeft: 'Slight left',\r\n left: 'Turn left',\r\n uTurnLeft: 'Make a U-turn',\r\n};\r\n\r\nfunction formatMeters(m: number): string {\r\n return `${String(Math.max(1, Math.round(m)))} m`;\r\n}\r\n\r\n/**\r\n * Split an A* node path into per-floor segments and turn-by-turn steps with\r\n * instruction labels. Steps keep segment boundaries + genuine turns (>25°).\r\n */\r\nexport function buildRoute(\r\n venue: Venue,\r\n path: string[],\r\n names: { origin: string; destination: string },\r\n): BuiltRoute | null {\r\n const nodes = path\r\n .map((id) => venue.getNode(id))\r\n .filter((n): n is NonNullable<typeof n> => n !== undefined);\r\n if (nodes.length < 2) return null;\r\n\r\n // --- segments by floor ------------------------------------------------------\r\n const segments: RouteSegment[] = [];\r\n let current: RouteSegment | null = null;\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n if (!node) continue;\r\n if (!current || current.floorId !== node.floorId) {\r\n // record which connection kind leaves the previous segment\r\n if (current && i > 0) {\r\n const prev = nodes[i - 1];\r\n const edge = prev?.edges.find((e) => e.toNodeId === node.id);\r\n if (edge?.connectionKind) current.exitKind = edge.connectionKind;\r\n }\r\n current = {\r\n floorId: node.floorId,\r\n buildingId: buildingIdForFloor(venue, node.floorId),\r\n points: [],\r\n nodeIds: [],\r\n };\r\n segments.push(current);\r\n }\r\n current.points.push([node.lng, node.lat]);\r\n current.nodeIds.push(node.id);\r\n }\r\n\r\n // landmark lookup: a NAMED, non-amenity location sitting on a node makes a\r\n // far better instruction anchor (\"turn right at Zara\") than coordinates\r\n const landmarkByNode = new Map<string, string>();\r\n for (const loc of venue.locations) {\r\n if (!loc.nodeId || loc.amenity || loc.hidden || !loc.name) continue;\r\n if (!landmarkByNode.has(loc.nodeId)) landmarkByNode.set(loc.nodeId, loc.name);\r\n }\r\n\r\n // --- cumulative meters + steps ----------------------------------------------\r\n // Every path point with its running distance; steps are CHOSEN from these,\r\n // so a leg can later be split at a real node instead of an invented point.\r\n interface PathPoint {\r\n lng: number;\r\n lat: number;\r\n floorId: string;\r\n buildingId: string | null;\r\n segmentIndex: number;\r\n cum: number;\r\n nodeId: string;\r\n direction: StepDirection;\r\n isStep: boolean;\r\n }\r\n const pts: PathPoint[] = [];\r\n let cum = 0;\r\n\r\n segments.forEach((segment, segmentIndex) => {\r\n for (let i = 0; i < segment.points.length; i++) {\r\n const p = segment.points[i];\r\n if (!p) continue;\r\n if (i > 0) {\r\n const prev = segment.points[i - 1];\r\n if (prev) cum += haversineMeters(prev[0], prev[1], p[0], p[1]);\r\n }\r\n const isSegmentEdge = i === 0 || i === segment.points.length - 1;\r\n let direction: StepDirection = 'none';\r\n let isTurn = false;\r\n if (!isSegmentEdge) {\r\n const prev = segment.points[i - 1];\r\n const next = segment.points[i + 1];\r\n if (prev && next) {\r\n const delta = bearingDelta(bearingDeg(prev, p), bearingDeg(p, next));\r\n if (Math.abs(delta) > TURN_MIN_DEG) {\r\n direction = turnFor(delta);\r\n isTurn = true;\r\n }\r\n }\r\n }\r\n pts.push({\r\n lng: p[0],\r\n lat: p[1],\r\n floorId: segment.floorId,\r\n buildingId: segment.buildingId,\r\n segmentIndex,\r\n cum,\r\n nodeId: segment.nodeIds[i] ?? '',\r\n direction,\r\n isStep: isSegmentEdge || isTurn,\r\n });\r\n }\r\n });\r\n\r\n // Break over-long legs into EVEN parts (87 m → 3 × 29 m, not 35+35+17), each\r\n // break snapped to the nearest real path node so it keeps a landmark.\r\n const stepIdx: number[] = [];\r\n pts.forEach((pt, i) => {\r\n if (pt.isStep) stepIdx.push(i);\r\n });\r\n const extras: PathPoint[] = [];\r\n for (let k = 1; k < stepIdx.length; k++) {\r\n const from = stepIdx[k - 1];\r\n const to = stepIdx[k];\r\n if (from === undefined || to === undefined) continue;\r\n const a = pts[from];\r\n const b = pts[to];\r\n if (!a || !b) continue;\r\n const run = b.cum - a.cum;\r\n if (run <= MAX_LEG_M) continue;\r\n const parts = Math.ceil(run / MAX_LEG_M);\r\n for (let n = 1; n < parts; n++) {\r\n const target = a.cum + (run * n) / parts;\r\n // A real node right at the mark is preferable — it carries a landmark.\r\n // The window is deliberately TIGHT: snapping further would skew the even\r\n // division and leave an over-long leg after the break.\r\n let best: PathPoint | undefined;\r\n let bestDiff = SNAP_M;\r\n for (let i = from + 1; i < to; i++) {\r\n const pt = pts[i];\r\n if (!pt) continue;\r\n const diff = Math.abs(pt.cum - target);\r\n if (diff <= bestDiff) {\r\n bestDiff = diff;\r\n best = pt;\r\n }\r\n }\r\n if (best) {\r\n best.isStep = true;\r\n continue;\r\n }\r\n // otherwise place the break exactly on the mark, interpolating along the\r\n // polyline (between the two points that bracket it — NOT across the whole\r\n // run, which would cut corners on a bent path)\r\n let lo = from;\r\n for (let i = from; i < to; i++) {\r\n if ((pts[i]?.cum ?? 0) <= target) lo = i;\r\n }\r\n const p0 = pts[lo];\r\n const p1 = pts[Math.min(lo + 1, to)];\r\n if (!p0 || !p1) continue;\r\n const span = p1.cum - p0.cum;\r\n const f = span > 0 ? (target - p0.cum) / span : 0;\r\n extras.push({\r\n lng: p0.lng + (p1.lng - p0.lng) * f,\r\n lat: p0.lat + (p1.lat - p0.lat) * f,\r\n floorId: p0.floorId,\r\n buildingId: p0.buildingId,\r\n segmentIndex: p0.segmentIndex,\r\n cum: target,\r\n nodeId: '',\r\n direction: 'none',\r\n isStep: true,\r\n });\r\n }\r\n }\r\n\r\n const steps: RouteStep[] = [...pts, ...extras]\r\n .sort((x, y) => x.cum - y.cum)\r\n .filter((pt) => pt.isStep)\r\n .map((pt) => ({\r\n lng: pt.lng,\r\n lat: pt.lat,\r\n floorId: pt.floorId,\r\n buildingId: pt.buildingId,\r\n segmentIndex: pt.segmentIndex,\r\n cumMeters: pt.cum,\r\n label: '',\r\n action: 'continue',\r\n direction: pt.direction,\r\n distanceMeters: 0,\r\n nodeId: pt.nodeId,\r\n landmark: landmarkByNode.get(pt.nodeId) ?? null,\r\n }));\r\n\r\n // dedupe consecutive same-place steps UNLESS they represent a floor change\r\n const deduped: RouteStep[] = [];\r\n for (const step of steps) {\r\n const prev = deduped[deduped.length - 1];\r\n const samePlace =\r\n prev !== undefined &&\r\n haversineMeters(prev.lng, prev.lat, step.lng, step.lat) < 0.5 &&\r\n prev.floorId === step.floorId;\r\n if (samePlace) continue;\r\n deduped.push(step);\r\n }\r\n\r\n // --- action, distance, and instruction label ---------------------------------\r\n const buildingName = (id: string | null): string =>\r\n (id ? venue.getBuilding(id)?.name : undefined) ?? 'outside';\r\n const floorName = (floorId: string): string => venue.getFloor(floorId)?.name ?? floorId;\r\n const floorLevel = (floorId: string): number => venue.getFloor(floorId)?.level ?? 0;\r\n for (let i = 0; i < deduped.length; i++) {\r\n const step = deduped[i];\r\n const next = deduped[i + 1];\r\n if (!step) continue;\r\n // how far the walker covers on the leg this step opens\r\n step.distanceMeters = next ? Math.max(0, next.cumMeters - step.cumMeters) : 0;\r\n const run = step.distanceMeters >= 1 ? formatMeters(step.distanceMeters) : '';\r\n\r\n if (i === 0) {\r\n step.action = 'depart';\r\n step.direction = 'none';\r\n step.label = run ? `Start at ${names.origin}, then walk ${run}` : `Start at ${names.origin}`;\r\n } else if (i === deduped.length - 1) {\r\n step.action = 'arrive';\r\n step.direction = 'none';\r\n step.label = `Arrive at ${names.destination}`;\r\n } else if (next && step.buildingId && next.buildingId === step.buildingId && next.floorId !== step.floorId) {\r\n const kind = segments[step.segmentIndex]?.exitKind ?? 'elevator';\r\n step.action = 'floorChange';\r\n step.direction = floorLevel(next.floorId) > floorLevel(step.floorId) ? 'up' : 'down';\r\n step.label = `Take the ${kind} to ${floorName(next.floorId)}`;\r\n } else if (next && step.buildingId && !next.buildingId) {\r\n step.action = 'exitBuilding';\r\n step.direction = 'none';\r\n step.label = `Exit ${buildingName(step.buildingId)}`;\r\n } else if (!step.buildingId && next?.buildingId) {\r\n step.action = 'enterBuilding';\r\n step.direction = 'none';\r\n step.label = `Enter ${buildingName(next.buildingId)}`;\r\n } else if (step.direction !== 'none' && step.direction !== 'straight') {\r\n // a REAL turn instruction — the direction was measured at build time\r\n step.action = 'turn';\r\n const phrase = TURN_PHRASE[step.direction] ?? 'Turn';\r\n const at = step.landmark ? ` at ${step.landmark}` : '';\r\n step.label = run ? `${phrase}${at}, then ${run}` : `${phrase}${at}`;\r\n } else {\r\n step.action = 'continue';\r\n step.direction = 'straight';\r\n const where = step.buildingId ? '' : ' outside';\r\n step.label = run ? `Continue${where} for ${run}` : `Continue${where}`;\r\n }\r\n }\r\n\r\n return { segments, steps: deduped, totalMeters: cum };\r\n}\r\n","import type maplibregl from 'maplibre-gl';\r\nimport type { RouteRibbon } from '../render/route-ribbon.js';\r\nimport type { RouteSegment, RouteStep, StepAction, StepDirection } from './segments.js';\r\nimport { haversineMeters } from '../data/venue-model.js';\r\n\r\nexport const PREVIEW_ZOOM = 18;\r\nexport const STEP_ZOOM = 18.2;\r\nexport const NAV_PITCH = 32;\r\n// Preview pacing: duration-bounded so LONG routes don't drag — the runner\r\n// covers any route in 4-8s (speed scales with length), instead of a fixed\r\n// walking pace that took forever on big venues.\r\nconst RUN_MPS = 4;\r\n// Pause at each floor connection: the runner stops, the instruction card shows\r\n// (1.6s, owned by the SDK host), the card closes, THEN the floor switches.\r\nconst TRANSITION_PAUSE_MS = 1800;\r\nconst PREVIEW_MIN_S = 5;\r\n// Arrival dwell: the runner STANDS at the destination (camera there, on the\r\n// destination floor) before the camera hands over to step navigation — ending\r\n// the same frame the runner arrived made the destination flash past unseen.\r\nconst END_DWELL_MS = 2000;\r\nconst PREVIEW_MAX_S = 12;\r\nconst VISITED_LERP = 0.08;\r\n\r\nexport interface NavStepInfo {\r\n index: number;\r\n total: number;\r\n label: string;\r\n isFirst: boolean;\r\n isLast: boolean;\r\n /** Structured action — localise or draw your own UI from this, not the label. */\r\n action: StepAction;\r\n /** Structured direction (turn / up / down). */\r\n direction: StepDirection;\r\n /** Meters covered from this step to the next (0 at the destination). */\r\n distanceMeters: number;\r\n /** Floor this step is on. */\r\n floorId: string;\r\n /** Named location at this step, when the step sits on one. */\r\n landmark: string | null;\r\n}\r\n\r\n/** Position along the raw segment polyline at a cumulative distance. */\r\nexport function routePointAt(segments: RouteSegment[], meters: number): [number, number] | null {\r\n let cum = 0;\r\n for (const segment of segments) {\r\n for (let i = 1; i < segment.points.length; i++) {\r\n const a = segment.points[i - 1];\r\n const b = segment.points[i];\r\n if (!a || !b) continue;\r\n const len = haversineMeters(a[0], a[1], b[0], b[1]);\r\n if (cum + len >= meters && len > 0) {\r\n const t = (meters - cum) / len;\r\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];\r\n }\r\n cum += len;\r\n }\r\n }\r\n const last = segments[segments.length - 1];\r\n const p = last?.points[last.points.length - 1];\r\n return p ? [p[0], p[1]] : null;\r\n}\r\n\r\n/**\r\n * The polyline the walker covers for one step: route points between two\r\n * cumulative distances, bracketed by the interpolated start/end positions.\r\n */\r\nexport function routeSubpath(\r\n segments: RouteSegment[],\r\n startMeters: number,\r\n endMeters: number,\r\n): [number, number][] {\r\n const out: [number, number][] = [];\r\n const start = routePointAt(segments, startMeters);\r\n if (start) out.push(start);\r\n let cum = 0;\r\n for (const segment of segments) {\r\n for (let i = 1; i < segment.points.length; i++) {\r\n const a = segment.points[i - 1];\r\n const b = segment.points[i];\r\n if (!a || !b) continue;\r\n cum += haversineMeters(a[0], a[1], b[0], b[1]);\r\n if (cum > startMeters && cum < endMeters) out.push([b[0], b[1]]);\r\n }\r\n }\r\n const end = routePointAt(segments, endMeters);\r\n if (end) out.push(end);\r\n return out;\r\n}\r\n\r\nconst LEG_PADDING = { top: 90, bottom: 180, left: 70, right: 70 };\r\nconst LEG_MAX_ZOOM = 19;\r\n\r\n/** Camera that frames a leg's polyline heading-up; null if it can't be framed. */\r\nfunction frameLeg(map: maplibregl.Map, pts: [number, number][], bearing: number) {\r\n if (pts.length < 2) return null;\r\n let minLng = Infinity;\r\n let minLat = Infinity;\r\n let maxLng = -Infinity;\r\n let maxLat = -Infinity;\r\n for (const [lng, lat] of pts) {\r\n if (lng < minLng) minLng = lng;\r\n if (lng > maxLng) maxLng = lng;\r\n if (lat < minLat) minLat = lat;\r\n if (lat > maxLat) maxLat = lat;\r\n }\r\n // a single point (e.g. a floor-change leg) has no extent to frame\r\n if (maxLng - minLng < 1e-9 && maxLat - minLat < 1e-9) return null;\r\n return (\r\n map.cameraForBounds(\r\n [\r\n [minLng, minLat],\r\n [maxLng, maxLat],\r\n ],\r\n { bearing, padding: LEG_PADDING, maxZoom: LEG_MAX_ZOOM },\r\n ) ?? null\r\n );\r\n}\r\n\r\n/**\r\n * Preview → step-by-step navigation state machine (POC-final behaviors):\r\n * preview reveals at walking pace (duration clamped 4–15s), the camera\r\n * follows the reveal head WITHOUT rotating, floors auto-switch along the\r\n * journey, then the camera returns to the start and Next/Previous take over\r\n * with heading-up bearing per step and a smoothly tweening visited boundary.\r\n */\r\nexport class NavigationController {\r\n #map: maplibregl.Map;\r\n #ribbon: RouteRibbon;\r\n #segments: RouteSegment[];\r\n #steps: RouteStep[];\r\n #showFloor: (floorId: string) => void;\r\n #onStep: (info: NavStepInfo) => void;\r\n #repaint: () => void;\r\n\r\n #state: 'preview' | 'step' | 'disposed' = 'preview';\r\n #onTransition: (t: { kind: string; toFloorId: string } | null) => void = () => undefined;\r\n #transitions: { cumMeters: number; kind: string; toFloorId: string }[] = [];\r\n #nextTransition = 0;\r\n #pauseUntil = 0;\r\n #pauseAt = 0;\r\n #endDwellUntil = 0;\r\n #currentStep = 0;\r\n #visitedTarget = 0;\r\n #revealStartMs = 0;\r\n #revealSpeed = RUN_MPS;\r\n #raf = 0;\r\n\r\n constructor(deps: {\r\n map: maplibregl.Map;\r\n ribbon: RouteRibbon;\r\n segments: RouteSegment[];\r\n steps: RouteStep[];\r\n showFloor: (floorId: string) => void;\r\n onStep: (info: NavStepInfo) => void;\r\n repaint: () => void;\r\n onTransition?: (t: { kind: string; toFloorId: string } | null) => void;\r\n }) {\r\n this.#map = deps.map;\r\n this.#ribbon = deps.ribbon;\r\n this.#segments = deps.segments;\r\n this.#steps = deps.steps;\r\n this.#showFloor = deps.showFloor;\r\n this.#onStep = deps.onStep;\r\n this.#repaint = deps.repaint;\r\n this.#onTransition = deps.onTransition ?? ((): void => undefined);\r\n // floor-change steps get an instruction card as the runner reaches them:\r\n // structured data (kind + destination floor), no parsing of label text\r\n this.#transitions = this.#steps\r\n .filter((st) => st.action === 'floorChange')\r\n .map((st) => ({\r\n cumMeters: st.cumMeters,\r\n kind: this.#segments[st.segmentIndex]?.exitKind ?? 'elevator',\r\n toFloorId: this.#segments[st.segmentIndex + 1]?.floorId ?? st.floorId,\r\n }));\r\n }\r\n\r\n get active(): boolean {\r\n return this.#state !== 'disposed';\r\n }\r\n\r\n start(): void {\r\n // the route is FULLY drawn immediately (no progressive reveal) …\r\n this.#ribbon.setProgress(this.#ribbon.totalLength);\r\n this.#ribbon.setVisited(0);\r\n this.#visitedTarget = 0;\r\n // … then the runner preview plays over it\r\n this.preview();\r\n this.#tick();\r\n }\r\n\r\n /**\r\n * Preview: a \"running person\" badge travels the fully-drawn route from start\r\n * to end (camera following, floors auto-switching), then hands over to step\r\n * navigation. Public — callable again any time to replay the journey.\r\n */\r\n preview(): void {\r\n if (this.#state === 'disposed') return;\r\n const first = this.#steps[0];\r\n if (!first || this.#ribbon.totalLength <= 0) return;\r\n if (first.buildingId) this.#showFloor(first.floorId);\r\n this.#map.easeTo({\r\n center: [first.lng, first.lat],\r\n zoom: PREVIEW_ZOOM,\r\n pitch: NAV_PITCH,\r\n duration: 800,\r\n });\r\n const total = this.#ribbon.totalLength;\r\n const duration = Math.min(PREVIEW_MAX_S, Math.max(PREVIEW_MIN_S, total / RUN_MPS));\r\n this.#revealSpeed = total / duration;\r\n this.#revealStartMs = performance.now() + 900; // runner sets off after the glide\r\n this.#ribbon.setRunner(0);\r\n this.#ribbon.showRunner();\r\n this.#nextTransition = 0;\r\n this.#pauseUntil = 0;\r\n this.#endDwellUntil = 0;\r\n this.#onTransition(null);\r\n this.#state = 'preview';\r\n }\r\n\r\n /** Leave the preview early (user stepped or replayed): park the runner. */\r\n #endPreview(): void {\r\n this.#ribbon.hideRunner();\r\n this.#onTransition(null);\r\n this.#state = 'step';\r\n }\r\n\r\n stepInfo(): NavStepInfo {\r\n const step = this.#steps[this.#currentStep];\r\n return {\r\n index: this.#currentStep,\r\n total: this.#steps.length,\r\n label: step?.label ?? '',\r\n isFirst: this.#currentStep === 0,\r\n isLast: this.#currentStep === this.#steps.length - 1,\r\n action: step?.action ?? 'continue',\r\n direction: step?.direction ?? 'none',\r\n distanceMeters: step?.distanceMeters ?? 0,\r\n floorId: step?.floorId ?? '',\r\n landmark: step?.landmark ?? null,\r\n };\r\n }\r\n\r\n next(): void {\r\n if (this.#state === 'preview') this.#endPreview();\r\n this.goToStep(this.#currentStep + 1);\r\n }\r\n previous(): void {\r\n if (this.#state === 'preview') this.#endPreview();\r\n this.goToStep(this.#currentStep - 1);\r\n }\r\n\r\n goToStep(index: number): void {\r\n if (this.#state !== 'step') return;\r\n this.#currentStep = Math.max(0, Math.min(this.#steps.length - 1, index));\r\n const step = this.#steps[this.#currentStep];\r\n if (!step) return;\r\n this.#visitedTarget = step.cumMeters;\r\n if (step.buildingId) this.#showFloor(step.floorId);\r\n // heading-up: face the next step far enough away to define a bearing\r\n let bearing: number | undefined;\r\n for (let j = this.#currentStep + 1; j < this.#steps.length; j++) {\r\n const nx = this.#steps[j];\r\n if (nx && haversineMeters(step.lng, step.lat, nx.lng, nx.lat) > 1) {\r\n bearing = (Math.atan2(nx.lng - step.lng, nx.lat - step.lat) * 180) / Math.PI;\r\n break;\r\n }\r\n }\r\n if (bearing === undefined) {\r\n for (let j = this.#currentStep - 1; j >= 0; j--) {\r\n const pv = this.#steps[j];\r\n if (pv && haversineMeters(pv.lng, pv.lat, step.lng, step.lat) > 1) {\r\n bearing = (Math.atan2(step.lng - pv.lng, step.lat - pv.lat) * 180) / Math.PI;\r\n break;\r\n }\r\n }\r\n }\r\n // Focus + zoom to the whole leg the walker covers for this step (from here\r\n // to the next step), framed heading-up — instead of just centering a point.\r\n const nextStep = this.#steps[this.#currentStep + 1];\r\n const endMeters = nextStep ? nextStep.cumMeters : this.#ribbon.totalLength;\r\n const leg = routeSubpath(this.#segments, step.cumMeters, endMeters);\r\n const framed = frameLeg(this.#map, leg, bearing ?? this.#map.getBearing());\r\n if (framed) {\r\n this.#map.easeTo({ ...framed, pitch: NAV_PITCH, duration: 700 });\r\n } else {\r\n // degenerate leg (floor change / single point): center on the step\r\n this.#map.easeTo({\r\n center: [step.lng, step.lat],\r\n zoom: STEP_ZOOM,\r\n pitch: NAV_PITCH,\r\n ...(bearing !== undefined ? { bearing } : {}),\r\n duration: 700,\r\n });\r\n }\r\n this.#onStep(this.stepInfo());\r\n }\r\n\r\n dispose(): void {\r\n this.#state = 'disposed';\r\n this.#onTransition(null);\r\n cancelAnimationFrame(this.#raf);\r\n }\r\n\r\n #tick = (): void => {\r\n if (this.#state === 'disposed') return;\r\n this.#ribbon.setTime(performance.now() / 1000); // flowing chevrons along the route\r\n\r\n if (this.#state === 'preview') {\r\n const now = performance.now();\r\n let progress: number;\r\n if (now < this.#pauseUntil) {\r\n // parked at the connection while the instruction card is up — the\r\n // runner waits just BEFORE the boundary so the floor doesn't switch yet\r\n progress = this.#pauseAt;\r\n } else {\r\n const elapsed = (now - this.#revealStartMs) / 1000;\r\n progress = Math.max(0, Math.min(this.#ribbon.totalLength, elapsed * this.#revealSpeed));\r\n // reaching a floor connection: show the card, freeze here, and shift\r\n // the timeline so the journey resumes from this exact point after the\r\n // card has closed — only THEN does the floor change\r\n const tr = this.#transitions[this.#nextTransition];\r\n // trigger at whichever comes FIRST: the step's metre-mark or the\r\n // ribbon's own segment boundary (they drift slightly apart — waiting\r\n // for the later one lets a frame slip onto the next floor early)\r\n const boundary = tr ? (this.#ribbon.nearestBoundary(tr.cumMeters) ?? tr.cumMeters) : 0;\r\n const trigger = tr ? Math.min(tr.cumMeters, Math.max(0, boundary - 0.05)) : 0;\r\n if (tr && progress >= trigger) {\r\n this.#onTransition({ kind: tr.kind, toFloorId: tr.toFloorId });\r\n // park BEFORE the boundary so the floor cannot switch until the card closes\r\n this.#pauseAt = trigger;\r\n this.#pauseUntil = now + TRANSITION_PAUSE_MS;\r\n this.#revealStartMs = now + TRANSITION_PAUSE_MS - (this.#pauseAt / this.#revealSpeed) * 1000;\r\n this.#nextTransition++;\r\n progress = this.#pauseAt;\r\n }\r\n }\r\n this.#ribbon.setRunner(progress); // the person runs the fully-drawn route\r\n if (progress > 0 && progress < this.#ribbon.totalLength) {\r\n const head = routePointAt(this.#segments, progress);\r\n if (head) this.#map.setCenter(head); // follow, no rotation (POC-final)\r\n const segment = this.#ribbon.segmentAt(progress);\r\n if (segment?.buildingId) this.#showFloor(segment.floorId);\r\n } else if (progress >= this.#ribbon.totalLength) {\r\n if (this.#endDwellUntil === 0) {\r\n // ARRIVED: park the runner ON the destination, make sure the\r\n // destination floor is the visible one, and settle the camera there\r\n this.#endDwellUntil = now + END_DWELL_MS;\r\n const lastStep = this.#steps[this.#steps.length - 1];\r\n if (lastStep?.buildingId) this.#showFloor(lastStep.floorId);\r\n if (lastStep) {\r\n this.#map.easeTo({ center: [lastStep.lng, lastStep.lat], duration: 500 });\r\n }\r\n } else if (now >= this.#endDwellUntil) {\r\n // journey shown: the camera STAYS at the destination, but the\r\n // walkthrough is primed at the FIRST step (\"Start at …\") — nothing\r\n // is marked visited and no camera/floor change happens until the\r\n // user actually steps forward\r\n this.#endDwellUntil = 0;\r\n this.#endPreview();\r\n this.#ribbon.setVisited(0);\r\n this.#visitedTarget = 0;\r\n this.#currentStep = 0;\r\n this.#onStep(this.stepInfo());\r\n }\r\n }\r\n } else {\r\n const current = this.#ribbon.getVisited();\r\n const nextValue = Math.abs(current - this.#visitedTarget) < 0.05\r\n ? this.#visitedTarget\r\n : current + (this.#visitedTarget - current) * VISITED_LERP;\r\n this.#ribbon.setVisited(nextValue);\r\n }\r\n\r\n this.#repaint();\r\n this.#raf = requestAnimationFrame(this.#tick);\r\n };\r\n}\r\n","import type { NavStepInfo } from '../routing/navigation.js';\r\n\r\n/**\r\n * Built-in navigation bar (bottom center): ◀ · Step i/n + instruction · ▶ ·\r\n * ✕. Clearing the route goes ONLY through the ✕ (ROUT-07). Inline styles;\r\n * disable via `options.ui.routeBar: false`.\r\n */\r\nexport interface RouteBar {\r\n update(info: NavStepInfo): void;\r\n dispose(): void;\r\n}\r\n\r\n/** Direction glyph for the current instruction — reads at a glance. */\r\nconst DIRECTION_GLYPH: Record<string, string> = {\r\n slightLeft: '↖', // ↖\r\n left: '←', // ←\r\n uTurnLeft: '↰', // ↰\r\n slightRight: '↗', // ↗\r\n right: '→', // →\r\n uTurnRight: '↱', // ↱\r\n straight: '↑', // ↑\r\n up: '⇧', // ⇧\r\n down: '⇩', // ⇩\r\n};\r\n\r\nexport function createRouteBar(\r\n container: HTMLElement,\r\n handlers: { onPrev: () => void; onNext: () => void; onClear: () => void },\r\n): RouteBar {\r\n const el = document.createElement('div');\r\n el.style.cssText =\r\n 'position:absolute;bottom:24px;left:50%;transform:translateX(-50%);z-index:10;display:flex;' +\r\n 'align-items:center;gap:10px;background:#1f2937;color:#fff;border-radius:999px;padding:8px 14px;' +\r\n 'font-family:system-ui,sans-serif;box-shadow:0 2px 12px rgba(0,0,0,.25)';\r\n const btn = (label: string, onClick: () => void, danger = false): HTMLButtonElement => {\r\n const b = document.createElement('button');\r\n b.textContent = label;\r\n b.style.cssText =\r\n `background:${danger ? '#7f1d1d' : '#374151'};color:#fff;border:none;border-radius:999px;` +\r\n 'width:38px;height:38px;font-size:15px;font-weight:700;cursor:pointer';\r\n b.onclick = onClick;\r\n return b;\r\n };\r\n const prev = btn('◀', handlers.onPrev);\r\n const next = btn('▶', handlers.onNext);\r\n const clear = btn('✕', handlers.onClear, true);\r\n const info = document.createElement('div');\r\n info.style.cssText = 'text-align:center;min-width:170px;font-size:12px;line-height:1.35';\r\n const stepEl = document.createElement('b');\r\n stepEl.style.fontSize = '13px';\r\n const glyphEl = document.createElement('span');\r\n glyphEl.style.cssText = 'font-size:15px;font-weight:700;margin-right:5px';\r\n const actionEl = document.createElement('span');\r\n info.append(stepEl, document.createElement('br'), glyphEl, actionEl);\r\n el.append(prev, info, next, clear);\r\n container.appendChild(el);\r\n\r\n return {\r\n update(state: NavStepInfo): void {\r\n stepEl.textContent = `Step ${String(state.index + 1)} / ${String(state.total)}`;\r\n glyphEl.textContent = DIRECTION_GLYPH[state.direction] ?? '';\r\n actionEl.textContent = state.label;\r\n prev.disabled = state.isFirst;\r\n next.disabled = state.isLast;\r\n prev.style.opacity = state.isFirst ? '0.35' : '1';\r\n next.style.opacity = state.isLast ? '0.35' : '1';\r\n },\r\n dispose(): void {\r\n el.remove();\r\n },\r\n };\r\n}\r\n","/**\r\n * Namespaced facade stubs. Each facade is a typed surface whose methods are\r\n * filled in by later phases; until then they throw a descriptive error so\r\n * consumers get a clear signal instead of silent no-ops.\r\n */\r\n\r\nimport type { Emitter, BecoMapEvents } from '../events.js';\r\nimport type { VenueProvider } from '../data/provider.js';\r\nimport type { VenueStats } from '../data/types.js';\r\nimport { buildVenue, Venue } from '../data/venue-model.js';\r\n\r\n/** Venue data access: loading and model lookups. */\r\nexport interface VenueFacade {\r\n /** Fetch venue data via the configured provider and build the model. */\r\n load(): Promise<VenueStats>;\r\n /** The built venue model, or null before {@link VenueFacade.load} resolves. */\r\n current(): Venue | null;\r\n /** Convenience: model stats, or null before load. */\r\n stats(): VenueStats | null;\r\n}\r\n\r\nexport function createVenueFacade(deps: {\r\n provider?: VenueProvider;\r\n emitter: Emitter<BecoMapEvents>;\r\n signal: AbortSignal;\r\n onLoaded?: (venue: Venue) => void;\r\n}): VenueFacade {\r\n let venue: Venue | null = null;\r\n return {\r\n async load(): Promise<VenueStats> {\r\n if (!deps.provider) {\r\n throw new Error('becomap: no venue provider configured — pass options.venue.provider to createMap');\r\n }\r\n try {\r\n const data = await deps.provider.fetchVenue(deps.signal);\r\n venue = buildVenue(data);\r\n deps.onLoaded?.(venue);\r\n return venue.stats();\r\n } catch (cause) {\r\n const message = cause instanceof Error ? cause.message : 'venue load failed';\r\n deps.emitter.emit('error', { message, cause });\r\n throw cause;\r\n }\r\n },\r\n current: () => venue,\r\n stats: () => venue?.stats() ?? null,\r\n };\r\n}\r\n\r\nimport type { BuildingView } from '../lod/floor-manager.js';\r\n\r\n/** Floor visibility and selection (live since Phase 4). */\r\nexport interface FloorsFacade {\r\n /** Show a floor (opens its building if sealed, focuses it). */\r\n select(floorId: string): void;\r\n /** Building whose floors the built-in switcher controls. */\r\n focusedBuildingId(): string | null;\r\n /** Current LOD view of a building (sealed vs open + visible floor). */\r\n viewOf(buildingId: string): BuildingView | undefined;\r\n}\r\nexport function createFloorsFacade(deps: {\r\n select: (floorId: string) => void;\r\n focusedBuildingId: () => string | null;\r\n viewOf: (buildingId: string) => BuildingView | undefined;\r\n}): FloorsFacade {\r\n return {\r\n select: deps.select,\r\n focusedBuildingId: deps.focusedBuildingId,\r\n viewOf: deps.viewOf,\r\n };\r\n}\r\n\r\nimport type { SearchResult } from '../search/index.js';\r\nimport type { VenueLocation } from '../data/types.js';\r\n\r\n/** Location search (live since Phase 5). */\r\nexport interface SearchFacade {\r\n /** Token-prefix search over names and categories (diacritic-insensitive, non-blocking). */\r\n query(text: string): Promise<SearchResult[]>;\r\n /** All visible locations in a category, sorted. */\r\n byCategory(categoryId: string): VenueLocation[];\r\n}\r\nexport function createSearchFacade(deps: {\r\n query: (text: string) => Promise<SearchResult[]>;\r\n byCategory: (categoryId: string) => VenueLocation[];\r\n}): SearchFacade {\r\n return { query: deps.query, byCategory: deps.byCategory };\r\n}\r\n\r\nimport type { NavStepInfo } from '../routing/navigation.js';\r\n\r\nexport interface RouteInfo {\r\n /** Total walking distance in meters. */\r\n distanceMeters: number;\r\n /** Number of turn-by-turn steps. */\r\n stepCount: number;\r\n}\r\n\r\n/** Routing and navigation (live since Phase 6). */\r\nexport interface RoutingFacade {\r\n /** Compute + render + preview a route between two locations. */\r\n route(\r\n fromLocationId: string,\r\n toLocationId: string,\r\n options?: { accessibleOnly?: boolean },\r\n ): Promise<RouteInfo>;\r\n /** Clear the active route (the ONLY way besides the route bar ✕). */\r\n clear(): void;\r\n /** Replay the runner preview along the active route. */\r\n preview(): void;\r\n /** Step navigation (mirrors the built-in route bar). */\r\n next(): void;\r\n previous(): void;\r\n stepInfo(): NavStepInfo | null;\r\n active(): boolean;\r\n}\r\nexport function createRoutingFacade(deps: {\r\n route: (from: string, to: string, options?: { accessibleOnly?: boolean }) => Promise<RouteInfo>;\r\n clear: () => void;\r\n preview: () => void;\r\n next: () => void;\r\n previous: () => void;\r\n stepInfo: () => NavStepInfo | null;\r\n active: () => boolean;\r\n}): RoutingFacade {\r\n return { ...deps };\r\n}\r\n\r\n/** Camera control helpers (live since Phase 5). */\r\nexport interface CameraFacade {\r\n /** Fit the camera to the loaded venue's extents. */\r\n focusVenue(options?: { pitch?: number; duration?: number }): void;\r\n /** Fly to a location, opening its building/floor if needed. */\r\n focusTo(locationId: string): void;\r\n}\r\nexport function createCameraFacade(deps: {\r\n focusVenue: (options?: { pitch?: number; duration?: number }) => void;\r\n focusTo: (locationId: string) => void;\r\n}): CameraFacade {\r\n return {\r\n focusVenue: deps.focusVenue,\r\n focusTo: deps.focusTo,\r\n };\r\n}\r\n","import type { VenueProvider } from './provider.js';\r\nimport type {\r\n LngLat,\r\n PolygonGeometry,\r\n RawBuilding,\r\n RawFloorConnection,\r\n RawLocation,\r\n RawNode,\r\n RawShape,\r\n VenueData,\r\n} from './types.js';\r\n\r\n/**\r\n * Procedural venue generator, ported from the validated POC\r\n * (`becomap-poc/src/venue.js`): 3 irregular buildings (curved stadium,\r\n * L-shape, rounded corner), multiple floors, organic store rows with varied\r\n * frontages/gaps, corridor + spine walk graph, elevators, doors, and an\r\n * outdoor plaza hub. Deterministic (seeded PRNG) so tests are stable.\r\n */\r\n\r\nconst CENTER: LngLat = [55.2708, 25.2048];\r\nconst M_PER_DEG_LAT = 111320;\r\n\r\nfunction metersToLngLat(dxEast: number, dyNorth: number): LngLat {\r\n return [\r\n CENTER[0] + dxEast / (M_PER_DEG_LAT * Math.cos((CENTER[1] * Math.PI) / 180)),\r\n CENTER[1] + dyNorth / M_PER_DEG_LAT,\r\n ];\r\n}\r\n\r\nfunction makeRng(seed: number): () => number {\r\n let s = seed >>> 0;\r\n return () => {\r\n s = (s * 1664525 + 1013904223) >>> 0;\r\n return s / 4294967296;\r\n };\r\n}\r\n\r\nfunction pointInPolygon(poly: [number, number][], x: number, y: number): boolean {\r\n let inside = false;\r\n for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {\r\n const pi = poly[i];\r\n const pj = poly[j];\r\n if (!pi || !pj) continue;\r\n const [xi, yi] = pi;\r\n const [xj, yj] = pj;\r\n if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) inside = !inside;\r\n }\r\n return inside;\r\n}\r\n\r\ninterface BuildingSpec {\r\n id: string;\r\n name: string;\r\n cx: number;\r\n cy: number;\r\n w: number;\r\n d: number;\r\n floors: number;\r\n}\r\n\r\nconst BUILDINGS: BuildingSpec[] = [\r\n { id: 'bldg-a', name: 'North Mall', cx: -175, cy: 95, w: 150, d: 120, floors: 3 },\r\n { id: 'bldg-b', name: 'East Wing', cx: 175, cy: 70, w: 140, d: 140, floors: 4 },\r\n { id: 'bldg-c', name: 'South Plaza', cx: -15, cy: -175, w: 165, d: 120, floors: 2 },\r\n];\r\n\r\nconst FLOOR_NAMES = ['G', '1', '2', '3'];\r\nconst PLAZA: [number, number] = [-5, -15];\r\n\r\n// mall interior layout (meters) — matches POC\r\nconst ROW_H = 10;\r\nconst CORR = 7;\r\nconst VCORR_HALF = 4;\r\nconst MARGIN = 5;\r\nconst STORE_W_MIN = 9;\r\nconst STORE_W_VAR = 7;\r\n\r\nconst CATEGORY_SPECS = [\r\n { id: 'cat-fashion', name: 'Fashion', colorHex: '#93b7d4' },\r\n { id: 'cat-food', name: 'Food & Drink', colorHex: '#f2a65e' },\r\n { id: 'cat-services', name: 'Services', colorHex: '#f7d488' },\r\n { id: 'cat-beauty', name: 'Beauty', colorHex: '#e8968a' },\r\n { id: 'cat-electronics', name: 'Electronics', colorHex: '#9ccfc3' },\r\n];\r\n\r\n/** Irregular footprint outlines in local meters (ported from POC). */\r\nfunction footprintOutline(spec: BuildingSpec): [number, number][] {\r\n const hw = spec.w / 2;\r\n const hd = spec.d / 2;\r\n const pts: [number, number][] = [];\r\n if (spec.id.startsWith('bldg-a')) {\r\n const flat = hw - hd;\r\n pts.push([-flat, -hd], [hw, -hd], [hw, hd], [-flat, hd]);\r\n for (let i = 1; i < 16; i++) {\r\n const t = Math.PI / 2 + (i / 16) * Math.PI;\r\n pts.push([-flat + Math.cos(t) * hd, Math.sin(t) * hd]);\r\n }\r\n } else if (spec.id.startsWith('bldg-b')) {\r\n const nx = 10;\r\n pts.push([-hw, -hd], [hw, -hd], [hw, nx], [nx, nx], [nx, hd], [-hw, hd]);\r\n } else {\r\n pts.push([-hw, -hd], [hw, -hd], [hw, hd - 40]);\r\n for (let i = 1; i <= 8; i++) {\r\n const t = (i / 8) * (Math.PI / 2);\r\n pts.push([hw - 45 + Math.cos(t) * 45 * (1 - i / 16), hd - 40 + Math.sin(t) * 40]);\r\n }\r\n pts.push([hw - 45, hd], [-hw + 22, hd], [-hw, hd - 25]);\r\n }\r\n return pts;\r\n}\r\n\r\nfunction polygonGeometry(outlineMeters: [number, number][]): PolygonGeometry {\r\n const ring = outlineMeters.map(([x, y]) => metersToLngLat(x, y));\r\n const first = ring[0];\r\n if (first) ring.push([first[0], first[1]]);\r\n return { type: 'Polygon', coordinates: [ring] };\r\n}\r\n\r\nfunction rectOutline(cx: number, cy: number, w: number, d: number): [number, number][] {\r\n return [\r\n [cx - w / 2, cy - d / 2],\r\n [cx + w / 2, cy - d / 2],\r\n [cx + w / 2, cy + d / 2],\r\n [cx - w / 2, cy + d / 2],\r\n ];\r\n}\r\n\r\nexport class MockVenueProvider implements VenueProvider {\r\n #seed: number;\r\n #stress: number;\r\n\r\n /**\r\n * @param options.stress Tile the campus stress×stress (default 1). Used to\r\n * exceed venue-scale polygon counts for performance verification.\r\n */\r\n constructor(options: { seed?: number; stress?: number } = {}) {\r\n this.#seed = options.seed ?? 1337;\r\n this.#stress = Math.max(1, Math.floor(options.stress ?? 1));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/require-await\r\n async fetchVenue(): Promise<VenueData> {\r\n const buildings: RawBuilding[] = [];\r\n const nodes: RawNode[] = [];\r\n const shapes: RawShape[] = [];\r\n const locations: RawLocation[] = [];\r\n const floorConnections: RawFloorConnection[] = [];\r\n\r\n const link = (a: RawNode, b: RawNode): void => {\r\n if (!a.siblings.includes(b.id)) a.siblings.push(b.id);\r\n if (!b.siblings.includes(a.id)) b.siblings.push(a.id);\r\n };\r\n\r\n // outdoor pseudo-floor: plaza hub + per-building door aprons\r\n const outdoorFloorId = 'outdoor';\r\n\r\n // stress mode tiles the whole campus in a grid\r\n const specs: (BuildingSpec & { plazaId: string; plazaY: number })[] = [];\r\n const plazaByTile = new Map<string, RawNode>();\r\n for (let ti = 0; ti < this.#stress; ti++) {\r\n for (let tj = 0; tj < this.#stress; tj++) {\r\n const ox = ti * 900;\r\n const oy = tj * 900;\r\n const tileSuffix = this.#stress > 1 ? `-t${String(ti)}${String(tj)}` : '';\r\n const plazaId = `node-plaza${tileSuffix}`;\r\n const plazaNode: RawNode = {\r\n id: plazaId,\r\n lng: metersToLngLat(PLAZA[0] + ox, PLAZA[1] + oy)[0],\r\n lat: metersToLngLat(PLAZA[0] + ox, PLAZA[1] + oy)[1],\r\n floorId: outdoorFloorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n nodes.push(plazaNode);\r\n plazaByTile.set(plazaId, plazaNode);\r\n for (const b of BUILDINGS) {\r\n specs.push({\r\n ...b,\r\n id: `${b.id}${tileSuffix}`,\r\n name: this.#stress > 1 ? `${b.name} ${String(ti)}${String(tj)}` : b.name,\r\n cx: b.cx + ox,\r\n cy: b.cy + oy,\r\n plazaId,\r\n plazaY: PLAZA[1] + oy,\r\n });\r\n }\r\n }\r\n }\r\n\r\n for (const spec of specs) {\r\n const plazaNode = plazaByTile.get(spec.plazaId);\r\n if (!plazaNode) continue;\r\n let idHash = 0;\r\n for (let i = 0; i < spec.id.length; i++) idHash = (idHash * 31 + spec.id.charCodeAt(i)) >>> 0;\r\n const rngBase = this.#seed + (idHash % 100000);\r\n const outline = footprintOutline(spec);\r\n const outlineAbs = outline.map(([x, y]): [number, number] => [x + spec.cx, y + spec.cy]);\r\n const doorSide = spec.plazaY - spec.cy > 0 ? 1 : -1;\r\n\r\n const building: RawBuilding = { id: spec.id, name: spec.name, floors: [] };\r\n const elevatorNodeIds: string[] = [];\r\n\r\n for (let f = 0; f < spec.floors; f++) {\r\n const rng = makeRng(rngBase + f * 7919);\r\n const floorId = `${spec.id}-f${String(f)}`;\r\n building.floors.push({\r\n id: floorId,\r\n name: FLOOR_NAMES[f] ?? String(f),\r\n level: f,\r\n buildingId: spec.id,\r\n });\r\n\r\n // building footprint shape (rendered as slab/shell in Phase 3+)\r\n shapes.push({\r\n id: `${floorId}-footprint`,\r\n floorId,\r\n layerId: 'footprint',\r\n type: 'polygon',\r\n geometry: polygonGeometry(outlineAbs),\r\n });\r\n\r\n // elevator node at the building center, on the spine\r\n const elevNode: RawNode = {\r\n id: `${floorId}-elev`,\r\n lng: metersToLngLat(spec.cx, spec.cy)[0],\r\n lat: metersToLngLat(spec.cx, spec.cy)[1],\r\n floorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n nodes.push(elevNode);\r\n elevatorNodeIds.push(elevNode.id);\r\n\r\n // organic store rows with corridor/spine graph\r\n const rowPitch = ROW_H + CORR;\r\n const yStart = spec.cy - spec.d / 2 + MARGIN + CORR + ROW_H / 2;\r\n const yEnd = spec.cy + spec.d / 2 - MARGIN - ROW_H / 2;\r\n const spineJunctions: RawNode[] = [];\r\n let storeIdx = 0;\r\n\r\n for (let ry = yStart; ry <= yEnd + 0.01; ry += rowPitch) {\r\n const corrY = ry - ROW_H / 2 - CORR / 2;\r\n const junction: RawNode = {\r\n id: `${floorId}-jn-${String(spineJunctions.length)}`,\r\n lng: metersToLngLat(spec.cx, corrY)[0],\r\n lat: metersToLngLat(spec.cx, corrY)[1],\r\n floorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n nodes.push(junction);\r\n spineJunctions.push(junction);\r\n\r\n const halves: [number, number][] = [\r\n [spec.cx - spec.w / 2 + MARGIN, spec.cx - VCORR_HALF],\r\n [spec.cx + VCORR_HALF, spec.cx + spec.w / 2 - MARGIN],\r\n ];\r\n for (const [hx0, hx1] of halves) {\r\n let cursor = hx0 + rng() * 3;\r\n let prevNode: RawNode = junction;\r\n const frontY = ry - ROW_H / 2;\r\n while (cursor < hx1 - STORE_W_MIN) {\r\n const sw = STORE_W_MIN + rng() * STORE_W_VAR;\r\n if (cursor + sw > hx1) break;\r\n const gap = 1.5 + rng() * 2.5;\r\n if (rng() < 0.08) {\r\n cursor += sw * 0.6;\r\n continue;\r\n }\r\n const depth = ROW_H * (0.85 + rng() * 0.35);\r\n const sx = cursor + sw / 2;\r\n const scy = frontY + depth / 2;\r\n const corners: [number, number][] = [\r\n [sx - sw / 2 - MARGIN, frontY - 1],\r\n [sx + sw / 2 + MARGIN, frontY - 1],\r\n [sx + sw / 2 + MARGIN, frontY + depth + MARGIN],\r\n [sx - sw / 2 - MARGIN, frontY + depth + MARGIN],\r\n ];\r\n if (!corners.every(([px, py]) => pointInPolygon(outlineAbs, px, py))) {\r\n cursor += sw + gap;\r\n continue;\r\n }\r\n storeIdx++;\r\n const storeId = `${floorId}-s${String(storeIdx).padStart(2, '0')}`;\r\n // store polygon\r\n shapes.push({\r\n id: `${storeId}-shape`,\r\n floorId,\r\n layerId: 'unit',\r\n type: 'polygon',\r\n geometry: polygonGeometry(rectOutline(sx, scy, sw, depth)),\r\n });\r\n // store front node on the corridor, chained along the row\r\n const frontNode: RawNode = {\r\n id: `${storeId}-node`,\r\n lng: metersToLngLat(sx, corrY)[0],\r\n lat: metersToLngLat(sx, corrY)[1],\r\n floorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n nodes.push(frontNode);\r\n link(prevNode, frontNode);\r\n prevNode = frontNode;\r\n // location\r\n const cat = CATEGORY_SPECS[Math.floor(rng() * CATEGORY_SPECS.length)];\r\n locations.push({\r\n id: `${storeId}-loc`,\r\n name: `${spec.name.split(' ')[0] ?? spec.id} ${FLOOR_NAMES[f] ?? String(f)}-${String(storeIdx).padStart(2, '0')}`,\r\n type: 'tenant',\r\n nodeId: frontNode.id,\r\n shapeId: `${storeId}-shape`,\r\n categoryIds: cat ? [cat.id] : [],\r\n hidden: false,\r\n sortOrder: storeIdx,\r\n });\r\n cursor += sw + gap;\r\n }\r\n }\r\n }\r\n\r\n // chain spine junctions vertically and hook in the elevator\r\n for (let i = 1; i < spineJunctions.length; i++) {\r\n const a = spineJunctions[i - 1];\r\n const b = spineJunctions[i];\r\n if (a && b) link(a, b);\r\n }\r\n // elevator connects to the nearest junction (by index around cy)\r\n let nearest: RawNode | undefined;\r\n let nearestDist = Infinity;\r\n for (const jn of spineJunctions) {\r\n const d = Math.abs(jn.lat - elevNode.lat);\r\n if (d < nearestDist) {\r\n nearestDist = d;\r\n nearest = jn;\r\n }\r\n }\r\n if (nearest) link(elevNode, nearest);\r\n\r\n // ground floor: door node on the plaza-facing wall + outdoor apron\r\n if (f === 0) {\r\n const doorY = spec.cy + doorSide * (spec.d / 2);\r\n const doorNode: RawNode = {\r\n id: `${spec.id}-door`,\r\n lng: metersToLngLat(spec.cx, doorY)[0],\r\n lat: metersToLngLat(spec.cx, doorY)[1],\r\n floorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n const apronNode: RawNode = {\r\n id: `${spec.id}-apron`,\r\n lng: metersToLngLat(spec.cx, doorY + doorSide * 10)[0],\r\n lat: metersToLngLat(spec.cx, doorY + doorSide * 10)[1],\r\n floorId: outdoorFloorId,\r\n accessible: true,\r\n privateNode: false,\r\n siblings: [],\r\n };\r\n nodes.push(doorNode, apronNode);\r\n // door chains to the spine end nearest the door\r\n const endJunction = doorSide === -1 ? spineJunctions[0] : spineJunctions[spineJunctions.length - 1];\r\n if (endJunction) link(doorNode, endJunction);\r\n link(doorNode, apronNode);\r\n link(apronNode, plazaNode);\r\n locations.push({\r\n id: `${spec.id}-entrance`,\r\n name: `${spec.name} Entrance`,\r\n type: 'entrance',\r\n nodeId: doorNode.id,\r\n categoryIds: [],\r\n hidden: false,\r\n sortOrder: 0,\r\n });\r\n }\r\n }\r\n\r\n // one elevator connection per adjacent floor pair (editor semantics:\r\n // a connection joins exactly two nodes, weight 0 → default cost 100)\r\n for (let i = 1; i < elevatorNodeIds.length; i++) {\r\n const startNodeId = elevatorNodeIds[i - 1];\r\n const endNodeId = elevatorNodeIds[i];\r\n if (!startNodeId || !endNodeId) continue;\r\n floorConnections.push({\r\n id: `${spec.id}-elevator-${String(i)}`,\r\n kind: 'elevator',\r\n name: `${spec.name} Elevator`,\r\n accessible: true,\r\n weight: 0,\r\n multiplier: 1,\r\n direction: 'both',\r\n startNodeId,\r\n endNodeId,\r\n });\r\n }\r\n buildings.push(building);\r\n }\r\n\r\n return {\r\n site: { id: 'mock-site', name: 'Mock Campus', center: CENTER },\r\n buildings,\r\n nodes,\r\n shapes,\r\n locations,\r\n categories: CATEGORY_SPECS.map((c, i) => ({\r\n id: c.id,\r\n name: c.name,\r\n sortOrder: i,\r\n colorHex: c.colorHex,\r\n })),\r\n mapObjects: [],\r\n floorConnections,\r\n };\r\n }\r\n}\r\n","/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-mixed-operators, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars, default-case, jsdoc/require-param*/\nimport $protobuf from \"protobufjs/minimal.js\";\n\n// Common aliases\nconst $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;\nconst $Object = $util.global.Object, $undefined = $util.global.undefined, $Error = $util.global.Error;\n\n// Exported root namespace\nconst $root = $protobuf.roots[\"default\"] || ($protobuf.roots[\"default\"] = {});\n\nexport const com = $root.com = (() => {\n\n /**\n * Namespace com.\n * @exports com\n * @namespace\n */\n const com = {};\n\n com.beco = (function() {\n\n /**\n * Namespace beco.\n * @memberof com\n * @namespace\n */\n const beco = {};\n\n beco.category = (function() {\n\n /**\n * Namespace category.\n * @memberof com.beco\n * @namespace\n */\n const category = {};\n\n category.Category = (function() {\n\n /**\n * Properties of a Category.\n * @typedef {Object} com.beco.category.Category.$Properties\n * @property {string|null} [categoryId] Category categoryId\n * @property {string|null} [name] Category name\n * @property {string|null} [iconFromDefaultList] Category iconFromDefaultList\n * @property {number|null} [sortOrder] Category sortOrder\n * @property {com.beco.category.Color.$Properties|null} [color] Category color\n * @property {string|null} [externalId] Category externalId\n * @property {string|null} [siteId] Category siteId\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Category.\n * @memberof com.beco.category\n * @interface ICategory\n * @augments com.beco.category.Category.$Properties\n * @deprecated Use com.beco.category.Category.$Properties instead.\n */\n\n /**\n * Shape of a Category.\n * @typedef {com.beco.category.Category.$Properties} com.beco.category.Category.$Shape\n */\n\n /**\n * Constructs a new Category.\n * @memberof com.beco.category\n * @classdesc Represents a Category.\n * @constructor\n * @param {com.beco.category.Category.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Category = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Category categoryId.\n * @member {string} categoryId\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.categoryId = \"\";\n\n /**\n * Category name.\n * @member {string} name\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.name = \"\";\n\n /**\n * Category iconFromDefaultList.\n * @member {string} iconFromDefaultList\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.iconFromDefaultList = \"\";\n\n /**\n * Category sortOrder.\n * @member {number} sortOrder\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.sortOrder = 0;\n\n /**\n * Category color.\n * @member {com.beco.category.Color.$Properties|null|undefined} color\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.color = null;\n\n /**\n * Category externalId.\n * @member {string} externalId\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.externalId = \"\";\n\n /**\n * Category siteId.\n * @member {string} siteId\n * @memberof com.beco.category.Category\n * @instance\n */\n Category.prototype.siteId = \"\";\n\n /**\n * Creates a new Category instance using the specified properties.\n * @function create\n * @memberof com.beco.category.Category\n * @static\n * @param {com.beco.category.Category.$Properties=} [properties] Properties to set\n * @returns {com.beco.category.Category} Category instance\n * @type {{\n * (properties: com.beco.category.Category.$Shape): com.beco.category.Category & com.beco.category.Category.$Shape;\n * (properties?: com.beco.category.Category.$Properties): com.beco.category.Category;\n * }}\n */\n Category.create = function(properties) {\n return new Category(properties);\n };\n\n /**\n * Encodes the specified Category message. Does not implicitly {@link com.beco.category.Category.verify|verify} messages.\n * @function encode\n * @memberof com.beco.category.Category\n * @static\n * @param {com.beco.category.Category.$Properties} message Category message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Category.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.categoryId != null && $Object.hasOwnProperty.call(message, \"categoryId\") && message.categoryId !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.categoryId);\n if (message.name != null && $Object.hasOwnProperty.call(message, \"name\") && message.name !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.name);\n if (message.iconFromDefaultList != null && $Object.hasOwnProperty.call(message, \"iconFromDefaultList\") && message.iconFromDefaultList !== \"\")\n writer.uint32(/* id 3, wireType 2 =*/26).string(message.iconFromDefaultList);\n if (message.sortOrder != null && $Object.hasOwnProperty.call(message, \"sortOrder\") && message.sortOrder !== 0)\n writer.uint32(/* id 4, wireType 0 =*/32).int32(message.sortOrder);\n if (message.color != null && $Object.hasOwnProperty.call(message, \"color\"))\n $root.com.beco.category.Color.encode(message.color, writer.uint32(/* id 5, wireType 2 =*/42).fork(), _depth + 1).ldelim();\n if (message.externalId != null && $Object.hasOwnProperty.call(message, \"externalId\") && message.externalId !== \"\")\n writer.uint32(/* id 6, wireType 2 =*/50).string(message.externalId);\n if (message.siteId != null && $Object.hasOwnProperty.call(message, \"siteId\") && message.siteId !== \"\")\n writer.uint32(/* id 7, wireType 2 =*/58).string(message.siteId);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Category message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.category.Category\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.category.Category & com.beco.category.Category.$Shape} Category\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Category.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.category.Category(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.categoryId = value;\n else\n delete message.categoryId;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.name = value;\n else\n delete message.name;\n continue;\n }\n case 3: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.iconFromDefaultList = value;\n else\n delete message.iconFromDefaultList;\n continue;\n }\n case 4: {\n if (wireType !== 0)\n break;\n if (value = reader.int32())\n message.sortOrder = value;\n else\n delete message.sortOrder;\n continue;\n }\n case 5: {\n if (wireType !== 2)\n break;\n message.color = $root.com.beco.category.Color.decode(reader, reader.uint32(), $undefined, _depth + 1, message.color);\n continue;\n }\n case 6: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.externalId = value;\n else\n delete message.externalId;\n continue;\n }\n case 7: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.siteId = value;\n else\n delete message.siteId;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Category\n * @function getTypeUrl\n * @memberof com.beco.category.Category\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Category.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.category.Category\";\n };\n\n return Category;\n })();\n\n category.Color = (function() {\n\n /**\n * Properties of a Color.\n * @typedef {Object} com.beco.category.Color.$Properties\n * @property {string|null} [rgba] Color rgba\n * @property {string|null} [hex] Color hex\n * @property {number|null} [opacity] Color opacity\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Color.\n * @memberof com.beco.category\n * @interface IColor\n * @augments com.beco.category.Color.$Properties\n * @deprecated Use com.beco.category.Color.$Properties instead.\n */\n\n /**\n * Shape of a Color.\n * @typedef {com.beco.category.Color.$Properties} com.beco.category.Color.$Shape\n */\n\n /**\n * Constructs a new Color.\n * @memberof com.beco.category\n * @classdesc Represents a Color.\n * @constructor\n * @param {com.beco.category.Color.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Color = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Color rgba.\n * @member {string} rgba\n * @memberof com.beco.category.Color\n * @instance\n */\n Color.prototype.rgba = \"\";\n\n /**\n * Color hex.\n * @member {string} hex\n * @memberof com.beco.category.Color\n * @instance\n */\n Color.prototype.hex = \"\";\n\n /**\n * Color opacity.\n * @member {number} opacity\n * @memberof com.beco.category.Color\n * @instance\n */\n Color.prototype.opacity = 0;\n\n /**\n * Creates a new Color instance using the specified properties.\n * @function create\n * @memberof com.beco.category.Color\n * @static\n * @param {com.beco.category.Color.$Properties=} [properties] Properties to set\n * @returns {com.beco.category.Color} Color instance\n * @type {{\n * (properties: com.beco.category.Color.$Shape): com.beco.category.Color & com.beco.category.Color.$Shape;\n * (properties?: com.beco.category.Color.$Properties): com.beco.category.Color;\n * }}\n */\n Color.create = function(properties) {\n return new Color(properties);\n };\n\n /**\n * Encodes the specified Color message. Does not implicitly {@link com.beco.category.Color.verify|verify} messages.\n * @function encode\n * @memberof com.beco.category.Color\n * @static\n * @param {com.beco.category.Color.$Properties} message Color message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Color.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.rgba != null && $Object.hasOwnProperty.call(message, \"rgba\") && message.rgba !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.rgba);\n if (message.hex != null && $Object.hasOwnProperty.call(message, \"hex\") && message.hex !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.hex);\n if (message.opacity != null && $Object.hasOwnProperty.call(message, \"opacity\") && !$Object.is(message.opacity, 0))\n writer.uint32(/* id 3, wireType 1 =*/25).double(message.opacity);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Color message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.category.Color\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.category.Color & com.beco.category.Color.$Shape} Color\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Color.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.category.Color(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.rgba = value;\n else\n delete message.rgba;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.hex = value;\n else\n delete message.hex;\n continue;\n }\n case 3: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.opacity = value;\n else\n delete message.opacity;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Color\n * @function getTypeUrl\n * @memberof com.beco.category.Color\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Color.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.category.Color\";\n };\n\n return Color;\n })();\n\n category.CategoryList = (function() {\n\n /**\n * Properties of a CategoryList.\n * @typedef {Object} com.beco.category.CategoryList.$Properties\n * @property {Array.<com.beco.category.Category.$Properties>|null} [categories] CategoryList categories\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a CategoryList.\n * @memberof com.beco.category\n * @interface ICategoryList\n * @augments com.beco.category.CategoryList.$Properties\n * @deprecated Use com.beco.category.CategoryList.$Properties instead.\n */\n\n /**\n * Shape of a CategoryList.\n * @typedef {com.beco.category.CategoryList.$Properties} com.beco.category.CategoryList.$Shape\n */\n\n /**\n * Constructs a new CategoryList.\n * @memberof com.beco.category\n * @classdesc Represents a CategoryList.\n * @constructor\n * @param {com.beco.category.CategoryList.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const CategoryList = function (properties) {\n this.categories = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * CategoryList categories.\n * @member {Array.<com.beco.category.Category.$Properties>} categories\n * @memberof com.beco.category.CategoryList\n * @instance\n */\n CategoryList.prototype.categories = $util.emptyArray;\n\n /**\n * Creates a new CategoryList instance using the specified properties.\n * @function create\n * @memberof com.beco.category.CategoryList\n * @static\n * @param {com.beco.category.CategoryList.$Properties=} [properties] Properties to set\n * @returns {com.beco.category.CategoryList} CategoryList instance\n * @type {{\n * (properties: com.beco.category.CategoryList.$Shape): com.beco.category.CategoryList & com.beco.category.CategoryList.$Shape;\n * (properties?: com.beco.category.CategoryList.$Properties): com.beco.category.CategoryList;\n * }}\n */\n CategoryList.create = function(properties) {\n return new CategoryList(properties);\n };\n\n /**\n * Encodes the specified CategoryList message. Does not implicitly {@link com.beco.category.CategoryList.verify|verify} messages.\n * @function encode\n * @memberof com.beco.category.CategoryList\n * @static\n * @param {com.beco.category.CategoryList.$Properties} message CategoryList message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n CategoryList.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.categories != null && message.categories.length)\n for (let i = 0; i < message.categories.length; ++i)\n $root.com.beco.category.Category.encode(message.categories[i], writer.uint32(/* id 1, wireType 2 =*/10).fork(), _depth + 1).ldelim();\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a CategoryList message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.category.CategoryList\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.category.CategoryList & com.beco.category.CategoryList.$Shape} CategoryList\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n CategoryList.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.category.CategoryList();\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if (!(message.categories && message.categories.length))\n message.categories = [];\n message.categories.push($root.com.beco.category.Category.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for CategoryList\n * @function getTypeUrl\n * @memberof com.beco.category.CategoryList\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n CategoryList.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.category.CategoryList\";\n };\n\n return CategoryList;\n })();\n\n return category;\n })();\n\n beco.location = (function() {\n\n /**\n * Namespace location.\n * @memberof com.beco\n * @namespace\n */\n const location = {};\n\n location.Location = (function() {\n\n /**\n * Properties of a Location.\n * @typedef {Object} com.beco.location.Location.$Properties\n * @property {string|null} [locationId] Location locationId\n * @property {string|null} [externalId] Location externalId\n * @property {string|null} [name] Location name\n * @property {string|null} [type] Location type\n * @property {string|null} [description] Location description\n * @property {string|null} [nodeId] Location nodeId\n * @property {string|null} [polygonId] Location polygonId\n * @property {boolean|null} [hidden] Location hidden\n * @property {number|null} [sortOrder] Location sortOrder\n * @property {string|null} [amenity] Location amenity\n * @property {Object.<string,string>|null} [phone] Location phone\n * @property {Object.<string,string>|null} [social] Location social\n * @property {Array.<com.beco.location.OperationHour.$Properties>|null} [operationHours] Location operationHours\n * @property {Array.<com.beco.location.Link.$Properties>|null} [links] Location links\n * @property {Array.<com.beco.location.SiblingGroup.$Properties>|null} [siblingGroups] Location siblingGroups\n * @property {boolean|null} [showSmartLabelWhenImagePresent] Location showSmartLabelWhenImagePresent\n * @property {Array.<string>|null} [categories] Location categories\n * @property {string|null} [stateName] Location stateName\n * @property {Array.<string>|null} [tags] Location tags\n * @property {string|null} [address] Location address\n * @property {string|null} [banner] Location banner\n * @property {string|null} [logo] Location logo\n * @property {com.beco.location.Zone.$Properties|null} [zone] Location zone\n * @property {boolean|null} [topLocation] Location topLocation\n * @property {boolean|null} [showLogo] Location showLogo\n * @property {number|null} [minZoom] Location minZoom\n * @property {com.beco.location.MapObject.$Properties|null} [mapObject] Location mapObject\n * @property {string|null} [area] Location area\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Location.\n * @memberof com.beco.location\n * @interface ILocation\n * @augments com.beco.location.Location.$Properties\n * @deprecated Use com.beco.location.Location.$Properties instead.\n */\n\n /**\n * Shape of a Location.\n * @typedef {com.beco.location.Location.$Properties} com.beco.location.Location.$Shape\n */\n\n /**\n * Constructs a new Location.\n * @memberof com.beco.location\n * @classdesc Represents a Location.\n * @constructor\n * @param {com.beco.location.Location.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Location = function (properties) {\n this.phone = {};\n this.social = {};\n this.operationHours = [];\n this.links = [];\n this.siblingGroups = [];\n this.categories = [];\n this.tags = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Location locationId.\n * @member {string} locationId\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.locationId = \"\";\n\n /**\n * Location externalId.\n * @member {string} externalId\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.externalId = \"\";\n\n /**\n * Location name.\n * @member {string} name\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.name = \"\";\n\n /**\n * Location type.\n * @member {string} type\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.type = \"\";\n\n /**\n * Location description.\n * @member {string} description\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.description = \"\";\n\n /**\n * Location nodeId.\n * @member {string} nodeId\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.nodeId = \"\";\n\n /**\n * Location polygonId.\n * @member {string} polygonId\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.polygonId = \"\";\n\n /**\n * Location hidden.\n * @member {boolean} hidden\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.hidden = false;\n\n /**\n * Location sortOrder.\n * @member {number} sortOrder\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.sortOrder = 0;\n\n /**\n * Location amenity.\n * @member {string} amenity\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.amenity = \"\";\n\n /**\n * Location phone.\n * @member {Object.<string,string>} phone\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.phone = $util.emptyObject;\n\n /**\n * Location social.\n * @member {Object.<string,string>} social\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.social = $util.emptyObject;\n\n /**\n * Location operationHours.\n * @member {Array.<com.beco.location.OperationHour.$Properties>} operationHours\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.operationHours = $util.emptyArray;\n\n /**\n * Location links.\n * @member {Array.<com.beco.location.Link.$Properties>} links\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.links = $util.emptyArray;\n\n /**\n * Location siblingGroups.\n * @member {Array.<com.beco.location.SiblingGroup.$Properties>} siblingGroups\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.siblingGroups = $util.emptyArray;\n\n /**\n * Location showSmartLabelWhenImagePresent.\n * @member {boolean} showSmartLabelWhenImagePresent\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.showSmartLabelWhenImagePresent = false;\n\n /**\n * Location categories.\n * @member {Array.<string>} categories\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.categories = $util.emptyArray;\n\n /**\n * Location stateName.\n * @member {string} stateName\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.stateName = \"\";\n\n /**\n * Location tags.\n * @member {Array.<string>} tags\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.tags = $util.emptyArray;\n\n /**\n * Location address.\n * @member {string} address\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.address = \"\";\n\n /**\n * Location banner.\n * @member {string} banner\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.banner = \"\";\n\n /**\n * Location logo.\n * @member {string} logo\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.logo = \"\";\n\n /**\n * Location zone.\n * @member {com.beco.location.Zone.$Properties|null|undefined} zone\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.zone = null;\n\n /**\n * Location topLocation.\n * @member {boolean} topLocation\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.topLocation = false;\n\n /**\n * Location showLogo.\n * @member {boolean} showLogo\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.showLogo = false;\n\n /**\n * Location minZoom.\n * @member {number} minZoom\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.minZoom = 0;\n\n /**\n * Location mapObject.\n * @member {com.beco.location.MapObject.$Properties|null|undefined} mapObject\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.mapObject = null;\n\n /**\n * Location area.\n * @member {string} area\n * @memberof com.beco.location.Location\n * @instance\n */\n Location.prototype.area = \"\";\n\n /**\n * Creates a new Location instance using the specified properties.\n * @function create\n * @memberof com.beco.location.Location\n * @static\n * @param {com.beco.location.Location.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.Location} Location instance\n * @type {{\n * (properties: com.beco.location.Location.$Shape): com.beco.location.Location & com.beco.location.Location.$Shape;\n * (properties?: com.beco.location.Location.$Properties): com.beco.location.Location;\n * }}\n */\n Location.create = function(properties) {\n return new Location(properties);\n };\n\n /**\n * Encodes the specified Location message. Does not implicitly {@link com.beco.location.Location.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.Location\n * @static\n * @param {com.beco.location.Location.$Properties} message Location message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Location.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.locationId != null && $Object.hasOwnProperty.call(message, \"locationId\") && message.locationId !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.locationId);\n if (message.externalId != null && $Object.hasOwnProperty.call(message, \"externalId\") && message.externalId !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.externalId);\n if (message.name != null && $Object.hasOwnProperty.call(message, \"name\") && message.name !== \"\")\n writer.uint32(/* id 3, wireType 2 =*/26).string(message.name);\n if (message.type != null && $Object.hasOwnProperty.call(message, \"type\") && message.type !== \"\")\n writer.uint32(/* id 4, wireType 2 =*/34).string(message.type);\n if (message.description != null && $Object.hasOwnProperty.call(message, \"description\") && message.description !== \"\")\n writer.uint32(/* id 5, wireType 2 =*/42).string(message.description);\n if (message.nodeId != null && $Object.hasOwnProperty.call(message, \"nodeId\") && message.nodeId !== \"\")\n writer.uint32(/* id 6, wireType 2 =*/50).string(message.nodeId);\n if (message.polygonId != null && $Object.hasOwnProperty.call(message, \"polygonId\") && message.polygonId !== \"\")\n writer.uint32(/* id 7, wireType 2 =*/58).string(message.polygonId);\n if (message.hidden != null && $Object.hasOwnProperty.call(message, \"hidden\") && message.hidden !== false)\n writer.uint32(/* id 8, wireType 0 =*/64).bool(message.hidden);\n if (message.sortOrder != null && $Object.hasOwnProperty.call(message, \"sortOrder\") && message.sortOrder !== 0)\n writer.uint32(/* id 9, wireType 0 =*/72).int32(message.sortOrder);\n if (message.amenity != null && $Object.hasOwnProperty.call(message, \"amenity\") && message.amenity !== \"\")\n writer.uint32(/* id 10, wireType 2 =*/82).string(message.amenity);\n if (message.phone != null && $Object.hasOwnProperty.call(message, \"phone\"))\n for (let keys = $Object.keys(message.phone), i = 0; i < keys.length; ++i)\n writer.uint32(/* id 11, wireType 2 =*/90).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.phone[keys[i]]).ldelim();\n if (message.social != null && $Object.hasOwnProperty.call(message, \"social\"))\n for (let keys = $Object.keys(message.social), i = 0; i < keys.length; ++i)\n writer.uint32(/* id 12, wireType 2 =*/98).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.social[keys[i]]).ldelim();\n if (message.operationHours != null && message.operationHours.length)\n for (let i = 0; i < message.operationHours.length; ++i)\n $root.com.beco.location.OperationHour.encode(message.operationHours[i], writer.uint32(/* id 13, wireType 2 =*/106).fork(), _depth + 1).ldelim();\n if (message.links != null && message.links.length)\n for (let i = 0; i < message.links.length; ++i)\n $root.com.beco.location.Link.encode(message.links[i], writer.uint32(/* id 14, wireType 2 =*/114).fork(), _depth + 1).ldelim();\n if (message.siblingGroups != null && message.siblingGroups.length)\n for (let i = 0; i < message.siblingGroups.length; ++i)\n $root.com.beco.location.SiblingGroup.encode(message.siblingGroups[i], writer.uint32(/* id 15, wireType 2 =*/122).fork(), _depth + 1).ldelim();\n if (message.showSmartLabelWhenImagePresent != null && $Object.hasOwnProperty.call(message, \"showSmartLabelWhenImagePresent\") && message.showSmartLabelWhenImagePresent !== false)\n writer.uint32(/* id 16, wireType 0 =*/128).bool(message.showSmartLabelWhenImagePresent);\n if (message.categories != null && message.categories.length)\n for (let i = 0; i < message.categories.length; ++i)\n writer.uint32(/* id 17, wireType 2 =*/138).string(message.categories[i]);\n if (message.stateName != null && $Object.hasOwnProperty.call(message, \"stateName\") && message.stateName !== \"\")\n writer.uint32(/* id 18, wireType 2 =*/146).string(message.stateName);\n if (message.tags != null && message.tags.length)\n for (let i = 0; i < message.tags.length; ++i)\n writer.uint32(/* id 19, wireType 2 =*/154).string(message.tags[i]);\n if (message.address != null && $Object.hasOwnProperty.call(message, \"address\") && message.address !== \"\")\n writer.uint32(/* id 20, wireType 2 =*/162).string(message.address);\n if (message.banner != null && $Object.hasOwnProperty.call(message, \"banner\") && message.banner !== \"\")\n writer.uint32(/* id 21, wireType 2 =*/170).string(message.banner);\n if (message.logo != null && $Object.hasOwnProperty.call(message, \"logo\") && message.logo !== \"\")\n writer.uint32(/* id 22, wireType 2 =*/178).string(message.logo);\n if (message.zone != null && $Object.hasOwnProperty.call(message, \"zone\"))\n $root.com.beco.location.Zone.encode(message.zone, writer.uint32(/* id 23, wireType 2 =*/186).fork(), _depth + 1).ldelim();\n if (message.topLocation != null && $Object.hasOwnProperty.call(message, \"topLocation\") && message.topLocation !== false)\n writer.uint32(/* id 24, wireType 0 =*/192).bool(message.topLocation);\n if (message.showLogo != null && $Object.hasOwnProperty.call(message, \"showLogo\") && message.showLogo !== false)\n writer.uint32(/* id 25, wireType 0 =*/200).bool(message.showLogo);\n if (message.minZoom != null && $Object.hasOwnProperty.call(message, \"minZoom\") && message.minZoom !== 0)\n writer.uint32(/* id 26, wireType 0 =*/208).int32(message.minZoom);\n if (message.mapObject != null && $Object.hasOwnProperty.call(message, \"mapObject\"))\n $root.com.beco.location.MapObject.encode(message.mapObject, writer.uint32(/* id 27, wireType 2 =*/218).fork(), _depth + 1).ldelim();\n if (message.area != null && $Object.hasOwnProperty.call(message, \"area\") && message.area !== \"\")\n writer.uint32(/* id 28, wireType 2 =*/226).string(message.area);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Location message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.Location\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.Location & com.beco.location.Location.$Shape} Location\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Location.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.Location(), key, value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.locationId = value;\n else\n delete message.locationId;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.externalId = value;\n else\n delete message.externalId;\n continue;\n }\n case 3: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.name = value;\n else\n delete message.name;\n continue;\n }\n case 4: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.type = value;\n else\n delete message.type;\n continue;\n }\n case 5: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.description = value;\n else\n delete message.description;\n continue;\n }\n case 6: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.nodeId = value;\n else\n delete message.nodeId;\n continue;\n }\n case 7: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.polygonId = value;\n else\n delete message.polygonId;\n continue;\n }\n case 8: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.hidden = value;\n else\n delete message.hidden;\n continue;\n }\n case 9: {\n if (wireType !== 0)\n break;\n if (value = reader.int32())\n message.sortOrder = value;\n else\n delete message.sortOrder;\n continue;\n }\n case 10: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.amenity = value;\n else\n delete message.amenity;\n continue;\n }\n case 11: {\n if (wireType !== 2)\n break;\n if (message.phone === $util.emptyObject)\n message.phone = {};\n let end2 = reader.uint32() + reader.pos;\n key = \"\";\n value = \"\";\n while (reader.pos < end2) {\n let tag2 = reader.tag();\n wireType = tag2 & 7;\n switch (tag2 >>>= 3) {\n case 1:\n if (wireType !== 2)\n break;\n key = reader.stringVerify();\n continue;\n case 2:\n if (wireType !== 2)\n break;\n value = reader.stringVerify();\n continue;\n }\n reader.skipType(wireType, _depth, tag2);\n }\n if (key === \"__proto__\")\n $util.makeProp(message.phone, key);\n message.phone[key] = value;\n continue;\n }\n case 12: {\n if (wireType !== 2)\n break;\n if (message.social === $util.emptyObject)\n message.social = {};\n let end2 = reader.uint32() + reader.pos;\n key = \"\";\n value = \"\";\n while (reader.pos < end2) {\n let tag2 = reader.tag();\n wireType = tag2 & 7;\n switch (tag2 >>>= 3) {\n case 1:\n if (wireType !== 2)\n break;\n key = reader.stringVerify();\n continue;\n case 2:\n if (wireType !== 2)\n break;\n value = reader.stringVerify();\n continue;\n }\n reader.skipType(wireType, _depth, tag2);\n }\n if (key === \"__proto__\")\n $util.makeProp(message.social, key);\n message.social[key] = value;\n continue;\n }\n case 13: {\n if (wireType !== 2)\n break;\n if (!(message.operationHours && message.operationHours.length))\n message.operationHours = [];\n message.operationHours.push($root.com.beco.location.OperationHour.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n case 14: {\n if (wireType !== 2)\n break;\n if (!(message.links && message.links.length))\n message.links = [];\n message.links.push($root.com.beco.location.Link.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n case 15: {\n if (wireType !== 2)\n break;\n if (!(message.siblingGroups && message.siblingGroups.length))\n message.siblingGroups = [];\n message.siblingGroups.push($root.com.beco.location.SiblingGroup.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n case 16: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.showSmartLabelWhenImagePresent = value;\n else\n delete message.showSmartLabelWhenImagePresent;\n continue;\n }\n case 17: {\n if (wireType !== 2)\n break;\n if (!(message.categories && message.categories.length))\n message.categories = [];\n message.categories.push(reader.stringVerify());\n continue;\n }\n case 18: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.stateName = value;\n else\n delete message.stateName;\n continue;\n }\n case 19: {\n if (wireType !== 2)\n break;\n if (!(message.tags && message.tags.length))\n message.tags = [];\n message.tags.push(reader.stringVerify());\n continue;\n }\n case 20: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.address = value;\n else\n delete message.address;\n continue;\n }\n case 21: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.banner = value;\n else\n delete message.banner;\n continue;\n }\n case 22: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.logo = value;\n else\n delete message.logo;\n continue;\n }\n case 23: {\n if (wireType !== 2)\n break;\n message.zone = $root.com.beco.location.Zone.decode(reader, reader.uint32(), $undefined, _depth + 1, message.zone);\n continue;\n }\n case 24: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.topLocation = value;\n else\n delete message.topLocation;\n continue;\n }\n case 25: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.showLogo = value;\n else\n delete message.showLogo;\n continue;\n }\n case 26: {\n if (wireType !== 0)\n break;\n if (value = reader.int32())\n message.minZoom = value;\n else\n delete message.minZoom;\n continue;\n }\n case 27: {\n if (wireType !== 2)\n break;\n message.mapObject = $root.com.beco.location.MapObject.decode(reader, reader.uint32(), $undefined, _depth + 1, message.mapObject);\n continue;\n }\n case 28: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.area = value;\n else\n delete message.area;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Location\n * @function getTypeUrl\n * @memberof com.beco.location.Location\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Location.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.Location\";\n };\n\n return Location;\n })();\n\n location.Zone = (function() {\n\n /**\n * Properties of a Zone.\n * @typedef {Object} com.beco.location.Zone.$Properties\n * @property {string|null} [zoneId] Zone zoneId\n * @property {string|null} [zoneName] Zone zoneName\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Zone.\n * @memberof com.beco.location\n * @interface IZone\n * @augments com.beco.location.Zone.$Properties\n * @deprecated Use com.beco.location.Zone.$Properties instead.\n */\n\n /**\n * Shape of a Zone.\n * @typedef {com.beco.location.Zone.$Properties} com.beco.location.Zone.$Shape\n */\n\n /**\n * Constructs a new Zone.\n * @memberof com.beco.location\n * @classdesc Represents a Zone.\n * @constructor\n * @param {com.beco.location.Zone.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Zone = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Zone zoneId.\n * @member {string} zoneId\n * @memberof com.beco.location.Zone\n * @instance\n */\n Zone.prototype.zoneId = \"\";\n\n /**\n * Zone zoneName.\n * @member {string} zoneName\n * @memberof com.beco.location.Zone\n * @instance\n */\n Zone.prototype.zoneName = \"\";\n\n /**\n * Creates a new Zone instance using the specified properties.\n * @function create\n * @memberof com.beco.location.Zone\n * @static\n * @param {com.beco.location.Zone.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.Zone} Zone instance\n * @type {{\n * (properties: com.beco.location.Zone.$Shape): com.beco.location.Zone & com.beco.location.Zone.$Shape;\n * (properties?: com.beco.location.Zone.$Properties): com.beco.location.Zone;\n * }}\n */\n Zone.create = function(properties) {\n return new Zone(properties);\n };\n\n /**\n * Encodes the specified Zone message. Does not implicitly {@link com.beco.location.Zone.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.Zone\n * @static\n * @param {com.beco.location.Zone.$Properties} message Zone message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Zone.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.zoneId != null && $Object.hasOwnProperty.call(message, \"zoneId\") && message.zoneId !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.zoneId);\n if (message.zoneName != null && $Object.hasOwnProperty.call(message, \"zoneName\") && message.zoneName !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.zoneName);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Zone message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.Zone\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.Zone & com.beco.location.Zone.$Shape} Zone\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Zone.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.Zone(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.zoneId = value;\n else\n delete message.zoneId;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.zoneName = value;\n else\n delete message.zoneName;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Zone\n * @function getTypeUrl\n * @memberof com.beco.location.Zone\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Zone.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.Zone\";\n };\n\n return Zone;\n })();\n\n location.Link = (function() {\n\n /**\n * Properties of a Link.\n * @typedef {Object} com.beco.location.Link.$Properties\n * @property {string|null} [url] Link url\n * @property {string|null} [label] Link label\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Link.\n * @memberof com.beco.location\n * @interface ILink\n * @augments com.beco.location.Link.$Properties\n * @deprecated Use com.beco.location.Link.$Properties instead.\n */\n\n /**\n * Shape of a Link.\n * @typedef {com.beco.location.Link.$Properties} com.beco.location.Link.$Shape\n */\n\n /**\n * Constructs a new Link.\n * @memberof com.beco.location\n * @classdesc Represents a Link.\n * @constructor\n * @param {com.beco.location.Link.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Link = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Link url.\n * @member {string} url\n * @memberof com.beco.location.Link\n * @instance\n */\n Link.prototype.url = \"\";\n\n /**\n * Link label.\n * @member {string} label\n * @memberof com.beco.location.Link\n * @instance\n */\n Link.prototype.label = \"\";\n\n /**\n * Creates a new Link instance using the specified properties.\n * @function create\n * @memberof com.beco.location.Link\n * @static\n * @param {com.beco.location.Link.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.Link} Link instance\n * @type {{\n * (properties: com.beco.location.Link.$Shape): com.beco.location.Link & com.beco.location.Link.$Shape;\n * (properties?: com.beco.location.Link.$Properties): com.beco.location.Link;\n * }}\n */\n Link.create = function(properties) {\n return new Link(properties);\n };\n\n /**\n * Encodes the specified Link message. Does not implicitly {@link com.beco.location.Link.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.Link\n * @static\n * @param {com.beco.location.Link.$Properties} message Link message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Link.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.url != null && $Object.hasOwnProperty.call(message, \"url\") && message.url !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);\n if (message.label != null && $Object.hasOwnProperty.call(message, \"label\") && message.label !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.label);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Link message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.Link\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.Link & com.beco.location.Link.$Shape} Link\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Link.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.Link(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.url = value;\n else\n delete message.url;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.label = value;\n else\n delete message.label;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Link\n * @function getTypeUrl\n * @memberof com.beco.location.Link\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Link.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.Link\";\n };\n\n return Link;\n })();\n\n location.SiblingGroup = (function() {\n\n /**\n * Properties of a SiblingGroup.\n * @typedef {Object} com.beco.location.SiblingGroup.$Properties\n * @property {string|null} [label] SiblingGroup label\n * @property {Array.<string>|null} [siblings] SiblingGroup siblings\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a SiblingGroup.\n * @memberof com.beco.location\n * @interface ISiblingGroup\n * @augments com.beco.location.SiblingGroup.$Properties\n * @deprecated Use com.beco.location.SiblingGroup.$Properties instead.\n */\n\n /**\n * Shape of a SiblingGroup.\n * @typedef {com.beco.location.SiblingGroup.$Properties} com.beco.location.SiblingGroup.$Shape\n */\n\n /**\n * Constructs a new SiblingGroup.\n * @memberof com.beco.location\n * @classdesc Represents a SiblingGroup.\n * @constructor\n * @param {com.beco.location.SiblingGroup.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const SiblingGroup = function (properties) {\n this.siblings = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * SiblingGroup label.\n * @member {string} label\n * @memberof com.beco.location.SiblingGroup\n * @instance\n */\n SiblingGroup.prototype.label = \"\";\n\n /**\n * SiblingGroup siblings.\n * @member {Array.<string>} siblings\n * @memberof com.beco.location.SiblingGroup\n * @instance\n */\n SiblingGroup.prototype.siblings = $util.emptyArray;\n\n /**\n * Creates a new SiblingGroup instance using the specified properties.\n * @function create\n * @memberof com.beco.location.SiblingGroup\n * @static\n * @param {com.beco.location.SiblingGroup.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.SiblingGroup} SiblingGroup instance\n * @type {{\n * (properties: com.beco.location.SiblingGroup.$Shape): com.beco.location.SiblingGroup & com.beco.location.SiblingGroup.$Shape;\n * (properties?: com.beco.location.SiblingGroup.$Properties): com.beco.location.SiblingGroup;\n * }}\n */\n SiblingGroup.create = function(properties) {\n return new SiblingGroup(properties);\n };\n\n /**\n * Encodes the specified SiblingGroup message. Does not implicitly {@link com.beco.location.SiblingGroup.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.SiblingGroup\n * @static\n * @param {com.beco.location.SiblingGroup.$Properties} message SiblingGroup message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SiblingGroup.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.label != null && $Object.hasOwnProperty.call(message, \"label\") && message.label !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.label);\n if (message.siblings != null && message.siblings.length)\n for (let i = 0; i < message.siblings.length; ++i)\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.siblings[i]);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a SiblingGroup message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.SiblingGroup\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.SiblingGroup & com.beco.location.SiblingGroup.$Shape} SiblingGroup\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SiblingGroup.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.SiblingGroup(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.label = value;\n else\n delete message.label;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if (!(message.siblings && message.siblings.length))\n message.siblings = [];\n message.siblings.push(reader.stringVerify());\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for SiblingGroup\n * @function getTypeUrl\n * @memberof com.beco.location.SiblingGroup\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n SiblingGroup.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.SiblingGroup\";\n };\n\n return SiblingGroup;\n })();\n\n location.OperationHour = (function() {\n\n /**\n * Properties of an OperationHour.\n * @typedef {Object} com.beco.location.OperationHour.$Properties\n * @property {string|null} [opens] OperationHour opens\n * @property {string|null} [closes] OperationHour closes\n * @property {Array.<string>|null} [dayOfWeek] OperationHour dayOfWeek\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of an OperationHour.\n * @memberof com.beco.location\n * @interface IOperationHour\n * @augments com.beco.location.OperationHour.$Properties\n * @deprecated Use com.beco.location.OperationHour.$Properties instead.\n */\n\n /**\n * Shape of an OperationHour.\n * @typedef {com.beco.location.OperationHour.$Properties} com.beco.location.OperationHour.$Shape\n */\n\n /**\n * Constructs a new OperationHour.\n * @memberof com.beco.location\n * @classdesc Represents an OperationHour.\n * @constructor\n * @param {com.beco.location.OperationHour.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const OperationHour = function (properties) {\n this.dayOfWeek = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * OperationHour opens.\n * @member {string} opens\n * @memberof com.beco.location.OperationHour\n * @instance\n */\n OperationHour.prototype.opens = \"\";\n\n /**\n * OperationHour closes.\n * @member {string} closes\n * @memberof com.beco.location.OperationHour\n * @instance\n */\n OperationHour.prototype.closes = \"\";\n\n /**\n * OperationHour dayOfWeek.\n * @member {Array.<string>} dayOfWeek\n * @memberof com.beco.location.OperationHour\n * @instance\n */\n OperationHour.prototype.dayOfWeek = $util.emptyArray;\n\n /**\n * Creates a new OperationHour instance using the specified properties.\n * @function create\n * @memberof com.beco.location.OperationHour\n * @static\n * @param {com.beco.location.OperationHour.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.OperationHour} OperationHour instance\n * @type {{\n * (properties: com.beco.location.OperationHour.$Shape): com.beco.location.OperationHour & com.beco.location.OperationHour.$Shape;\n * (properties?: com.beco.location.OperationHour.$Properties): com.beco.location.OperationHour;\n * }}\n */\n OperationHour.create = function(properties) {\n return new OperationHour(properties);\n };\n\n /**\n * Encodes the specified OperationHour message. Does not implicitly {@link com.beco.location.OperationHour.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.OperationHour\n * @static\n * @param {com.beco.location.OperationHour.$Properties} message OperationHour message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n OperationHour.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.opens != null && $Object.hasOwnProperty.call(message, \"opens\") && message.opens !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.opens);\n if (message.closes != null && $Object.hasOwnProperty.call(message, \"closes\") && message.closes !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.closes);\n if (message.dayOfWeek != null && message.dayOfWeek.length)\n for (let i = 0; i < message.dayOfWeek.length; ++i)\n writer.uint32(/* id 3, wireType 2 =*/26).string(message.dayOfWeek[i]);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes an OperationHour message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.OperationHour\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.OperationHour & com.beco.location.OperationHour.$Shape} OperationHour\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n OperationHour.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.OperationHour(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.opens = value;\n else\n delete message.opens;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.closes = value;\n else\n delete message.closes;\n continue;\n }\n case 3: {\n if (wireType !== 2)\n break;\n if (!(message.dayOfWeek && message.dayOfWeek.length))\n message.dayOfWeek = [];\n message.dayOfWeek.push(reader.stringVerify());\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for OperationHour\n * @function getTypeUrl\n * @memberof com.beco.location.OperationHour\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n OperationHour.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.OperationHour\";\n };\n\n return OperationHour;\n })();\n\n location.MapObject = (function() {\n\n /**\n * Properties of a MapObject.\n * @typedef {Object} com.beco.location.MapObject.$Properties\n * @property {string|null} [modelPath] MapObject modelPath\n * @property {number|null} [scale] MapObject scale\n * @property {number|null} [rotation] MapObject rotation\n * @property {number|null} [modelAltitude] MapObject modelAltitude\n * @property {number|null} [modelLight] MapObject modelLight\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a MapObject.\n * @memberof com.beco.location\n * @interface IMapObject\n * @augments com.beco.location.MapObject.$Properties\n * @deprecated Use com.beco.location.MapObject.$Properties instead.\n */\n\n /**\n * Shape of a MapObject.\n * @typedef {com.beco.location.MapObject.$Properties} com.beco.location.MapObject.$Shape\n */\n\n /**\n * Constructs a new MapObject.\n * @memberof com.beco.location\n * @classdesc Represents a MapObject.\n * @constructor\n * @param {com.beco.location.MapObject.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const MapObject = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * MapObject modelPath.\n * @member {string} modelPath\n * @memberof com.beco.location.MapObject\n * @instance\n */\n MapObject.prototype.modelPath = \"\";\n\n /**\n * MapObject scale.\n * @member {number} scale\n * @memberof com.beco.location.MapObject\n * @instance\n */\n MapObject.prototype.scale = 0;\n\n /**\n * MapObject rotation.\n * @member {number} rotation\n * @memberof com.beco.location.MapObject\n * @instance\n */\n MapObject.prototype.rotation = 0;\n\n /**\n * MapObject modelAltitude.\n * @member {number} modelAltitude\n * @memberof com.beco.location.MapObject\n * @instance\n */\n MapObject.prototype.modelAltitude = 0;\n\n /**\n * MapObject modelLight.\n * @member {number} modelLight\n * @memberof com.beco.location.MapObject\n * @instance\n */\n MapObject.prototype.modelLight = 0;\n\n /**\n * Creates a new MapObject instance using the specified properties.\n * @function create\n * @memberof com.beco.location.MapObject\n * @static\n * @param {com.beco.location.MapObject.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.MapObject} MapObject instance\n * @type {{\n * (properties: com.beco.location.MapObject.$Shape): com.beco.location.MapObject & com.beco.location.MapObject.$Shape;\n * (properties?: com.beco.location.MapObject.$Properties): com.beco.location.MapObject;\n * }}\n */\n MapObject.create = function(properties) {\n return new MapObject(properties);\n };\n\n /**\n * Encodes the specified MapObject message. Does not implicitly {@link com.beco.location.MapObject.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.MapObject\n * @static\n * @param {com.beco.location.MapObject.$Properties} message MapObject message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n MapObject.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.modelPath != null && $Object.hasOwnProperty.call(message, \"modelPath\") && message.modelPath !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.modelPath);\n if (message.scale != null && $Object.hasOwnProperty.call(message, \"scale\") && !$Object.is(message.scale, 0))\n writer.uint32(/* id 2, wireType 1 =*/17).double(message.scale);\n if (message.rotation != null && $Object.hasOwnProperty.call(message, \"rotation\") && !$Object.is(message.rotation, 0))\n writer.uint32(/* id 3, wireType 1 =*/25).double(message.rotation);\n if (message.modelAltitude != null && $Object.hasOwnProperty.call(message, \"modelAltitude\") && !$Object.is(message.modelAltitude, 0))\n writer.uint32(/* id 4, wireType 1 =*/33).double(message.modelAltitude);\n if (message.modelLight != null && $Object.hasOwnProperty.call(message, \"modelLight\") && !$Object.is(message.modelLight, 0))\n writer.uint32(/* id 5, wireType 1 =*/41).double(message.modelLight);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a MapObject message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.MapObject\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.MapObject & com.beco.location.MapObject.$Shape} MapObject\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n MapObject.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.MapObject(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.modelPath = value;\n else\n delete message.modelPath;\n continue;\n }\n case 2: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.scale = value;\n else\n delete message.scale;\n continue;\n }\n case 3: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.rotation = value;\n else\n delete message.rotation;\n continue;\n }\n case 4: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.modelAltitude = value;\n else\n delete message.modelAltitude;\n continue;\n }\n case 5: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.modelLight = value;\n else\n delete message.modelLight;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for MapObject\n * @function getTypeUrl\n * @memberof com.beco.location.MapObject\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n MapObject.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.MapObject\";\n };\n\n return MapObject;\n })();\n\n location.LocationList = (function() {\n\n /**\n * Properties of a LocationList.\n * @typedef {Object} com.beco.location.LocationList.$Properties\n * @property {Array.<com.beco.location.Location.$Properties>|null} [locations] LocationList locations\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a LocationList.\n * @memberof com.beco.location\n * @interface ILocationList\n * @augments com.beco.location.LocationList.$Properties\n * @deprecated Use com.beco.location.LocationList.$Properties instead.\n */\n\n /**\n * Shape of a LocationList.\n * @typedef {com.beco.location.LocationList.$Properties} com.beco.location.LocationList.$Shape\n */\n\n /**\n * Constructs a new LocationList.\n * @memberof com.beco.location\n * @classdesc Represents a LocationList.\n * @constructor\n * @param {com.beco.location.LocationList.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const LocationList = function (properties) {\n this.locations = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * LocationList locations.\n * @member {Array.<com.beco.location.Location.$Properties>} locations\n * @memberof com.beco.location.LocationList\n * @instance\n */\n LocationList.prototype.locations = $util.emptyArray;\n\n /**\n * Creates a new LocationList instance using the specified properties.\n * @function create\n * @memberof com.beco.location.LocationList\n * @static\n * @param {com.beco.location.LocationList.$Properties=} [properties] Properties to set\n * @returns {com.beco.location.LocationList} LocationList instance\n * @type {{\n * (properties: com.beco.location.LocationList.$Shape): com.beco.location.LocationList & com.beco.location.LocationList.$Shape;\n * (properties?: com.beco.location.LocationList.$Properties): com.beco.location.LocationList;\n * }}\n */\n LocationList.create = function(properties) {\n return new LocationList(properties);\n };\n\n /**\n * Encodes the specified LocationList message. Does not implicitly {@link com.beco.location.LocationList.verify|verify} messages.\n * @function encode\n * @memberof com.beco.location.LocationList\n * @static\n * @param {com.beco.location.LocationList.$Properties} message LocationList message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n LocationList.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.locations != null && message.locations.length)\n for (let i = 0; i < message.locations.length; ++i)\n $root.com.beco.location.Location.encode(message.locations[i], writer.uint32(/* id 1, wireType 2 =*/10).fork(), _depth + 1).ldelim();\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a LocationList message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.location.LocationList\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.location.LocationList & com.beco.location.LocationList.$Shape} LocationList\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n LocationList.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.location.LocationList();\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if (!(message.locations && message.locations.length))\n message.locations = [];\n message.locations.push($root.com.beco.location.Location.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for LocationList\n * @function getTypeUrl\n * @memberof com.beco.location.LocationList\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n LocationList.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.location.LocationList\";\n };\n\n return LocationList;\n })();\n\n return location;\n })();\n\n beco.map_object = (function() {\n\n /**\n * Namespace map_object.\n * @memberof com.beco\n * @namespace\n */\n const map_object = {};\n\n map_object.MapObject = (function() {\n\n /**\n * Properties of a MapObject.\n * @typedef {Object} com.beco.map_object.MapObject.$Properties\n * @property {string|null} [id] MapObject id\n * @property {string|null} [siteId] MapObject siteId\n * @property {string|null} [nodeId] MapObject nodeId\n * @property {string|null} [mapObjectPath] MapObject mapObjectPath\n * @property {number|null} [scale] MapObject scale\n * @property {number|null} [rotation] MapObject rotation\n * @property {number|null} [altitude] MapObject altitude\n * @property {number|null} [light] MapObject light\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a MapObject.\n * @memberof com.beco.map_object\n * @interface IMapObject\n * @augments com.beco.map_object.MapObject.$Properties\n * @deprecated Use com.beco.map_object.MapObject.$Properties instead.\n */\n\n /**\n * Shape of a MapObject.\n * @typedef {com.beco.map_object.MapObject.$Properties} com.beco.map_object.MapObject.$Shape\n */\n\n /**\n * Constructs a new MapObject.\n * @memberof com.beco.map_object\n * @classdesc Represents a MapObject.\n * @constructor\n * @param {com.beco.map_object.MapObject.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const MapObject = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * MapObject id.\n * @member {string} id\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.id = \"\";\n\n /**\n * MapObject siteId.\n * @member {string} siteId\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.siteId = \"\";\n\n /**\n * MapObject nodeId.\n * @member {string} nodeId\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.nodeId = \"\";\n\n /**\n * MapObject mapObjectPath.\n * @member {string} mapObjectPath\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.mapObjectPath = \"\";\n\n /**\n * MapObject scale.\n * @member {number} scale\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.scale = 0;\n\n /**\n * MapObject rotation.\n * @member {number} rotation\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.rotation = 0;\n\n /**\n * MapObject altitude.\n * @member {number} altitude\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.altitude = 0;\n\n /**\n * MapObject light.\n * @member {number} light\n * @memberof com.beco.map_object.MapObject\n * @instance\n */\n MapObject.prototype.light = 0;\n\n /**\n * Creates a new MapObject instance using the specified properties.\n * @function create\n * @memberof com.beco.map_object.MapObject\n * @static\n * @param {com.beco.map_object.MapObject.$Properties=} [properties] Properties to set\n * @returns {com.beco.map_object.MapObject} MapObject instance\n * @type {{\n * (properties: com.beco.map_object.MapObject.$Shape): com.beco.map_object.MapObject & com.beco.map_object.MapObject.$Shape;\n * (properties?: com.beco.map_object.MapObject.$Properties): com.beco.map_object.MapObject;\n * }}\n */\n MapObject.create = function(properties) {\n return new MapObject(properties);\n };\n\n /**\n * Encodes the specified MapObject message. Does not implicitly {@link com.beco.map_object.MapObject.verify|verify} messages.\n * @function encode\n * @memberof com.beco.map_object.MapObject\n * @static\n * @param {com.beco.map_object.MapObject.$Properties} message MapObject message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n MapObject.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.id != null && $Object.hasOwnProperty.call(message, \"id\") && message.id !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);\n if (message.siteId != null && $Object.hasOwnProperty.call(message, \"siteId\") && message.siteId !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.siteId);\n if (message.nodeId != null && $Object.hasOwnProperty.call(message, \"nodeId\") && message.nodeId !== \"\")\n writer.uint32(/* id 3, wireType 2 =*/26).string(message.nodeId);\n if (message.mapObjectPath != null && $Object.hasOwnProperty.call(message, \"mapObjectPath\") && message.mapObjectPath !== \"\")\n writer.uint32(/* id 4, wireType 2 =*/34).string(message.mapObjectPath);\n if (message.scale != null && $Object.hasOwnProperty.call(message, \"scale\") && !$Object.is(message.scale, 0))\n writer.uint32(/* id 5, wireType 1 =*/41).double(message.scale);\n if (message.rotation != null && $Object.hasOwnProperty.call(message, \"rotation\") && !$Object.is(message.rotation, 0))\n writer.uint32(/* id 6, wireType 1 =*/49).double(message.rotation);\n if (message.altitude != null && $Object.hasOwnProperty.call(message, \"altitude\") && !$Object.is(message.altitude, 0))\n writer.uint32(/* id 7, wireType 1 =*/57).double(message.altitude);\n if (message.light != null && $Object.hasOwnProperty.call(message, \"light\") && !$Object.is(message.light, 0))\n writer.uint32(/* id 8, wireType 1 =*/65).double(message.light);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a MapObject message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.map_object.MapObject\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.map_object.MapObject & com.beco.map_object.MapObject.$Shape} MapObject\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n MapObject.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.map_object.MapObject(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.id = value;\n else\n delete message.id;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.siteId = value;\n else\n delete message.siteId;\n continue;\n }\n case 3: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.nodeId = value;\n else\n delete message.nodeId;\n continue;\n }\n case 4: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.mapObjectPath = value;\n else\n delete message.mapObjectPath;\n continue;\n }\n case 5: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.scale = value;\n else\n delete message.scale;\n continue;\n }\n case 6: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.rotation = value;\n else\n delete message.rotation;\n continue;\n }\n case 7: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.altitude = value;\n else\n delete message.altitude;\n continue;\n }\n case 8: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.light = value;\n else\n delete message.light;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for MapObject\n * @function getTypeUrl\n * @memberof com.beco.map_object.MapObject\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n MapObject.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.map_object.MapObject\";\n };\n\n return MapObject;\n })();\n\n map_object.MapObjectsList = (function() {\n\n /**\n * Properties of a MapObjectsList.\n * @typedef {Object} com.beco.map_object.MapObjectsList.$Properties\n * @property {Array.<com.beco.map_object.MapObject.$Properties>|null} [mapObjects] MapObjectsList mapObjects\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a MapObjectsList.\n * @memberof com.beco.map_object\n * @interface IMapObjectsList\n * @augments com.beco.map_object.MapObjectsList.$Properties\n * @deprecated Use com.beco.map_object.MapObjectsList.$Properties instead.\n */\n\n /**\n * Shape of a MapObjectsList.\n * @typedef {com.beco.map_object.MapObjectsList.$Properties} com.beco.map_object.MapObjectsList.$Shape\n */\n\n /**\n * Constructs a new MapObjectsList.\n * @memberof com.beco.map_object\n * @classdesc Represents a MapObjectsList.\n * @constructor\n * @param {com.beco.map_object.MapObjectsList.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const MapObjectsList = function (properties) {\n this.mapObjects = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * MapObjectsList mapObjects.\n * @member {Array.<com.beco.map_object.MapObject.$Properties>} mapObjects\n * @memberof com.beco.map_object.MapObjectsList\n * @instance\n */\n MapObjectsList.prototype.mapObjects = $util.emptyArray;\n\n /**\n * Creates a new MapObjectsList instance using the specified properties.\n * @function create\n * @memberof com.beco.map_object.MapObjectsList\n * @static\n * @param {com.beco.map_object.MapObjectsList.$Properties=} [properties] Properties to set\n * @returns {com.beco.map_object.MapObjectsList} MapObjectsList instance\n * @type {{\n * (properties: com.beco.map_object.MapObjectsList.$Shape): com.beco.map_object.MapObjectsList & com.beco.map_object.MapObjectsList.$Shape;\n * (properties?: com.beco.map_object.MapObjectsList.$Properties): com.beco.map_object.MapObjectsList;\n * }}\n */\n MapObjectsList.create = function(properties) {\n return new MapObjectsList(properties);\n };\n\n /**\n * Encodes the specified MapObjectsList message. Does not implicitly {@link com.beco.map_object.MapObjectsList.verify|verify} messages.\n * @function encode\n * @memberof com.beco.map_object.MapObjectsList\n * @static\n * @param {com.beco.map_object.MapObjectsList.$Properties} message MapObjectsList message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n MapObjectsList.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.mapObjects != null && message.mapObjects.length)\n for (let i = 0; i < message.mapObjects.length; ++i)\n $root.com.beco.map_object.MapObject.encode(message.mapObjects[i], writer.uint32(/* id 1, wireType 2 =*/10).fork(), _depth + 1).ldelim();\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a MapObjectsList message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.map_object.MapObjectsList\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.map_object.MapObjectsList & com.beco.map_object.MapObjectsList.$Shape} MapObjectsList\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n MapObjectsList.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.map_object.MapObjectsList();\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if (!(message.mapObjects && message.mapObjects.length))\n message.mapObjects = [];\n message.mapObjects.push($root.com.beco.map_object.MapObject.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for MapObjectsList\n * @function getTypeUrl\n * @memberof com.beco.map_object.MapObjectsList\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n MapObjectsList.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.map_object.MapObjectsList\";\n };\n\n return MapObjectsList;\n })();\n\n return map_object;\n })();\n\n beco.node = (function() {\n\n /**\n * Namespace node.\n * @memberof com.beco\n * @namespace\n */\n const node = {};\n\n node.Node = (function() {\n\n /**\n * Properties of a Node.\n * @typedef {Object} com.beco.node.Node.$Properties\n * @property {string|null} [nodeId] Node nodeId\n * @property {number|null} [lat] Node lat\n * @property {number|null} [lng] Node lng\n * @property {boolean|null} [accessible] Node accessible\n * @property {string|null} [floorId] Node floorId\n * @property {Array.<string>|null} [siblings] Node siblings\n * @property {boolean|null} [privateNode] Node privateNode\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a Node.\n * @memberof com.beco.node\n * @interface INode\n * @augments com.beco.node.Node.$Properties\n * @deprecated Use com.beco.node.Node.$Properties instead.\n */\n\n /**\n * Shape of a Node.\n * @typedef {com.beco.node.Node.$Properties} com.beco.node.Node.$Shape\n */\n\n /**\n * Constructs a new Node.\n * @memberof com.beco.node\n * @classdesc Represents a Node.\n * @constructor\n * @param {com.beco.node.Node.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const Node = function (properties) {\n this.siblings = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * Node nodeId.\n * @member {string} nodeId\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.nodeId = \"\";\n\n /**\n * Node lat.\n * @member {number} lat\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.lat = 0;\n\n /**\n * Node lng.\n * @member {number} lng\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.lng = 0;\n\n /**\n * Node accessible.\n * @member {boolean} accessible\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.accessible = false;\n\n /**\n * Node floorId.\n * @member {string} floorId\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.floorId = \"\";\n\n /**\n * Node siblings.\n * @member {Array.<string>} siblings\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.siblings = $util.emptyArray;\n\n /**\n * Node privateNode.\n * @member {boolean} privateNode\n * @memberof com.beco.node.Node\n * @instance\n */\n Node.prototype.privateNode = false;\n\n /**\n * Creates a new Node instance using the specified properties.\n * @function create\n * @memberof com.beco.node.Node\n * @static\n * @param {com.beco.node.Node.$Properties=} [properties] Properties to set\n * @returns {com.beco.node.Node} Node instance\n * @type {{\n * (properties: com.beco.node.Node.$Shape): com.beco.node.Node & com.beco.node.Node.$Shape;\n * (properties?: com.beco.node.Node.$Properties): com.beco.node.Node;\n * }}\n */\n Node.create = function(properties) {\n return new Node(properties);\n };\n\n /**\n * Encodes the specified Node message. Does not implicitly {@link com.beco.node.Node.verify|verify} messages.\n * @function encode\n * @memberof com.beco.node.Node\n * @static\n * @param {com.beco.node.Node.$Properties} message Node message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n Node.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.nodeId != null && $Object.hasOwnProperty.call(message, \"nodeId\") && message.nodeId !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.nodeId);\n if (message.lat != null && $Object.hasOwnProperty.call(message, \"lat\") && !$Object.is(message.lat, 0))\n writer.uint32(/* id 2, wireType 1 =*/17).double(message.lat);\n if (message.lng != null && $Object.hasOwnProperty.call(message, \"lng\") && !$Object.is(message.lng, 0))\n writer.uint32(/* id 3, wireType 1 =*/25).double(message.lng);\n if (message.accessible != null && $Object.hasOwnProperty.call(message, \"accessible\") && message.accessible !== false)\n writer.uint32(/* id 4, wireType 0 =*/32).bool(message.accessible);\n if (message.floorId != null && $Object.hasOwnProperty.call(message, \"floorId\") && message.floorId !== \"\")\n writer.uint32(/* id 5, wireType 2 =*/42).string(message.floorId);\n if (message.siblings != null && message.siblings.length)\n for (let i = 0; i < message.siblings.length; ++i)\n writer.uint32(/* id 6, wireType 2 =*/50).string(message.siblings[i]);\n if (message.privateNode != null && $Object.hasOwnProperty.call(message, \"privateNode\") && message.privateNode !== false)\n writer.uint32(/* id 7, wireType 0 =*/56).bool(message.privateNode);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a Node message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.node.Node\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.node.Node & com.beco.node.Node.$Shape} Node\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n Node.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.node.Node(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.nodeId = value;\n else\n delete message.nodeId;\n continue;\n }\n case 2: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.lat = value;\n else\n delete message.lat;\n continue;\n }\n case 3: {\n if (wireType !== 1)\n break;\n if (!$Object.is(value = reader.double(), 0))\n message.lng = value;\n else\n delete message.lng;\n continue;\n }\n case 4: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.accessible = value;\n else\n delete message.accessible;\n continue;\n }\n case 5: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.floorId = value;\n else\n delete message.floorId;\n continue;\n }\n case 6: {\n if (wireType !== 2)\n break;\n if (!(message.siblings && message.siblings.length))\n message.siblings = [];\n message.siblings.push(reader.stringVerify());\n continue;\n }\n case 7: {\n if (wireType !== 0)\n break;\n if (value = reader.bool())\n message.privateNode = value;\n else\n delete message.privateNode;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for Node\n * @function getTypeUrl\n * @memberof com.beco.node.Node\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n Node.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.node.Node\";\n };\n\n return Node;\n })();\n\n node.NodeList = (function() {\n\n /**\n * Properties of a NodeList.\n * @typedef {Object} com.beco.node.NodeList.$Properties\n * @property {Array.<com.beco.node.Node.$Properties>|null} [nodes] NodeList nodes\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a NodeList.\n * @memberof com.beco.node\n * @interface INodeList\n * @augments com.beco.node.NodeList.$Properties\n * @deprecated Use com.beco.node.NodeList.$Properties instead.\n */\n\n /**\n * Shape of a NodeList.\n * @typedef {com.beco.node.NodeList.$Properties} com.beco.node.NodeList.$Shape\n */\n\n /**\n * Constructs a new NodeList.\n * @memberof com.beco.node\n * @classdesc Represents a NodeList.\n * @constructor\n * @param {com.beco.node.NodeList.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const NodeList = function (properties) {\n this.nodes = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * NodeList nodes.\n * @member {Array.<com.beco.node.Node.$Properties>} nodes\n * @memberof com.beco.node.NodeList\n * @instance\n */\n NodeList.prototype.nodes = $util.emptyArray;\n\n /**\n * Creates a new NodeList instance using the specified properties.\n * @function create\n * @memberof com.beco.node.NodeList\n * @static\n * @param {com.beco.node.NodeList.$Properties=} [properties] Properties to set\n * @returns {com.beco.node.NodeList} NodeList instance\n * @type {{\n * (properties: com.beco.node.NodeList.$Shape): com.beco.node.NodeList & com.beco.node.NodeList.$Shape;\n * (properties?: com.beco.node.NodeList.$Properties): com.beco.node.NodeList;\n * }}\n */\n NodeList.create = function(properties) {\n return new NodeList(properties);\n };\n\n /**\n * Encodes the specified NodeList message. Does not implicitly {@link com.beco.node.NodeList.verify|verify} messages.\n * @function encode\n * @memberof com.beco.node.NodeList\n * @static\n * @param {com.beco.node.NodeList.$Properties} message NodeList message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n NodeList.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.nodes != null && message.nodes.length)\n for (let i = 0; i < message.nodes.length; ++i)\n $root.com.beco.node.Node.encode(message.nodes[i], writer.uint32(/* id 1, wireType 2 =*/10).fork(), _depth + 1).ldelim();\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a NodeList message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.node.NodeList\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.node.NodeList & com.beco.node.NodeList.$Shape} NodeList\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n NodeList.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.node.NodeList();\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if (!(message.nodes && message.nodes.length))\n message.nodes = [];\n message.nodes.push($root.com.beco.node.Node.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for NodeList\n * @function getTypeUrl\n * @memberof com.beco.node.NodeList\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n NodeList.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.node.NodeList\";\n };\n\n return NodeList;\n })();\n\n return node;\n })();\n\n beco.geoshapes = (function() {\n\n /**\n * Namespace geoshapes.\n * @memberof com.beco\n * @namespace\n */\n const geoshapes = {};\n\n geoshapes.GeoShapes = (function() {\n\n /**\n * Properties of a GeoShapes.\n * @typedef {Object} com.beco.geoshapes.GeoShapes.$Properties\n * @property {string|null} [shapeId] GeoShapes shapeId\n * @property {string|null} [jsonData] GeoShapes jsonData\n * @property {string|null} [type] GeoShapes type\n * @property {string|null} [floorId] GeoShapes floorId\n * @property {string|null} [siteId] GeoShapes siteId\n * @property {string|null} [layerId] GeoShapes layerId\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a GeoShapes.\n * @memberof com.beco.geoshapes\n * @interface IGeoShapes\n * @augments com.beco.geoshapes.GeoShapes.$Properties\n * @deprecated Use com.beco.geoshapes.GeoShapes.$Properties instead.\n */\n\n /**\n * Shape of a GeoShapes.\n * @typedef {com.beco.geoshapes.GeoShapes.$Properties} com.beco.geoshapes.GeoShapes.$Shape\n */\n\n /**\n * Constructs a new GeoShapes.\n * @memberof com.beco.geoshapes\n * @classdesc Represents a GeoShapes.\n * @constructor\n * @param {com.beco.geoshapes.GeoShapes.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const GeoShapes = function (properties) {\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * GeoShapes shapeId.\n * @member {string} shapeId\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.shapeId = \"\";\n\n /**\n * GeoShapes jsonData.\n * @member {string} jsonData\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.jsonData = \"\";\n\n /**\n * GeoShapes type.\n * @member {string} type\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.type = \"\";\n\n /**\n * GeoShapes floorId.\n * @member {string} floorId\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.floorId = \"\";\n\n /**\n * GeoShapes siteId.\n * @member {string} siteId\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.siteId = \"\";\n\n /**\n * GeoShapes layerId.\n * @member {string} layerId\n * @memberof com.beco.geoshapes.GeoShapes\n * @instance\n */\n GeoShapes.prototype.layerId = \"\";\n\n /**\n * Creates a new GeoShapes instance using the specified properties.\n * @function create\n * @memberof com.beco.geoshapes.GeoShapes\n * @static\n * @param {com.beco.geoshapes.GeoShapes.$Properties=} [properties] Properties to set\n * @returns {com.beco.geoshapes.GeoShapes} GeoShapes instance\n * @type {{\n * (properties: com.beco.geoshapes.GeoShapes.$Shape): com.beco.geoshapes.GeoShapes & com.beco.geoshapes.GeoShapes.$Shape;\n * (properties?: com.beco.geoshapes.GeoShapes.$Properties): com.beco.geoshapes.GeoShapes;\n * }}\n */\n GeoShapes.create = function(properties) {\n return new GeoShapes(properties);\n };\n\n /**\n * Encodes the specified GeoShapes message. Does not implicitly {@link com.beco.geoshapes.GeoShapes.verify|verify} messages.\n * @function encode\n * @memberof com.beco.geoshapes.GeoShapes\n * @static\n * @param {com.beco.geoshapes.GeoShapes.$Properties} message GeoShapes message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n GeoShapes.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.shapeId != null && $Object.hasOwnProperty.call(message, \"shapeId\") && message.shapeId !== \"\")\n writer.uint32(/* id 1, wireType 2 =*/10).string(message.shapeId);\n if (message.jsonData != null && $Object.hasOwnProperty.call(message, \"jsonData\") && message.jsonData !== \"\")\n writer.uint32(/* id 2, wireType 2 =*/18).string(message.jsonData);\n if (message.type != null && $Object.hasOwnProperty.call(message, \"type\") && message.type !== \"\")\n writer.uint32(/* id 3, wireType 2 =*/26).string(message.type);\n if (message.floorId != null && $Object.hasOwnProperty.call(message, \"floorId\") && message.floorId !== \"\")\n writer.uint32(/* id 4, wireType 2 =*/34).string(message.floorId);\n if (message.siteId != null && $Object.hasOwnProperty.call(message, \"siteId\") && message.siteId !== \"\")\n writer.uint32(/* id 5, wireType 2 =*/42).string(message.siteId);\n if (message.layerId != null && $Object.hasOwnProperty.call(message, \"layerId\") && message.layerId !== \"\")\n writer.uint32(/* id 6, wireType 2 =*/50).string(message.layerId);\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a GeoShapes message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.geoshapes.GeoShapes\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.geoshapes.GeoShapes & com.beco.geoshapes.GeoShapes.$Shape} GeoShapes\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n GeoShapes.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.geoshapes.GeoShapes(), value;\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.shapeId = value;\n else\n delete message.shapeId;\n continue;\n }\n case 2: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.jsonData = value;\n else\n delete message.jsonData;\n continue;\n }\n case 3: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.type = value;\n else\n delete message.type;\n continue;\n }\n case 4: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.floorId = value;\n else\n delete message.floorId;\n continue;\n }\n case 5: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.siteId = value;\n else\n delete message.siteId;\n continue;\n }\n case 6: {\n if (wireType !== 2)\n break;\n if ((value = reader.stringVerify()).length)\n message.layerId = value;\n else\n delete message.layerId;\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for GeoShapes\n * @function getTypeUrl\n * @memberof com.beco.geoshapes.GeoShapes\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n GeoShapes.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.geoshapes.GeoShapes\";\n };\n\n return GeoShapes;\n })();\n\n geoshapes.GeoShapesList = (function() {\n\n /**\n * Properties of a GeoShapesList.\n * @typedef {Object} com.beco.geoshapes.GeoShapesList.$Properties\n * @property {Array.<com.beco.geoshapes.GeoShapes.$Properties>|null} [shapes] GeoShapesList shapes\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n\n /**\n * Properties of a GeoShapesList.\n * @memberof com.beco.geoshapes\n * @interface IGeoShapesList\n * @augments com.beco.geoshapes.GeoShapesList.$Properties\n * @deprecated Use com.beco.geoshapes.GeoShapesList.$Properties instead.\n */\n\n /**\n * Shape of a GeoShapesList.\n * @typedef {com.beco.geoshapes.GeoShapesList.$Properties} com.beco.geoshapes.GeoShapesList.$Shape\n */\n\n /**\n * Constructs a new GeoShapesList.\n * @memberof com.beco.geoshapes\n * @classdesc Represents a GeoShapesList.\n * @constructor\n * @param {com.beco.geoshapes.GeoShapesList.$Properties=} [properties] Properties to set\n * @property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding when enabled\n */\n const GeoShapesList = function (properties) {\n this.shapes = [];\n if (properties)\n for (let keys = $Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null && keys[i] !== \"__proto__\")\n this[keys[i]] = properties[keys[i]];\n };\n\n /**\n * GeoShapesList shapes.\n * @member {Array.<com.beco.geoshapes.GeoShapes.$Properties>} shapes\n * @memberof com.beco.geoshapes.GeoShapesList\n * @instance\n */\n GeoShapesList.prototype.shapes = $util.emptyArray;\n\n /**\n * Creates a new GeoShapesList instance using the specified properties.\n * @function create\n * @memberof com.beco.geoshapes.GeoShapesList\n * @static\n * @param {com.beco.geoshapes.GeoShapesList.$Properties=} [properties] Properties to set\n * @returns {com.beco.geoshapes.GeoShapesList} GeoShapesList instance\n * @type {{\n * (properties: com.beco.geoshapes.GeoShapesList.$Shape): com.beco.geoshapes.GeoShapesList & com.beco.geoshapes.GeoShapesList.$Shape;\n * (properties?: com.beco.geoshapes.GeoShapesList.$Properties): com.beco.geoshapes.GeoShapesList;\n * }}\n */\n GeoShapesList.create = function(properties) {\n return new GeoShapesList(properties);\n };\n\n /**\n * Encodes the specified GeoShapesList message. Does not implicitly {@link com.beco.geoshapes.GeoShapesList.verify|verify} messages.\n * @function encode\n * @memberof com.beco.geoshapes.GeoShapesList\n * @static\n * @param {com.beco.geoshapes.GeoShapesList.$Properties} message GeoShapesList message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n GeoShapesList.encode = function (message, writer, _depth) {\n if (!writer)\n writer = $Writer.create();\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $util.recursionLimit)\n throw $Error(\"max depth exceeded\");\n if (message.shapes != null && message.shapes.length)\n for (let i = 0; i < message.shapes.length; ++i)\n $root.com.beco.geoshapes.GeoShapes.encode(message.shapes[i], writer.uint32(/* id 1, wireType 2 =*/10).fork(), _depth + 1).ldelim();\n if (message.$unknowns != null && $Object.hasOwnProperty.call(message, \"$unknowns\"))\n for (let i = 0; i < message.$unknowns.length; ++i)\n writer.raw(message.$unknowns[i]);\n return writer;\n };\n\n /**\n * Decodes a GeoShapesList message from the specified reader or buffer.\n * @function decode\n * @memberof com.beco.geoshapes.GeoShapesList\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {com.beco.geoshapes.GeoShapesList & com.beco.geoshapes.GeoShapesList.$Shape} GeoShapesList\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n GeoShapesList.decode = function (reader, length, _end, _depth, _target) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n if (_depth === $undefined)\n _depth = 0;\n if (_depth > $Reader.recursionLimit)\n throw $Error(\"max depth exceeded\");\n let end = length === $undefined ? reader.len : reader.pos + length, message = _target || new $root.com.beco.geoshapes.GeoShapesList();\n while (reader.pos < end) {\n let start = reader.pos;\n let tag = reader.tag();\n if (tag === _end) {\n _end = $undefined;\n break;\n }\n let wireType = tag & 7;\n switch (tag >>>= 3) {\n case 1: {\n if (wireType !== 2)\n break;\n if (!(message.shapes && message.shapes.length))\n message.shapes = [];\n message.shapes.push($root.com.beco.geoshapes.GeoShapes.decode(reader, reader.uint32(), $undefined, _depth + 1));\n continue;\n }\n }\n reader.skipType(wireType, _depth, tag);\n if (!reader.discardUnknown) {\n $util.makeProp(message, \"$unknowns\", false);\n (message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));\n }\n }\n if (_end !== $undefined)\n throw $Error(\"missing end group\");\n return message;\n };\n\n /**\n * Gets the type url for GeoShapesList\n * @function getTypeUrl\n * @memberof com.beco.geoshapes.GeoShapesList\n * @static\n * @param {string} [prefix] Custom type url prefix, defaults to `\"type.googleapis.com\"`\n * @returns {string} The type url\n */\n GeoShapesList.getTypeUrl = function(prefix) {\n if (prefix === $undefined)\n prefix = \"type.googleapis.com\";\n return prefix + \"/com.beco.geoshapes.GeoShapesList\";\n };\n\n return GeoShapesList;\n })();\n\n return geoshapes;\n })();\n\n return beco;\n })();\n\n return com;\n})();\n\nexport {\n $root as default\n};\n","/**\r\n * Minimal fetch client: 15s per-request timeout, retry ×2 with exponential\r\n * backoff + jitter on network errors and 5xx (never 4xx), and composition\r\n * with the instance-level abort signal (destroy() cancels in-flight work).\r\n */\r\n\r\nconst REQUEST_TIMEOUT_MS = 15_000;\r\nconst MAX_RETRIES = 2;\r\n\r\nexport interface HttpOptions {\r\n headers?: Record<string, string>;\r\n method?: 'GET' | 'POST';\r\n body?: unknown;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport class HttpError extends Error {\r\n readonly status: number;\r\n constructor(status: number, url: string) {\r\n super(`becomap: HTTP ${String(status)} for ${url}`);\r\n this.status = status;\r\n }\r\n}\r\n\r\nfunction composeSignal(caller?: AbortSignal): AbortSignal {\r\n const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);\r\n return caller ? AbortSignal.any([caller, timeout]) : timeout;\r\n}\r\n\r\nasync function backoff(attempt: number): Promise<void> {\r\n const base = 300 * 2 ** attempt;\r\n const jitter = Math.random() * 200;\r\n await new Promise((resolve) => setTimeout(resolve, base + jitter));\r\n}\r\n\r\nasync function request(url: string, options: HttpOptions): Promise<Response> {\r\n let lastError: unknown;\r\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\r\n if (options.signal?.aborted) {\r\n throw lastError instanceof Error ? lastError : new DOMException('aborted', 'AbortError');\r\n }\r\n try {\r\n const response = await fetch(url, {\r\n method: options.method ?? 'GET',\r\n headers: {\r\n ...(options.body !== undefined ? { 'Content-Type': 'application/json' } : {}),\r\n ...options.headers,\r\n },\r\n ...(options.body !== undefined ? { body: JSON.stringify(options.body) } : {}),\r\n signal: composeSignal(options.signal),\r\n });\r\n if (response.status >= 500) {\r\n lastError = new HttpError(response.status, url);\r\n await backoff(attempt);\r\n continue;\r\n }\r\n if (!response.ok) throw new HttpError(response.status, url);\r\n return response;\r\n } catch (err) {\r\n if (err instanceof HttpError) throw err; // 4xx — never retried\r\n if (options.signal?.aborted) throw err; // caller cancelled — stop\r\n lastError = err; // network / timeout — retry\r\n if (attempt < MAX_RETRIES) await backoff(attempt);\r\n }\r\n }\r\n throw lastError instanceof Error ? lastError : new Error('becomap: request failed');\r\n}\r\n\r\nexport async function fetchJson<T>(url: string, options: HttpOptions = {}): Promise<T> {\r\n const response = await request(url, options);\r\n return (await response.json()) as T;\r\n}\r\n\r\nexport async function fetchBinary(url: string, options: HttpOptions = {}): Promise<Uint8Array> {\r\n const response = await request(url, options);\r\n return new Uint8Array(await response.arrayBuffer());\r\n}\r\n","import { com } from './gen/becomap-proto.js';\r\nimport { fetchBinary, fetchJson } from './http.js';\r\nimport type { VenueProvider } from './provider.js';\r\nimport type {\r\n FloorConnectionKind,\r\n LineStringGeometry,\r\n PolygonGeometry,\r\n ShapeGeometryData,\r\n RawBuilding,\r\n RawCategory,\r\n RawFloorConnection,\r\n RawLocation,\r\n RawMapObject,\r\n RawNode,\r\n RawShape,\r\n ShapeStyle,\r\n VenueData,\r\n} from './types.js';\r\n\r\n// ---------------------------------------------------------------------------\r\n// REST response contracts (extracted from v1 source — see 02-RESEARCH.md)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface AuthResponse {\r\n accessToken: string;\r\n}\r\n\r\ninterface SiteResponse {\r\n siteId: string;\r\n siteName: string;\r\n latitude: number;\r\n longitude: number;\r\n buildings: { buildingId: string; buildingName: string }[];\r\n binaryUrl: {\r\n route: string;\r\n shape: string;\r\n location: string;\r\n category: string;\r\n map_object: string;\r\n };\r\n}\r\n\r\ninterface FloorResponse {\r\n floorId: string;\r\n name: string;\r\n elevation: number;\r\n}\r\n\r\ninterface ConnectionResponse {\r\n connectionId: string;\r\n weight: number;\r\n multiplier: number;\r\n name: string;\r\n type: string;\r\n accessible: boolean;\r\n node: string[];\r\n direction: string;\r\n}\r\n\r\nexport interface RestVenueProviderOptions {\r\n baseUrl: string;\r\n siteId: string;\r\n clientId: string;\r\n clientSecret: string;\r\n}\r\n\r\nconst CONNECTION_KIND: Record<string, FloorConnectionKind> = {\r\n ELEVATOR: 'elevator',\r\n ESCALATOR: 'escalator',\r\n STAIRS: 'stairs',\r\n PASSAGE: 'passage',\r\n DOOR: 'door',\r\n RAMP: 'ramp',\r\n};\r\n\r\ninterface EditorShapeProperties {\r\n height?: number;\r\n color?: string;\r\n fillColor?: string;\r\n opacity?: number;\r\n label?: { fontSize?: number; nextRotation?: number; labelColor?: string };\r\n}\r\n\r\nfunction parseShapeFeature(\r\n jsonData: string,\r\n): { geometry: ShapeGeometryData; style: ShapeStyle } | null {\r\n try {\r\n const parsed = JSON.parse(jsonData) as {\r\n type?: string;\r\n geometry?: { type?: string; coordinates?: unknown };\r\n properties?: { shapeProperties?: EditorShapeProperties };\r\n coordinates?: unknown;\r\n };\r\n // editor emits a GeoJSON Feature; tolerate bare geometry too\r\n const geometry = parsed.type === 'Feature' ? parsed.geometry : parsed;\r\n let geometryData: ShapeGeometryData | null = null;\r\n if (geometry?.type === 'Polygon' && Array.isArray(geometry.coordinates)) {\r\n geometryData = {\r\n type: 'Polygon',\r\n coordinates: geometry.coordinates as PolygonGeometry['coordinates'],\r\n };\r\n } else if (geometry?.type === 'LineString' && Array.isArray(geometry.coordinates)) {\r\n // INNER_WALL shapes are centerlines, buffered into wall bands at render\r\n geometryData = {\r\n type: 'LineString',\r\n coordinates: geometry.coordinates as LineStringGeometry['coordinates'],\r\n };\r\n }\r\n if (!geometryData) return null;\r\n const props = parsed.type === 'Feature' ? parsed.properties?.shapeProperties : undefined;\r\n const style: ShapeStyle = {};\r\n if (typeof props?.height === 'number') style.height = props.height;\r\n if (typeof props?.color === 'string') style.color = props.color;\r\n if (typeof props?.fillColor === 'string') style.fillColor = props.fillColor;\r\n if (typeof props?.opacity === 'number') style.opacity = props.opacity;\r\n if (typeof props?.label?.fontSize === 'number') style.labelSize = props.label.fontSize;\r\n if (typeof props?.label?.nextRotation === 'number') style.labelRotation = props.label.nextRotation;\r\n return { geometry: geometryData, style };\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Loads a venue from the beCoMap backend: token auth, site + floors + floor\r\n * connections via JSON, and the five editor-generated protobuf binaries via\r\n * the absolute URLs the site payload provides. Produces the same `VenueData`\r\n * contract as the mock provider.\r\n */\r\nexport class RestVenueProvider implements VenueProvider {\r\n #options: RestVenueProviderOptions;\r\n\r\n constructor(options: RestVenueProviderOptions) {\r\n this.#options = options;\r\n }\r\n\r\n async fetchVenue(signal?: AbortSignal): Promise<VenueData> {\r\n const { baseUrl, siteId, clientId, clientSecret } = this.#options;\r\n const httpOptions = signal ? { signal } : {};\r\n\r\n // 1. auth\r\n const auth = await fetchJson<AuthResponse>(`${baseUrl}/api/v1/auth/sdk/generate-token`, {\r\n method: 'POST',\r\n body: { clientId, clientSecret },\r\n ...httpOptions,\r\n });\r\n const authed = {\r\n headers: { Authorization: `Bearer ${auth.accessToken}` },\r\n ...httpOptions,\r\n };\r\n\r\n // 2. site metadata (carries building list + binary asset URLs)\r\n const site = await fetchJson<SiteResponse>(`${baseUrl}/api/v1/sdk/site/${siteId}`, authed);\r\n\r\n // 3. floors per building + 4. binaries + connections, all parallel.\r\n // Binaries are public CDN assets: sending the Authorization header\r\n // triggers a CORS preflight the CDN rejects (verified live) — fetch them\r\n // plain.\r\n const [floorLists, routeBin, shapeBin, locationBin, categoryBin, mapObjectBin, connections, iconset] =\r\n await Promise.all([\r\n Promise.all(\r\n site.buildings.map((b) =>\r\n fetchJson<FloorResponse[]>(`${baseUrl}/api/v1/sdk/floor/${siteId}/${b.buildingId}`, authed),\r\n ),\r\n ),\r\n fetchBinary(site.binaryUrl.route, httpOptions),\r\n fetchBinary(site.binaryUrl.shape, httpOptions),\r\n fetchBinary(site.binaryUrl.location, httpOptions),\r\n fetchBinary(site.binaryUrl.category, httpOptions),\r\n fetchBinary(site.binaryUrl.map_object, httpOptions),\r\n fetchJson<ConnectionResponse[]>(`${baseUrl}/api/v1/sdk/connection/${siteId}`, authed),\r\n // default icon set (key -> SVG url): category + amenity marker icons.\r\n // Optional — a failure must not sink the whole venue load.\r\n fetchJson<Record<string, string>>(`${baseUrl}/api/v1/category/get-icons`, authed).catch(\r\n (): Record<string, string> => ({}),\r\n ),\r\n ]);\r\n\r\n // 5. decode + map to the raw contract\r\n const buildings: RawBuilding[] = site.buildings.map((b, i) => ({\r\n id: b.buildingId,\r\n name: b.buildingName,\r\n floors: (floorLists[i] ?? []).map((f) => ({\r\n id: f.floorId,\r\n name: f.name,\r\n level: f.elevation,\r\n buildingId: b.buildingId,\r\n })),\r\n }));\r\n\r\n const nodes: RawNode[] = com.beco.node.NodeList.decode(routeBin).nodes.map((n) => ({\r\n id: n.nodeId ?? '',\r\n lat: n.lat ?? 0,\r\n lng: n.lng ?? 0,\r\n floorId: n.floorId ?? '',\r\n // v1 treats every node as accessible (`accessible || true`); editor data\r\n // was authored under that behavior, so v2 matches it deliberately.\r\n accessible: true,\r\n privateNode: n.privateNode ?? false,\r\n siblings: [...(n.siblings ?? [])],\r\n }));\r\n\r\n const shapes: RawShape[] = [];\r\n for (const s of com.beco.geoshapes.GeoShapesList.decode(shapeBin).shapes) {\r\n const parsed = parseShapeFeature(s.jsonData ?? '');\r\n if (!parsed) continue; // skip-and-collect: unparseable geometry\r\n shapes.push({\r\n id: s.shapeId ?? '',\r\n floorId: s.floorId ?? '',\r\n layerId: s.layerId ?? '',\r\n type: s.type ?? '',\r\n geometry: parsed.geometry,\r\n style: parsed.style,\r\n });\r\n }\r\n\r\n const locations: RawLocation[] = com.beco.location.LocationList.decode(locationBin).locations.map(\r\n (l) => {\r\n const loc: RawLocation = {\r\n id: l.locationId ?? '',\r\n name: l.name ?? '',\r\n type: l.type ?? '',\r\n categoryIds: [...(l.categories ?? [])],\r\n hidden: l.hidden ?? false,\r\n sortOrder: l.sortOrder ?? 0,\r\n };\r\n if (l.description) loc.description = l.description;\r\n if (l.nodeId) loc.nodeId = l.nodeId;\r\n if (l.polygonId) loc.shapeId = l.polygonId;\r\n if (l.amenity) loc.amenity = l.amenity;\r\n if (l.logo) loc.logoUrl = l.logo;\r\n return loc;\r\n },\r\n );\r\n\r\n const categories: RawCategory[] = com.beco.category.CategoryList.decode(categoryBin).categories.map(\r\n (c) => {\r\n const cat: RawCategory = { id: c.categoryId ?? '', name: c.name ?? '', sortOrder: c.sortOrder ?? 0 };\r\n // resolve the default-list KEY to its real CDN url via the iconset\r\n if (c.iconFromDefaultList) {\r\n const url = iconset[c.iconFromDefaultList];\r\n if (url) cat.icon = url;\r\n }\r\n if (c.color?.hex) cat.colorHex = c.color.hex;\r\n return cat;\r\n },\r\n );\r\n\r\n const mapObjects: RawMapObject[] = com.beco.map_object.MapObjectsList.decode(\r\n mapObjectBin,\r\n ).mapObjects.map((m) => ({\r\n id: m.id ?? '',\r\n nodeId: m.nodeId ?? '',\r\n modelUrl: m.mapObjectPath ?? '',\r\n scale: m.scale ?? 1,\r\n rotation: m.rotation ?? 0,\r\n altitude: m.altitude ?? 0,\r\n light: m.light ?? 1,\r\n }));\r\n\r\n const floorConnections: RawFloorConnection[] = [];\r\n for (const c of connections) {\r\n const [startNodeId, endNodeId] = c.node;\r\n if (!startNodeId || !endNodeId) continue;\r\n floorConnections.push({\r\n id: c.connectionId,\r\n kind: CONNECTION_KIND[c.type] ?? 'other',\r\n name: c.name,\r\n accessible: c.accessible,\r\n weight: c.weight,\r\n multiplier: c.multiplier,\r\n direction:\r\n c.direction === 'START_TO_END' ? 'startToEnd' : c.direction === 'END_TO_START' ? 'endToStart' : 'both',\r\n startNodeId,\r\n endNodeId,\r\n });\r\n }\r\n\r\n return {\r\n site: { id: site.siteId, name: site.siteName, center: [site.longitude, site.latitude] },\r\n buildings,\r\n nodes,\r\n shapes,\r\n locations,\r\n categories,\r\n iconset,\r\n mapObjects,\r\n floorConnections,\r\n };\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,OAAOA,iBAAgB;;;ACAvB;AAyDO,IAAM,UAAN,MAAsC;AAAA,EAAtC;AACL,mCAAa,oBAAI,IAAyC;AAAA;AAAA,EAE1D,GAA4B,OAAU,UAAsC;AAC1E,QAAI,MAAM,mBAAK,YAAW,IAAI,KAAK;AACnC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,yBAAK,YAAW,IAAI,OAAO,GAAG;AAAA,IAChC;AACA,QAAI,IAAI,QAAQ;AAAA,EAClB;AAAA,EAEA,IAA6B,OAAU,UAAsC;AAC3E,uBAAK,YAAW,IAAI,KAAK,GAAG,OAAO,QAAQ;AAAA,EAC7C;AAAA;AAAA,EAGA,KAA8B,OAAU,SAA2B;AACjE,UAAM,MAAM,mBAAK,YAAW,IAAI,KAAK;AACrC,QAAI,CAAC,IAAK;AACV,eAAW,YAAY,CAAC,GAAG,GAAG,EAAG,CAAC,SAAkC,OAAO;AAAA,EAC7E;AAAA,EAEA,YAAkB;AAChB,uBAAK,YAAW,MAAM;AAAA,EACxB;AACF;AAzBE;;;ACnBK,SAAS,gBAAgB,WAAsD;AACpF,MAAI,OAAO,gBAAgB,eAAe,EAAE,qBAAqB,cAAc;AAC7E,UAAM,IAAI,UAAU,yEAAoE;AAAA,EAC1F;AACF;;;AC3CA,YAAYC,YAAW;AACvB,OAAOC,iBAAgB;;;ACYvB,IAAM,gBAAgB;AAEf,SAAS,YAAY,QAA4B;AACtD,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB;AAAA,IACjB,iBAAiB,gBAAgB,KAAK,IAAK,OAAO,CAAC,IAAI,KAAK,KAAM,GAAG;AAAA,EACvE;AACF;AAGO,SAAS,SAAS,OAAmB,QAAkC;AAC5E,SAAO;AAAA,KACJ,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,KAAK,MAAM;AAAA,KACrC,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,KAAK,MAAM;AAAA,EACxC;AACF;AAGO,SAAS,SAAS,OAAmB,GAAW,GAAmB;AACxE,SAAO,CAAC,MAAM,OAAO,CAAC,IAAI,IAAI,MAAM,iBAAiB,MAAM,OAAO,CAAC,IAAI,IAAI,MAAM,eAAe;AAClG;AAGO,SAAS,aAAa,OAAmB,MAAoC;AAClF,QAAM,MAAM,KAAK,IAAI,CAAC,MAAM,SAAS,OAAO,CAAC,CAAC;AAC9C,QAAM,QAAQ,IAAI,CAAC;AACnB,QAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAC/B,MAAI,IAAI,SAAS,KAAK,SAAS,QAAQ,KAAK,MAAM,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,MAAM;AAChG,QAAI,IAAI;AAAA,EACV;AACA,SAAO;AACT;AAGO,SAAS,gBAAgB,KAA2C;AACzE,MAAI,IAAI;AACR,MAAI,KAAK;AACT,MAAI,KAAK;AACT,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,KAAK,IAAI,CAAC;AAChB,UAAM,KAAK,KAAK,IAAI,KAAK,IAAI,MAAM;AACnC,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,QAAQ,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;AAC1C,SAAK;AACL,WAAO,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AACxB,WAAO,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AAAA,EAC1B;AACA,MAAI,KAAK,IAAI,CAAC,IAAI,KAAM,QAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAC9C,OAAK;AACL,SAAO,CAAC,MAAM,IAAI,IAAI,MAAM,IAAI,EAAE;AACpC;AAGO,SAAS,YAAY,MAAgB,KAAa,KAAsB;AAC7E,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,IAAI,KAAK,QAAQ,IAAI,KAAK;AAC7D,UAAM,KAAK,KAAK,CAAC;AACjB,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,CAAC,IAAI,EAAE,IAAI;AACjB,UAAM,CAAC,IAAI,EAAE,IAAI;AACjB,QAAI,KAAK,QAAQ,KAAK,OAAO,OAAQ,KAAK,OAAO,MAAM,OAAQ,KAAK,MAAM,GAAI,UAAS,CAAC;AAAA,EAC1F;AACA,SAAO;AACT;;;AC9EA,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAMzB,IAAM,cAAc;AACpB,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AAEhC,IAAM,mBAAmB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAC/E,IAAM,WAAW,IAAU,YAAM,SAAS;AAGnC,SAAS,OAAO,IAAoB;AACzC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,SAAK,GAAG,WAAW,CAAC;AACpB,QAAI,KAAK,KAAK,GAAG,QAAQ;AAAA,EAC3B;AACA,SAAO,MAAM;AACf;AAEO,SAAS,YAAY,IAAoB;AAC9C,SAAO,mBAAoB,OAAO,EAAE,IAAI,OAAS,qBAAqB;AACxE;AAEO,SAAS,aAAa,UAAqC,SAA8B;AAC9F,QAAM,MAAM,UAAU,WAAW,CAAC,GAAG;AACrC,MAAI,IAAK,QAAO,IAAU,YAAM,GAAG;AACnC,SAAO,IAAU,YAAM,iBAAiB,OAAO,OAAO,IAAI,iBAAiB,MAAM,CAAC;AACpF;AAcO,SAAS,gBACd,KACA,SACA,IACA,IACM;AACN,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,KAAK,QAAQ,CAAC;AACpB,UAAM,KAAK,SAAS,IAAI,KAAK,QAAQ,MAAM;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AACnD,QAAI,MAAM,KAAM;AAChB,UAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AAC7B,UAAM,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AAC9B,UAAM,OAAO,IAAI,IAAI,SAAS;AAC9B,QAAI,IAAI,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE;AACnF,QAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC;AACvD,UAAM,KAAK,IAAI,MAAM;AACrB,QAAI,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC;AACpC,QAAI,IAAI,KAAK,MAAM,OAAO,GAAG,OAAO,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC;AAC/D,QAAI;AAAA,EACN;AACF;AAEA,SAAS,sBAAsB,KAAwC;AACrE,QAAM,MAAM,IAAU,qBAAe;AACrC,MAAI,aAAa,YAAY,IAAU,sBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACpF,MAAI,aAAa,UAAU,IAAU,sBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AAClF,MAAI,aAAa,MAAM,IAAU,sBAAgB,IAAI,aAAa,IAAI,EAAE,GAAG,CAAC,CAAC;AAC7E,MAAI,SAAS,IAAI,GAAG;AACpB,SAAO;AACT;AAwCO,SAAS,UAAU,OAAyB;AACjD,MAAI,MAAM,YAAY,YAAa,QAAO;AAC1C,QAAM,IAAI,MAAM,KAAK,YAAY;AACjC,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,MAAM,gBAAgB,MAAM,SAAS,SAAS,aAAc,QAAO;AAIvE,MAAI,MAAM,OAAO;AACf,UAAM,IAAI,MAAM,MAAM;AACtB,WAAO,MAAM,UAAa,IAAI,MAAM,SAAS;AAAA,EAC/C;AACA,SAAO;AACT;AAGO,SAAS,YAAY,OAAc,MAAyB;AACjE,QAAM,IAAI,MAAM,OAAO;AACvB,MAAI,SAAS,cAAc,SAAS,YAAa,QAAO,MAAM,UAAa,IAAI,IAAI,IAAI;AACvF,MAAI,SAAS,OAAQ,QAAO,KAAK,YAAY,MAAM,EAAE;AACrD,SAAO;AACT;AAOO,SAAS,gBAAgB,OAAc,UAAkD;AAC9F,MAAI,MAAM,OAAO,MAAO,QAAO,IAAU,YAAM,MAAM,MAAM,KAAK;AAChE,MAAI,MAAM,OAAO,UAAW,QAAO,IAAU,YAAM,MAAM,MAAM,SAAS;AACxE,SAAO,aAAa,UAAU,MAAM,EAAE;AACxC;AAGO,IAAM,yBAAyB;AAO/B,SAAS,mBACd,QACA,QACA,IACA,IACA,MACA,OACwB;AACxB,QAAM,MAA8B,CAAC;AACrC,QAAM,QAAQ,SAAS,OAAO,SAAS,OAAO,SAAS;AACvD,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,OAAO,CAAC;AAClB,UAAM,IAAI,QAAQ,IAAI,KAAK,OAAO,MAAM;AACxC,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,MAAM,KAAM;AAChB,UAAM,KAAM,CAAC,KAAK,MAAO;AACzB,UAAM,KAAM,KAAK,MAAO;AAExB,UAAM,KAAM,KAAK,MAAO;AACxB,UAAM,KAAM,KAAK,MAAO;AACxB,UAAM,OAA2B;AAAA,MAC/B,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,MAC/B,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,MAC/B,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,MAC/B,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,IACjC;AACA,QAAI,KAAK,aAAa,CAAC,IAAI,GAAG,IAAI,IAAI,KAAK,CAAC;AAC5C,QAAI,KAAK,aAAa,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,IAAM,oBAAoB,IAAU,YAAM,SAAS;AAEnD,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,eAAe;AAGrB,IAAM,iBAAiB,IAAU,YAAM,SAAS;AAChD,IAAM,0BAA0B;AAChC,IAAM,aAAa;AACnB,IAAM,cAAc;AAUpB,SAAS,UACP,MACA,IACA,IACA,OACyB;AACzB,QAAM,KAAK,KAAK,IAAI,KAAK;AACzB,QAAM,KAAK,KAAK,IAAI,KAAK;AACzB,QAAM,KAAe,CAAC;AACtB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;AACpC,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,MAAM,KAAK,KAAK,KAAK;AAC3B,QAAI,KAAK,IAAI,GAAG,IAAI,KAAM;AAC1B,UAAM,KAAK,MAAM,EAAE,CAAC,IAAI,MAAM,MAAM,EAAE,CAAC,IAAI,OAAO;AAClD,QAAI,IAAI,KAAK,IAAI,EAAG;AACpB,UAAM,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,KAAK,MAAM,MAAM,EAAE,CAAC,IAAI,IAAI,KAAK,MAAM;AAC3F,OAAG,KAAK,CAAC;AAAA,EACX;AACA,MAAI,GAAG,SAAS,EAAG,QAAO;AAC1B,KAAG,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK;AACtC,UAAM,KAAK,GAAG,CAAC;AACf,UAAM,KAAK,GAAG,IAAI,CAAC;AACnB,QAAI,OAAO,UAAa,OAAO,UAAa,MAAM,KAAK,MAAM,EAAG,QAAO,CAAC,IAAI,EAAE;AAAA,EAChF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAA0B,IAAY,IAAY,OAA8B;AACpG,QAAM,OAAO,UAAU,MAAM,IAAI,IAAI,KAAK;AAC1C,SAAO,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI;AACpC;AAQA,SAAS,YAAY,MAA0B,IAAY,IAAY,OAA8B;AACnG,QAAM,OAAO,UAAU,MAAM,IAAI,IAAI,KAAK;AAC1C,SAAO,OAAO,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI;AAClD;AAGA,IAAM,aAAa;AAGnB,SAAS,UAAU,MAAsB;AACvC,MAAI,OAAO;AACX,MAAI,WAAW;AACf,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,IAAK;AACrB,UAAM,OAAO,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,EAAE;AAC/C,QAAI,OAAO,UAAU;AACnB,iBAAW;AACX,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAeA,SAAS,WACP,MACA,MACA,IACA,IACA,OACgB;AAChB,QAAM,MAAM,KAAK,IAAI,CAAC,KAAK;AAC3B,QAAM,MAAM,KAAK,IAAI,CAAC,KAAK;AAC3B,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI;AAC9B,UAAM,IAAI,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI;AAC9B,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AAAA,EACvB;AACA,QAAM,QAAQ,aAAa,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO;AAC1D,QAAM,SAAS,aAAa,MAAM,IAAI,IAAI,QAAQ,KAAK,KAAK,CAAC,KAAK,OAAO;AAEzE,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,IACA,KAAK,IAAI,gBAAgB,QAAQ,YAAY,SAAS,WAAW;AAAA,EACnE;AACA,MAAI,KAAK,SAAS,eAAe,YAAY,QAAQ,YAAY;AAC/D,WAAO,EAAE,MAAM,MAAM,UAAU,UAAU,OAAO,QAAQ,OAAO,SAAS,OAAO;AAAA,EACjF;AAMA,QAAM,UAAU,KAAK;AAAA,IACnB;AAAA,IACA,KAAK,IAAI,UAAW,QAAQ,cAAe,KAAK,SAAS,aAAa;AAAA,EACxE;AACA,QAAM,QAAQ,UAAU,IAAI;AAC5B,MAAI,QAAQ,GAAG;AACb,UAAM,KAAK,KAAK,MAAM,GAAG,KAAK;AAC9B,UAAM,KAAK,KAAK,MAAM,QAAQ,CAAC;AAC/B,UAAM,WAAW,KAAK,IAAI,GAAG,GAAG,QAAQ,GAAG,MAAM;AACjD,UAAM,YAAa,SAAS,cAAe;AAC3C,QAAI,UAAU,KAAK;AAAA,MACjB;AAAA,MACA,KAAK,IAAI,UAAW,QAAQ,cAAe,WAAW,eAAe,SAAS;AAAA,IAChF;AAGA,UAAM,KAAK,CAAC,KAAK,IAAI,KAAK;AAC1B,UAAM,KAAK,KAAK,IAAI,KAAK;AACzB,UAAM,MAAM,OAAO;AACnB,UAAM,OAAO,aAAa,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AACxE,UAAM,OAAO,aAAa,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AACxE,UAAM,SAAS,KAAK,IAAI,OAAO,MAAM,IAAI;AACzC,cAAU,KAAK;AAAA,MACb;AAAA,MACA,KAAK,IAAI,SAAU,SAAS,cAAe,WAAW,aAAa;AAAA,IACrE;AACA,QAAI,UAAU,UAAU,MAAM;AAC5B,aAAO;AAAA,QACL,MAAM,GAAG,EAAE;AAAA,EACjB,EAAE;AAAA,QACI,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,MAAM,UAAU,SAAS,UAAU,OAAO,QAAQ,OAAO,SAAS,OAAO;AAC1F;AAGA,IAAM,gBAAgB;AAGtB,SAAS,mBAAmB,GAAmB;AAC7C,SAAO,IAAI,KAAK,KAAK,EAAG,MAAK,KAAK;AAClC,SAAO,KAAK,CAAC,KAAK,KAAK,EAAG,MAAK,KAAK;AACpC,SAAO;AACT;AAUA,SAAS,SAAS,MAA0B,MAAc,IAAY,IAA4B;AAChG,QAAM,OAAO,KAAK,KAAK;AACvB,QAAM,QAAQ,kBAAkB,IAAI;AACpC,QAAM,QAAQ,mBAAmB,QAAQ,KAAK,KAAK,CAAC;AAEpD,QAAMC,aAAY,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,QAAQ;AAC/D,QAAM,YAAYA,eAAc,QAAQ,QAAQ;AAChD,QAAM,QAAQ,WAAW,MAAM,MAAM,IAAI,IAAIA,UAAS;AACtD,MAAI,MAAM,YAAY,cAAe,QAAO;AAC5C,QAAM,QAAQ,WAAW,MAAM,MAAM,IAAI,IAAI,SAAS;AACtD,SAAO,MAAM,WAAW,MAAM,WAAW,OAAO,QAAQ;AAC1D;AAGA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AASzB,SAAS,WACP,MACA,IACA,IACA,OACA,QACA,SACwC;AAExC,QAAM,SAAS,YAAY,MAAM,IAAI,IAAI,KAAK;AAC9C,QAAM,UAAU,YAAY,MAAM,IAAI,IAAI,QAAQ,KAAK,KAAK,CAAC;AAC7D,MAAI,SAAS,mBAAmB,UAAU,SAAS;AACnD,MAAI,SAAS,oBAAoB,WAAW,UAAU;AACtD,QAAM,KAAK,CAAC,KAAK,IAAI,KAAK;AAC1B,QAAM,KAAK,KAAK,IAAI,KAAK;AACzB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,MAAM,OAAO;AACnB,UAAM,OAAO,YAAY,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAClE,UAAM,OAAO,YAAY,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAClE,QAAI,SAAS,QAAQ,SAAS,MAAM;AAElC,gBAAU;AACV;AAAA,IACF;AACA,aAAS,KAAK,IAAI,QAAQ,kBAAkB,KAAK,IAAI,MAAM,IAAI,CAAC;AAChE;AAAA,EACF;AACA,SAAO,EAAE,UAAU,QAAQ,UAAU,OAAO;AAC9C;AAQO,SAAS,kBAAkB,MAAkC;AAClE,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AACxC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,KAAK,IAAI,CAAC;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrB,UAAM,SAAS,KAAK,KAAK,KAAK;AAC9B,QAAI,SAAS,WAAW;AACtB,kBAAY;AACZ,cAAQ,KAAK,MAAM,IAAI,EAAE;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,SAAS,CAAC,KAAK,KAAK,EAAG,UAAS,KAAK;AAC5C,SAAO,QAAQ,KAAK,KAAK,EAAG,UAAS,KAAK;AAC1C,SAAO;AACT;AAIA,SAAS,WAAW,OAAmB,OAAoC;AACzE,MAAI,MAAM,SAAS,SAAS,UAAW,QAAO,CAAC;AAC/C,SAAO,MAAM,SAAS,YACnB,IAAI,CAAC,SAAS,WAAW,aAAa,OAAO,IAAI,CAAC,CAAC,EACnD,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AAChC;AAGA,SAAS,aAAa,OAA6B,GAAW,OAA0C;AACtG,QAAM,QAAQ,MAAM,CAAC,KAAK,CAAC;AAC3B,QAAM,QAAQ,IAAU,YAAM,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,cAAQ,GAAG,CAAC,CAAC,CAAC;AAC5E,aAAW,QAAQ,MAAM,MAAM,CAAC,GAAG;AACjC,UAAM,MAAM,KAAK,IAAU,WAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,cAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;AAAA,EAChF;AACA,QAAM,MAAM,IAAU,oBAAc,KAAK;AACzC,QAAM,QAAQ,IAAI,WAAW,UAAU,SAAS;AAChD,QAAM,SAAS,IAAI,aAAa,QAAQ,CAAC;AACzC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,WAAO,IAAI,CAAC,IAAI,MAAM;AACtB,WAAO,IAAI,IAAI,CAAC,IAAI,MAAM;AAC1B,WAAO,IAAI,IAAI,CAAC,IAAI,MAAM;AAAA,EAC5B;AACA,MAAI,aAAa,SAAS,IAAU,sBAAgB,QAAQ,CAAC,CAAC;AAC9D,MAAI,UAAU,GAAG,GAAG,CAAC;AACrB,SAAO;AACT;AAUA,IAAM,QAAQ;AACd,IAAM,QAAQ;AAId,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,SAAS,UAAU,IAAY,IAAoB;AACjD,SAAO,eAAe,eAAe,KAAK,IAAI,GAAG,KAAK,QAAQ,KAAK,KAAK;AAC1E;AAGA,SAAS,aACP,OACA,IACA,IACA,OACsB;AACtB,QAAM,MAAmB,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE;AAC7D,aAAW,QAAQ,MAAO,iBAAgB,KAAK,MAAM,IAAI,EAAE;AAC3D,QAAM,MAAM,sBAAsB,GAAG;AACrC,QAAM,QAAQ,IAAI,WAAW,UAAU,SAAS;AAChD,QAAM,MAAM,IAAI,WAAW;AAC3B,QAAM,SAAS,IAAI,aAAa,QAAQ,CAAC;AACzC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,MAAM,UAAU,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI;AACtD,WAAO,IAAI,CAAC,IAAI,MAAM,IAAI;AAC1B,WAAO,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI;AAC9B,WAAO,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI;AAAA,EAChC;AACA,MAAI,aAAa,SAAS,IAAU,sBAAgB,QAAQ,CAAC,CAAC;AAC9D,SAAO;AACT;AAQA,SAAS,cACP,OACA,IACA,IACA,UACA,WACsB;AACtB,QAAM,MAAmB,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE;AAC7D,aAAW,QAAQ,MAAO,iBAAgB,KAAK,MAAM,IAAI,EAAE;AAC3D,QAAM,MAAM,sBAAsB,GAAG;AACrC,QAAM,QAAQ,IAAI,WAAW,UAAU,SAAS;AAChD,QAAM,SAAS,IAAI,aAAa,QAAQ,CAAC;AACzC,QAAM,MAAM,IAAI,WAAW;AAK3B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,IAAI,KAAK,IAAI,WAAW;AAClC,UAAM,IAAI,MAAM,UAAU,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI;AACtD,WAAO,IAAI,CAAC,IAAI,EAAE,IAAI;AACtB,WAAO,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI;AAC1B,WAAO,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,EAC5B;AACA,MAAI,aAAa,SAAS,IAAU,sBAAgB,QAAQ,CAAC,CAAC;AAC9D,SAAO;AACT;AAGA,SAAS,SAAS,MAAkC;AAClD,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;AACpC,QAAI,KAAK,EAAG,MAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EAC3C;AACA,SAAO,IAAI;AACb;AAGA,SAAS,cAAc,MAAkC;AACvD,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;AACpC,QAAI,KAAK,EAAG,MAAK,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAOA,IAAM,eAAe;AAGrB,IAAM,kBAAkB;AAGxB,SAASC,aAAY,GAAW,GAAW,MAAmC;AAC5E,MAAI,SAAS;AACb,QAAM,IAAI,KAAK;AACf,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK;AACzC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,QAAI,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,KAAK,KAAM,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG;AACpF,eAAS,CAAC;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAUA,SAAS,UAAU,MAA0B,QAAoC;AAC/E,QAAM,IAAI,KAAK;AACf,MAAI,IAAI,EAAG,QAAO;AAClB,QAAM,OAAO,SAAS,IAAI;AAC1B,MAAI,KAAK,IAAI,IAAI,IAAI,KAAM,QAAO;AAClC,QAAM,IAAI,OAAO,IAAI,IAAI;AAGzB,QAAM,KAAe,CAAC;AACtB,QAAM,KAAe,CAAC;AACtB,QAAM,KAAe,CAAC;AACtB,QAAM,KAAe,CAAC;AACtB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,MAAM,IAAI,KAAK,CAAC;AAC1B,QAAI,CAAC,KAAK,CAAC,GAAG;AACZ,SAAG,KAAK,CAAC;AACT,SAAG,KAAK,CAAC;AACT,SAAG,KAAK,CAAC;AACT,SAAG,KAAK,CAAC;AACT;AAAA,IACF;AACA,QAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB,QAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE,KAAK;AAClC,UAAM;AACN,UAAM;AACN,OAAG,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM;AAC/B,OAAG,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,MAAM;AAC9B,OAAG,KAAK,EAAE;AACV,OAAG,KAAK,EAAE;AAAA,EACZ;AAGA,QAAM,MAA0B,CAAC;AACjC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,KAAK,IAAI,IAAI,KAAK;AACxB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,MAAM,GAAG,CAAC,KAAK;AACrB,UAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,QAAI,KAAK,IAAI,KAAK,IAAI,MAAM;AAC1B,UAAI,KAAK,CAAC,KAAK,GAAG,CAAC;AACnB;AAAA,IACF;AACA,UAAM,MAAM,MAAM,OAAO,OAAO,MAAM,OAAO,OAAO;AACpD,QAAI,KAAK,CAAC,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC;AAAA,EACzC;AAGA,QAAM,KAAK,SAAS,GAAG;AACvB,MAAI,KAAK,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,IAAI,IAAK,QAAO;AACrF,aAAW,KAAK,KAAK;AACnB,QAAI,CAACA,aAAY,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAG,QAAO;AAAA,EAC7C;AACA,SAAO;AACT;AAKA,IAAM,0BAA0B;AAChC,IAAM,uBAAuB;AAG7B,SAAS,mBAAmB,MAAmC;AAC7D,QAAM,IAAI,KAAK;AACf,QAAM,QAAQ,CACZ,IACA,IACA,IACA,OACY;AACZ,UAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC;AAC7E,QAAI,KAAK,IAAI,CAAC,IAAI,MAAO,QAAO;AAChC,UAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM;AACpF,UAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM;AACpF,WAAO,IAAI,QAAQ,IAAI,IAAI,QAAQ,IAAI,QAAQ,IAAI,IAAI;AAAA,EACzD;AACA,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,KAAK,KAAK,CAAC;AACjB,UAAM,KAAK,MAAM,IAAI,KAAK,CAAC;AAC3B,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,aAAS,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;AAC9B,UAAI,MAAM,KAAK,MAAM,IAAI,EAAG;AAC5B,YAAM,KAAK,KAAK,CAAC;AACjB,YAAM,KAAK,MAAM,IAAI,KAAK,CAAC;AAC3B,UAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAI,MAAM,IAAI,IAAI,IAAI,EAAE,EAAG,QAAO;AAAA,IACpC;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,WACP,MACA,aAAa,yBACb,eAAe,sBACK;AACpB,QAAM,UAAU,KAAK,IAAK,eAAe,KAAK,KAAM,GAAG;AACvD,MAAI,MAAM;AACV,WAAS,KAAK,GAAG,KAAK,YAAY,MAAM;AACtC,UAAM,IAAI,IAAI;AACd,QAAI,IAAI,EAAG;AACX,UAAM,MAA0B,CAAC;AACjC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC;AAChC,YAAM,MAAM,IAAI,CAAC;AACjB,YAAM,OAAO,KAAK,IAAI,KAAK,CAAC;AAC5B,UAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;AAC1B,YAAI,IAAK,KAAI,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAClC;AAAA,MACF;AACA,YAAM,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC;AAC3B,YAAM,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC;AAC3B,YAAM,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC;AAC3B,YAAM,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC;AAC3B,YAAM,KAAK,KAAK,MAAM,KAAK,GAAG,KAAK;AACnC,YAAM,KAAK,KAAK,MAAM,KAAK,GAAG,KAAK;AACnC,YAAM,OAAO,MAAM,MAAM,MAAM,QAAQ,KAAK;AAC5C,UAAI,OAAO,SAAS;AAClB,YAAI,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAAA,MAC3B,OAAO;AACL,YAAI,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,GAAG,CAAC;AACnD,YAAI,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,GAAG,CAAC;AAAA,MACrD;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,SAAO,mBAAmB,GAAG,IAAI,OAAO;AAC1C;AAUO,SAAS,mBACd,OACA,OACA,OACe;AACf,QAAM,QAAgC,CAAC;AACvC,QAAM,QAAgC,CAAC;AACvC,QAAM,aAA0B,CAAC;AAGjC,QAAM,YAAsB,CAAC;AAC7B,QAAM,aAAa,CAAC,OAA6B,MAAoB;AACnE,eAAW,QAAQ,OAAO;AACxB,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,IAAI,KAAK,CAAC;AAChB,cAAM,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;AACpC,YAAI,KAAK,EAAG,WAAU,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,oBAAI,IAA2B;AACzD,aAAW,OAAO,MAAM,WAAW;AACjC,QAAI,IAAI,QAAS,mBAAkB,IAAI,IAAI,SAAS,GAAG;AAAA,EACzD;AAEA,aAAW,SAAS,MAAM,QAAQ;AAChC,UAAM,OAAO,UAAU,KAAK;AAC5B,UAAM,QAAQ,MAAM;AAIpB,UAAM,SAAS;AACf,UAAM,SAAS,YAAY,OAAO,IAAI;AAItC,UAAM,eAAgB,OAAO,MAAM,EAAE,IAAI,KAAM;AAC/C,UAAM,KAAK,cAAc,SAAS;AAGlC,QAAI,SAAS,aAAa;AACxB,YAAM,MACJ,MAAM,SAAS,SAAS,eACpB,MAAM,SAAS,YAAY,IAAI,CAAC,MAAM,SAAS,OAAO,CAAC,CAAC,IACxD,WAAW,OAAO,KAAK,EAAE,CAAC;AAGhC,UAAI,CAAC,OAAO,IAAI,SAAS,KAAM,CAAC,MAAM,SAAS,UAAU,EAAI;AAC7D,YAAM,IAAI,MAAM;AAChB,YAAM,SAAS,IAAI,cAAc,EAAE,aAAa;AAIhD,YAAM,WAAW,IACb,EAAE,eACC,OAAO,SAAS,EAAE,YACnB,EAAE,YACH,OAAO,SAAS,kBAAkB,SAAS;AAChD,aAAO;AAAA,QACL,GAAG,mBAAmB,KAAK,OAAO,aAAa,QAAQ,wBAAwB,IAAU,YAAM,QAAQ,CAAC;AAAA,MAC1G;AACA;AAAA,IACF;AAEA,UAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,CAAC,MAAO;AAEZ,QAAI,SAAS,QAAQ;AACnB,YAAM,YAAY,kBAAkB,IAAI,MAAM,EAAE;AAChD,UAAI,MAAM,YAAY,aAAa;AAEjC,eAAO,KAAK,aAAa,OAAO,aAAa,IAAU,YAAM,OAAO,aAAa,SAAS,SAAS,CAAC,CAAC,CAAC;AACtG,eAAO,KAAK,aAAa,OAAO,GAAG,aAAa,IAAU,YAAM,SAAS,CAAC,CAAC;AAAA,MAC7E,OAAO;AAGL,cAAM,IAAI,cAAc,SAAS,OAAO,UAAU,KAAK,IAAI,OAAO,KAAM,OAAO,MAAM,EAAE,IAAI,IAAK;AAIhG,cAAM,YACJ,MAAM,SAAS,CAAC,MAAM,MAAM,mBACxB,IAAU,YAAM,MAAM,MAAM,KAAK,IACjC,gBAAgB,OAAO,SAAS;AAItC,cAAM,YAAY,MAAM,IAAI,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC;AAChE,eAAO,KAAK,aAAa,WAAW,GAAG,SAAS,CAAC;AACjD,mBAAW,WAAW,IAAI,IAAI;AAC9B,YAAI,aAAa,CAAC,UAAU,UAAU,CAAC,UAAU,SAAS;AACxD,gBAAM,CAAC,KAAK,GAAG,IAAI,gBAAgB,KAAK;AACxC,gBAAM,OAAO,SAAS,OAAO,UAAU,MAAM,KAAK,GAAG;AACrD,qBAAW,KAAK;AAAA,YACd,MAAM,KAAK;AAAA,YACX,GAAG;AAAA,YACH,GAAG;AAAA,YACH,GAAG,IAAI;AAAA,YACP,UAAU,KAAK;AAAA,YACf,cAAc,KAAK;AAAA,YACnB,YAAY,UAAU;AAAA,YACtB,GAAI,UAAU,UACV,EAAE,SAAS,UAAU,SAAS,GAAG,WAAW,OAAO,KAAK,KAAK,KAAK,UAAU,KAAK,QAAQ,KAAK,OAAO,EAAE,IACvG,CAAC;AAAA,UACP,CAAC;AAAA,QACH;AAAA,MACF;AACA;AAAA,IACF;AAMA,QAAI,SAAS,YAAY;AACvB,YAAM,IAAI,MAAM;AAGhB,YAAM,WAAW,IACb,EAAE,eACC,OAAO,aAAa,EAAE,WACvB,EAAE,WACH,OAAO,aAAa;AACzB,YAAM,KAAK,aAAa,OAAO,aAAa,IAAU,YAAM,QAAQ,CAAC,CAAC;AACtE,YAAM,KAAK,aAAa,OAAO,GAAG,aAAa,IAAU,YAAM,SAAS,CAAC,CAAC;AAE1E,YAAM,SAAS,IAAI,cAAc,EAAE,aAAa;AAChD,YAAM,UAAU,IACZ,EAAE,eACC,OAAO,SAAS,EAAE,OACnB,EAAE,OACH,OAAO,SAAS;AACrB,aAAO;AAAA,QACL,GAAG,mBAAmB,OAAO,MAAM,aAAa,QAAQ,wBAAwB,IAAU,YAAM,OAAO,CAAC;AAAA,MAC1G;AACA;AAAA,IACF;AAEA,UAAM,WAAW,kBAAkB,IAAI,MAAM,EAAE;AAI/C,UAAM,QAAQ,cAAc,KAAK;AACjC,UAAM,YAAY,QAAQ,IAAK,IAAI,KAAK,IAAI,SAAS,KAAK,CAAC,IAAK,QAAQ;AACxE,QAAI,YAAY,cAAc;AAC5B,YAAM,KAAK,cAAc;AACzB,YAAM,aAAa,IAAU,YAAM,SAAS;AAC5C,aAAO,KAAK,cAAc,OAAO,aAAa,IAAI,YAAY,UAAU,CAAC;AACzE,aAAO,KAAK,aAAa,OAAO,IAAI,UAAU,CAAC;AAC/C;AAAA,IACF;AAIA,QAAI,MAAM,OAAO;AACf,YAAM,IAAI,MAAM;AAGhB,YAAM,cAAc,MAAM,cAAc,QAAQ;AAIhD,YAAM,OAAO,EAAE,iBAAiB;AAChC,YAAM,OAAO,cAAc,OAAO;AAClC,YAAM,WAAW,OAAO,OAAO,EAAE;AACjC,YAAM,WAAW,EAAE,mBACf,gBAAgB,OAAO,QAAQ,IAC/B,IAAU,YAAM,EAAE,QAAQ;AAI9B,YAAM,UAAU,IAAU,YAAM,EAAE,IAAI;AACtC,YAAM,UAAU,IAAU,YAAM,EAAE,IAAI;AACtC,YAAM,WAAW,IAAU,YAAM,EAAE,QAAQ;AAG3C,kBAAY;AAAA,QACV;AAAA,UACE,MAAM,IAAI,CAAC,MAAM,UAAU,GAAG,CAAC,uBAAuB,CAAC;AAAA,UACvD,cAAc;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAIA,YAAM,WAAW,cAAc,KAAK,IAAI,KAAK,KAAK,IAAI,MAAM,WAAW,eAAe,GAAG,CAAC;AAC1F,kBAAY,KAAK,cAAc,OAAO,aAAa,UAAU,SAAS,OAAO,CAAC;AAC9E,kBAAY,KAAK,cAAc,OAAO,UAAU,UAAU,SAAS,OAAO,CAAC;AAC3E,kBAAY,KAAK,aAAa,OAAO,UAAU,QAAQ,CAAC;AACxD,YAAM,SAAS,MAAM,IAAI,CAAC,MAAM,UAAU,GAAG,EAAE,QAAQ,CAAC;AAIxD,YAAM,WAAW,EAAE,mBAAmB,WAAW,IAAU,YAAM,EAAE,SAAS,EAAE,IAAI;AAClF,kBAAY,KAAK,cAAc,QAAQ,UAAU,MAAM,UAAU,QAAQ,CAAC;AAC1E,kBAAY,KAAK,aAAa,QAAQ,MAAM,QAAQ,CAAC;AACrD,iBAAW,OAAO,WAAW,IAAI;AACjC,UAAI,YAAY,CAAC,SAAS,UAAU,CAAC,SAAS,SAAS;AACrD,cAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,KAAK;AACtC,cAAM,MAAM,SAAS,OAAO,SAAS,MAAM,IAAI,EAAE;AACjD,mBAAW,KAAK;AAAA,UACd,MAAM,IAAI;AAAA,UACV,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG,OAAO;AAAA,UACV,UAAU,IAAI;AAAA,UACd,cAAc,IAAI;AAAA,UAClB,YAAY,SAAS;AAAA,UACrB,GAAI,SAAS,UACT,EAAE,SAAS,SAAS,SAAS,GAAG,WAAW,OAAO,IAAI,IAAI,IAAI,UAAU,IAAI,QAAQ,IAAI,OAAO,EAAE,IACjG,CAAC;AAAA,QACP,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAIA,UAAM,OAAO,gBAAgB,OAAO,QAAQ;AAC5C,UAAM,aAAa,MAAM,cAAc,QAAQ;AAC/C,eAAW,KAAK,cAAc,OAAO,aAAa,IAAI,MAAM,QAAQ,IAAI,GAAG,MAAM,SAAS,IAAI,CAAC,CAAC;AAChG,eAAW,KAAK,aAAa,OAAO,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC;AACzD,eAAW,OAAO,KAAK,IAAI;AAE3B,QAAI,YAAY,CAAC,SAAS,UAAU,CAAC,SAAS,SAAS;AACrD,YAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,KAAK;AACtC,YAAM,MAAM,SAAS,OAAO,SAAS,MAAM,IAAI,EAAE;AACjD,iBAAW,KAAK;AAAA,QACd,MAAM,IAAI;AAAA,QACV,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG,KAAK;AAAA,QACR,UAAU,IAAI;AAAA,QACd,cAAc,IAAI;AAAA,QAClB,YAAY,SAAS;AAAA,QACrB,GAAI,SAAS,UACT,EAAE,SAAS,SAAS,SAAS,GAAG,WAAW,OAAO,IAAI,IAAI,IAAI,UAAU,IAAI,QAAQ,IAAI,OAAO,EAAE,IACjG,CAAC;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,UAAuC;AAC3C,MAAI,UAAU,QAAQ;AACpB,cAAU,IAAU,qBAAe;AACnC,YAAQ,aAAa,YAAY,IAAU,sBAAgB,IAAI,aAAa,SAAS,GAAG,CAAC,CAAC;AAAA,EAC5F;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,SAAS,gBAAgB,OAAO,KAAK,IAAI;AAAA,IACtD,aAAa,MAAM,SAAS,gBAAgB,OAAO,KAAK,IAAI;AAAA,IAC5D;AAAA,IACA;AAAA,EACF;AACF;;;AC9gCA,YAAYC,YAAW;AAGvB,SAAS,aAAa,YAAY;AAiClC,SAAS,WAAW,GAAe,OAAqB;AACtD,IAAE,QAAQ;AACV,IAAE,aAAa;AACf,IAAE,eAAe;AACjB,IAAE,UAAU;AACZ,IAAE,UAAU;AACZ,IAAE,YAAY;AAChB;AASO,SAAS,kBACd,MACA,SACa;AAEb,QAAM,IAAI,IAAI,KAAK;AACnB,IAAE,OAAO,KAAK;AACd,IAAE,WAAW,KAAK;AAClB,aAAW,GAAG,KAAK,SAAS,CAAQ;AACpC,IAAE,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACrC,QAAM,OAAO,KAAK,gBAAgB;AAClC,IAAE,SAAS,IAAI;AACf,IAAE,KAAK,OAAO;AACd,SAAO;AAAA,IACL,QAAQ;AAAA;AAAA,IAER,QAAQ,SAAwB;AAC9B,QAAE,SAAS,IAAI,QAAQ,UAAU,KAAK,KAAK;AAAA,IAC7C;AAAA,IACA,UAAgB;AACd,QAAE,QAAQ;AAAA,IACZ;AAAA,EACF;AACF;AAgBA,SAAS,UAAU,GAAc,OAAqB;AACpD,QAAM,MAAM,EAAE,OAAO;AACrB,QAAM,KAAK,CAAC,KAAK,IAAI,GAAG;AACxB,QAAM,KAAK,KAAK,IAAI,GAAG;AACvB,IAAE,KAAK,SAAS,IAAI,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC;AAC3D,IAAE,KAAK,SAAS,IAAI;AACtB;AAEO,SAAS,kBAAkB,OAAoB,OAAe,SAAmC;AAEtG,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,UAAgD,CAAC;AACvD,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,QAAS;AAElB,UAAM,IAAI,IAAI,KAAK;AACnB,MAAE,OAAO,KAAK;AACd,MAAE,WAAW,KAAK;AAClB,eAAW,GAAG,KAAK;AACnB,MAAE,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACrC,MAAE,SAAS,IAAI,KAAK;AACpB,IAAC,QAAsC,IAAI,CAAC;AAC5C,YAAQ,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,aAAa,CAAC;AAAA,EACnD;AACA,UAAQ,KAAK,OAAO;AAKpB,QAAM,QAAQ,IAAU,aAAM;AAC9B,QAAM,IAAI,OAAO;AACjB,QAAM,QAAqB,CAAC;AAC5B,QAAM,SAAS,IAAU,qBAAc;AACvC,SAAO,eAAe,WAAW;AACjC,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAK,QAAS;AAEnB,UAAM,SAAS,KAAK,YAAY,IAAI,KAAK;AACzC,UAAM,SAAS,KAAK,YAAY,MAAM,KAAK;AAC3C,UAAM,MAAM;AACZ,UAAM,MAAM,IAAU,yBAAkB,EAAE,aAAa,MAAM,SAAS,GAAG,YAAY,MAAM,CAAC;AAC5F,UAAM,OAAO,IAAU,YAAK,IAAU,qBAAc,GAAG,CAAC,GAAG,GAAG;AAC9D,UAAM,QAAmB,EAAE,MAAM,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,IAAI,MAAM,MAAM,KAAK,cAAc,IAAI;AACtG,cAAU,OAAO,CAAC;AAClB,WAAO;AAAA,MACL,KAAK;AAAA,MACL,CAAC,QAAQ;AACP,YAAI,aAAmB;AACvB,cAAM,MAAM,IAAI;AAChB,cAAM,SAAS,KAAK,IAAI,OAAO,IAAI,SAAS,KAAK,KAAK,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC;AAE7E,cAAM,IAAI,KAAK,IAAI,QAAQ,SAAS,MAAM;AAC1C,aAAK,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC;AAC/B,YAAI,MAAM;AACV,YAAI,UAAU;AACd,YAAI,cAAc;AAClB,kBAAU;AAAA,MACZ;AAAA,MACA;AAAA,MACA,MAAM;AAAA;AAAA,IACR;AACA,UAAM,IAAI,IAAI;AACd,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA;AAAA;AAAA,IAGR,QAAQ,SAAwB;AAC9B,YAAM,QAAQ,UAAU,KAAK,KAAK;AAClC,iBAAW,EAAE,MAAM,KAAK,KAAK,QAAS,MAAK,SAAS,IAAI,OAAO;AAC/D,iBAAW,KAAK,MAAO,WAAU,GAAG,KAAK;AAAA,IAC3C;AAAA,IACA,UAAgB;AACd,cAAQ,QAAQ;AAChB,iBAAW,EAAE,KAAK,KAAK,OAAO;AAC5B,aAAK,SAAS,QAAQ;AACtB,cAAM,IAAI,KAAK;AACf,UAAE,KAAK,QAAQ;AACf,UAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,eAAeC,aAAoB,kBAAoC;AACrF,MAAI,IAAIA,cAAa;AACrB,MAAI,IAAI,IAAK,MAAK;AAClB,MAAI,KAAK,KAAM,MAAK;AACpB,SAAO,mBAAmB,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI;AAC7D;;;AC1LA,YAAYC,YAAW;AAMvB,IAAMC,gBAAe;AAErB,SAAS,cAAc,MAAkC;AACvD,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,UAAM,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM;AACpC,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,YAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAChC,aAAS,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,EAC9C;AAEA,SAAO,QAAQ,IAAI,KAAK,IAAI,IAAI,IAAI,QAAQ;AAC9C;AAGA,SAAS,UAAU,MAAkC;AACnD,QAAM,IAAI,kBAAkB,IAAI;AAChC,MAAI,IAAI,IAAI,KAAK,KAAK;AACtB,SAAO,IAAI,KAAK,KAAK,EAAG,MAAK,KAAK;AAClC,SAAO,KAAK,CAAC,KAAK,KAAK,EAAG,MAAK,KAAK;AACpC,SAAO,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI;AAC1C;AAgBA,IAAM,oBAAoB;AAI1B,IAAM,mBAAmB;AACzB,IAAM,iBAAiB;AACvB,IAAM,aAAa;AACnB,IAAM,YAAY;AAKlB,SAAS,aAAa,SAA0B;AAC9C,QAAM,IAAI,QAAQ,YAAY;AAC9B,SACE,EAAE,SAAS,WAAW,KACtB,EAAE,SAAS,OAAO,KAClB,EAAE,SAAS,UAAU,KACrB,EAAE,SAAS,MAAM,KACjB,EAAE,SAAS,YAAY,KACvB,EAAE,SAAS,SAAS,KACpB,EAAE,SAAS,MAAM;AAErB;AAEA,SAAS,SAAS,SAAwB;AACxC,QAAM,IAAI,QAAQ,YAAY;AAC9B,MAAI,EAAE,SAAS,WAAW,EAAG,QAAO;AACpC,MAAI,EAAE,SAAS,OAAO,EAAG,QAAO;AAChC,MAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACzD,MAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,QAAQ,EAAG,QAAO;AACrF,MAAI,EAAE,SAAS,aAAa,EAAG,QAAO;AACtC,SAAO;AACT;AAGA,SAAS,UAAU,KAAqC;AACtD,MAAI,UAAU;AACd,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO,IAAI,EAAE;AACjB,MAAI,OAAO;AACb;AAEA,IAAM,eAAe,oBAAI,IAAgC;AAEzD,SAAS,aAAa,OAAmC;AACvD,QAAM,SAAS,aAAa,IAAI,KAAK;AACrC,MAAI,OAAQ,QAAO;AACnB,QAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,IAAE,QAAQ;AACV,IAAE,SAAS;AACX,QAAM,MAAM,EAAE,WAAW,IAAI;AAC7B,MAAI,KAAK;AAEP,QAAI,UAAU;AACd,QAAI,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;AAClC,QAAI,YAAY;AAChB,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,QAAI,cAAc;AAClB,QAAI,OAAO;AACX,QAAI,cAAc;AAClB,QAAI,YAAY;AAChB,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,WAAW;AACf,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,kBAAU,GAAG;AACb;AAAA,MACF,KAAK,aAAa;AAChB,kBAAU,GAAG;AAEb,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO;AACX,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,UAAU;AACd,YAAI,KAAK;AACT;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AACf,YAAI,YAAY;AAChB,YAAI,WAAW,IAAI,IAAI,IAAI,EAAE;AAC7B,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,UAAU;AACd,YAAI,KAAK;AACT,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,OAAO,IAAI,EAAE;AACjB,YAAI,UAAU;AACd,YAAI,KAAK;AACT;AAAA,MACF;AAAA,MACA,KAAK;AACH,YAAI,OAAO;AACX,YAAI,SAAS,MAAM,IAAI,EAAE;AACzB;AAAA,MACF,KAAK;AACH,YAAI,OAAO;AACX,YAAI,SAAS,KAAK,IAAI,EAAE;AACxB;AAAA,MACF;AACE,YAAI,UAAU;AACd,YAAI,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;AAClC,YAAI,KAAK;AAAA,IACb;AAAA,EACF;AACA,QAAM,MAAM,IAAU,qBAAc,CAAC;AACrC,MAAI,aAAmB;AACvB,MAAI,aAAa;AACjB,eAAa,IAAI,OAAO,GAAG;AAC3B,SAAO;AACT;AAOA,IAAM,mBAAmB,oBAAI,IAAiC;AAE9D,SAAS,iBACP,SACA,MACA,UACA,QACqB;AACrB,QAAM,MAAM,GAAG,OAAO,IAAI,IAAI;AAC9B,QAAM,SAAS,iBAAiB,IAAI,GAAG;AACvC,MAAI,OAAQ,QAAO;AACnB,QAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,IAAE,QAAQ;AACV,IAAE,SAAS;AACX,QAAM,MAAM,EAAE,WAAW,IAAI;AAC7B,QAAM,MAAM,IAAU,qBAAc,CAAC;AACrC,MAAI,aAAmB;AACvB,MAAI,aAAa;AACjB,QAAM,aAAa,MAAY;AAC7B,QAAI,CAAC,IAAK;AACV,QAAI,UAAU,GAAG,GAAG,KAAK,GAAG;AAC5B,QAAI,UAAU;AACd,QAAI,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;AAClC,QAAI,YAAY;AAChB,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,QAAI,cAAc;AAClB,QAAI,OAAO;AAAA,EACb;AACA,aAAW;AACX,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,cAAc;AAClB,MAAI,SAAS,MAAM;AACjB,QAAI,CAAC,IAAK;AACV,eAAW;AACX,QAAI,UAAU,KAAK,IAAI,IAAI,IAAI,EAAE;AACjC,QAAI,cAAc;AAClB,aAAS;AAAA,EACX;AACA,MAAI,UAAU,MAAM;AAElB,UAAM,cAAc,aAAa,QAAQ,EAAE;AAC3C,QAAI,IAAK,KAAI,UAAU,aAAa,GAAG,CAAC;AACxC,QAAI,cAAc;AAClB,aAAS;AAAA,EACX;AACA,MAAI,MAAM;AACV,mBAAiB,IAAI,KAAK,GAAG;AAC7B,SAAO;AACT;AAWO,SAAS,qBACd,OACA,OACA,UAAkC,CAAC,GACnC,YACuB;AACvB,QAAM,YAAY,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3D,QAAM,aAAa,IAAI,IAAI,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7D,QAAM,QAAQ,IAAU,aAAM;AAC9B,QAAM,UAAgD,CAAC;AACvD,QAAM,WAAyB,CAAC;AAChC,QAAM,MAAM,IAAU,qBAAc,GAAG,CAAC;AACxC,QAAM,WAAW,IAAU,qBAAc,GAAG,CAAC;AAC7C,aAAW,OAAO,MAAM,WAAW;AACjC,QAAI,CAAC,IAAI,WAAW,IAAI,OAAQ;AAChC,QAAI;AACJ,QAAI;AACJ,QAAI,IAAI,cAAc;AACtB,QAAI,OAAO;AACX,UAAM,QAAQ,IAAI,UAAU,WAAW,IAAI,IAAI,OAAO,IAAI;AAC1D,QAAI,SAAS,MAAM,SAAS,SAAS,aAAa,MAAM,SAAS,YAAY,CAAC,GAAG;AAK/E,YAAM,OAAO,MAAM,SAAS,YAAY,CAAC,EAAE,IAAI,CAAC,MAAM,SAAS,OAAO,CAAC,CAAC;AACxE,OAAC,GAAG,CAAC,IAAI,gBAAgB,IAAI;AAC7B,aAAO,UAAU,IAAI;AACrB,YAAM,OAAO,UAAU,KAAK;AAC5B,UAAI,YAAY;AAChB,UAAI,SAAS,QAAQ;AACnB,oBAAY,cAAc,IAAI,IAAIA,gBAAe,OAAO,YAAY,OAAO,IAAI;AAAA,MACjF;AACA,UAAI,cAAc,YAAY;AAAA,IAChC,WAAW,IAAI,QAAQ;AACrB,YAAM,OAAO,UAAU,IAAI,IAAI,MAAM;AACrC,UAAI,KAAM,EAAC,GAAG,CAAC,IAAI,SAAS,OAAO,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,IACzD;AACA,QAAI,MAAM,UAAa,MAAM,OAAW;AAGxC,UAAM,WAAW,IAAI,WAAW,CAAC;AACjC,UAAM,UAAU,UAAU,QAAQ,QAAQ,IAAI,QAAQ,YAAY,CAAC;AACnE,UAAM,OAAO,UAAU,YAAY;AACnC,UAAM,QAAQ,SAAS,IAAI,OAAO;AAClC,UAAM,MAAM,IAAU,yBAAkB;AAAA,MACtC,KAAK,UAAU,iBAAiB,SAAS,MAAM,OAAO,UAAU,IAAI,aAAa,KAAK;AAAA,MACtF,aAAa;AAAA,MACb,YAAY;AAAA,IACd,CAAC;AACD,QAAI,aAAa,IAAI,OAAO,GAAG;AAG7B,YAAM,QAAQ,IAAU,YAAK,UAAU,GAAG;AAC1C,YAAM,MAAM,IAAI,kBAAkB,kBAAkB,CAAC;AACrD,YAAM,SAAS,IAAI,GAAG,GAAG,IAAI,cAAc;AAC3C,YAAM,cAAc;AACpB,YAAM,gBAAgB;AACtB,YAAM,IAAI,KAAK;AACf,eAAS,KAAK,KAAK;AACnB;AAAA,IACF;AACA,UAAM,OAAO,IAAU,YAAK,KAAK,GAAG;AACpC,SAAK,MAAM,IAAI,mBAAmB,mBAAmB,CAAC;AACtD,SAAK,SAAS,IAAI,GAAG,GAAG,CAAC;AACzB,SAAK,SAAS,IAAI;AAClB,UAAM,IAAI,IAAI;AACd,YAAQ,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,EAC7B;AACA,MAAI,CAAC,QAAQ,UAAU,CAAC,SAAS,QAAQ;AACvC,QAAI,QAAQ;AACZ,aAAS,QAAQ;AACjB,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ;AAAA;AAAA;AAAA,IAGR,QAAQ,SAAwB;AAC9B,YAAM,QAAQ,UAAU,KAAK,KAAK;AAClC,iBAAW,KAAK,QAAS,GAAE,KAAK,SAAS,IAAI,EAAE,OAAO;AAAA,IACxD;AAAA;AAAA;AAAA;AAAA,IAIA,cAAcC,aAAoB,UAAwB;AACxD,YAAM,KAAM,WAAW,KAAK,KAAM;AAClC,YAAM,KAAM,CAACA,cAAa,KAAK,KAAM;AACrC,iBAAW,SAAS,SAAU,OAAM,SAAS,IAAI,IAAI,GAAG,IAAI,KAAK;AAAA,IACnE;AAAA,IACA,UAAgB;AACd,UAAI,QAAQ;AACZ,eAAS,QAAQ;AACjB,iBAAW,KAAK,QAAS,CAAC,EAAE,KAAK,SAA4B,QAAQ;AACrE,iBAAW,KAAK,SAAU,CAAC,EAAE,SAA4B,QAAQ;AAAA,IAEnE;AAAA,EACF;AACF;;;ACnVA,YAAYC,YAAW;AACvB,SAAS,kBAAkB;AAgBpB,SAAS,sBACd,OACA,OACA,SAC8B;AAC9B,QAAM,QAAQ,oBAAI,IAA6B;AAC/C,QAAM,QAAQ,IAAU,gBAAS;AACjC,aAAW,OAAO,MAAM,YAAY;AAClC,UAAM,OAAO,MAAM,QAAQ,IAAI,MAAM;AACrC,QAAI,CAAC,QAAQ,KAAK,YAAY,WAAW,CAAC,IAAI,SAAU;AACxD,UAAM,CAAC,GAAG,CAAC,IAAI,SAAS,OAAO,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AAGnD,UAAM,SAAS,IAAI,GAAG,GAAG,cAAc,IAAI,QAAQ;AAMnD,UAAM,MAAM,IAAI,aAAa,IAAI,KAAK,KAAK,IAAI,WAAW;AAC1D,UAAM,SAAS,IAAI,KAAK,KAAK,GAAG,KAAK,CAAC;AACtC,UAAM,MAAM,UAAU,IAAI,SAAS,CAAC;AACpC,UAAM,aAAa;AACnB,UAAM,OAAO,MAAM,IAAI,IAAI,QAAQ,KAAK,CAAC;AACzC,SAAK,KAAK,MAAM,OAAO,MAAM,CAAC;AAC9B,UAAM,IAAI,IAAI,UAAU,IAAI;AAAA,EAC9B;AACA,SAAO;AACT;AAOA,eAAsB,gBACpB,OACA,OACA,SACA,MAC6B;AAC7B,OAAK;AACL,QAAM,QAAQ,sBAAsB,OAAO,OAAO,OAAO;AACzD,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,IAAI,WAAW;AAC9B,QAAM,QAAQ,IAAU,aAAM;AAC9B,QAAM,QAAQ;AAAA,IACZ,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,KAAK,QAAQ,MAAM;AAClD,UAAI;AACF,cAAM,OAAO,MAAM,OAAO,UAAU,GAAG;AACvC,aAAK,MAAM,SAAS,CAAC,QAAQ;AAC3B,cAAI,EAAE,eAAqB,aAAO;AAClC,gBAAM,OAAO;AACb,gBAAM,YAAY,IAAU,qBAAc,KAAK,UAAU,KAAK,UAAU,SAAS,MAAM;AACvF,mBAAS,QAAQ,CAAC,GAAG,MAAM;AACzB,sBAAU,YAAY,GAAG,IAAU,eAAQ,EAAE,iBAAiB,GAAG,KAAK,WAAW,CAAC;AAAA,UACpF,CAAC;AACD,oBAAU,eAAe,cAAc;AACvC,gBAAM,IAAI,SAAS;AAAA,QACrB,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,gBAAQ,KAAK,iCAAiC,GAAG,IAAI,GAAG;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACnFA,YAAYC,YAAW;AA2FvB,IAAM,QAAQ,IAAU,aAAM,GAAG,GAAG,CAAC;AACrC,IAAM,UAAU,CAAC,GAAgB,MAA2B,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;AACnF,IAAM,SAAS,CAAC,GAAgB,MAA2B,EAAE,MAAM,EAAE,eAAe,IAAI,CAAC;AAEzF,IAAM,QAAQ,CAAC,QAAgB,MAAmB,IAAU,aAAM,GAAG;AAGrE,IAAM,cAAc;AAAA,EAClB,YAAY;AAAA;AAAA,EACZ,aAAa;AAAA;AAAA,EACb,UAAU;AAAA;AACZ;AAeA,IAAM,QAAQ,CAAC,OAAiC,EAAE,GAAG,aAAa,GAAG,EAAE;AAQvE,IAAM,gBAA8B;AAAA,EAClC,OAAO;AAAA;AAAA,EACP,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,UAAU;AAAA;AAAA,EACV,MAAM;AAAA;AAAA,EACN,WAAW;AAAA;AAAA,EACX,UAAU;AAAA;AAAA,EACV,UAAU;AAAA;AAAA,EACV,OAAO;AAAA;AACT;AAGA,IAAM,QAAsB;AAAA,EAC1B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA;AAAA,EACZ,YAAY;AAAA;AAAA,EACZ,MAAM,MAAM,cAAc,QAAQ;AAAA,EAClC,SAAS,MAAM,cAAc,IAAI;AAAA,EACjC,UAAU,MAAM,cAAc,IAAI;AAAA,EAClC,OAAO,MAAM,aAAa;AAC5B;AAQA,IAAM,OAAqB;AAAA,EACzB,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA;AAAA,EACZ,YAAY;AAAA;AAAA,EACZ,MAAM,CAAC,SAAS,QAAQ,MAAM,IAAI;AAAA,EAClC,SAAS,CAAC,SAAS,OAAO,MAAM,IAAI;AAAA,EACpC,UAAU,CAAC,SAAS,OAAO,MAAM,IAAI;AAAA,EACrC,OAAO;AAAA,IACL,GAAG,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA,IAItB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA;AAAA;AAAA,IAGN,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,UAAU;AAAA;AAAA,IACV,kBAAkB;AAAA;AAAA;AAAA,EAGpB;AACF;AAEA,IAAM,SAAiD;AAAA,EACrD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA;AACX;AAGO,SAAS,oBAAoB,MAAkD;AACpF,SAAO,OAAO,QAAQ,OAAO;AAC/B;;;ACjMA,YAAYC,YAAW;AACvB,OAAO,gBAAgB;AADvB;AAeO,IAAM,cAAN,MAA6D;AAAA,EAgBlE,YAAY,MAAsB,QAAgB;AAflD,SAAS,KAAK;AACd,SAAS,OAAO;AAChB,SAAS,gBAAgB;AAEzB;AACA;AACA,gCAAU,IAAU,cAAO;AAC3B,+BAAS,IAAU,aAAM;AACzB,kCAAwC;AACxC,sCAAgB,IAAU,eAAQ;AAClC,6BAA8B;AAC9B,+BAAqB,EAAE,WAAW,GAAG,WAAW,EAAE;AAClD,oCAAc,IAAU,eAAQ;AAChC,mCAAa;AA+Bb;AAAA;AAAA,kBAAwC,CAAC,KAAK,WAAW;AACvD,UAAI,CAAC,mBAAK,WAAW;AACrB,yBAAK,SAAQ,mBAAmB,IAAU,eAAQ,EAC/C,UAAU,MAAM,KAAK,MAA2B,CAAC,EACjD,SAAS,mBAAK,cAAa;AAC9B,yBAAK,aAAY,KAAK,mBAAK,SAAQ,gBAAgB;AACnD,yBAAK,YAAa;AAClB,yBAAK,WAAU,WAAW;AAC1B,yBAAK,WAAU,OAAO,mBAAK,SAAQ,mBAAK,QAAO;AAC/C,yBAAK,QAAS;AAAA,QACZ,WAAW,mBAAK,WAAU,KAAK,OAAO;AAAA,QACtC,WAAW,mBAAK,WAAU,KAAK,OAAO;AAAA,MACxC;AAAA,IACF;AAzCE,uBAAK,OAAQ;AACb,uBAAK,SAAU;AAAA,EACjB;AAAA,EAEA,MAAM,KAAqB,IAA0D;AACnF,uBAAK,MAAO;AACZ,uBAAK,QAAO,IAAI,mBAAK,MAAK;AAC1B,UAAM,KAAK,WAAW,mBAAmB;AAAA,MACvC,EAAE,KAAK,mBAAK,SAAQ,CAAC,GAAG,KAAK,mBAAK,SAAQ,CAAC,EAAE;AAAA,MAC7C;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,+BAA+B;AAGhD,uBAAK,eAAgB,IAAU,eAAQ,EACpC,gBAAgB,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAChC,MAAM,IAAU,eAAQ,OAAO,CAAC,OAAO,KAAK,CAAC,EAC7C,SAAS,IAAU,eAAQ,EAAE,cAAc,KAAK,KAAK,CAAC,CAAC;AAC1D,uBAAK,WAAY,IAAU,qBAAc;AAAA,MACvC,QAAQ,IAAI,UAAU;AAAA,MACtB,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AACD,uBAAK,WAAU,YAAY;AAAA,EAC7B;AAAA,EAmBA,WAAiB;AACf,uBAAK,QAAO,OAAO,mBAAK,MAAK;AAC7B,uBAAK,YAAW,QAAQ;AACxB,uBAAK,WAAY;AACjB,uBAAK,MAAO;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,uBAAK,OAAM,eAAe;AAAA,EAC5B;AAAA,EAEA,gBAA4B;AAC1B,WAAO,mBAAK;AAAA,EACd;AAAA;AAAA,EAGA,aAA0B;AACxB,WAAO,mBAAK;AAAA,EACd;AAAA;AAAA,EAGA,cAA+B;AAC7B,WAAO,mBAAK,cAAa,mBAAK,aAAY,QAAQ,IAAI;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,aAAa,GAAW,GAAW,GAA4C;AAC7E,QAAI,CAAC,mBAAK,eAAc,CAAC,mBAAK,MAAM,QAAO;AAC3C,UAAM,SAAS,mBAAK,MAAK,UAAU;AACnC,UAAM,IAAI,OAAO;AACjB,UAAM,IAAI,OAAO;AACjB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,OAAO,IAAU,eAAQ,EAAE;AAAA,MAC/B,mBAAK;AAAA,MACL,IAAU,eAAQ,EAAE,cAAc,CAAC,KAAK,KAAK,CAAC;AAAA,IAChD;AACA,UAAM,IAAI,IAAU,eAAQ,GAAG,GAAG,GAAG,CAAC,EAAE,aAAa,IAAI;AACzD,QAAI,EAAE,KAAK,EAAG,QAAO;AACrB,WAAO,EAAE,IAAK,EAAE,IAAI,EAAE,IAAI,KAAK,IAAK,GAAG,IAAK,IAAI,EAAE,IAAI,EAAE,KAAK,IAAK,EAAE;AAAA,EACtE;AAAA,EAEA,QAAQ,IAAY,IAAkE;AACpF,QAAI,CAAC,mBAAK,eAAc,CAAC,mBAAK,MAAM,QAAO;AAC3C,UAAM,SAAS,mBAAK,MAAK,UAAU;AACnC,UAAM,IAAI,OAAO;AACjB,UAAM,IAAI,OAAO;AACjB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,OAAQ,KAAK,IAAK,IAAI;AAC5B,UAAM,OAAO,IAAK,KAAK,IAAK;AAE5B,UAAM,OAAO,IAAU,eAAQ,EAAE;AAAA,MAC/B,mBAAK;AAAA,MACL,IAAU,eAAQ,EAAE,cAAc,CAAC,KAAK,KAAK,CAAC;AAAA,IAChD;AACA,UAAM,MAAM,KAAK,OAAO;AACxB,UAAM,KAAK,IAAU,eAAQ,MAAM,MAAM,IAAI,CAAC,EAAE,aAAa,GAAG;AAChE,UAAM,KAAK,IAAU,eAAQ,MAAM,MAAM,GAAG,CAAC,EAAE,aAAa,GAAG;AAC/D,QAAI,CAAC,GAAG,KAAK,CAAC,GAAG,EAAG,QAAO;AAC3B,UAAM,SAAS,IAAU,eAAQ,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AACtE,UAAM,MAAM,IAAU,eAAQ,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AACnE,UAAM,MAAM,IAAI,IAAI,MAAM,EAAE,UAAU;AACtC,WAAO,EAAE,QAAQ,IAAI;AAAA,EACvB;AACF;AA9HE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7BF,YAAYC,YAAW;AAKvB,IAAM,eAAe;AAErB,IAAM,mBACJ;AACF,IAAM,kBAAkB;AACxB,IAAM,WAAW,cAAc;AAC/B,IAAM,YAAY;AAElB,IAAM;AAAA;AAAA,EAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUjC,IAAM;AAAA;AAAA,EAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBnC,SAAS,mBAAmB,OAAsC;AAChE,SAAO,IAAU,sBAAe;AAAA,IAC9B,aAAa;AAAA,IACb,YAAY;AAAA;AAAA;AAAA;AAAA,IAIZ,WAAW,CAAC;AAAA,IACZ,MAAY;AAAA,IACZ,UAAU;AAAA,MACR,WAAW,EAAE,OAAO,EAAE;AAAA,MACtB,UAAU,EAAE,OAAO,EAAE;AAAA,MACrB,OAAO,EAAE,OAAO,EAAE;AAAA,MAClB,QAAQ,EAAE,OAAO,QAAQ,IAAI,EAAE;AAAA,IACjC;AAAA,IACA,cAAc;AAAA,IACd,gBAAgB;AAAA,EAClB,CAAC;AACH;AAjEA;AA6EO,IAAM,cAAN,MAAkB;AAAA,EAuBvB,YAAY,QAAwB,OAAmB,UAAsB,MAAM,QAAW;AAvBzF;AACL,kCAAY,mBAAmB,KAAK;AACpC,uCAAiB,mBAAmB,IAAI;AACxC,gCASM,CAAC;AACP,gCAA8B;AAC9B,qCAAkC;AAClC,kCAAwC;AACxC,qCAAe;AACf,mCAAa,EAAE,SAAS,GAAG,OAAO,GAAG,KAAK,KAAK;AAC/C;AACA;AACA,qCAAe;AACf;AAGE,uBAAK,SAAU;AACf,uBAAK,QAAS;AACd,uBAAK,UAAW;AAAA,EAClB;AAAA;AAAA,EAGA,SAAS,UAAkC;AACzC,SAAK,MAAM;AACX,QAAI,SAAS;AACb,eAAW,WAAW,UAAU;AAC9B,YAAM,WAAW,aAAa,mBAAK,SAAQ,QAAQ,MAAM;AACzD,UAAI,SAAS,SAAS,EAAG;AACzB,YAAM,IAAI,QAAQ,aAAa,WAAW;AAC1C,YAAM,QAAQ,IAAU;AAAA,QACtB,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,eAAQ,GAAG,GAAG,CAAC,CAAC;AAAA,QACnD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,SAAS,MAAM,UAAU;AAC/B,YAAM,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,GAAG,CAAC;AAC7C,YAAM,MAAM,MAAM,gBAAgB,CAAC;AACnC,YAAM,MAAM,IAAI,cAAc,IAAI,KAAK,IAAI,CAAC;AAC5C,YAAM,MAAM,IAAI,cAAc,IAAI,KAAK,IAAI,CAAC;AAC5C,YAAM,MAAgB,CAAC;AACvB,YAAM,MAAM,IAAU,eAAQ;AAC9B,UAAI,MAAM;AACV,YAAM,OAAiB,CAAC;AACxB,eAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,cAAM,IAAI,IAAI,CAAC;AACf,cAAM,OAAO,IAAI,IAAI,CAAC;AACtB,cAAM,OAAO,IAAI,IAAI,CAAC;AACtB,YAAI,CAAC,EAAG;AACR,YAAI,IAAI,KAAK,KAAM,QAAO,EAAE,WAAW,IAAI;AAC3C,aAAK,KAAK,GAAG;AACb,YAAI,MAAM,KAAK,KAAM,KAAI,WAAW,MAAM,CAAC;AAAA,iBAClC,MAAM,KAAK,KAAM,KAAI,WAAW,GAAG,IAAI;AAAA,iBACvC,QAAQ,KAAM,KAAI,WAAW,MAAM,IAAI;AAChD,YAAI,IAAI;AACR,YAAI,UAAU;AACd,cAAM,KAAK,CAAC,IAAI,IAAI,eAAe;AACnC,cAAM,KAAK,IAAI,IAAI,eAAe;AAClC,YAAI,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;AACjE,YAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;AAC/B,YAAI,IAAI,GAAG;AACT,gBAAM,IAAI,IAAI;AACd,cAAI,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAAA,QAC/C;AAAA,MACF;AACA,YAAM,MAAM,IAAU,sBAAe;AACrC,UAAI,aAAa,YAAY,IAAU,uBAAgB,KAAK,CAAC,CAAC;AAC9D,UAAI,aAAa,MAAM,IAAU,uBAAgB,KAAK,CAAC,CAAC;AACxD,UAAI,SAAS,GAAG;AAEhB,YAAM,QAAQ,IAAU,YAAK,KAAK,mBAAK,eAAc;AACrD,YAAM,cAAc;AACpB,YAAM,QAAQ,IAAU,YAAK,KAAK,mBAAK,UAAS;AAChD,YAAM,cAAc;AACpB,yBAAK,SAAQ,IAAI,OAAO,KAAK;AAC7B,yBAAK,SAAQ,KAAK,EAAE,OAAO,OAAO,SAAS,OAAO,QAAQ,KAAK,KAAK,KAAK,KAAK,CAAC;AAC/E,eAAS;AAAA,IACX;AACA,uBAAK,cAAe;AAEpB,UAAM,QAAQ,mBAAK,SAAQ,CAAC;AAC5B,UAAM,QAAQ,OAAO,IAAI,CAAC;AAC1B,QAAI,SAAS,OAAO;AAClB,YAAM,SAAS,sBAAK,8CAAL;AACf,aAAO,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,IAAI;AACpD,aAAO,UAAU;AACjB,4BAAK,iDAAL;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,mBAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,mBAAK,SAAQ,SAAS;AAAA,EAC/B;AAAA;AAAA,EAGA,iBAAiB,gBAA+E;AAC9F,eAAW,SAAS,mBAAK,UAAS;AAChC,YAAM,UACJ,MAAM,QAAQ,eAAe,OACzB,OACA,eAAe,MAAM,QAAQ,SAAS,MAAM,QAAQ,UAAU;AACpE,YAAM,MAAM,UAAU;AACtB,YAAM,MAAM,UAAU;AAAA,IACxB;AAEA,UAAM,QAAQ,mBAAK,SAAQ,CAAC;AAC5B,QAAI,mBAAK,iBAAgB,OAAO;AAC9B,yBAAK,cAAa,UAChB,MAAM,QAAQ,eAAe,OACzB,OACA,eAAe,MAAM,QAAQ,SAAS,MAAM,QAAQ,UAAU;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,QAA+B;AAC7C,QAAI,OAAsB;AAC1B,eAAW,SAAS,mBAAK,UAAS;AAChC,UAAI,SAAS,QAAQ,KAAK,IAAI,MAAM,MAAM,MAAM,IAAI,KAAK,IAAI,OAAO,MAAM,EAAG,QAAO,MAAM;AAAA,IAC5F;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,UAAU,gBAAkD;AAC1D,WAAO,mBAAK,SAAQ,KAAK,CAAC,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAAE,GAAG,GAAG;AAAA,EACxF;AAAA,EAQA,YAAY,QAAsB;AAChC,0BAAK,uCAAL,WAAiB,aAAa;AAAA,EAChC;AAAA,EACA,WAAW,QAAsB;AAC/B,0BAAK,uCAAL,WAAiB,YAAY;AAAA,EAC/B;AAAA,EACA,aAAqB;AACnB,WAAQ,mBAAK,WAAU,SAAS,UAAU,SAAgC;AAAA,EAC5E;AAAA,EACA,QAAQ,SAAuB;AAC7B,0BAAK,uCAAL,WAAiB,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAiEA,uBAAuB,GAAiB;AACtC,UAAM,IAAI,mBAAK;AACf,QAAI,EAAG,GAAE,SAAS,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA,EAIA,mBAAmBC,aAAoB,UAAkB,gBAA8B;AACrF,uBAAK,YAAa,EAAE,SAASA,aAAY,OAAO,UAAU,KAAK,eAAe;AAC9E,0BAAK,iDAAL;AAAA,EACF;AAAA,EAwCA,aAAmB;AACjB,0BAAK,yCAAL,WAAqB,UAAU;AAAA,EACjC;AAAA,EAEA,aAAmB;AACjB,QAAI,mBAAK,SAAS,oBAAK,SAAQ,UAAU;AAAA,EAC3C;AAAA;AAAA,EAGA,UAAU,QAAsB;AAC9B,UAAM,QAAQ,mBAAK,SAAQ,KAAK,CAAC,MAAM,UAAU,EAAE,SAAS,UAAU,EAAE,GAAG,KAAK,mBAAK,SAAQ,CAAC;AAC9F,QAAI,CAAC,MAAO;AACZ,UAAM,SAAS,sBAAK,yCAAL;AACf,UAAM,EAAE,KAAK,KAAK,IAAI;AACtB,QAAI,IAAI;AACR,WAAO,IAAI,KAAK,SAAS,MAAM,KAAK,IAAI,CAAC,KAAK,YAAY,OAAQ;AAClE,UAAM,IAAI,IAAI,CAAC;AACf,UAAM,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,CAAC,CAAC;AAC7C,UAAM,KAAK,KAAK,CAAC,KAAK;AACtB,UAAM,KAAK,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,KAAK;AACrD,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,OAAO,KAAK,GAAG,CAAC,IAAI;AAC1E,WAAO,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,IAAI,IAAI;AAAA,EAC9E;AAAA,EAEA,QAAc;AACZ,eAAW,SAAS,mBAAK,UAAS;AAChC,yBAAK,SAAQ,OAAO,MAAM,OAAO,MAAM,KAAK;AAC5C,YAAM,MAAM,SAAS,QAAQ;AAAA,IAC/B;AACA,uBAAK,SAAU,CAAC;AAChB,uBAAK,cAAe;AACpB,SAAK,WAAW;AAChB,QAAI,mBAAK,cAAc,oBAAK,cAAa,UAAU;AACnD,SAAK,YAAY,CAAC;AAClB,SAAK,WAAW,CAAC;AAAA,EACnB;AAAA,EAEA,UAAgB;AACd,SAAK,MAAM;AACX,QAAI,mBAAK,UAAS;AAChB,yBAAK,SAAQ,OAAO,mBAAK,QAAO;AAChC,yBAAK,SAAQ,SAAS,CAAC,QAAQ;AAC7B,YAAI,eAAqB,aAAM;AAC7B,UAAC,IAAI,SAAkC,QAAQ;AAC/C,UAAC,IAAI,SAA4B,QAAQ;AAAA,QAC3C;AAAA,MACF,CAAC;AACD,yBAAK,SAAU;AAAA,IACjB;AACA,QAAI,mBAAK,eAAc;AACrB,yBAAK,SAAQ,OAAO,mBAAK,aAAY;AACrC,yBAAK,cAAa,SAAS,QAAQ;AACnC,MAAC,mBAAK,cAAa,SAA4B,QAAQ;AACvD,yBAAK,cAAe;AAAA,IACtB;AACA,uBAAK,YAAW,QAAQ;AACxB,uBAAK,WAAY;AACjB,uBAAK,WAAU,QAAQ;AACvB,uBAAK,gBAAe,QAAQ;AAAA,EAC9B;AACF;AAhVE;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AArBK;AAgJL,gBAAW,SAAC,MAA0C,OAAqB;AACzE,QAAM,IAAI,mBAAK,WAAU,SAAS,IAAI;AACtC,QAAM,IAAI,mBAAK,gBAAe,SAAS,IAAI;AAC3C,MAAI,EAAG,GAAE,QAAQ;AACjB,MAAI,EAAG,GAAE,QAAQ;AACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBA,uBAAkB,WAAe;AAC/B,MAAI,mBAAK,cAAc,QAAO,mBAAK;AAMnC,QAAM,MAAM,IAAU,yBAAkB;AAAA,IACtC,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,SAAS;AAAA,EACX,CAAC;AACD,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,cAAc;AAClB,MAAI,SAAS,MAAM;AACjB,UAAM,IAAI;AACV,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAO,IAAI,QAAQ,IAAI,SAAU,CAAC,KAAK,CAAC;AACnE,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,WAAO,WAAW,IAAI,GAAG,UAAU,KAAK,GAAG,GAAG,GAAG,CAAC;AAClD,UAAM,MAAM,IAAU,qBAAc,MAAM;AAC1C,QAAI,aAAmB;AACvB,QAAI,aAAa;AACjB,QAAI,kBAAkB;AACtB,QAAI,YAAkB;AACtB,uBAAK,YAAW,QAAQ;AACxB,uBAAK,WAAY;AACjB,QAAI,MAAM;AACV,QAAI,UAAU;AACd,QAAI,cAAc;AAClB,uBAAK,cAAe,IAAI;AACxB,0BAAK,iDAAL;AACA,uBAAK,UAAL;AAAA,EACF;AACA,MAAI,MAAM;AACV,QAAM,MAAM,IAAU,qBAAc,GAAG,CAAC;AACxC,MAAI,UAAU,GAAG,KAAK,CAAC;AAGvB,QAAM,OAAO,IAAU,YAAK,KAAK,GAAG;AACpC,OAAK,cAAc;AACnB,OAAK,gBAAgB;AACrB,OAAK,UAAU;AACf,qBAAK,SAAQ,IAAI,IAAI;AACrB,qBAAK,cAAe;AACpB,SAAO;AACT;AAkBA,0BAAqB,WAAS;AAC5B,QAAM,IAAI,mBAAK;AACf,MAAI,CAAC,EAAG;AACR,QAAM,EAAE,SAAS,OAAO,IAAI,IAAI,mBAAK;AACrC,QAAM,IAAI,kBAAkB;AAC5B,IAAE,MAAM,IAAI,IAAI,mBAAK,eAAc,GAAG,CAAC;AAGvC,IAAE,SAAS,IAAK,QAAQ,KAAK,KAAM,KAAK,GAAI,CAAC,UAAU,KAAK,KAAM,KAAK,KAAK;AAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,kBAAa,WAAgB;AAC3B,MAAI,mBAAK,SAAS,QAAO,mBAAK;AAC9B,QAAM,QAAQ,IAAU,aAAM;AAC9B,QAAM,MAAM,IAAU,2BAAoB,EAAE,OAAO,UAAU,CAAC;AAC9D,QAAM,OAAO,IAAU,oBAAa,KAAK,GAAK,EAAE;AAChD,OAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;AACzB,QAAM,MAAM,IAAU,YAAK,MAAM,GAAG;AACpC,MAAI,SAAS,IAAI;AACjB,QAAM,OAAO,IAAU,YAAK,IAAU,sBAAe,MAAM,IAAI,EAAE,GAAG,GAAG;AACvE,OAAK,SAAS,IAAI;AAClB,QAAM,IAAI,KAAK,IAAI;AAGnB,QAAM,SAAS,CAAC,MAAO,EAAE,gBAAgB,KAAM;AAC/C,QAAM,cAAc;AACpB,QAAM,UAAU;AAChB,qBAAK,SAAQ,IAAI,KAAK;AACtB,qBAAK,SAAU;AACf,SAAO;AACT;;;AR9TF,IAAM,yBAAyB;AAE/B,IAAM,iBAAiB;AACvB,IAAM,qBAAqB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAEjF,IAAM,gBAAgB;AAtCtB,YAAAC,SAAAC,OAAA,QAAAC,QAAA;AA6CO,IAAM,gBAAN,MAAoB;AAAA,EAuDzB,YAAY,KAAqB,OAAc,OAA0B;AAvDpE;AACL;AACA,uBAAAF;AACA,uBAAAC;AACA;AACA,uBAAAC,QAAQ,IAAU,aAAM;AACxB,gCAAU,oBAAI,IAAwB;AACtC,gCAAU,oBAAI,IAAwB;AACtC;AACA;AACA;AACA,wCAAkB,IAAU,2BAAoB;AAAA,MAC9C,cAAc;AAAA,MACd,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAY;AAAA,IACd,CAAC;AACD,mCAAa,IAAU,yBAAkB,EAAE,OAAO,UAAU,CAAC;AAI7D;AAAA;AAAA;AAAA,sCAAgB,IAAU,yBAAkB;AAAA,MAC1C,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAY;AAAA,MACZ,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,IACtB,CAAC;AACD,mCAAiC;AAGjC;AAAA;AAAA,kCAAY,IAAU,yBAAkB;AAAA,MACtC,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAY;AAAA,MACZ,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,IACtB,CAAC;AACD,+BAA6B;AAC7B,qCAAmC;AACnC,uCAAiB;AACjB;AACA;AAGA;AAAA;AAAA,qCAAe;AACf,0CAAoB;AACpB,oCAAc;AAGZ,uBAAKD,OAAO;AACZ,uBAAK,QAAS;AACd,uBAAKD,SAAS,YAAY,MAAM,MAAM;AACtC,uBAAK,QAAS,oBAAoB,KAAK;AAKvC,uBAAK,SAAU,IAAU,yBAAkB,EAAE,cAAc,MAAM,MAAY,kBAAW,CAAC;AACzF,uBAAK,eAAgB,IAAU,2BAAoB,EAAE,OAAO,WAAW,MAAY,kBAAW,CAAC;AAE/F,uBAAKE,QAAM,IAAI,IAAU,uBAAgB,UAAU,UAAU,IAAI,CAAC;AAClE,UAAM,MAAM,IAAU,wBAAiB,UAAU,GAAG;AACpD,QAAI,SAAS,IAAI,MAAM,MAAM,GAAG;AAChC,uBAAKA,QAAM,IAAI,GAAG;AAClB,uBAAKA,QAAM,SAAS,IAAI,CAAC,KAAK,KAAK;AAEnC,uBAAK,QAAS,IAAI,YAAY,mBAAKA,SAAO,MAAM,MAAM;AACtD,QAAI,SAAS,mBAAK,OAAM;AAIxB,uBAAK,WAAY,MAAM;AACrB,YAAM,OAAO,eAAe,mBAAKD,OAAK,WAAW,GAAG,mBAAK,eAAc;AACvE,UAAI,SAAS,mBAAK,gBAAgB;AAClC,yBAAK,gBAAiB;AACtB,iBAAW,SAAS,mBAAK,SAAQ,OAAO,GAAG;AACzC,cAAM,QAAQ,QAAQ,IAAI;AAC1B,cAAM,SAAS,QAAQ,IAAI;AAAA,MAC7B;AACA,iBAAW,SAAS,mBAAK,SAAQ,OAAO,EAAG,OAAM,OAAO,QAAQ,IAAI;AACpE,yBAAK,QAAO,QAAQ;AAAA,IACtB;AACA,QAAI,GAAG,UAAU,mBAAK,UAAS;AAG/B,uBAAK,eAAgB,MAAM;AACzB,YAAM,UAAU,mBAAKA,OAAK,WAAW;AACrC,YAAM,QAAQ,mBAAKA,OAAK,SAAS;AACjC,iBAAW,SAAS,mBAAK,SAAQ,OAAO,EAAG,OAAM,SAAS,cAAc,SAAS,KAAK;AAAA,IACxF;AACA,QAAI,GAAG,QAAQ,mBAAK,cAAa;AACjC,uBAAK,gBAAiB,eAAe,IAAI,WAAW,GAAG,KAAK;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,eAA0C,eAAe,GAAS;AAC7E,QAAI,mBAAK,aAAY;AACnB,yBAAKC,QAAM,OAAO,mBAAK,WAAU;AACjC,yBAAK,YAAW,SAAS,CAAC,QAAQ;AAChC,YAAI,eAAqB,YAAM,CAAC,IAAI,SAAkC,QAAQ;AAAA,MAChF,CAAC;AACD,yBAAK,YAAa;AAAA,IACpB;AACA,QAAI,eAAe;AACjB,YAAM,UAAU,aAAa,mBAAKF,UAAQ,aAAa;AACvD,YAAM,QAAQ,IAAU,aAAM;AAC9B,YAAM,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE;AAQhD,YAAM,OAAO,mBAAK,QAAO,OAAO,iBAAiB;AACjD,YAAM,KAAK,MAAM,OAAO;AACxB,sBAAgB,KAAK,SAAS,MAAM,EAAE;AACtC,YAAM,QAAQ,IAAU,sBAAe;AACvC,YAAM,aAAa,YAAY,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACtF,YAAM,aAAa,UAAU,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACpF,YAAM,SAAS,IAAI,GAAG;AACtB,YAAM,IAAI,IAAU,YAAK,OAAO,mBAAK,cAAa,CAAC;AACnD,YAAM,QAAQ,IAAU,aAAM,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,eAAQ,GAAG,CAAC,CAAC,CAAC;AAC9E,YAAM,MAAM,IAAU,qBAAc,KAAK;AACzC,UAAI,UAAU,GAAG,GAAG,EAAE;AACtB,YAAM,IAAI,IAAU,YAAK,KAAK,mBAAK,cAAa,CAAC;AACjD,yBAAKE,QAAM,IAAI,KAAK;AACpB,yBAAK,YAAa;AAAA,IACpB;AACA,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA,EAIA,SAAS,eAA0C,eAAe,GAAS;AACzE,QAAI,mBAAK,SAAQ;AACf,yBAAKA,QAAM,OAAO,mBAAK,OAAM;AAC7B,yBAAK,QAAO,SAAS,CAAC,QAAQ;AAC5B,YAAI,eAAqB,YAAM,CAAC,IAAI,SAAkC,QAAQ;AAAA,MAChF,CAAC;AACD,yBAAK,QAAS;AAAA,IAChB;AACA,QAAI,eAAe;AACjB,YAAM,UAAU,aAAa,mBAAKF,UAAQ,aAAa;AACvD,YAAM,QAAQ,IAAU,aAAM;AAC9B,YAAM,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE;AAMhD,YAAM,OAAO,mBAAK,QAAO,OAAO,iBAAiB;AACjD,YAAM,KAAK,MAAM,OAAO;AACxB,sBAAgB,KAAK,SAAS,MAAM,EAAE;AACtC,YAAM,QAAQ,IAAU,sBAAe;AACvC,YAAM,aAAa,YAAY,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACtF,YAAM,aAAa,UAAU,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACpF,YAAM,SAAS,IAAI,GAAG;AACtB,YAAM,IAAI,IAAU,YAAK,OAAO,mBAAK,UAAS,CAAC;AAC/C,YAAM,QAAQ,IAAU,aAAM,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,eAAQ,GAAG,CAAC,CAAC,CAAC;AAC9E,YAAM,MAAM,IAAU,qBAAc,KAAK;AACzC,UAAI,UAAU,GAAG,GAAG,EAAE;AACtB,YAAM,IAAI,IAAU,YAAK,KAAK,mBAAK,UAAS,CAAC;AAC7C,yBAAKE,QAAM,IAAI,KAAK;AACpB,yBAAK,QAAS;AAAA,IAChB;AACA,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA,EAEA,oBAAoB,SAAwB;AAC1C,QAAI,mBAAK,aAAY;AACnB,yBAAK,YAAW,UAAU;AAC1B,yBAAK,QAAO,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGA,cAA2B;AACzB,uBAAK,iBAAL,mBAAK,cAAiB,IAAI,YAAY,mBAAKA,SAAO,mBAAKF,UAAQ,MAAM;AACnE,yBAAK,QAAO,QAAQ;AAAA,IACtB,CAAC;AACD,WAAO,mBAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAqB;AAChC,uBAAK,mBAAoB,OAAO,gBAAgB;AAChD,QAAI,mBAAK,aAAa;AACtB,UAAM,OAAO,MAAY;AACvB,YAAM,OAAO,mBAAK,qBAAoB,mBAAK;AAC3C,yBAAK,cAAL,mBAAK,gBAAgB,OAAO;AAC5B,UAAI,KAAK,IAAI,IAAI,IAAI,KAAO,oBAAK,cAAe,mBAAK;AACrD,iBAAW,SAAS,mBAAK,SAAQ,OAAO,EAAG,OAAM,MAAM,MAAM,IAAI,mBAAK;AACtE,yBAAK,QAAO,QAAQ;AACpB,UAAI,mBAAK,kBAAiB,mBAAK,oBAAmB;AAChD,2BAAK,aAAc,sBAAsB,IAAI;AAAA,MAC/C,OAAO;AACL,2BAAK,aAAc;AAAA,MACrB;AAAA,IACF;AACA,uBAAK,aAAc,sBAAsB,IAAI;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,UAAU,YAAoB,MAA0B;AACtD,UAAM,WAAW,mBAAK,QAAO,YAAY,UAAU;AACnD,QAAI,CAAC,SAAU;AACf,UAAM,QAAQ,sBAAK,0CAAL,WAAkB;AAChC,QAAI,MAAO,OAAM,MAAM,UAAU,CAAC,KAAK;AACvC,eAAW,SAAS,SAAS,QAAQ;AACnC,UAAI,KAAK,QAAQ,MAAM,OAAO,KAAK,SAAS;AAC1C,aAAK,UAAU,MAAM,EAAE;AAAA,MACzB,OAAO;AACL,aAAK,UAAU,MAAM,EAAE;AAAA,MACzB;AAAA,IACF;AACA,0BAAK,qDAAL;AACA,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,SAAuB;AAClC,UAAM,aAAa,mBAAK,SAAQ,IAAI,OAAO,GAAG,MAAM,WAAW;AAC/D,UAAM,QAAQ,sBAAK,0CAAL,WAAkB;AAChC,QAAI,SAAS,CAAC,WAAY,OAAM,MAAM,UAAU;AAAA,EAClD;AAAA;AAAA,EAGA,UAAU,SAAuB;AAC/B,UAAM,QAAQ,sBAAK,0CAAL,WAAkB;AAChC,QAAI,MAAO,OAAM,MAAM,UAAU;AACjC,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA,EAEA,UAAU,SAAuB;AAC/B,UAAM,QAAQ,mBAAK,SAAQ,IAAI,OAAO;AACtC,QAAI,MAAO,OAAM,MAAM,UAAU;AACjC,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA,EAEA,kBAA4B;AAC1B,WAAO,CAAC,GAAG,mBAAK,SAAQ,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,MAA8B;AACrC,UAAM,QAAQ,oBAAoB,IAAI;AACtC,QAAI,MAAM,SAAS,mBAAK,QAAO,KAAM;AACrC,uBAAK,QAAS;AACd,UAAM,UAAU,KAAK,gBAAgB;AACrC,eAAW,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,mBAAK,SAAQ,QAAQ,CAAC,GAAG;AACrD,YAAM,QAAQ,QAAQ;AACtB,YAAM,SAAS,QAAQ;AACvB,YAAM,MAAM,SAAS,CAAC,QAAQ;AAC5B,YAAI,eAAqB,YAAM,CAAC,IAAI,SAAkC,QAAQ;AAAA,MAChF,CAAC;AACD,yBAAKE,QAAM,OAAO,MAAM,KAAK;AAC7B,yBAAK,SAAQ,OAAO,EAAE;AAAA,IACxB;AACA,eAAW,MAAM,QAAS,MAAK,UAAU,EAAE;AAC3C,0BAAK,qDAAL;AACA,uBAAK,QAAO,QAAQ;AAAA,EACtB;AAAA;AAAA,EAGA,aAAa,SAA0B;AACrC,WAAO,mBAAK,SAAQ,IAAI,OAAO,GAAG,SAAS;AAAA,EAC7C;AAAA;AAAA,EAGA,aAAa,GAAW,GAAW,GAA4C;AAC7E,WAAO,mBAAK,QAAO,aAAa,GAAG,GAAG,CAAC;AAAA,EACzC;AAAA;AAAA,EAGA,QAAQ,IAAY,IAAkE;AACpF,WAAO,mBAAK,QAAO,QAAQ,IAAI,EAAE;AAAA,EACnC;AAAA,EAEA,gBAA4B;AAC1B,WAAO,mBAAK,QAAO,cAAc;AAAA,EACnC;AAAA;AAAA,EAGA,WAAW,UAAiD,CAAC,GAAS;AACpE,UAAM,SAAS,IAAIC,YAAW,aAAa;AAC3C,QAAI,MAAM;AACV,eAAW,YAAY,mBAAK,QAAO,WAAW;AAC5C,iBAAW,SAAS,SAAS,QAAQ;AACnC,mBAAW,SAAS,MAAM,QAAQ;AAChC,cAAI,MAAM,SAAS,SAAS,UAAW;AACvC,qBAAW,OAAO,MAAM,SAAS,YAAY,CAAC,KAAK,CAAC,GAAG;AACrD,mBAAO,OAAO,GAAG;AACjB,kBAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,IAAK;AACV,uBAAKF,OAAK,UAAU,QAAQ;AAAA,MAC1B,SAAS;AAAA,MACT,OAAO,QAAQ,SAAS;AAAA,MACxB,UAAU,QAAQ,YAAY;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEA,UAAgB;AACd,yBAAqB,mBAAK,YAAW;AACrC,uBAAKA,OAAK,IAAI,UAAU,mBAAK,UAAS;AACtC,uBAAKA,OAAK,IAAI,QAAQ,mBAAK,cAAa;AACxC,eAAW,SAAS,mBAAK,SAAQ,OAAO,GAAG;AACzC,YAAM,QAAQ,QAAQ;AACtB,YAAM,SAAS,QAAQ;AACvB,YAAM,MAAM,SAAS,CAAC,QAAQ;AAC5B,YAAI,eAAqB,YAAM,CAAC,IAAI,SAAkC,QAAQ;AAAA,MAChF,CAAC;AAAA,IACH;AACA,eAAW,SAAS,mBAAK,SAAQ,OAAO,GAAG;AACzC,YAAM,OAAO,QAAQ;AACrB,YAAM,MAAM,SAAS,CAAC,QAAQ;AAC5B,YAAI,eAAqB,YAAM,CAAC,IAAI,SAAkC,QAAQ;AAAA,MAChF,CAAC;AAAA,IACH;AACA,uBAAK,eAAc,QAAQ;AAC3B,QAAI,mBAAKA,OAAK,SAAS,mBAAK,QAAO,EAAE,EAAG,oBAAKA,OAAK,YAAY,mBAAK,QAAO,EAAE;AAC5E,uBAAK,SAAQ,QAAQ;AACrB,uBAAK,eAAc,QAAQ;AAC3B,uBAAK,iBAAgB,QAAQ;AAC7B,uBAAK,YAAW,QAAQ;AACxB,uBAAK,eAAc,QAAQ;AAC3B,uBAAK,WAAU,QAAQ;AAAA,EACzB;AAkHF;AA9dE;AACAD,UAAA;AACAC,QAAA;AACA;AACAC,SAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAIA;AAUA;AAGA;AAUA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AArDK;AA6NL,4BAAuB,WAAS;AAC9B,qBAAK,eAAc;AAAA,IACjB,CAAC,YAAY,mBAAK,SAAQ,IAAI,OAAO,GAAG,MAAM,WAAW;AAAA,EAC3D;AACF;AAAA;AA+IA,iBAAY,SAAC,UAA4C;AACvD,MAAI,QAAQ,mBAAK,SAAQ,IAAI,SAAS,EAAE;AACxC,MAAI,MAAO,QAAO;AAClB,QAAM,SAAS,SAAS,OAAO,CAAC;AAChC,QAAM,YAAY,QAAQ,OAAO;AAAA,IAC/B,CAAC,OAAO,EAAE,YAAY,eAAe,EAAE,KAAK,YAAY,MAAM,WAAW,EAAE,SAAS,SAAS;AAAA,EAC/F;AACA,QAAM,OAAO,WAAW,SAAS,SAAS,YAAY,UAAU,SAAS,YAAY,CAAC,IAAI;AAC1F,MAAI,CAAC,QAAQ,KAAK,SAAS,EAAG,QAAO;AACrC,QAAM,UAAU,aAAa,mBAAKF,UAAQ,IAAI;AAC9C,QAAM,SAAS,SAAS,OAAO,SAAS,iBAAiB;AAEzD,QAAM,QAAQ,IAAU,aAAM;AAC9B,QAAM,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE;AAMhD,kBAAgB,KAAK,SAAS,GAAG,MAAM;AACvC,QAAM,QAAQ,IAAU,sBAAe;AACvC,QAAM,aAAa,YAAY,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACtF,QAAM,aAAa,UAAU,IAAU,uBAAgB,IAAI,aAAa,IAAI,GAAG,GAAG,CAAC,CAAC;AACpF,QAAM,SAAS,IAAI,GAAG;AACtB,QAAM,IAAI,IAAU,YAAK,OAAO,mBAAK,cAAa,CAAC;AAEnD,QAAM,YAAY,IAAU;AAAA,IAC1B,mBAAmB,OAAO,SAAS,EAAE,IAAI,mBAAmB,MAAM;AAAA,EACpE;AACA,QAAM,QAAQ,IAAU,aAAM,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAU,eAAQ,GAAG,CAAC,CAAC,CAAC;AAC9E,QAAM,OAAO,IAAU,qBAAc,KAAK;AAC1C,QAAM,QAAQ,KAAK,WAAW,UAAU,SAAS;AACjD,QAAM,SAAS,IAAI,aAAa,QAAQ,CAAC;AACzC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,WAAO,IAAI,CAAC,IAAI,UAAU;AAC1B,WAAO,IAAI,IAAI,CAAC,IAAI,UAAU;AAC9B,WAAO,IAAI,IAAI,CAAC,IAAI,UAAU;AAAA,EAChC;AACA,OAAK,aAAa,SAAS,IAAU,uBAAgB,QAAQ,CAAC,CAAC;AAC/D,OAAK,UAAU,GAAG,GAAG,MAAM;AAC3B,QAAM,IAAI,IAAU,YAAK,MAAM,mBAAK,QAAO,CAAC;AAE5C,QAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,OAAO;AACxC,QAAM,QAAQ;AAAA,IACZ;AAAA,MACE,MAAM,SAAS;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG,SAAS;AAAA,MACZ,UAAU;AAAA,MACV,cAAc,kBAAkB,OAAO;AAAA;AAAA,MACvC,OAAO,mBAAK,QAAO;AAAA,IACrB;AAAA,IACA,MAAM;AACJ,yBAAK,QAAO,QAAQ;AAAA,IACtB;AAAA,EACF;AACA,QAAM,QAAQ,mBAAK,eAAc;AACjC,QAAM,IAAI,MAAM,MAAM;AAEtB,QAAM,UAAU;AAChB,qBAAKE,QAAM,IAAI,KAAK;AACpB,UAAQ,EAAE,OAAO,MAAM;AACvB,qBAAK,SAAQ,IAAI,SAAS,IAAI,KAAK;AACnC,SAAO;AACT;AAEA,iBAAY,SAAC,SAAyC;AACpD,MAAI,QAAQ,mBAAK,SAAQ,IAAI,OAAO;AACpC,MAAI,OAAO,MAAO,QAAO;AACzB,QAAM,QAAQ,mBAAK,QAAO,SAAS,OAAO;AAC1C,MAAI,CAAC,MAAO,QAAO;AACnB,UAAQ,EAAE,OAAO,IAAU,aAAM,GAAG,QAAQ,MAAM,SAAS,MAAM,OAAO,MAAM;AAC9E,wBAAK,yCAAL,WAAiB,OAAO;AACxB,QAAM,QAAQ;AACd,QAAM,MAAM,MAAM,IAAI,mBAAK;AAC3B,qBAAK,SAAQ,IAAI,SAAS,KAAK;AAC/B,qBAAKA,QAAM,IAAI,MAAM,KAAK;AAC1B,SAAO;AACT;AAEA,gBAAW,SAAC,OAAmB,OAAoB;AACjD,QAAM,MAAM,mBAAmB,mBAAKF,UAAQ,OAAO,mBAAK,OAAM;AAC9D,MAAI,IAAI,MAAO,OAAM,MAAM,IAAI,IAAU,YAAK,IAAI,OAAO,mBAAK,QAAO,CAAC;AACtE,MAAI,IAAI,YAAa,OAAM,MAAM,IAAI,IAAU,YAAK,IAAI,aAAa,mBAAK,gBAAe,CAAC;AAE1F,MAAI,IAAI,WAAW,QAAQ;AACzB,UAAM,SAAS,kBAAkB,IAAI,YAAY,mBAAK,QAAO,YAAY,MAAM;AAC7E,yBAAK,QAAO,QAAQ;AAAA,IACtB,CAAC;AACD,UAAM,OAAO,QAAQ,mBAAK,eAAc;AACxC,UAAM,MAAM,IAAI,MAAM,OAAO,MAAM;AAAA,EACrC;AAEA,QAAM,UAAU,qBAAqB,mBAAKA,UAAQ,OAAO,mBAAK,QAAO,SAAS,MAAM;AAClF,uBAAK,QAAO,QAAQ;AAAA,EACtB,CAAC;AACD,MAAI,MAAM,SAAS;AACjB,UAAM,QAAQ,QAAQ,mBAAK,eAAc;AACzC,UAAM,QAAQ,cAAc,mBAAKC,OAAK,WAAW,GAAG,mBAAKA,OAAK,SAAS,CAAC;AACxE,UAAM,MAAM,IAAI,MAAM,QAAQ,MAAM;AAAA,EACtC;AAEA,OAAK,gBAAgB,mBAAKD,UAAQ,mBAAK,SAAQ,MAAM,EAAE,EAAE,KAAK,CAAC,WAAW;AACxE,QAAI,QAAQ;AACV,aAAO,UAAU;AACjB,YAAM,MAAM,IAAI,MAAM;AACtB,yBAAK,QAAO,QAAQ;AAAA,IACtB;AAAA,EACF,CAAC;AACH;;;ASxgBK,IAAM,YAAY;AAElB,IAAM,aAAa;AAL1B,IAAAI,SAAA;AAsBO,IAAM,eAAN,MAAmB;AAAA,EAUxB,YAAY,OAAc,UAAqD,CAAC,GAAG;AAV9E;AACL,uBAAAA;AACA;AACA;AACA,8BAAQ;AACR,kCAAY,oBAAI,IAAoB;AACpC;AAAA,oCAAc,oBAAI,IAAY;AAC9B,2CAAoC;AACpC,mCAAa,oBAAI,IAA0B;AAGzC,uBAAKA,SAAS;AACd,uBAAK,WAAY,QAAQ,YAAY;AACrC,uBAAK,YAAa,QAAQ,aAAa;AACvC,eAAW,KAAK,MAAM,WAAW;AAC/B,YAAM,SAAS,EAAE,OAAO,CAAC;AACzB,UAAI,OAAQ,oBAAK,WAAU,IAAI,EAAE,IAAI,OAAO,EAAE;AAAA,IAChD;AACA,uBAAK,oBAAqB,MAAM,UAAU,CAAC,GAAG,MAAM;AAAA,EACtD;AAAA,EAEA,oBAAmC;AACjC,WAAO,mBAAK;AAAA,EACd;AAAA,EAEA,cAAc,YAA0B;AACtC,QAAI,mBAAKA,SAAO,YAAY,UAAU,EAAG,oBAAK,oBAAqB;AAAA,EACrE;AAAA,EAEA,OAAO,YAA8C;AACnD,WAAO,sBAAK,yCAAL,WAAkB;AAAA,EAC3B;AAAA,EAEA,QAAmC;AACjC,UAAM,MAAM,oBAAI,IAA0B;AAC1C,eAAW,KAAK,mBAAKA,SAAO,WAAW;AACrC,YAAM,IAAI,sBAAK,yCAAL,WAAkB,EAAE;AAC9B,UAAI,EAAG,KAAI,IAAI,EAAE,IAAI,CAAC;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAO,MAA4B;AACjC,uBAAK,OAAQ;AACb,WAAO,sBAAK,kCAAL;AAAA,EACT;AAAA;AAAA,EAGA,UAAU,MAA4B;AACpC,uBAAK,OAAQ;AACb,QAAI,OAAO,mBAAK,eAAc,mBAAK,aAAY,OAAO,EAAG,oBAAK,aAAY,MAAM;AAChF,WAAO,sBAAK,kCAAL;AAAA,EACT;AAAA;AAAA,EAGA,UAAU,YAAkC;AAC1C,QAAI,CAAC,mBAAKA,SAAO,YAAY,UAAU,EAAG,QAAO,CAAC;AAClD,uBAAK,aAAY,IAAI,UAAU;AAC/B,uBAAK,oBAAqB;AAC1B,WAAO,sBAAK,kCAAL;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,SAA+B;AACzC,UAAM,QAAQ,mBAAKA,SAAO,SAAS,OAAO;AAC1C,QAAI,CAAC,MAAO,QAAO,CAAC;AACpB,uBAAK,WAAU,IAAI,MAAM,YAAY,OAAO;AAC5C,uBAAK,oBAAqB,MAAM;AAChC,UAAM,OAAO,sBAAK,yCAAL,WAAkB,MAAM;AACrC,QAAI,QAAQ,CAAC,KAAK,KAAM,oBAAK,aAAY,IAAI,MAAM,UAAU;AAC7D,WAAO,sBAAK,kCAAL;AAAA,EACT;AAyBF;AAnGEA,UAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARK;AA6EL,YAAO,SAAC,YAA6B;AACnC,SAAO,mBAAK,UAAS,mBAAK,cAAa,mBAAK,aAAY,IAAI,UAAU;AACxE;AAEA,iBAAY,SAAC,YAA8C;AACzD,QAAM,UAAU,mBAAK,WAAU,IAAI,UAAU;AAC7C,MAAI,YAAY,OAAW,QAAO;AAClC,SAAO,EAAE,MAAM,sBAAK,oCAAL,WAAa,aAAa,QAAQ;AACnD;AAEA,UAAK,WAAiB;AACpB,QAAM,UAAwB,CAAC;AAC/B,aAAW,KAAK,mBAAKA,SAAO,WAAW;AACrC,UAAM,OAAO,sBAAK,yCAAL,WAAkB,EAAE;AACjC,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,mBAAK,YAAW,IAAI,EAAE,EAAE;AACrC,QAAI,CAAC,QAAQ,KAAK,SAAS,KAAK,QAAQ,KAAK,YAAY,KAAK,SAAS;AACrE,cAAQ,KAAK,EAAE,YAAY,EAAE,IAAI,MAAM,KAAK,CAAC;AAC7C,yBAAK,YAAW,IAAI,EAAE,IAAI,IAAI;AAAA,IAChC;AAAA,EACF;AACA,SAAO;AACT;;;AC1GK,SAAS,oBACd,WACA,UACe;AACf,QAAM,KAAK,SAAS,cAAc,KAAK;AACvC,KAAG,MAAM,UACP;AAGF,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,MAAM,UAAU;AACrB,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,MAAM,UAAU;AACxB,KAAG,OAAO,MAAM,OAAO;AACvB,YAAU,YAAY,EAAE;AAExB,SAAO;AAAA,IACL,OAAO,UAAU,MAAY;AAC3B,UAAI,CAAC,UAAU;AACb,WAAG,MAAM,UAAU;AACnB;AAAA,MACF;AACA,SAAG,MAAM,UAAU;AACnB,WAAK,cAAc,SAAS;AAC5B,cAAQ,gBAAgB;AACxB,iBAAW,SAAS,SAAS,QAAQ;AACnC,cAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,YAAI,cAAc,MAAM;AACxB,cAAM,SAAS,MAAM,SAAS,QAAQ,KAAK,YAAY,MAAM;AAC7D,YAAI,MAAM,UACR,oIAEC,SAAS,uDAAuD;AACnE,YAAI,UAAU,MAAM;AAClB,mBAAS,MAAM,EAAE;AAAA,QACnB;AACA,gBAAQ,YAAY,GAAG;AAAA,MACzB;AAAA,IACF;AAAA,IACA,UAAgB;AACd,SAAG,OAAO;AAAA,IACZ;AAAA,EACF;AACF;;;AClCO,SAAS,aACd,OACA,QACA,KACA,KACa;AACb,aAAW,YAAY,MAAM,WAAW;AACtC,UAAM,OAAO,OAAO,SAAS,EAAE;AAC/B,QAAI,CAAC,KAAM;AACX,UAAM,YAAY,SAAS,OAAO,CAAC,GAAG,OAAO;AAAA,MAC3C,CAAC,OAAO,EAAE,YAAY,eAAe,EAAE,KAAK,YAAY,MAAM,WAAW,EAAE,SAAS,SAAS;AAAA,IAC/F;AACA,UAAM,OAAO,WAAW,SAAS,SAAS,YAAY,UAAU,SAAS,YAAY,CAAC,IAAI;AAC1F,QAAI,CAAC,QAAQ,CAAC,YAAY,MAAM,KAAK,GAAG,EAAG;AAE3C,QAAI,CAAC,KAAK,KAAM,QAAO,EAAE,MAAM,UAAU,YAAY,SAAS,IAAI,KAAK;AAEvE,UAAM,QAAQ,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO;AAC/D,QAAI,OAAO;AACT,YAAM,oBAAoB,oBAAI,IAA2B;AACzD,iBAAW,OAAO,MAAM,WAAW;AACjC,YAAI,IAAI,QAAS,mBAAkB,IAAI,IAAI,SAAS,GAAG;AAAA,MACzD;AACA,iBAAW,SAAS,MAAM,QAAQ;AAChC,YAAI,MAAM,YAAY,eAAe,MAAM,SAAS,SAAS,UAAW;AACxE,cAAM,YAAY,MAAM,SAAS,YAAY,CAAC;AAC9C,YAAI,CAAC,aAAa,CAAC,YAAY,WAAW,KAAK,GAAG,EAAG;AACrD,cAAM,WAAW,kBAAkB,IAAI,MAAM,EAAE;AAC/C,YAAI,YAAY,CAAC,SAAS,QAAQ;AAChC,iBAAO,EAAE,MAAM,SAAS,YAAY,SAAS,IAAI,SAAS,MAAM,IAAI,UAAU,MAAM;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,MAAM,YAAY,YAAY,SAAS,GAAG;AAAA,EACrD;AACA,SAAO,EAAE,MAAM,UAAU;AAC3B;;;AC5CO,SAAS,SAAS,MAAwB;AAC/C,SAAO,KACJ,YAAY,EACZ,UAAU,KAAK,EACf,QAAQ,UAAU,EAAE,EACpB,MAAM,YAAY,EAClB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC/B;AAvBA;AA+BO,IAAM,eAAN,MAAM,aAAY;AAAA,EAIvB,YAAY,OAAc;AAF1B,iCAAyB,CAAC;AAGxB,eAAW,YAAY,MAAM,WAAW;AACtC,UAAI,SAAS,OAAQ;AACrB,yBAAK,UAAS,KAAK;AAAA,QACjB;AAAA,QACA,YAAY,SAAS,SAAS,IAAI;AAAA,QAClC,gBAAgB,SAAS,WAAW,QAAQ,CAAC,MAAM,SAAS,EAAE,IAAI,CAAC;AAAA,MACrE,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,mBAAK,UAAS;AAAA,EACvB;AAAA,EAEA,MAAM,MAAM,MAAuC;AACjD,UAAM,cAAc,SAAS,IAAI;AACjC,QAAI,YAAY,WAAW,EAAG,QAAO,CAAC;AACtC,UAAM,UAA0B,CAAC;AACjC,aAAS,IAAI,GAAG,IAAI,mBAAK,UAAS,QAAQ,KAAK;AAC7C,UAAI,IAAI,KAAK,IAAI,aAAY,UAAU,GAAG;AACxC,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,MACvD;AACA,YAAM,QAAQ,mBAAK,UAAS,CAAC;AAC7B,UAAI,CAAC,MAAO;AACZ,YAAM,QAAQ,WAAW,OAAO,WAAW;AAC3C,UAAI,QAAQ,EAAG,SAAQ,KAAK,EAAE,UAAU,MAAM,UAAU,MAAM,CAAC;AAAA,IACjE;AACA,YAAQ;AAAA,MACN,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,YAAY,EAAE,SAAS;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,YAAqC;AAC9C,WAAO,mBAAK,UACT,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC,EACpE,IAAI,CAAC,MAAM,EAAE,QAAQ,EACrB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,EAC7C;AACF;AA1CE;AAFW,aACJ,QAAQ;AADV,IAAM,cAAN;AA8CP,SAAS,WAAW,OAAmB,aAA+B;AACpE,MAAI,QAAQ;AACZ,QAAM,aAAa,CAAC,GAAG,MAAM,YAAY,GAAG,MAAM,cAAc;AAChE,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,KAAK,aAAa;AAC3B,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,UAAI,KAAK,IAAI,CAAC,EAAG;AACjB,YAAM,IAAI,WAAW,CAAC;AACtB,UAAI,MAAM,UAAa,EAAE,WAAW,CAAC,GAAG;AACtC,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,YAAY,GAAI,QAAO;AAC3B,SAAK,IAAI,OAAO;AAChB,aAAS,KAAK,WAAW,OAAO,MAAM,IAAI,MAAM;AAAA,EAClD;AACA,SAAO;AACT;;;AC1EO,SAAS,SACd,OACA,QACA,MACA,gBACoB;AACpB,QAAM,QAAQ,MAAM,MAAM;AAC1B,QAAM,OAAO,MAAM,IAAI;AACvB,MAAI,CAAC,SAAS,CAAC,KAAM,QAAO;AAE5B,QAAM,IAAI;AACV,QAAM,QAAQ,KAAK,KAAK;AACxB,QAAM,YAAY,CAAC,GAAiC,MAA4C;AAC9F,UAAM,QAAQ,EAAE,MAAM,EAAE,OAAO;AAC/B,UAAM,QAAQ,EAAE,MAAM,EAAE,OAAO;AAC/B,UAAM,IACJ,KAAK,IAAI,OAAO,CAAC,KAAK,IACtB,KAAK,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK;AAC5E,WAAO,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,CAAC,CAAC;AAAA,EACvC;AAGA,QAAM,UAAoB,CAAC;AAC3B,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAO,CAAC,IAAY,MAAoB;AAC5C,YAAQ,KAAK,EAAE;AACf,UAAM,KAAK,CAAC;AACZ,QAAI,IAAI,QAAQ,SAAS;AACzB,WAAO,IAAI,GAAG;AACZ,YAAM,IAAK,IAAI,KAAM;AACrB,YAAM,KAAK,MAAM,CAAC;AAClB,YAAM,KAAK,MAAM,CAAC;AAClB,UAAI,OAAO,UAAa,OAAO,UAAa,MAAM,GAAI;AACtD,OAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;AAC9B,YAAM,MAAM,QAAQ,CAAC;AACrB,YAAM,MAAM,QAAQ,CAAC;AACrB,UAAI,QAAQ,UAAa,QAAQ,QAAW;AAC1C,gBAAQ,CAAC,IAAI;AACb,gBAAQ,CAAC,IAAI;AAAA,MACf;AACA,UAAI;AAAA,IACN;AAAA,EACF;AACA,QAAM,MAAM,MAA0B;AACpC,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,UAAM,MAAM,QAAQ,CAAC;AACrB,UAAM,SAAS,QAAQ,IAAI;AAC3B,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,QAAQ,SAAS,KAAK,WAAW,UAAa,UAAU,QAAW;AACrE,cAAQ,CAAC,IAAI;AACb,YAAM,CAAC,IAAI;AACX,UAAI,IAAI;AACR,iBAAS;AACP,cAAM,IAAI,IAAI,IAAI;AAClB,cAAM,IAAI,IAAI;AACd,YAAI,WAAW;AACf,cAAM,KAAK,MAAM,CAAC,KAAK;AACvB,cAAM,KAAK,MAAM,CAAC,KAAK;AACvB,cAAM,KAAK,MAAM,CAAC,KAAK;AACvB,YAAI,IAAI,MAAM,UAAU,KAAK,GAAI,YAAW;AAC5C,YAAI,IAAI,MAAM,UAAU,MAAM,MAAM,QAAQ,KAAK,UAAW,YAAW;AACvE,YAAI,aAAa,EAAG;AACpB,cAAM,KAAK,QAAQ,QAAQ;AAC3B,cAAM,KAAK,QAAQ,CAAC;AACpB,cAAM,KAAK,MAAM,QAAQ;AACzB,cAAM,MAAM,MAAM,CAAC;AACnB,YAAI,OAAO,UAAa,OAAO,UAAa,OAAO,UAAa,QAAQ,OAAW;AACnF,gBAAQ,CAAC,IAAI;AACb,gBAAQ,QAAQ,IAAI;AACpB,cAAM,CAAC,IAAI;AACX,cAAM,QAAQ,IAAI;AAClB,YAAI;AAAA,MACN;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,oBAAI,IAAoB;AACvC,QAAM,WAAW,oBAAI,IAAoB;AACzC,QAAM,SAAS,oBAAI,IAAY;AAC/B,SAAO,IAAI,QAAQ,CAAC;AACpB,OAAK,QAAQ,UAAU,OAAO,IAAI,CAAC;AAEnC,aAAS;AACP,UAAM,UAAU,IAAI;AACpB,QAAI,YAAY,OAAW,QAAO;AAClC,QAAI,YAAY,KAAM;AACtB,QAAI,OAAO,IAAI,OAAO,EAAG;AACzB,WAAO,IAAI,OAAO;AAClB,UAAM,OAAO,MAAM,OAAO;AAC1B,QAAI,CAAC,KAAM;AACX,UAAM,IAAI,OAAO,IAAI,OAAO,KAAK;AACjC,eAAW,QAAQ,KAAK,OAAO;AAC7B,UAAI,kBAAkB,CAAC,KAAK,WAAY;AACxC,YAAM,WAAW,MAAM,KAAK,EAAE;AAC9B,UAAI,CAAC,YAAY,OAAO,IAAI,KAAK,EAAE,EAAG;AACtC,YAAM,YAAY,IAAI,KAAK;AAC3B,UAAI,aAAa,OAAO,IAAI,KAAK,EAAE,KAAK,WAAW;AACjD,eAAO,IAAI,KAAK,IAAI,SAAS;AAC7B,iBAAS,IAAI,KAAK,IAAI,OAAO;AAC7B,aAAK,KAAK,IAAI,YAAY,UAAU,UAAU,IAAI,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAiB,CAAC,IAAI;AAC5B,MAAI,SAAS;AACb,SAAO,WAAW,QAAQ;AACxB,UAAM,OAAO,SAAS,IAAI,MAAM;AAChC,QAAI,SAAS,OAAW,QAAO;AAC/B,SAAK,KAAK,IAAI;AACd,aAAS;AAAA,EACX;AACA,OAAK,QAAQ;AACb,SAAO,EAAE,MAAM,MAAM,OAAO,IAAI,IAAI,KAAK,EAAE;AAC7C;;;ACzIA;AAUO,IAAM,gBAAN,MAAM,cAAa;AAAA,EAQxB,YAAY,OAAc;AAP1B;AACA,gCAAyB;AACzB,iCAAW,oBAAI,IAAkD;AACjE,gCAAU;AACV,+BAAS,oBAAI,IAAgC;AAI3C,uBAAK,QAAS,eAAe,KAAK;AAClC,QAAI,OAAO,WAAW,eAAe,OAAO,IAAI,oBAAoB,YAAY;AAC9E,UAAI;AACF,cAAM,SACJ,oBAAoB,SAAS,SAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQzC,cAAM,MAAM,IAAI,gBAAgB,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,kBAAkB,CAAC,CAAC;AAC/E,2BAAK,SAAU,IAAI,OAAO,GAAG;AAC7B,YAAI,gBAAgB,GAAG;AACvB,2BAAK,SAAQ,YAAY,CAAC,MAAgE;AACxF,gBAAM,UAAU,mBAAK,UAAS,IAAI,EAAE,KAAK,EAAE;AAC3C,cAAI,SAAS;AACX,+BAAK,UAAS,OAAO,EAAE,KAAK,EAAE;AAC9B,oBAAQ,EAAE,KAAK,MAAM;AAAA,UACvB;AAAA,QACF;AACA,2BAAK,SAAQ,YAAY,EAAE,MAAM,QAAQ,OAAO,mBAAK,QAAO,CAAC;AAAA,MAC/D,QAAQ;AACN,2BAAK,SAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAI,cAAuB;AACzB,WAAO,mBAAK,aAAY;AAAA,EAC1B;AAAA,EAEA,MAAM,SACJ,YACA,UACA,UAAwC,CAAC,GACZ;AAC7B,UAAM,iBAAiB,QAAQ,kBAAkB;AACjD,UAAM,MAAM,GAAG,UAAU,IAAI,QAAQ,IAAI,OAAO,cAAc,CAAC;AAC/D,UAAM,SAAS,mBAAK,QAAO,IAAI,GAAG;AAClC,QAAI,WAAW,QAAW;AAExB,yBAAK,QAAO,OAAO,GAAG;AACtB,yBAAK,QAAO,IAAI,KAAK,MAAM;AAC3B,aAAO;AAAA,IACT;AACA,UAAM,SAAS,mBAAK,WAChB,MAAM,IAAI,QAA4B,CAAC,YAAY;AACjD,YAAM,KAAK,uBAAK,SAAL;AACX,yBAAK,UAAS,IAAI,IAAI,OAAO;AAC7B,yBAAK,UAAS,YAAY,EAAE,IAAI,MAAM,YAAY,IAAI,UAAU,eAAe,CAAC;AAAA,IAClF,CAAC,IACD,SAAS,mBAAK,SAAQ,YAAY,UAAU,cAAc;AAC9D,QAAI,mBAAK,QAAO,QAAQ,cAAa,WAAW;AAC9C,YAAM,SAAS,mBAAK,QAAO,KAAK,EAAE,KAAK,EAAE;AACzC,UAAI,WAAW,OAAW,oBAAK,QAAO,OAAO,MAAM;AAAA,IACrD;AACA,uBAAK,QAAO,IAAI,KAAK,MAAM;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,uBAAK,UAAS,UAAU;AACxB,uBAAK,SAAU;AACf,uBAAK,UAAS,MAAM;AACpB,uBAAK,QAAO,MAAM;AAAA,EACpB;AACF;AA5EE;AACA;AACA;AACA;AACA;AALW,cAMJ,YAAY;AANd,IAAM,eAAN;AA+EP,SAAS,eAAe,OAA+B;AACrD,QAAM,QAAyB,CAAC;AAChC,aAAW,QAAQ,MAAM,OAAO;AAC9B,UAAM,KAAK,EAAE,IAAI;AAAA,MACf,KAAK,KAAK;AAAA,MACV,KAAK,KAAK;AAAA,MACV,OAAO,KAAK,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,MAAM,EAAE,MAAM,YAAY,EAAE,WAAW,EAAE;AAAA,IAC3F;AAAA,EACF;AACA,SAAO;AACT;;;ACrFO,SAAS,gBAAgB,MAAc,MAAc,MAAc,MAAsB;AAC9F,QAAM,IAAI;AACV,QAAM,QAAQ,KAAK,KAAK;AACxB,QAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAM,IACJ,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK;AACpG,SAAO,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,CAAC,CAAC;AACvC;AAtBA;AA4BO,IAAM,QAAN,MAAY;AAAA,EAkBjB,YAAY,MAYT;AApBH,uBAAS,gBAAiB,oBAAI,IAAsB;AACpD,uBAAS,aAAc,oBAAI,IAAmB;AAC9C,uBAAS,gBAAiB,oBAAI,IAA2B;AACzD,uBAAS,aAAc,oBAAI,IAAmB;AAC9C,uBAAS,YAAa,oBAAI,IAAuB;AACjD,uBAAS,iBAAkB,oBAAI,IAAsB;AACrD,mCAAa;AAeX,SAAK,KAAK,KAAK;AACf,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS,KAAK;AACnB,SAAK,YAAY,KAAK;AACtB,SAAK,aAAa,KAAK;AACvB,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,KAAK,WAAW,CAAC;AAChC,uBAAK,YAAa,KAAK;AACvB,eAAW,KAAK,KAAK,WAAW;AAC9B,yBAAK,gBAAe,IAAI,EAAE,IAAI,CAAC;AAC/B,iBAAW,KAAK,EAAE,OAAQ,oBAAK,aAAY,IAAI,EAAE,IAAI,CAAC;AAAA,IACxD;AACA,eAAW,KAAK,KAAK,WAAY,oBAAK,iBAAgB,IAAI,EAAE,IAAI,CAAC;AACjE,eAAW,KAAK,KAAK,MAAO,oBAAK,YAAW,IAAI,EAAE,IAAI,CAAC;AACvD,eAAW,KAAK,KAAK,OAAQ,oBAAK,aAAY,IAAI,EAAE,IAAI,CAAC;AACzD,eAAW,KAAK,KAAK,UAAW,oBAAK,gBAAe,IAAI,EAAE,IAAI,CAAC;AAAA,EACjE;AAAA,EAEA,YAAY,IAAkC;AAC5C,WAAO,mBAAK,gBAAe,IAAI,EAAE;AAAA,EACnC;AAAA,EACA,SAAS,IAA+B;AACtC,WAAO,mBAAK,aAAY,IAAI,EAAE;AAAA,EAChC;AAAA,EACA,YAAY,IAAuC;AACjD,WAAO,mBAAK,gBAAe,IAAI,EAAE;AAAA,EACnC;AAAA,EACA,SAAS,IAA+B;AACtC,WAAO,mBAAK,aAAY,IAAI,EAAE;AAAA,EAChC;AAAA,EACA,QAAQ,IAAmC;AACzC,WAAO,mBAAK,YAAW,IAAI,EAAE;AAAA,EAC/B;AAAA,EACA,YAAY,IAAkC;AAC5C,WAAO,mBAAK,iBAAgB,IAAI,EAAE;AAAA,EACpC;AAAA,EAEA,IAAI,YAA6C;AAC/C,WAAO,mBAAK,gBAAe,OAAO;AAAA,EACpC;AAAA,EACA,IAAI,QAAqC;AACvC,WAAO,mBAAK,YAAW,OAAO;AAAA,EAChC;AAAA,EAEA,QAAoB;AAClB,WAAO;AAAA,MACL,WAAW,KAAK,UAAU;AAAA,MAC1B,QAAQ,mBAAK,aAAY;AAAA,MACzB,WAAW,mBAAK,gBAAe;AAAA,MAC/B,QAAQ,mBAAK,aAAY;AAAA,MACzB,OAAO,mBAAK,YAAW;AAAA,MACvB,OAAO,mBAAK;AAAA,MACZ,YAAY,mBAAK,iBAAgB;AAAA,MACjC,YAAY,KAAK,WAAW;AAAA,IAC9B;AAAA,EACF;AACF;AA7EW;AACA;AACA;AACA;AACA;AACA;AACT;AA+EK,SAAS,WAAW,MAAwB;AAEjD,QAAM,QAAQ,oBAAI,IAAuB;AACzC,aAAW,MAAM,KAAK,OAAO;AAC3B,UAAM,IAAI,GAAG,IAAI;AAAA,MACf,IAAI,GAAG;AAAA,MACP,KAAK,GAAG;AAAA,MACR,KAAK,GAAG;AAAA,MACR,SAAS,GAAG;AAAA,MACZ,YAAY,GAAG;AAAA,MACf,aAAa,GAAG;AAAA,MAChB,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH;AACA,MAAI,YAAY;AAChB,QAAM,UAAU,CACd,MACA,IACA,MACA,YACA,SACS;AACT,QAAI,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,EAAE,EAAG;AAClD,SAAK,MAAM;AAAA,MACT,OACI,EAAE,UAAU,GAAG,IAAI,MAAM,YAAY,gBAAgB,KAAK,IAC1D,EAAE,UAAU,GAAG,IAAI,MAAM,WAAW;AAAA,IAC1C;AACA;AAAA,EACF;AAGA,aAAW,MAAM,KAAK,OAAO;AAC3B,UAAM,OAAO,MAAM,IAAI,GAAG,EAAE;AAC5B,QAAI,CAAC,KAAM;AACX,eAAW,OAAO,GAAG,UAAU;AAC7B,YAAM,KAAK,MAAM,IAAI,GAAG;AACxB,UAAI,CAAC,GAAI;AACT,cAAQ,MAAM,IAAI,gBAAgB,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI;AAAA,IAC7E;AAAA,EACF;AAEA,aAAW,MAAM,KAAK,kBAAkB;AACtC,UAAM,QAAQ,MAAM,IAAI,GAAG,WAAW;AACtC,UAAM,MAAM,MAAM,IAAI,GAAG,SAAS;AAClC,QAAI,CAAC,SAAS,CAAC,IAAK;AACpB,UAAM,QAAQ,GAAG,SAAS,IAAI,GAAG,SAAS,QAAQ,GAAG,cAAc;AACnE,QAAI,GAAG,cAAc,gBAAgB,GAAG,cAAc,QAAQ;AAC5D,cAAQ,OAAO,KAAK,MAAM,GAAG,YAAY,GAAG,IAAI;AAAA,IAClD;AACA,QAAI,GAAG,cAAc,gBAAgB,GAAG,cAAc,QAAQ;AAC5D,cAAQ,KAAK,OAAO,MAAM,GAAG,YAAY,GAAG,IAAI;AAAA,IAClD;AAAA,EACF;AAGA,QAAM,aAAa,oBAAI,IAAsB;AAC7C,aAAW,MAAM,KAAK,YAAY;AAChC,UAAM,MAAgB,EAAE,IAAI,GAAG,IAAI,MAAM,GAAG,MAAM,WAAW,GAAG,UAAU;AAC1E,QAAI,GAAG,SAAS,OAAW,KAAI,OAAO,GAAG;AACzC,QAAI,GAAG,aAAa,OAAW,KAAI,WAAW,GAAG;AACjD,eAAW,IAAI,GAAG,IAAI,GAAG;AAAA,EAC3B;AAGA,QAAM,SAAS,oBAAI,IAAmB;AACtC,aAAW,MAAM,KAAK,QAAQ;AAC5B,UAAM,QAAe;AAAA,MACnB,IAAI,GAAG;AAAA,MACP,SAAS,GAAG;AAAA,MACZ,SAAS,GAAG;AAAA,MACZ,MAAM,GAAG;AAAA,MACT,UAAU,GAAG;AAAA,IACf;AACA,QAAI,GAAG,MAAO,OAAM,QAAQ,GAAG;AAC/B,WAAO,IAAI,GAAG,IAAI,KAAK;AAAA,EACzB;AAGA,QAAM,YAAY,oBAAI,IAA2B;AACjD,aAAW,MAAM,KAAK,WAAW;AAC/B,UAAM,YAAY,GAAG,SAAS,MAAM,IAAI,GAAG,MAAM,GAAG,UAAU;AAC9D,UAAM,aAAa,GAAG,UAAU,OAAO,IAAI,GAAG,OAAO,GAAG,UAAU;AAClE,UAAM,UAAU,aAAa;AAC7B,UAAM,MAAqB;AAAA,MACzB,IAAI,GAAG;AAAA,MACP,MAAM,GAAG;AAAA,MACT,MAAM,GAAG;AAAA,MACT,YAAY,GAAG,YACZ,IAAI,CAAC,OAAO,WAAW,IAAI,EAAE,CAAC,EAC9B,OAAO,CAAC,MAAqB,MAAM,MAAS;AAAA,MAC/C,QAAQ,GAAG;AAAA,MACX,WAAW,GAAG;AAAA,IAChB;AACA,QAAI,GAAG,gBAAgB,OAAW,KAAI,cAAc,GAAG;AACvD,QAAI,GAAG,WAAW,OAAW,KAAI,SAAS,GAAG;AAC7C,QAAI,GAAG,YAAY,OAAW,KAAI,UAAU,GAAG;AAC/C,QAAI,YAAY,OAAW,KAAI,UAAU;AACzC,QAAI,GAAG,YAAY,OAAW,KAAI,UAAU,GAAG;AAC/C,QAAI,GAAG,YAAY,OAAW,KAAI,UAAU,GAAG;AAC/C,cAAU,IAAI,GAAG,IAAI,GAAG;AAAA,EAC1B;AAKA,QAAM,mBAAmB,oBAAI,IAA2B;AACxD,aAAW,OAAO,UAAU,OAAO,GAAG;AACpC,QAAI,IAAI,OAAQ,kBAAiB,IAAI,IAAI,QAAQ,GAAG;AAAA,EACtD;AACA,aAAW,MAAM,KAAK,kBAAkB;AACtC,eAAW,OAAO,CAAC,GAAG,aAAa,GAAG,SAAS,GAAG;AAChD,YAAM,OAAO,MAAM,IAAI,GAAG;AAC1B,UAAI,CAAC,QAAQ,iBAAiB,IAAI,GAAG,EAAG;AACxC,YAAM,MAAqB;AAAA,QACzB,IAAI,QAAQ,GAAG,EAAE,IAAI,GAAG;AAAA,QACxB,MAAM,GAAG,QAAQ,GAAG;AAAA,QACpB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS,KAAK;AAAA,QACd,SAAS,GAAG;AAAA,QACZ,YAAY,CAAC;AAAA,QACb,QAAQ;AAAA,QACR,WAAW;AAAA,MACb;AACA,gBAAU,IAAI,IAAI,IAAI,GAAG;AACzB,uBAAiB,IAAI,KAAK,GAAG;AAAA,IAC/B;AAAA,EACF;AAGA,QAAM,iBAAiB,oBAAI,IAA6B;AACxD,aAAW,OAAO,UAAU,OAAO,GAAG;AACpC,QAAI,CAAC,IAAI,QAAS;AAClB,UAAM,OAAO,eAAe,IAAI,IAAI,OAAO,KAAK,CAAC;AACjD,SAAK,KAAK,GAAG;AACb,mBAAe,IAAI,IAAI,SAAS,IAAI;AAAA,EACtC;AACA,QAAM,cAAc,oBAAI,IAAqB;AAC7C,aAAW,KAAK,OAAO,OAAO,GAAG;AAC/B,UAAM,OAAO,YAAY,IAAI,EAAE,OAAO,KAAK,CAAC;AAC5C,SAAK,KAAK,CAAC;AACX,gBAAY,IAAI,EAAE,SAAS,IAAI;AAAA,EACjC;AACA,QAAM,aAAa,oBAAI,IAAyB;AAChD,aAAW,KAAK,MAAM,OAAO,GAAG;AAC9B,UAAM,OAAO,WAAW,IAAI,EAAE,OAAO,KAAK,CAAC;AAC3C,SAAK,KAAK,CAAC;AACX,eAAW,IAAI,EAAE,SAAS,IAAI;AAAA,EAChC;AAEA,QAAM,YAAwB,KAAK,UAAU,IAAI,CAAC,QAAQ;AAAA,IACxD,IAAI,GAAG;AAAA,IACP,MAAM,GAAG;AAAA,IACT,QAAQ,CAAC,GAAG,GAAG,MAAM,EAClB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,IAAI,CAAC,QAAQ;AAAA,MACZ,IAAI,GAAG;AAAA,MACP,MAAM,GAAG;AAAA,MACT,OAAO,GAAG;AAAA,MACV,YAAY,GAAG;AAAA,MACf,WAAW,eAAe,IAAI,GAAG,EAAE,KAAK,CAAC;AAAA,MACzC,QAAQ,YAAY,IAAI,GAAG,EAAE,KAAK,CAAC;AAAA,MACnC,OAAO,WAAW,IAAI,GAAG,EAAE,KAAK,CAAC;AAAA,IACnC,EAAE;AAAA,EACN,EAAE;AAEF,QAAM,aAA6B,KAAK,WAAW,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAExE,SAAO,IAAI,MAAM;AAAA,IACf,IAAI,KAAK,KAAK;AAAA,IACd,MAAM,KAAK,KAAK;AAAA,IAChB,QAAQ,KAAK,KAAK;AAAA,IAClB;AAAA,IACA,YAAY,CAAC,GAAG,WAAW,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAAA,IAC7E;AAAA,IACA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAAA,IACzB,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC;AAAA,IAC3B,WAAW,CAAC,GAAG,UAAU,OAAO,CAAC;AAAA,IACjC;AAAA,IACA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,EAClD,CAAC;AACH;;;AC/OA,SAAS,mBAAmB,OAAc,SAAgC;AACxE,SAAO,MAAM,SAAS,OAAO,GAAG,cAAc;AAChD;AAOA,SAAS,WAAW,GAAW,GAAmB;AAChD,QAAM,SAAS,KAAK,KAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAK,KAAK,KAAM,GAAG;AAC7D,SAAQ,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAO,KAAK;AACxE;AAGA,SAAS,aAAa,MAAc,IAAoB;AACtD,UAAS,KAAK,OAAO,OAAO,MAAO;AACrC;AAGA,SAAS,QAAQ,OAA8B;AAC7C,MAAI,SAAS,OAAO,SAAS,GAAI,QAAO;AACxC,MAAI,QAAQ,IAAK,QAAO;AACxB,MAAI,QAAQ,GAAI,QAAO;AACvB,MAAI,QAAQ,GAAI,QAAO;AACvB,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,QAAQ,IAAK,QAAO;AACxB,SAAO;AACT;AAGA,IAAM,eAAe;AAOrB,IAAM,YAAY;AAGlB,IAAM,SAAS;AAEf,IAAM,cAAsC;AAAA,EAC1C,aAAa;AAAA,EACb,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,WAAW;AACb;AAEA,SAAS,aAAa,GAAmB;AACvC,SAAO,GAAG,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9C;AAMO,SAAS,WACd,OACA,MACA,OACmB;AACnB,QAAM,QAAQ,KACX,IAAI,CAAC,OAAO,MAAM,QAAQ,EAAE,CAAC,EAC7B,OAAO,CAAC,MAAkC,MAAM,MAAS;AAC5D,MAAI,MAAM,SAAS,EAAG,QAAO;AAG7B,QAAM,WAA2B,CAAC;AAClC,MAAI,UAA+B;AACnC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,CAAC,KAAM;AACX,QAAI,CAAC,WAAW,QAAQ,YAAY,KAAK,SAAS;AAEhD,UAAI,WAAW,IAAI,GAAG;AACpB,cAAM,OAAO,MAAM,IAAI,CAAC;AACxB,cAAM,OAAO,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,aAAa,KAAK,EAAE;AAC3D,YAAI,MAAM,eAAgB,SAAQ,WAAW,KAAK;AAAA,MACpD;AACA,gBAAU;AAAA,QACR,SAAS,KAAK;AAAA,QACd,YAAY,mBAAmB,OAAO,KAAK,OAAO;AAAA,QAClD,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC;AAAA,MACZ;AACA,eAAS,KAAK,OAAO;AAAA,IACvB;AACA,YAAQ,OAAO,KAAK,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AACxC,YAAQ,QAAQ,KAAK,KAAK,EAAE;AAAA,EAC9B;AAIA,QAAM,iBAAiB,oBAAI,IAAoB;AAC/C,aAAW,OAAO,MAAM,WAAW;AACjC,QAAI,CAAC,IAAI,UAAU,IAAI,WAAW,IAAI,UAAU,CAAC,IAAI,KAAM;AAC3D,QAAI,CAAC,eAAe,IAAI,IAAI,MAAM,EAAG,gBAAe,IAAI,IAAI,QAAQ,IAAI,IAAI;AAAA,EAC9E;AAgBA,QAAM,MAAmB,CAAC;AAC1B,MAAI,MAAM;AAEV,WAAS,QAAQ,CAAC,SAAS,iBAAiB;AAC1C,aAAS,IAAI,GAAG,IAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9C,YAAM,IAAI,QAAQ,OAAO,CAAC;AAC1B,UAAI,CAAC,EAAG;AACR,UAAI,IAAI,GAAG;AACT,cAAM,OAAO,QAAQ,OAAO,IAAI,CAAC;AACjC,YAAI,KAAM,QAAO,gBAAgB,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAAA,MAC/D;AACA,YAAM,gBAAgB,MAAM,KAAK,MAAM,QAAQ,OAAO,SAAS;AAC/D,UAAI,YAA2B;AAC/B,UAAI,SAAS;AACb,UAAI,CAAC,eAAe;AAClB,cAAM,OAAO,QAAQ,OAAO,IAAI,CAAC;AACjC,cAAM,OAAO,QAAQ,OAAO,IAAI,CAAC;AACjC,YAAI,QAAQ,MAAM;AAChB,gBAAM,QAAQ,aAAa,WAAW,MAAM,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC;AACnE,cAAI,KAAK,IAAI,KAAK,IAAI,cAAc;AAClC,wBAAY,QAAQ,KAAK;AACzB,qBAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK;AAAA,QACP,KAAK,EAAE,CAAC;AAAA,QACR,KAAK,EAAE,CAAC;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,YAAY,QAAQ;AAAA,QACpB;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,QAAQ,CAAC,KAAK;AAAA,QAC9B;AAAA,QACA,QAAQ,iBAAiB;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAID,QAAM,UAAoB,CAAC;AAC3B,MAAI,QAAQ,CAAC,IAAI,MAAM;AACrB,QAAI,GAAG,OAAQ,SAAQ,KAAK,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,SAAsB,CAAC;AAC7B,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,IAAI,CAAC;AAC1B,UAAM,KAAK,QAAQ,CAAC;AACpB,QAAI,SAAS,UAAa,OAAO,OAAW;AAC5C,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,IAAI,IAAI,EAAE;AAChB,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,MAAM,EAAE,MAAM,EAAE;AACtB,QAAI,OAAO,UAAW;AACtB,UAAM,QAAQ,KAAK,KAAK,MAAM,SAAS;AACvC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,SAAS,EAAE,MAAO,MAAM,IAAK;AAInC,UAAI;AACJ,UAAI,WAAW;AACf,eAAS,IAAI,OAAO,GAAG,IAAI,IAAI,KAAK;AAClC,cAAM,KAAK,IAAI,CAAC;AAChB,YAAI,CAAC,GAAI;AACT,cAAM,OAAO,KAAK,IAAI,GAAG,MAAM,MAAM;AACrC,YAAI,QAAQ,UAAU;AACpB,qBAAW;AACX,iBAAO;AAAA,QACT;AAAA,MACF;AACA,UAAI,MAAM;AACR,aAAK,SAAS;AACd;AAAA,MACF;AAIA,UAAI,KAAK;AACT,eAAS,IAAI,MAAM,IAAI,IAAI,KAAK;AAC9B,aAAK,IAAI,CAAC,GAAG,OAAO,MAAM,OAAQ,MAAK;AAAA,MACzC;AACA,YAAM,KAAK,IAAI,EAAE;AACjB,YAAM,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AACnC,UAAI,CAAC,MAAM,CAAC,GAAI;AAChB,YAAM,OAAO,GAAG,MAAM,GAAG;AACzB,YAAM,IAAI,OAAO,KAAK,SAAS,GAAG,OAAO,OAAO;AAChD,aAAO,KAAK;AAAA,QACV,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO;AAAA,QAClC,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO;AAAA,QAClC,SAAS,GAAG;AAAA,QACZ,YAAY,GAAG;AAAA,QACf,cAAc,GAAG;AAAA,QACjB,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,QAAqB,CAAC,GAAG,KAAK,GAAG,MAAM,EAC1C,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAC5B,OAAO,CAAC,OAAO,GAAG,MAAM,EACxB,IAAI,CAAC,QAAQ;AAAA,IACZ,KAAK,GAAG;AAAA,IACR,KAAK,GAAG;AAAA,IACR,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,cAAc,GAAG;AAAA,IACjB,WAAW,GAAG;AAAA,IACd,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW,GAAG;AAAA,IACd,gBAAgB;AAAA,IAChB,QAAQ,GAAG;AAAA,IACX,UAAU,eAAe,IAAI,GAAG,MAAM,KAAK;AAAA,EAC7C,EAAE;AAGJ,QAAM,UAAuB,CAAC;AAC9B,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,QAAQ,QAAQ,SAAS,CAAC;AACvC,UAAM,YACJ,SAAS,UACT,gBAAgB,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,IAAI,OAC1D,KAAK,YAAY,KAAK;AACxB,QAAI,UAAW;AACf,YAAQ,KAAK,IAAI;AAAA,EACnB;AAGA,QAAM,eAAe,CAAC,QACnB,KAAK,MAAM,YAAY,EAAE,GAAG,OAAO,WAAc;AACpD,QAAM,YAAY,CAAC,YAA4B,MAAM,SAAS,OAAO,GAAG,QAAQ;AAChF,QAAM,aAAa,CAAC,YAA4B,MAAM,SAAS,OAAO,GAAG,SAAS;AAClF,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,UAAM,OAAO,QAAQ,IAAI,CAAC;AAC1B,QAAI,CAAC,KAAM;AAEX,SAAK,iBAAiB,OAAO,KAAK,IAAI,GAAG,KAAK,YAAY,KAAK,SAAS,IAAI;AAC5E,UAAM,MAAM,KAAK,kBAAkB,IAAI,aAAa,KAAK,cAAc,IAAI;AAE3E,QAAI,MAAM,GAAG;AACX,WAAK,SAAS;AACd,WAAK,YAAY;AACjB,WAAK,QAAQ,MAAM,YAAY,MAAM,MAAM,eAAe,GAAG,KAAK,YAAY,MAAM,MAAM;AAAA,IAC5F,WAAW,MAAM,QAAQ,SAAS,GAAG;AACnC,WAAK,SAAS;AACd,WAAK,YAAY;AACjB,WAAK,QAAQ,aAAa,MAAM,WAAW;AAAA,IAC7C,WAAW,QAAQ,KAAK,cAAc,KAAK,eAAe,KAAK,cAAc,KAAK,YAAY,KAAK,SAAS;AAC1G,YAAM,OAAO,SAAS,KAAK,YAAY,GAAG,YAAY;AACtD,WAAK,SAAS;AACd,WAAK,YAAY,WAAW,KAAK,OAAO,IAAI,WAAW,KAAK,OAAO,IAAI,OAAO;AAC9E,WAAK,QAAQ,YAAY,IAAI,OAAO,UAAU,KAAK,OAAO,CAAC;AAAA,IAC7D,WAAW,QAAQ,KAAK,cAAc,CAAC,KAAK,YAAY;AACtD,WAAK,SAAS;AACd,WAAK,YAAY;AACjB,WAAK,QAAQ,QAAQ,aAAa,KAAK,UAAU,CAAC;AAAA,IACpD,WAAW,CAAC,KAAK,cAAc,MAAM,YAAY;AAC/C,WAAK,SAAS;AACd,WAAK,YAAY;AACjB,WAAK,QAAQ,SAAS,aAAa,KAAK,UAAU,CAAC;AAAA,IACrD,WAAW,KAAK,cAAc,UAAU,KAAK,cAAc,YAAY;AAErE,WAAK,SAAS;AACd,YAAM,SAAS,YAAY,KAAK,SAAS,KAAK;AAC9C,YAAM,KAAK,KAAK,WAAW,OAAO,KAAK,QAAQ,KAAK;AACpD,WAAK,QAAQ,MAAM,GAAG,MAAM,GAAG,EAAE,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,EAAE;AAAA,IACnE,OAAO;AACL,WAAK,SAAS;AACd,WAAK,YAAY;AACjB,YAAM,QAAQ,KAAK,aAAa,KAAK;AACrC,WAAK,QAAQ,MAAM,WAAW,KAAK,QAAQ,GAAG,KAAK,WAAW,KAAK;AAAA,IACrE;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,OAAO,SAAS,aAAa,IAAI;AACtD;;;ACvWO,IAAM,eAAe;AACrB,IAAM,YAAY;AAClB,IAAM,YAAY;AAIzB,IAAM,UAAU;AAGhB,IAAM,sBAAsB;AAC5B,IAAM,gBAAgB;AAItB,IAAM,eAAe;AACrB,IAAM,gBAAgB;AACtB,IAAM,eAAe;AAqBd,SAAS,aAAa,UAA0B,QAAyC;AAC9F,MAAI,MAAM;AACV,aAAW,WAAW,UAAU;AAC9B,aAAS,IAAI,GAAG,IAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9C,YAAM,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC9B,YAAM,IAAI,QAAQ,OAAO,CAAC;AAC1B,UAAI,CAAC,KAAK,CAAC,EAAG;AACd,YAAM,MAAM,gBAAgB,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAClD,UAAI,MAAM,OAAO,UAAU,MAAM,GAAG;AAClC,cAAM,KAAK,SAAS,OAAO;AAC3B,eAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,QAAM,IAAI,MAAM,OAAO,KAAK,OAAO,SAAS,CAAC;AAC7C,SAAO,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI;AAC5B;AAMO,SAAS,aACd,UACA,aACA,WACoB;AACpB,QAAM,MAA0B,CAAC;AACjC,QAAM,QAAQ,aAAa,UAAU,WAAW;AAChD,MAAI,MAAO,KAAI,KAAK,KAAK;AACzB,MAAI,MAAM;AACV,aAAW,WAAW,UAAU;AAC9B,aAAS,IAAI,GAAG,IAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9C,YAAM,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC9B,YAAM,IAAI,QAAQ,OAAO,CAAC;AAC1B,UAAI,CAAC,KAAK,CAAC,EAAG;AACd,aAAO,gBAAgB,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7C,UAAI,MAAM,eAAe,MAAM,UAAW,KAAI,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,IACjE;AAAA,EACF;AACA,QAAM,MAAM,aAAa,UAAU,SAAS;AAC5C,MAAI,IAAK,KAAI,KAAK,GAAG;AACrB,SAAO;AACT;AAEA,IAAM,cAAc,EAAE,KAAK,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,GAAG;AAChE,IAAM,eAAe;AAGrB,SAAS,SAAS,KAAqB,KAAyB,SAAiB;AAC/E,MAAI,IAAI,SAAS,EAAG,QAAO;AAC3B,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,SAAS;AACb,aAAW,CAAC,KAAK,GAAG,KAAK,KAAK;AAC5B,QAAI,MAAM,OAAQ,UAAS;AAC3B,QAAI,MAAM,OAAQ,UAAS;AAC3B,QAAI,MAAM,OAAQ,UAAS;AAC3B,QAAI,MAAM,OAAQ,UAAS;AAAA,EAC7B;AAEA,MAAI,SAAS,SAAS,QAAQ,SAAS,SAAS,KAAM,QAAO;AAC7D,SACE,IAAI;AAAA,IACF;AAAA,MACE,CAAC,QAAQ,MAAM;AAAA,MACf,CAAC,QAAQ,MAAM;AAAA,IACjB;AAAA,IACA,EAAE,SAAS,SAAS,aAAa,SAAS,aAAa;AAAA,EACzD,KAAK;AAET;AApHA,IAAAC,OAAA,iDAAAC,WAAA;AA6HO,IAAM,uBAAN,MAA2B;AAAA,EAsBhC,YAAY,MAST;AA/BE;AACL,uBAAAD;AACA;AACA;AACA;AACA;AACA;AACA,uBAAAC;AAEA,+BAA0C;AAC1C,sCAAyE,MAAM;AAC/E,qCAAyE,CAAC;AAC1E,wCAAkB;AAClB,oCAAc;AACd,iCAAW;AACX,uCAAiB;AACjB,qCAAe;AACf,uCAAiB;AACjB,uCAAiB;AACjB,qCAAe;AACf,6BAAO;AA8JP,8BAAQ,MAAY;AAClB,UAAI,mBAAK,YAAW,WAAY;AAChC,yBAAK,SAAQ,QAAQ,YAAY,IAAI,IAAI,GAAI;AAE7C,UAAI,mBAAK,YAAW,WAAW;AAC7B,cAAM,MAAM,YAAY,IAAI;AAC5B,YAAI;AACJ,YAAI,MAAM,mBAAK,cAAa;AAG1B,qBAAW,mBAAK;AAAA,QAClB,OAAO;AACL,gBAAM,WAAW,MAAM,mBAAK,mBAAkB;AAC9C,qBAAW,KAAK,IAAI,GAAG,KAAK,IAAI,mBAAK,SAAQ,aAAa,UAAU,mBAAK,aAAY,CAAC;AAItF,gBAAM,KAAK,mBAAK,cAAa,mBAAK,gBAAe;AAIjD,gBAAM,WAAW,KAAM,mBAAK,SAAQ,gBAAgB,GAAG,SAAS,KAAK,GAAG,YAAa;AACrF,gBAAM,UAAU,KAAK,KAAK,IAAI,GAAG,WAAW,KAAK,IAAI,GAAG,WAAW,IAAI,CAAC,IAAI;AAC5E,cAAI,MAAM,YAAY,SAAS;AAC7B,+BAAK,eAAL,WAAmB,EAAE,MAAM,GAAG,MAAM,WAAW,GAAG,UAAU;AAE5D,+BAAK,UAAW;AAChB,+BAAK,aAAc,MAAM;AACzB,+BAAK,gBAAiB,MAAM,sBAAuB,mBAAK,YAAW,mBAAK,gBAAgB;AACxF,mCAAK,iBAAL;AACA,uBAAW,mBAAK;AAAA,UAClB;AAAA,QACF;AACA,2BAAK,SAAQ,UAAU,QAAQ;AAC/B,YAAI,WAAW,KAAK,WAAW,mBAAK,SAAQ,aAAa;AACvD,gBAAM,OAAO,aAAa,mBAAK,YAAW,QAAQ;AAClD,cAAI,KAAM,oBAAKD,OAAK,UAAU,IAAI;AAClC,gBAAM,UAAU,mBAAK,SAAQ,UAAU,QAAQ;AAC/C,cAAI,SAAS,WAAY,oBAAK,YAAL,WAAgB,QAAQ;AAAA,QACnD,WAAW,YAAY,mBAAK,SAAQ,aAAa;AAC/C,cAAI,mBAAK,oBAAmB,GAAG;AAG7B,+BAAK,gBAAiB,MAAM;AAC5B,kBAAM,WAAW,mBAAK,QAAO,mBAAK,QAAO,SAAS,CAAC;AACnD,gBAAI,UAAU,WAAY,oBAAK,YAAL,WAAgB,SAAS;AACnD,gBAAI,UAAU;AACZ,iCAAKA,OAAK,OAAO,EAAE,QAAQ,CAAC,SAAS,KAAK,SAAS,GAAG,GAAG,UAAU,IAAI,CAAC;AAAA,YAC1E;AAAA,UACF,WAAW,OAAO,mBAAK,iBAAgB;AAKrC,+BAAK,gBAAiB;AACtB,kCAAK,gDAAL;AACA,+BAAK,SAAQ,WAAW,CAAC;AACzB,+BAAK,gBAAiB;AACtB,+BAAK,cAAe;AACpB,+BAAK,SAAL,WAAa,KAAK,SAAS;AAAA,UAC7B;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,UAAU,mBAAK,SAAQ,WAAW;AACxC,cAAM,YAAY,KAAK,IAAI,UAAU,mBAAK,eAAc,IAAI,OACxD,mBAAK,kBACL,WAAW,mBAAK,kBAAiB,WAAW;AAChD,2BAAK,SAAQ,WAAW,SAAS;AAAA,MACnC;AAEA,yBAAKC,WAAL;AACA,yBAAK,MAAO,sBAAsB,mBAAK,MAAK;AAAA,IAC9C;AA1NE,uBAAKD,OAAO,KAAK;AACjB,uBAAK,SAAU,KAAK;AACpB,uBAAK,WAAY,KAAK;AACtB,uBAAK,QAAS,KAAK;AACnB,uBAAK,YAAa,KAAK;AACvB,uBAAK,SAAU,KAAK;AACpB,uBAAKC,WAAW,KAAK;AACrB,uBAAK,eAAgB,KAAK,iBAAiB,MAAY;AAGvD,uBAAK,cAAe,mBAAK,QACtB,OAAO,CAAC,OAAO,GAAG,WAAW,aAAa,EAC1C,IAAI,CAAC,QAAQ;AAAA,MACZ,WAAW,GAAG;AAAA,MACd,MAAM,mBAAK,WAAU,GAAG,YAAY,GAAG,YAAY;AAAA,MACnD,WAAW,mBAAK,WAAU,GAAG,eAAe,CAAC,GAAG,WAAW,GAAG;AAAA,IAChE,EAAE;AAAA,EACN;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,mBAAK,YAAW;AAAA,EACzB;AAAA,EAEA,QAAc;AAEZ,uBAAK,SAAQ,YAAY,mBAAK,SAAQ,WAAW;AACjD,uBAAK,SAAQ,WAAW,CAAC;AACzB,uBAAK,gBAAiB;AAEtB,SAAK,QAAQ;AACb,uBAAK,OAAL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAgB;AACd,QAAI,mBAAK,YAAW,WAAY;AAChC,UAAM,QAAQ,mBAAK,QAAO,CAAC;AAC3B,QAAI,CAAC,SAAS,mBAAK,SAAQ,eAAe,EAAG;AAC7C,QAAI,MAAM,WAAY,oBAAK,YAAL,WAAgB,MAAM;AAC5C,uBAAKD,OAAK,OAAO;AAAA,MACf,QAAQ,CAAC,MAAM,KAAK,MAAM,GAAG;AAAA,MAC7B,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AACD,UAAM,QAAQ,mBAAK,SAAQ;AAC3B,UAAM,WAAW,KAAK,IAAI,eAAe,KAAK,IAAI,eAAe,QAAQ,OAAO,CAAC;AACjF,uBAAK,cAAe,QAAQ;AAC5B,uBAAK,gBAAiB,YAAY,IAAI,IAAI;AAC1C,uBAAK,SAAQ,UAAU,CAAC;AACxB,uBAAK,SAAQ,WAAW;AACxB,uBAAK,iBAAkB;AACvB,uBAAK,aAAc;AACnB,uBAAK,gBAAiB;AACtB,uBAAK,eAAL,WAAmB;AACnB,uBAAK,QAAS;AAAA,EAChB;AAAA,EASA,WAAwB;AACtB,UAAM,OAAO,mBAAK,QAAO,mBAAK,aAAY;AAC1C,WAAO;AAAA,MACL,OAAO,mBAAK;AAAA,MACZ,OAAO,mBAAK,QAAO;AAAA,MACnB,OAAO,MAAM,SAAS;AAAA,MACtB,SAAS,mBAAK,kBAAiB;AAAA,MAC/B,QAAQ,mBAAK,kBAAiB,mBAAK,QAAO,SAAS;AAAA,MACnD,QAAQ,MAAM,UAAU;AAAA,MACxB,WAAW,MAAM,aAAa;AAAA,MAC9B,gBAAgB,MAAM,kBAAkB;AAAA,MACxC,SAAS,MAAM,WAAW;AAAA,MAC1B,UAAU,MAAM,YAAY;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,OAAa;AACX,QAAI,mBAAK,YAAW,UAAW,uBAAK,gDAAL;AAC/B,SAAK,SAAS,mBAAK,gBAAe,CAAC;AAAA,EACrC;AAAA,EACA,WAAiB;AACf,QAAI,mBAAK,YAAW,UAAW,uBAAK,gDAAL;AAC/B,SAAK,SAAS,mBAAK,gBAAe,CAAC;AAAA,EACrC;AAAA,EAEA,SAAS,OAAqB;AAC5B,QAAI,mBAAK,YAAW,OAAQ;AAC5B,uBAAK,cAAe,KAAK,IAAI,GAAG,KAAK,IAAI,mBAAK,QAAO,SAAS,GAAG,KAAK,CAAC;AACvE,UAAM,OAAO,mBAAK,QAAO,mBAAK,aAAY;AAC1C,QAAI,CAAC,KAAM;AACX,uBAAK,gBAAiB,KAAK;AAC3B,QAAI,KAAK,WAAY,oBAAK,YAAL,WAAgB,KAAK;AAE1C,QAAI;AACJ,aAAS,IAAI,mBAAK,gBAAe,GAAG,IAAI,mBAAK,QAAO,QAAQ,KAAK;AAC/D,YAAM,KAAK,mBAAK,QAAO,CAAC;AACxB,UAAI,MAAM,gBAAgB,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG;AACjE,kBAAW,KAAK,MAAM,GAAG,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,GAAG,IAAI,MAAO,KAAK;AAC1E;AAAA,MACF;AAAA,IACF;AACA,QAAI,YAAY,QAAW;AACzB,eAAS,IAAI,mBAAK,gBAAe,GAAG,KAAK,GAAG,KAAK;AAC/C,cAAM,KAAK,mBAAK,QAAO,CAAC;AACxB,YAAI,MAAM,gBAAgB,GAAG,KAAK,GAAG,KAAK,KAAK,KAAK,KAAK,GAAG,IAAI,GAAG;AACjE,oBAAW,KAAK,MAAM,KAAK,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,MAAO,KAAK;AAC1E;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,mBAAK,QAAO,mBAAK,gBAAe,CAAC;AAClD,UAAM,YAAY,WAAW,SAAS,YAAY,mBAAK,SAAQ;AAC/D,UAAM,MAAM,aAAa,mBAAK,YAAW,KAAK,WAAW,SAAS;AAClE,UAAM,SAAS,SAAS,mBAAKA,QAAM,KAAK,WAAW,mBAAKA,OAAK,WAAW,CAAC;AACzE,QAAI,QAAQ;AACV,yBAAKA,OAAK,OAAO,EAAE,GAAG,QAAQ,OAAO,WAAW,UAAU,IAAI,CAAC;AAAA,IACjE,OAAO;AAEL,yBAAKA,OAAK,OAAO;AAAA,QACf,QAAQ,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,QAC3B,MAAM;AAAA,QACN,OAAO;AAAA,QACP,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC3C,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AACA,uBAAK,SAAL,WAAa,KAAK,SAAS;AAAA,EAC7B;AAAA,EAEA,UAAgB;AACd,uBAAK,QAAS;AACd,uBAAK,eAAL,WAAmB;AACnB,yBAAqB,mBAAK,KAAI;AAAA,EAChC;AA2EF;AA1PEA,QAAA;AACA;AACA;AACA;AACA;AACA;AACAC,YAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApBK;AAAA;AA+FL,gBAAW,WAAS;AAClB,qBAAK,SAAQ,WAAW;AACxB,qBAAK,eAAL,WAAmB;AACnB,qBAAK,QAAS;AAChB;AA+EA;;;AClSF,IAAM,kBAA0C;AAAA,EAC9C,YAAY;AAAA;AAAA,EACZ,MAAM;AAAA;AAAA,EACN,WAAW;AAAA;AAAA,EACX,aAAa;AAAA;AAAA,EACb,OAAO;AAAA;AAAA,EACP,YAAY;AAAA;AAAA,EACZ,UAAU;AAAA;AAAA,EACV,IAAI;AAAA;AAAA,EACJ,MAAM;AAAA;AACR;AAEO,SAAS,eACd,WACA,UACU;AACV,QAAM,KAAK,SAAS,cAAc,KAAK;AACvC,KAAG,MAAM,UACP;AAGF,QAAM,MAAM,CAAC,OAAe,SAAqB,SAAS,UAA6B;AACrF,UAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,MAAE,cAAc;AAChB,MAAE,MAAM,UACN,cAAc,SAAS,YAAY,SAAS;AAE9C,MAAE,UAAU;AACZ,WAAO;AAAA,EACT;AACA,QAAM,OAAO,IAAI,UAAK,SAAS,MAAM;AACrC,QAAM,OAAO,IAAI,UAAK,SAAS,MAAM;AACrC,QAAM,QAAQ,IAAI,UAAK,SAAS,SAAS,IAAI;AAC7C,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,MAAM,UAAU;AACrB,QAAM,SAAS,SAAS,cAAc,GAAG;AACzC,SAAO,MAAM,WAAW;AACxB,QAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,UAAQ,MAAM,UAAU;AACxB,QAAM,WAAW,SAAS,cAAc,MAAM;AAC9C,OAAK,OAAO,QAAQ,SAAS,cAAc,IAAI,GAAG,SAAS,QAAQ;AACnE,KAAG,OAAO,MAAM,MAAM,MAAM,KAAK;AACjC,YAAU,YAAY,EAAE;AAExB,SAAO;AAAA,IACL,OAAO,OAA0B;AAC/B,aAAO,cAAc,QAAQ,OAAO,MAAM,QAAQ,CAAC,CAAC,MAAM,OAAO,MAAM,KAAK,CAAC;AAC7E,cAAQ,cAAc,gBAAgB,MAAM,SAAS,KAAK;AAC1D,eAAS,cAAc,MAAM;AAC7B,WAAK,WAAW,MAAM;AACtB,WAAK,WAAW,MAAM;AACtB,WAAK,MAAM,UAAU,MAAM,UAAU,SAAS;AAC9C,WAAK,MAAM,UAAU,MAAM,SAAS,SAAS;AAAA,IAC/C;AAAA,IACA,UAAgB;AACd,SAAG,OAAO;AAAA,IACZ;AAAA,EACF;AACF;;;AClDO,SAAS,kBAAkB,MAKlB;AACd,MAAI,QAAsB;AAC1B,SAAO;AAAA,IACL,MAAM,OAA4B;AAChC,UAAI,CAAC,KAAK,UAAU;AAClB,cAAM,IAAI,MAAM,uFAAkF;AAAA,MACpG;AACA,UAAI;AACF,cAAM,OAAO,MAAM,KAAK,SAAS,WAAW,KAAK,MAAM;AACvD,gBAAQ,WAAW,IAAI;AACvB,aAAK,WAAW,KAAK;AACrB,eAAO,MAAM,MAAM;AAAA,MACrB,SAAS,OAAO;AACd,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,aAAK,QAAQ,KAAK,SAAS,EAAE,SAAS,MAAM,CAAC;AAC7C,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,SAAS,MAAM;AAAA,IACf,OAAO,MAAM,OAAO,MAAM,KAAK;AAAA,EACjC;AACF;AAaO,SAAS,mBAAmB,MAIlB;AACf,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,mBAAmB,KAAK;AAAA,IACxB,QAAQ,KAAK;AAAA,EACf;AACF;AAYO,SAAS,mBAAmB,MAGlB;AACf,SAAO,EAAE,OAAO,KAAK,OAAO,YAAY,KAAK,WAAW;AAC1D;AA6BO,SAAS,oBAAoB,MAQlB;AAChB,SAAO,EAAE,GAAG,KAAK;AACnB;AASO,SAAS,mBAAmB,MAGlB;AACf,SAAO;AAAA,IACL,YAAY,KAAK;AAAA,IACjB,SAAS,KAAK;AAAA,EAChB;AACF;;;AtB1EA,SAAS,kBAAwB;AAC/B,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,eAAe,EAAG;AACjF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,QAAM,OAAO;AACb,IAAE,cACA,kEACc,IAAI,+fAOuF,IAAI,wQAGJ,IAAI,qGACV,IAAI,qGACJ,IAAI;AACzG,WAAS,KAAK,YAAY,CAAC;AAC7B;AAKA,SAAS,wBAA8B;AACrC,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,qBAAqB,EAAG;AACvF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cACA;AAOF,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,SAAS,mBAAmB,WAAkC;AAC5D,SAAO,cAAc,OACjB,qEACA;AACN;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,QAAM,IAAI,KAAK,YAAY;AAC3B,MAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,MAAM,GAAG;AAChD,WAAO;AAAA,EACT;AACA,MAAI,EAAE,SAAS,OAAO,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AA9HA,IAAAC,OAAA,uHAAAC,SAAA,cAAAC,YAAA;AAiIA,IAAM,cAAN,MAAqC;AAAA,EA2DnC,YAAY,WAAwB,SAAyB;AA3D/D;AACE,uBAAAF;AACA,iCAAW,IAAI,QAAuB;AACtC,gCAAU;AACV,+BAAS,IAAI,gBAAgB;AAC7B;AACA;AACA;AAIA,SAAS,SAAS,mBAAmB;AAAA,MACnC,OAAO,OAAO,SAAU,mBAAK,gBAAe,mBAAK,cAAa,MAAM,IAAI,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,MAC9F,YAAY,CAAC,eAAe,mBAAK,eAAc,WAAW,UAAU,KAAK,CAAC;AAAA,IAC5E,CAAC;AACD,SAAS,UAAU,oBAAoB;AAAA,MACrC,OAAO,CAAC,MAAM,IAAI,YAAY,sBAAK,kCAAL,WAAY,MAAM,IAAI;AAAA,MACpD,OAAO,MAAM;AACX,8BAAK,uCAAL;AAAA,MACF;AAAA,MACA,SAAS,MAAM;AACb,2BAAK,OAAM,QAAQ;AAAA,MACrB;AAAA,MACA,MAAM,MAAM;AACV,2BAAK,OAAM,KAAK;AAAA,MAClB;AAAA,MACA,UAAU,MAAM;AACd,2BAAK,OAAM,SAAS;AAAA,MACtB;AAAA,MACA,UAAU,MAAM,mBAAK,OAAM,SAAS,KAAK;AAAA,MACzC,QAAQ,MAAM,mBAAK,OAAM,UAAU;AAAA,IACrC,CAAC;AACD,SAAS,SAAS,mBAAmB;AAAA,MACnC,YAAY,CAAC,YAAY;AACvB,2BAAK,iBAAgB,WAAW,OAAO;AAAA,MACzC;AAAA,MACA,SAAS,CAAC,eAAe;AACvB,8BAAK,oCAAL,WAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAED,uCAAuC;AACvC,sCAAqC;AACrC,uCAAuC;AACvC,uBAAAC,SAAuB;AACvB,qCAAmC;AACnC,uBAAAC,YAA0F;AAC1F,qCAAoC;AACpC,mCAA4B;AAC5B,4CAAsB;AACtB,sCAAqC;AACrC,6BAAoC;AACpC,yCAAwC;AACxC,wCAAsC;AACtC,yCAAyD;AACzD,0CAAoB;AACpB,kCAA6B;AAC7B,oCAAc;AAGZ,uBAAK,YAAa;AAClB,uBAAK,kBAAmB,QAAQ,IAAI,kBAAkB;AACtD,uBAAK,aAAc,QAAQ,IAAI,aAAa;AAC5C,uBAAK,mBAAoB,QAAQ,IAAI,mBAAmB;AACxD,uBAAK,eAAgB,QAAQ,gBAAgB;AAC7C,SAAK,QAAQ,kBAAkB;AAAA,MAC7B,GAAI,QAAQ,OAAO,WAAW,EAAE,UAAU,QAAQ,MAAM,SAAS,IAAI,CAAC;AAAA,MACtE,SAAS,mBAAK;AAAA,MACd,QAAQ,mBAAK,QAAO;AAAA,MACpB,UAAU,CAAC,UAAU;AACnB,8BAAK,2CAAL,WAAqB;AAAA,MACvB;AAAA,IACF,CAAC;AACD,SAAK,SAAS,mBAAmB;AAAA,MAC/B,QAAQ,CAAC,YAAY;AACnB,8BAAK,yCAAL,WAAmB,mBAAK,gBAAe,YAAY,OAAO,KAAK,CAAC;AAAA,MAClE;AAAA,MACA,mBAAmB,MAAM,mBAAK,gBAAe,kBAAkB,KAAK;AAAA,MACpE,QAAQ,CAAC,eAAe,mBAAK,gBAAe,OAAO,UAAU;AAAA,IAC/D,CAAC;AACD,uBAAKF,OAAO,IAAIG,YAAW,IAAI;AAAA,MAC7B;AAAA,MACA,QAAQ,QAAQ,UAAU,CAAC,GAAG,CAAC;AAAA,MAC/B,MAAM,QAAQ,QAAQ;AAAA,MACtB,OAAO,QAAQ,SAAS;AAAA,MACxB,SAAS,QAAQ,WAAW;AAAA,MAC5B,WAAW;AAAA,MACX,oBAAoB;AAAA;AAAA;AAAA,MAGpB,OAAO;AAAA,IACT,CAAC;AACD,uBAAKH,OAAK,GAAG,QAAQ,MAAM;AAGzB,UAAI,CAAC,mBAAKA,OAAK,SAAS,QAAQ,GAAG;AACjC,2BAAKA,OAAK,SAAS;AAAA,UACjB,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,oBAAoB,WAAW,sBAAsB,KAAK;AAAA,QACrE,CAAC;AAAA,MACH;AACA,yBAAK,SAAU;AACf,yBAAK,UAAS,KAAK,QAAQ,MAAS;AAAA,IACtC,CAAC;AACD,uBAAKA,OAAK,GAAG,SAAS,CAAC,MAAM;AAC3B,YAAM,QAAkB,EAA0B;AAClD,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,yBAAK,UAAS,KAAK,SAAS,EAAE,SAAS,MAAM,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAAA,EAEA,GAAkC,OAAU,UAA4C;AACtF,uBAAK,UAAS,GAAG,OAAO,QAAQ;AAEhC,QAAI,UAAU,UAAU,mBAAK,UAAS;AACpC,MAAC,SAA6C,MAAS;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,IAAmC,OAAU,UAA4C;AACvF,uBAAK,UAAS,IAAI,OAAO,QAAQ;AAAA,EACnC;AAAA,EAEA,UAAgB;AACd,uBAAK,QAAO,MAAM;AAClB,uBAAK,OAAM,QAAQ;AACnB,uBAAK,MAAO;AACZ,uBAAK,YAAW,QAAQ;AACxB,uBAAK,WAAY;AACjB,uBAAK,gBAAe,QAAQ;AAC5B,uBAAK,eAAgB;AACrB,uBAAK,iBAAgB,QAAQ;AAC7B,uBAAK,gBAAiB;AACtB,uBAAK,iBAAgB,QAAQ;AAC7B,uBAAK,gBAAiB;AACtB,uBAAKA,OAAK,OAAO;AACjB,uBAAK,UAAS,UAAU;AAAA,EAC1B;AAAA,EAEA,gBAA4B;AAC1B,WAAO,mBAAK,iBAAgB,cAAc,KAAK,EAAE,WAAW,GAAG,WAAW,EAAE;AAAA,EAC9E;AAAA,EAEA,iBAAiC;AAC/B,WAAO,mBAAKA;AAAA,EACd;AAAA,EAEA,gBAAgB,OAA+B;AAC7C,uBAAK,eAAgB;AACrB,uBAAK,iBAAgB,SAAS,KAAK;AAGnC,QAAI,mBAAKA,OAAK,SAAS,IAAI,GAAG;AAC5B,yBAAKA,OAAK,iBAAiB,MAAM,oBAAoB,oBAAoB,KAAK,EAAE,UAAU;AAAA,IAC5F;AAAA,EACF;AAAA,EAqLA,eAAe,YAA0B;AACvC,UAAM,WAAW,mBAAKC,UAAQ,YAAY,UAAU;AACpD,QAAI,CAAC,SAAU;AACf,QAAI,SAAS,SAAS;AACpB,4BAAK,yCAAL,WAAmB,mBAAK,gBAAe,YAAY,SAAS,OAAO,KAAK,CAAC;AAAA,IAC3E;AACA,0BAAK,mCAAL,WAAa;AACb,0BAAK,4CAAL;AAAA,EACF;AAAA,EAEA,iBAAuB;AA5dzB;AA6dI,6BAAK,kBAAL;AACA,uBAAK,cAAe;AACpB,QAAI,CAAC,mBAAKC,YAAW;AACrB,uBAAKA,YAAU,MAAM,OAAO;AAC5B,uBAAKA,YAAY;AACjB,uBAAK,iBAAgB,aAAa,IAAI;AAAA,EACxC;AAgUF;AAjqBEF,QAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAkCA;AACA;AACA;AACAC,UAAA;AACA;AACAC,aAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAzDF;AAAA;AA+JE,oBAAe,SAAC,OAAoB;AAClC,qBAAK,iBAAgB,QAAQ;AAC7B,qBAAKD,SAAS;AACd,QAAM,SAAS,MAAY;AACzB,uBAAK,gBAAiB,IAAI,cAAc,mBAAKD,QAAM,OAAO,mBAAK,cAAa;AAC5E,uBAAK,eAAgB,IAAI,aAAa,KAAK;AAC3C,uBAAK,cAAe,IAAI,YAAY,KAAK;AACzC,uBAAK,eAAgB,IAAI,aAAa,KAAK;AAC3C,QAAI,mBAAK,mBAAkB;AACzB,yBAAK,gBAAiB,oBAAoB,mBAAK,aAAY,CAAC,YAAY;AACtE,aAAK,OAAO,OAAO,OAAO;AAAA,MAC5B,CAAC;AAAA,IACH;AAEA,0BAAK,yCAAL,WAAmB,mBAAK,eAAc,OAAO,mBAAKA,OAAK,QAAQ,CAAC;AAChE,0BAAK,4CAAL;AACA,uBAAK,gBAAe,WAAW;AAE/B,uBAAKA,OAAK,GAAG,QAAQ,MAAM;AACzB,4BAAK,yCAAL,WAAmB,mBAAK,gBAAe,OAAO,mBAAKA,OAAK,QAAQ,CAAC,KAAK,CAAC;AAAA,IACzE,CAAC;AACD,uBAAKA,OAAK,GAAG,WAAW,MAAM;AAC5B,4BAAK,yCAAL,WAAmB,mBAAK,gBAAe,UAAU,mBAAKA,OAAK,QAAQ,CAAC,KAAK,CAAC;AAAA,IAC5E,CAAC;AACD,uBAAKA,OAAK,GAAG,SAAS,CAAC,MAAM;AAC3B,4BAAK,wCAAL,WAAkB,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,KAAK,EAAE,OAAO;AAAA,IACjE,CAAC;AACD,uBAAKA,OAAK,GAAG,aAAa,CAAC,MAAM;AAC/B,4BAAK,wCAAL,WAAkB,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,KAAK,EAAE,OAAO;AAAA,IACjE,CAAC;AACD,uBAAKA,OAAK,UAAU,EAAE,iBAAiB,cAAc,MAAM;AACzD,yBAAK,YAAa;AAClB,yBAAK,iBAAgB,SAAS,IAAI;AAAA,IACpC,CAAC;AAAA,EACH;AACA,MAAI,mBAAK,SAAS,QAAO;AAAA,MACpB,oBAAKA,OAAK,GAAG,QAAQ,MAAM;AAClC;AAAA;AAGA,aAAQ,SAAC,YAA0B;AACjC,QAAM,WAAW,mBAAKC,UAAQ,YAAY,UAAU;AACpD,MAAI,CAAC,UAAU,WAAW,CAAC,mBAAKA,SAAQ;AACxC,OAAK,eAAe,UAAU;AAC9B,MAAI,SAAkC;AACtC,MAAI,SAAS,QAAQ;AACnB,UAAM,OAAO,mBAAKA,SAAO,QAAQ,SAAS,MAAM;AAChD,QAAI,KAAM,UAAS,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,UAAU,SAAS,SAAS;AAC/B,UAAM,OAAO,mBAAKA,SAAO,SAAS,SAAS,OAAO,GAAG;AACrD,UAAM,OAAO,MAAM,SAAS,YAAY,KAAK,YAAY,CAAC,IAAI;AAC9D,QAAI,QAAQ,KAAK,UAAU,GAAG;AAC5B,YAAM,QAAQ,YAAY,mBAAKA,SAAO,MAAM;AAC5C,YAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,aAAa,OAAO,IAAI,CAAC;AAC1D,eAAS,SAAS,OAAO,IAAI,EAAE;AAAA,IACjC;AAAA,EACF;AACA,MAAI,QAAQ;AACV,uBAAKD,OAAK,OAAO,EAAE,QAAQ,QAAQ,MAAM,IAAI,OAAO,IAAI,UAAU,IAAI,CAAC;AAAA,EACzE;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,eAAU,SAAC,IAAY,IAAY,KAAa,KAA8C;AAC5F,MAAI,CAAC,mBAAKC,YAAU,CAAC,mBAAK,eAAe,QAAO,EAAE,MAAM,UAAU;AAClE,QAAM,SAAS,aAAa,mBAAKA,UAAQ,CAAC,OAAO,mBAAK,gBAAe,OAAO,EAAE,GAAG,KAAK,GAAG;AACzF,QAAM,MAAM,mBAAK,iBAAgB,QAAQ,IAAI,EAAE;AAC/C,MAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,KAAM,QAAO;AAC/C,QAAM,QAAQ,oBAAoB,mBAAK,cAAa;AACpD,QAAM,QAAQ,YAAY,mBAAKA,SAAO,MAAM;AAC5C,MAAI,OAAsE;AAC1E,aAAW,YAAY,mBAAKA,SAAO,WAAW;AAC5C,UAAM,OAAO,mBAAK,eAAc,OAAO,SAAS,EAAE;AAClD,QAAI,CAAC,MAAM,KAAM;AACjB,UAAM,QAAQ,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO;AAC/D,QAAI,CAAC,MAAO;AACZ,UAAM,aAAa,IAAI;AAAA,MACrB,MAAM,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;AAAA,IACjF;AACA,eAAW,SAAS,MAAM,QAAQ;AAChC,UAAI,MAAM,SAAS,SAAS,UAAW;AACvC,YAAM,WAAW,WAAW,IAAI,MAAM,EAAE;AACxC,UAAI,CAAC,SAAU;AACf,YAAM,IAAI,MAAM,OAAO,iBAAiB,MAAM,OAAO,UAAU,YAAY,MAAM,EAAE;AACnF,UAAI,KAAK,IAAK;AACd,YAAM,OAAO,MAAM;AACnB,YAAM,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI,IAAI;AAC1C,UAAI,KAAK,EAAG;AACZ,YAAM,KAAK,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI;AACtC,YAAM,KAAK,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI;AACtC,YAAM,CAAC,MAAM,IAAI,IAAI,SAAS,OAAO,IAAI,EAAE;AAC3C,YAAM,OAAO,MAAM,SAAS,YAAY,CAAC;AACzC,UAAI,QAAQ,KAAK,UAAU,KAAK,YAAY,MAAM,MAAM,IAAI,GAAG;AAC7D,YAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,iBAAO;AAAA,YACL;AAAA,YACA,QAAQ,EAAE,MAAM,SAAS,YAAY,SAAS,IAAI,SAAS,MAAM,IAAI,UAAU,MAAM;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,KAAK,SAAS;AAC9B;AAAA;AAGA,iBAAY,SAAC,IAAY,IAAY,KAAa,KAAmB;AACnE,MAAI,CAAC,mBAAKA,YAAU,CAAC,mBAAK,eAAe;AACzC,QAAM,SAAS,sBAAK,sCAAL,WAAgB,IAAI,IAAI,KAAK;AAC5C,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,UAAU;AACb,4BAAK,yCAAL,WAAmB,mBAAK,eAAc,UAAU,OAAO,UAAU;AACjE,4BAAK,4CAAL;AACA,UAAI,KAAK;AACT,UAAI,KAAK;AACT,iBAAW,KAAK,OAAO,MAAM;AAC3B,cAAM,EAAE,CAAC;AACT,cAAM,EAAE,CAAC;AAAA,MACX;AACA,yBAAKD,OAAK,MAAM;AAAA,QACd,QAAQ,CAAC,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,QACzD,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK;AACH,UAAI,mBAAK,OAAM,OAAQ;AACvB,4BAAK,mCAAL,WAAa,OAAO;AACpB,yBAAK,eAAc,cAAc,OAAO,UAAU;AAClD,4BAAK,4CAAL;AACA;AAAA,IACF,KAAK;AAEH,yBAAK,eAAc,cAAc,OAAO,UAAU;AAClD,4BAAK,4CAAL;AACA;AAAA,IACF,KAAK;AACH,UAAI,CAAC,mBAAK,OAAM,OAAQ,MAAK,eAAe;AAC5C;AAAA,EACJ;AACF;AAAA;AAGA,iBAAY,SAAC,IAAY,IAAY,KAAa,KAAmB;AACnE,MAAI,CAAC,mBAAKC,YAAU,CAAC,mBAAK,eAAe;AACzC,QAAM,SAAS,sBAAK,sCAAL,WAAgB,IAAI,IAAI,KAAK;AAC5C,qBAAKD,OAAK,UAAU,EAAE,MAAM,SAC1B,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU,YAAY;AAEpE,QAAM,UACJ,OAAO,SAAS,WAChB,CAAC,mBAAK,OAAM,UACZ,OAAO,SAAS,OAAO,mBAAKE,aAAW,SAAS,KAC5C,OAAO,WACP;AACN,OAAK,SAAS,MAAM,UAAU,mBAAK,YAAY;AAC/C,qBAAK,YAAa,SAAS,MAAM;AACjC,MAAI,SAAS,SAAS;AACpB,UAAM,QAAQ,mBAAKD,SAAO,SAAS,QAAQ,OAAO;AAClD,UAAM,OAAO,OAAO,SAAS,SAAS,YAAY,MAAM,SAAS,YAAY,CAAC,IAAI;AAClF,QAAI,SAAS,QAAQ,KAAK,UAAU,GAAG;AACrC,yBAAK,iBAAgB,SAAS,MAAM,MAAM,OAAO,UAAU,YAAY,MAAM,EAAE,CAAC;AAChF;AAAA,IACF;AAAA,EACF;AACA,qBAAK,iBAAgB,SAAS,IAAI;AACpC;AAAA;AAsBA,YAAO,SAAC,UAA+B;AACrC,MAAI,CAAC,mBAAKA,YAAU,CAAC,SAAS,QAAS;AACvC,OAAK,eAAe;AACpB,QAAM,QAAQ,SAAS,UAAU,mBAAKA,SAAO,SAAS,SAAS,OAAO,IAAI;AAC1E,MAAI,SAAkC;AAItC,MAAI,OAAmD;AACvD,MAAI,SAAS,MAAM,SAAS,SAAS,WAAW;AAC9C,UAAM,OAAO,MAAM,SAAS,YAAY,CAAC;AACzC,QAAI,QAAQ,KAAK,UAAU,GAAG;AAC5B,YAAM,SAAS,MAAM,OAAO,UAAU,YAAY,MAAM,EAAE;AAC1D,yBAAK,iBAAgB,aAAa,MAAM,MAAM;AAC9C,YAAM,QAAQ,YAAY,mBAAKA,SAAO,MAAM;AAC5C,YAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,aAAa,OAAO,IAAI,CAAC;AAC1D,eAAS,SAAS,OAAO,IAAI,EAAE;AAC/B,YAAM,QAAQ,oBAAoB,mBAAK,cAAa;AACpD,YAAM,MAAM,MAAM,OAAO,iBAAiB;AAC1C,aAAO,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,KAAK,IAAI,KAAK,GAAG,IAAI,IAAI;AAAA,IAC3D;AAAA,EACF;AACA,MAAI,CAAC,UAAU,SAAS,QAAQ;AAC9B,UAAM,OAAO,mBAAKA,SAAO,QAAQ,SAAS,MAAM;AAChD,QAAI,KAAM,UAAS,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,OAAQ;AACb,kBAAgB;AAChB,QAAM,QAAQ,IAAIE,YAAW,MAAM;AAAA,IACjC,cAAc;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,WAAW;AAAA,EACb,CAAC,EACE,UAAU,MAAM,EAChB,QAAQ,SAAS,IAAI,EACrB,MAAM,mBAAKH,MAAI;AAClB,MAAI,MAAM;AAGR,QAAI,QAAQ;AACZ,QAAI,QAAQ;AACZ,UAAM,SAAS,MAAY;AACzB,YAAM,MAAM,mBAAK,iBAAgB,aAAa,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACpE,UAAI,CAAC,IAAK;AACV,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAK;AACpE,cAAQ,IAAI;AACZ,cAAQ,IAAI;AACZ,YAAM,UAAU,mBAAKA,OAAK,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;AAAA,IACrD;AACA,uBAAKA,OAAK,GAAG,UAAU,MAAM;AAC7B,uBAAK,cAAe,MAAM;AACxB,yBAAKA,OAAK,IAAI,UAAU,MAAM;AAAA,IAChC;AACA,uBAAKA,OAAK,eAAe;AAAA,EAC3B;AACA,QAAM,GAAG,SAAS,MAAM;AA9hB5B;AAgiBM,QAAI,CAAC,mBAAK,wBAAuB,mBAAKE,aAAW,UAAU,OAAO;AAChE,+BAAK,kBAAL;AACA,yBAAK,cAAe;AACpB,yBAAKA,YAAY;AACjB,yBAAK,iBAAgB,aAAa,IAAI;AAAA,IACxC;AAAA,EACF,CAAC;AACD,qBAAKA,YAAY,EAAE,UAAU,SAAS,SAAS,SAAS,MAAM;AAC9D,qBAAK,UAAS,KAAK,UAAU,EAAE,YAAY,SAAS,GAAG,CAAC;AACxD,wBAAK,uDAAL;AACF;AAGM,WAAM,eACV,gBACA,cACA,UAAwC,CAAC,GACQ;AACjD,MAAI,CAAC,mBAAKD,YAAU,CAAC,mBAAK,kBAAiB,CAAC,mBAAK,mBAAkB,CAAC,mBAAK,gBAAe;AACtF,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,QAAM,OAAO,mBAAKA,SAAO,YAAY,cAAc;AACnD,QAAM,KAAK,mBAAKA,SAAO,YAAY,YAAY;AAC/C,MAAI,CAAC,MAAM,UAAU,CAAC,IAAI,QAAQ;AAChC,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,QAAM,SAAS,MAAM,mBAAK,eAAc,SAAS,KAAK,QAAQ,GAAG,QAAQ,OAAO;AAChF,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yBAAyB;AACtD,QAAM,QAAQ,WAAW,mBAAKA,UAAQ,OAAO,MAAM;AAAA,IACjD,QAAQ,KAAK;AAAA,IACb,aAAa,GAAG;AAAA,EAClB,CAAC;AACD,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,mCAAmC;AAE/D,wBAAK,uCAAL,WAAiB;AACjB,QAAM,SAAS,mBAAK,gBAAe,YAAY;AAC/C,SAAO,SAAS,MAAM,QAAQ;AAI9B,aAAW,OAAO,MAAM,UAAU;AAChC,QAAI,IAAI,WAAY,oBAAK,gBAAe,aAAa,IAAI,OAAO;AAAA,EAClE;AACA,SAAO,iBAAiB,CAAC,SAAS,eAAe;AAC/C,UAAM,OAAO,aAAa,mBAAK,gBAAe,OAAO,UAAU,IAAI;AACnE,WAAO,MAAM,SAAS,QAAQ,KAAK,YAAY;AAAA,EACjD,CAAC;AAKD,QAAM,WAAW,MAAM,SAAS,CAAC;AACjC,QAAM,WAAW,UAAU,OAAO,CAAC;AACnC,MAAI,SAAS;AACb,MAAI,UAAmC;AACvC,MAAI,YAAY,UAAU;AAIxB,UAAM,aAAa,mBAAKA,SAAO,SAAS,SAAS,OAAO;AACxD,UAAM,QAAQ,oBAAoB,mBAAK,cAAa;AACpD,eAAW,SAAS,YAAY,UAAU,CAAC,GAAG;AAC5C,UAAI,MAAM,SAAS,SAAS,UAAW;AACvC,YAAM,OAAO,MAAM,SAAS,YAAY,CAAC;AACzC,UAAI,CAAC,QAAQ,KAAK,SAAS,KAAK,CAAC,YAAY,MAAM,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,EAAG;AAC9E,YAAM,IAAI,MAAM,OAAO,iBAAiB,MAAM,OAAO,UAAU,YAAY,MAAM,EAAE;AACnF,eAAS,KAAK,IAAI,QAAQ,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI;AAAA,IACzD;AACA,WAAO,uBAAuB,MAAM;AACpC,UAAM,QAAQ,YAAY,mBAAKA,SAAO,MAAM;AAC5C,cAAU,aAAa,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK;AAAA,EAClD;AACA,QAAM,WAAW,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK;AACtD,QAAM,SAAS,KAAK,IAAK,WAAW,KAAK,KAAM,GAAG;AAClD,QAAM,iBAAiB,MAAY;AACjC,UAAM,UAAU,mBAAKD,OAAK,WAAW;AACrC,UAAM,QAAQ,mBAAKA,OAAK,SAAS;AAKjC,QAAI,MAAO,SAAS,kBAAiB,MAAM,KAAK,IAAI,GAAG,mBAAKA,OAAK,QAAQ,CAAC;AAC1E,QAAI,SAAS;AACX,YAAM,IAAK,UAAU,KAAK,KAAM;AAChC,YAAM,KAAM,QAAQ,KAAK,KAAM;AAC/B,YAAM,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;AACjF,YAAM,OAAO,mBAAK,iBAAgB,aAAa,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM;AAC7E,YAAM,MAAM,mBAAK,iBAAgB;AAAA,QAC/B,QAAQ,CAAC,KAAK,IAAI,CAAC,KAAK;AAAA,QACxB,QAAQ,CAAC,KAAK,IAAI,CAAC,KAAK;AAAA,QACxB,UAAU,IAAI,CAAC,KAAK;AAAA,MACtB;AACA,UAAI,QAAQ,KAAK;AACf,cAAM,SAAS,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC;AACxD,YAAI,SAAS,KAAM,OAAM,IAAI;AAAA,MAC/B;AAAA,IACF;AACA,WAAO,mBAAmB,SAAS,OAAO,GAAG;AAAA,EAC/C;AACA,iBAAe;AACf,qBAAK,kBAAmB;AACxB,qBAAKA,OAAK,GAAG,QAAQ,cAAc;AACnC,qBAAKA,OAAK,GAAG,UAAU,cAAc;AACrC,MAAI,mBAAK,cAAa;AACpB,uBAAK,WAAY,eAAe,mBAAK,aAAY;AAAA,MAC/C,QAAQ,MAAM;AACZ,2BAAK,OAAM,SAAS;AAAA,MACtB;AAAA,MACA,QAAQ,MAAM;AACZ,2BAAK,OAAM,KAAK;AAAA,MAClB;AAAA,MACA,SAAS,MAAM;AACb,8BAAK,uCAAL;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACA,qBAAK,MAAO,IAAI,qBAAqB;AAAA,IACnC,KAAK,mBAAKA;AAAA,IACV;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,IACb,WAAW,CAAC,YAAY;AACtB,4BAAK,yCAAL,WAAmB,mBAAK,gBAAe,YAAY,OAAO,KAAK,CAAC;AAAA,IAClE;AAAA,IACA,QAAQ,CAAC,SAAS;AAChB,yBAAK,YAAW,OAAO,IAAI;AAC3B,yBAAK,UAAS,KAAK,QAAQ,IAAI;AAAA,IACjC;AAAA,IACA,cAAc,CAAC,MAAM;AACnB,4BAAK,+CAAL,WAAyB;AAAA,IAC3B;AAAA,IACA,SAAS,MAAM;AACb,yBAAK,iBAAgB,QAAQ;AAAA,IAC/B;AAAA,EACF,CAAC;AACD,qBAAK,MAAK,MAAM;AAGhB,qBAAK,UAAS,KAAK,eAAe,EAAE,SAAS,GAAG,cAAc,KAAK,YAAY,GAAG,CAAC;AACnF,SAAO,EAAE,gBAAgB,KAAK,MAAM,MAAM,WAAW,GAAG,WAAW,MAAM,MAAM,OAAO;AACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,wBAAmB,SAAC,GAAqD;AACvE,MAAI,mBAAK,mBAAkB;AACzB,iBAAa,mBAAK,iBAAgB;AAClC,uBAAK,kBAAmB;AAAA,EAC1B;AACA,qBAAK,kBAAiB,OAAO;AAC7B,qBAAK,iBAAkB;AACvB,MAAI,CAAC,GAAG;AACN,uBAAK,UAAS,KAAK,cAAc,IAAI;AACrC;AAAA,EACF;AACA,QAAM,UAAU,mBAAKC,UAAQ,SAAS,EAAE,SAAS;AACjD,QAAM,YAAY,sBAAK,4DAAL,WAAsC,EAAE;AAC1D,QAAM,aAA4B,SAAS,SAAS,MAAM,YAAY,OAAO;AAC7E,QAAM,YAAY,EAAE,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,KAAK,MAAM,CAAC;AACjE,QAAM,YAAY,SAAS,QAAQ,EAAE;AACrC,QAAM,QAAQ,YAAY,SAAS,OAAO,SAAS;AACnD,qBAAK,UAAS,KAAK,cAAc;AAAA,IAC/B,MAAM,EAAE;AAAA,IACR,WAAW,EAAE;AAAA,IACb,aAAa;AAAA,IACb;AAAA,IACA;AAAA,EACF,CAAC;AAGD,qBAAK,iBAAgB,aAAa,EAAE,SAAS;AAC7C,MAAI,CAAC,mBAAK,mBAAmB;AAC7B,wBAAsB;AACtB,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AACjB,QAAM,QAAQ,mBAAmB,SAAS;AAC1C,OAAK,YACH,2EACoC,KAAK,GAAG,kBAAkB,EAAE,IAAI,CAAC,GAAG,KAAK;AAC/E,QAAM,QAAQ,KAAK,cAAc,sBAAsB;AACvD,MAAI,MAAO,OAAM,cAAc;AAC/B,qBAAK,YAAW,YAAY,IAAI;AAChC,qBAAK,iBAAkB;AACvB,qBAAK,kBAAmB,WAAW,MAAM;AACvC,0BAAK,+CAAL,WAAyB;AAAA,EAC3B,GAAG,IAAI;AACT;AAAA;AAGA,qCAAgC,SAAC,WAA2B;AAC1D,QAAM,WAAW,mBAAKA,UAAQ,SAAS,SAAS,GAAG;AACnD,QAAM,OAAO,WAAW,mBAAK,gBAAe,OAAO,QAAQ,IAAI;AAC/D,QAAM,UAAU,MAAM,UAAU,mBAAKA,UAAQ,SAAS,KAAK,OAAO,IAAI;AACtE,SAAO,SAAS,UAAU,mBAAKA,UAAQ,SAAS,SAAS,GAAG,SAAS,KAAK;AAC5E;AAEA,gBAAW,SAAC,OAAO,MAAY;AAC7B,QAAM,WAAW,mBAAK,UAAS;AAC/B,qBAAK,OAAM,QAAQ;AACnB,qBAAK,MAAO;AACZ,qBAAK,YAAW,QAAQ;AACxB,qBAAK,WAAY;AACjB,qBAAK,iBAAgB,YAAY,EAAE,MAAM;AACzC,MAAI,mBAAK,mBAAkB;AACzB,uBAAKD,OAAK,IAAI,QAAQ,mBAAK,iBAAgB;AAC3C,uBAAKA,OAAK,IAAI,UAAU,mBAAK,iBAAgB;AAC7C,uBAAK,kBAAmB;AAAA,EAC1B;AACA,qBAAK,iBAAgB,QAAQ;AAC7B,MAAI,QAAQ,UAAU;AACpB,uBAAK,UAAS,KAAK,QAAQ,IAAI;AAC/B,uBAAK,UAAS,KAAK,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,EACrD;AACF;AAAA;AAGA,gCAA2B,WAAS;AAClC,MAAI,CAAC,mBAAKE,eAAa,CAAC,mBAAKD,YAAU,CAAC,mBAAK,eAAe;AAC5D,QAAM,QAAQ,mBAAKA,SAAO,SAAS,mBAAKC,YAAU,OAAO;AACzD,QAAM,OAAO,QAAQ,mBAAK,eAAc,OAAO,MAAM,UAAU,IAAI;AACnE,QAAM,UAAU,MAAM,SAAS,QAAQ,KAAK,YAAY,mBAAKA,YAAU;AACvE,qBAAK,iBAAgB,oBAAoB,OAAO;AAChD,QAAM,aAAa,mBAAKA,YAAU,MAAM,OAAO;AAC/C,MAAI,WAAW,CAAC,WAAY,oBAAKA,YAAU,MAAM,MAAM,mBAAKF,MAAI;AAChE,MAAI,CAAC,WAAW,YAAY;AAE1B,uBAAK,qBAAsB;AAC3B,uBAAKE,YAAU,MAAM,OAAO;AAC5B,uBAAK,qBAAsB;AAAA,EAC7B;AACF;AAEA,kBAAa,SAAC,SAA6B;AACzC,MAAI,CAAC,mBAAK,mBAAkB,QAAQ,WAAW,GAAG;AAChD,QAAI,QAAQ,SAAS,EAAG;AACxB,0BAAK,4CAAL;AACA;AAAA,EACF;AACA,aAAW,UAAU,SAAS;AAC5B,uBAAK,gBAAe,UAAU,OAAO,YAAY,OAAO,IAAI;AAC5D,QAAI,OAAO,KAAK,MAAM;AACpB,yBAAK,UAAS,KAAK,eAAe,EAAE,SAAS,OAAO,KAAK,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF;AACA,wBAAK,uDAAL;AACA,wBAAK,4CAAL;AACF;AAEA,qBAAgB,WAAS;AACvB,MAAI,CAAC,mBAAK,mBAAkB,CAAC,mBAAKD,YAAU,CAAC,mBAAK,eAAe;AACjE,QAAM,YAAY,mBAAK,eAAc,kBAAkB;AACvD,QAAM,WAAW,YAAa,mBAAKA,SAAO,YAAY,SAAS,KAAK,OAAQ;AAC5E,qBAAK,gBAAe,OAAO,UAAU,YAAY,mBAAK,eAAc,OAAO,SAAS,IAAI,MAAS;AACnG;AAaK,SAAS,UAAU,WAAwB,UAA0B,CAAC,GAAY;AACvF,kBAAgB,SAAS;AACzB,SAAO,IAAI,YAAY,WAAW,OAAO;AAC3C;;;AuB9xBA,IAAM,SAAiB,CAAC,SAAS,OAAO;AACxC,IAAMG,iBAAgB;AAEtB,SAAS,eAAe,QAAgB,SAAyB;AAC/D,SAAO;AAAA,IACL,OAAO,CAAC,IAAI,UAAUA,iBAAgB,KAAK,IAAK,OAAO,CAAC,IAAI,KAAK,KAAM,GAAG;AAAA,IAC1E,OAAO,CAAC,IAAI,UAAUA;AAAA,EACxB;AACF;AAEA,SAAS,QAAQ,MAA4B;AAC3C,MAAI,IAAI,SAAS;AACjB,SAAO,MAAM;AACX,QAAK,IAAI,UAAU,eAAgB;AACnC,WAAO,IAAI;AAAA,EACb;AACF;AAEA,SAAS,eAAe,MAA0B,GAAW,GAAoB;AAC/E,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,IAAI,KAAK,QAAQ,IAAI,KAAK;AAC7D,UAAM,KAAK,KAAK,CAAC;AACjB,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,CAAC,IAAI,EAAE,IAAI;AACjB,UAAM,CAAC,IAAI,EAAE,IAAI;AACjB,QAAI,KAAK,MAAM,KAAK,KAAK,KAAM,KAAK,OAAO,IAAI,OAAQ,KAAK,MAAM,GAAI,UAAS,CAAC;AAAA,EAClF;AACA,SAAO;AACT;AAYA,IAAM,YAA4B;AAAA,EAChC,EAAE,IAAI,UAAU,MAAM,cAAc,IAAI,MAAM,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,QAAQ,EAAE;AAAA,EAChF,EAAE,IAAI,UAAU,MAAM,aAAa,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,QAAQ,EAAE;AAAA,EAC9E,EAAE,IAAI,UAAU,MAAM,eAAe,IAAI,KAAK,IAAI,MAAM,GAAG,KAAK,GAAG,KAAK,QAAQ,EAAE;AACpF;AAEA,IAAM,cAAc,CAAC,KAAK,KAAK,KAAK,GAAG;AACvC,IAAM,QAA0B,CAAC,IAAI,GAAG;AAGxC,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,aAAa;AACnB,IAAM,SAAS;AACf,IAAM,cAAc;AACpB,IAAM,cAAc;AAEpB,IAAM,iBAAiB;AAAA,EACrB,EAAE,IAAI,eAAe,MAAM,WAAW,UAAU,UAAU;AAAA,EAC1D,EAAE,IAAI,YAAY,MAAM,gBAAgB,UAAU,UAAU;AAAA,EAC5D,EAAE,IAAI,gBAAgB,MAAM,YAAY,UAAU,UAAU;AAAA,EAC5D,EAAE,IAAI,cAAc,MAAM,UAAU,UAAU,UAAU;AAAA,EACxD,EAAE,IAAI,mBAAmB,MAAM,eAAe,UAAU,UAAU;AACpE;AAGA,SAAS,iBAAiB,MAAwC;AAChE,QAAM,KAAK,KAAK,IAAI;AACpB,QAAM,KAAK,KAAK,IAAI;AACpB,QAAM,MAA0B,CAAC;AACjC,MAAI,KAAK,GAAG,WAAW,QAAQ,GAAG;AAChC,UAAM,OAAO,KAAK;AAClB,QAAI,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;AACvD,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,IAAI,KAAK,KAAK,IAAK,IAAI,KAAM,KAAK;AACxC,UAAI,KAAK,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAAA,IACvD;AAAA,EACF,WAAW,KAAK,GAAG,WAAW,QAAQ,GAAG;AACvC,UAAM,KAAK;AACX,QAAI,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAAA,EACzE,OAAO;AACL,QAAI,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;AAC7C,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,YAAM,IAAK,IAAI,KAAM,KAAK,KAAK;AAC/B,UAAI,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAAA,IAClF;AACA,QAAI,KAAK,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,eAAoD;AAC3E,QAAM,OAAO,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAC/D,QAAM,QAAQ,KAAK,CAAC;AACpB,MAAI,MAAO,MAAK,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AACzC,SAAO,EAAE,MAAM,WAAW,aAAa,CAAC,IAAI,EAAE;AAChD;AAEA,SAAS,YAAY,IAAY,IAAY,GAAW,GAA+B;AACrF,SAAO;AAAA,IACL,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,IACvB,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,IACvB,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,IACvB,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AAAA,EACzB;AACF;AA9HA;AAgIO,IAAM,oBAAN,MAAiD;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtD,YAAY,UAA8C,CAAC,GAAG;AAP9D;AACA;AAOE,uBAAK,OAAQ,QAAQ,QAAQ;AAC7B,uBAAK,SAAU,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,UAAU,CAAC,CAAC;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,aAAiC;AACrC,UAAM,YAA2B,CAAC;AAClC,UAAM,QAAmB,CAAC;AAC1B,UAAM,SAAqB,CAAC;AAC5B,UAAM,YAA2B,CAAC;AAClC,UAAM,mBAAyC,CAAC;AAEhD,UAAM,OAAO,CAAC,GAAY,MAAqB;AAC7C,UAAI,CAAC,EAAE,SAAS,SAAS,EAAE,EAAE,EAAG,GAAE,SAAS,KAAK,EAAE,EAAE;AACpD,UAAI,CAAC,EAAE,SAAS,SAAS,EAAE,EAAE,EAAG,GAAE,SAAS,KAAK,EAAE,EAAE;AAAA,IACtD;AAGA,UAAM,iBAAiB;AAGvB,UAAM,QAAgE,CAAC;AACvE,UAAM,cAAc,oBAAI,IAAqB;AAC7C,aAAS,KAAK,GAAG,KAAK,mBAAK,UAAS,MAAM;AACxC,eAAS,KAAK,GAAG,KAAK,mBAAK,UAAS,MAAM;AACxC,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,KAAK;AAChB,cAAM,aAAa,mBAAK,WAAU,IAAI,KAAK,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,KAAK;AACvE,cAAM,UAAU,aAAa,UAAU;AACvC,cAAM,YAAqB;AAAA,UACzB,IAAI;AAAA,UACJ,KAAK,eAAe,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AAAA,UACnD,KAAK,eAAe,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AAAA,UACnD,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,UAAU,CAAC;AAAA,QACb;AACA,cAAM,KAAK,SAAS;AACpB,oBAAY,IAAI,SAAS,SAAS;AAClC,mBAAW,KAAK,WAAW;AACzB,gBAAM,KAAK;AAAA,YACT,GAAG;AAAA,YACH,IAAI,GAAG,EAAE,EAAE,GAAG,UAAU;AAAA,YACxB,MAAM,mBAAK,WAAU,IAAI,GAAG,EAAE,IAAI,IAAI,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,KAAK,EAAE;AAAA,YACpE,IAAI,EAAE,KAAK;AAAA,YACX,IAAI,EAAE,KAAK;AAAA,YACX;AAAA,YACA,QAAQ,MAAM,CAAC,IAAI;AAAA,UACrB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,YAAY,IAAI,KAAK,OAAO;AAC9C,UAAI,CAAC,UAAW;AAChB,UAAI,SAAS;AACb,eAAS,IAAI,GAAG,IAAI,KAAK,GAAG,QAAQ,IAAK,UAAU,SAAS,KAAK,KAAK,GAAG,WAAW,CAAC,MAAO;AAC5F,YAAM,UAAU,mBAAK,SAAS,SAAS;AACvC,YAAM,UAAU,iBAAiB,IAAI;AACrC,YAAM,aAAa,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAwB,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,EAAE,CAAC;AACvF,YAAM,WAAW,KAAK,SAAS,KAAK,KAAK,IAAI,IAAI;AAEjD,YAAM,WAAwB,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,QAAQ,CAAC,EAAE;AACzE,YAAM,kBAA4B,CAAC;AAEnC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,MAAM,QAAQ,UAAU,IAAI,IAAI;AACtC,cAAM,UAAU,GAAG,KAAK,EAAE,KAAK,OAAO,CAAC,CAAC;AACxC,iBAAS,OAAO,KAAK;AAAA,UACnB,IAAI;AAAA,UACJ,MAAM,YAAY,CAAC,KAAK,OAAO,CAAC;AAAA,UAChC,OAAO;AAAA,UACP,YAAY,KAAK;AAAA,QACnB,CAAC;AAGD,eAAO,KAAK;AAAA,UACV,IAAI,GAAG,OAAO;AAAA,UACd;AAAA,UACA,SAAS;AAAA,UACT,MAAM;AAAA,UACN,UAAU,gBAAgB,UAAU;AAAA,QACtC,CAAC;AAGD,cAAM,WAAoB;AAAA,UACxB,IAAI,GAAG,OAAO;AAAA,UACd,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AAAA,UACvC,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AAAA,UACvC;AAAA,UACA,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,UAAU,CAAC;AAAA,QACb;AACA,cAAM,KAAK,QAAQ;AACnB,wBAAgB,KAAK,SAAS,EAAE;AAGhC,cAAM,WAAW,QAAQ;AACzB,cAAM,SAAS,KAAK,KAAK,KAAK,IAAI,IAAI,SAAS,OAAO,QAAQ;AAC9D,cAAM,OAAO,KAAK,KAAK,KAAK,IAAI,IAAI,SAAS,QAAQ;AACrD,cAAM,iBAA4B,CAAC;AACnC,YAAI,WAAW;AAEf,iBAAS,KAAK,QAAQ,MAAM,OAAO,MAAM,MAAM,UAAU;AACvD,gBAAM,QAAQ,KAAK,QAAQ,IAAI,OAAO;AACtC,gBAAM,WAAoB;AAAA,YACxB,IAAI,GAAG,OAAO,OAAO,OAAO,eAAe,MAAM,CAAC;AAAA,YAClD,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,YACrC,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,YACrC;AAAA,YACA,YAAY;AAAA,YACZ,aAAa;AAAA,YACb,UAAU,CAAC;AAAA,UACb;AACA,gBAAM,KAAK,QAAQ;AACnB,yBAAe,KAAK,QAAQ;AAE5B,gBAAM,SAA6B;AAAA,YACjC,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK,KAAK,UAAU;AAAA,YACpD,CAAC,KAAK,KAAK,YAAY,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM;AAAA,UACtD;AACA,qBAAW,CAAC,KAAK,GAAG,KAAK,QAAQ;AAC/B,gBAAI,SAAS,MAAM,IAAI,IAAI;AAC3B,gBAAI,WAAoB;AACxB,kBAAM,SAAS,KAAK,QAAQ;AAC5B,mBAAO,SAAS,MAAM,aAAa;AACjC,oBAAM,KAAK,cAAc,IAAI,IAAI;AACjC,kBAAI,SAAS,KAAK,IAAK;AACvB,oBAAM,MAAM,MAAM,IAAI,IAAI;AAC1B,kBAAI,IAAI,IAAI,MAAM;AAChB,0BAAU,KAAK;AACf;AAAA,cACF;AACA,oBAAM,QAAQ,SAAS,OAAO,IAAI,IAAI;AACtC,oBAAM,KAAK,SAAS,KAAK;AACzB,oBAAM,MAAM,SAAS,QAAQ;AAC7B,oBAAM,UAA8B;AAAA,gBAClC,CAAC,KAAK,KAAK,IAAI,QAAQ,SAAS,CAAC;AAAA,gBACjC,CAAC,KAAK,KAAK,IAAI,QAAQ,SAAS,CAAC;AAAA,gBACjC,CAAC,KAAK,KAAK,IAAI,QAAQ,SAAS,QAAQ,MAAM;AAAA,gBAC9C,CAAC,KAAK,KAAK,IAAI,QAAQ,SAAS,QAAQ,MAAM;AAAA,cAChD;AACA,kBAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,eAAe,YAAY,IAAI,EAAE,CAAC,GAAG;AACpE,0BAAU,KAAK;AACf;AAAA,cACF;AACA;AACA,oBAAM,UAAU,GAAG,OAAO,KAAK,OAAO,QAAQ,EAAE,SAAS,GAAG,GAAG,CAAC;AAEhE,qBAAO,KAAK;AAAA,gBACV,IAAI,GAAG,OAAO;AAAA,gBACd;AAAA,gBACA,SAAS;AAAA,gBACT,MAAM;AAAA,gBACN,UAAU,gBAAgB,YAAY,IAAI,KAAK,IAAI,KAAK,CAAC;AAAA,cAC3D,CAAC;AAED,oBAAM,YAAqB;AAAA,gBACzB,IAAI,GAAG,OAAO;AAAA,gBACd,KAAK,eAAe,IAAI,KAAK,EAAE,CAAC;AAAA,gBAChC,KAAK,eAAe,IAAI,KAAK,EAAE,CAAC;AAAA,gBAChC;AAAA,gBACA,YAAY;AAAA,gBACZ,aAAa;AAAA,gBACb,UAAU,CAAC;AAAA,cACb;AACA,oBAAM,KAAK,SAAS;AACpB,mBAAK,UAAU,SAAS;AACxB,yBAAW;AAEX,oBAAM,MAAM,eAAe,KAAK,MAAM,IAAI,IAAI,eAAe,MAAM,CAAC;AACpE,wBAAU,KAAK;AAAA,gBACb,IAAI,GAAG,OAAO;AAAA,gBACd,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,IAAI,YAAY,CAAC,KAAK,OAAO,CAAC,CAAC,IAAI,OAAO,QAAQ,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,gBAC/G,MAAM;AAAA,gBACN,QAAQ,UAAU;AAAA,gBAClB,SAAS,GAAG,OAAO;AAAA,gBACnB,aAAa,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;AAAA,gBAC/B,QAAQ;AAAA,gBACR,WAAW;AAAA,cACb,CAAC;AACD,wBAAU,KAAK;AAAA,YACjB;AAAA,UACF;AAAA,QACF;AAGA,iBAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,gBAAM,IAAI,eAAe,IAAI,CAAC;AAC9B,gBAAM,IAAI,eAAe,CAAC;AAC1B,cAAI,KAAK,EAAG,MAAK,GAAG,CAAC;AAAA,QACvB;AAEA,YAAI;AACJ,YAAI,cAAc;AAClB,mBAAW,MAAM,gBAAgB;AAC/B,gBAAM,IAAI,KAAK,IAAI,GAAG,MAAM,SAAS,GAAG;AACxC,cAAI,IAAI,aAAa;AACnB,0BAAc;AACd,sBAAU;AAAA,UACZ;AAAA,QACF;AACA,YAAI,QAAS,MAAK,UAAU,OAAO;AAGnC,YAAI,MAAM,GAAG;AACX,gBAAM,QAAQ,KAAK,KAAK,YAAY,KAAK,IAAI;AAC7C,gBAAM,WAAoB;AAAA,YACxB,IAAI,GAAG,KAAK,EAAE;AAAA,YACd,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,YACrC,KAAK,eAAe,KAAK,IAAI,KAAK,EAAE,CAAC;AAAA,YACrC;AAAA,YACA,YAAY;AAAA,YACZ,aAAa;AAAA,YACb,UAAU,CAAC;AAAA,UACb;AACA,gBAAM,YAAqB;AAAA,YACzB,IAAI,GAAG,KAAK,EAAE;AAAA,YACd,KAAK,eAAe,KAAK,IAAI,QAAQ,WAAW,EAAE,EAAE,CAAC;AAAA,YACrD,KAAK,eAAe,KAAK,IAAI,QAAQ,WAAW,EAAE,EAAE,CAAC;AAAA,YACrD,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,aAAa;AAAA,YACb,UAAU,CAAC;AAAA,UACb;AACA,gBAAM,KAAK,UAAU,SAAS;AAE9B,gBAAM,cAAc,aAAa,KAAK,eAAe,CAAC,IAAI,eAAe,eAAe,SAAS,CAAC;AAClG,cAAI,YAAa,MAAK,UAAU,WAAW;AAC3C,eAAK,UAAU,SAAS;AACxB,eAAK,WAAW,SAAS;AACzB,oBAAU,KAAK;AAAA,YACb,IAAI,GAAG,KAAK,EAAE;AAAA,YACd,MAAM,GAAG,KAAK,IAAI;AAAA,YAClB,MAAM;AAAA,YACN,QAAQ,SAAS;AAAA,YACjB,aAAa,CAAC;AAAA,YACd,QAAQ;AAAA,YACR,WAAW;AAAA,UACb,CAAC;AAAA,QACH;AAAA,MACF;AAIA,eAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;AAC/C,cAAM,cAAc,gBAAgB,IAAI,CAAC;AACzC,cAAM,YAAY,gBAAgB,CAAC;AACnC,YAAI,CAAC,eAAe,CAAC,UAAW;AAChC,yBAAiB,KAAK;AAAA,UACpB,IAAI,GAAG,KAAK,EAAE,aAAa,OAAO,CAAC,CAAC;AAAA,UACpC,MAAM;AAAA,UACN,MAAM,GAAG,KAAK,IAAI;AAAA,UAClB,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,WAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAEA,WAAO;AAAA,MACL,MAAM,EAAE,IAAI,aAAa,MAAM,eAAe,QAAQ,OAAO;AAAA,MAC7D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,eAAe,IAAI,CAAC,GAAG,OAAO;AAAA,QACxC,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,WAAW;AAAA,QACX,UAAU,EAAE;AAAA,MACd,EAAE;AAAA,MACF,YAAY,CAAC;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAnSE;AACA;;;ACjIF,OAAO,eAAe;AAGtB,IAAM,UAAU,UAAU;AAA1B,IAAkC,UAAU,UAAU;AAAtD,IAA8D,QAAQ,UAAU;AAChF,IAAM,UAAU,MAAM,OAAO;AAA7B,IAAqC,aAAa,MAAM,OAAO;AAA/D,IAA0E,SAAS,MAAM,OAAO;AAGhG,IAAM,QAAQ,UAAU,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS,IAAI,CAAC;AAEpE,IAAM,MAAM,MAAM,OAAO,MAAM;AAOlC,QAAMC,OAAM,CAAC;AAEb,EAAAA,KAAI,QAAQ,WAAW;AAOnB,UAAM,OAAO,CAAC;AAEd,SAAK,YAAY,WAAW;AAOxB,YAAM,WAAW,CAAC;AAElB,eAAS,YAAY,WAAW;AAoC5B,cAAM,WAAW,SAAU,YAAY;AACnC,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,iBAAS,UAAU,aAAa;AAQhC,iBAAS,UAAU,OAAO;AAQ1B,iBAAS,UAAU,sBAAsB;AAQzC,iBAAS,UAAU,YAAY;AAQ/B,iBAAS,UAAU,QAAQ;AAQ3B,iBAAS,UAAU,aAAa;AAQhC,iBAAS,UAAU,SAAS;AAc5B,iBAAS,SAAS,SAAS,YAAY;AACnC,iBAAO,IAAI,SAAS,UAAU;AAAA,QAClC;AAWA,iBAAS,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACjD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,QAAQ,eAAe;AAC3G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,UAAU;AACtE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,IAAI;AAChE,cAAI,QAAQ,uBAAuB,QAAQ,QAAQ,eAAe,KAAK,SAAS,qBAAqB,KAAK,QAAQ,wBAAwB;AACtI,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,mBAAmB;AAC/E,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW,KAAK,QAAQ,cAAc;AACxG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,MAAM,QAAQ,SAAS;AACpE,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO;AACrE,kBAAM,IAAI,KAAK,SAAS,MAAM,OAAO,QAAQ,OAAO,OAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC5H,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,QAAQ,eAAe;AAC3G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,UAAU;AACtE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,iBAAS,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC/D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,SAAS,GAAG;AACjI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,sBAAsB;AAAA;AAE9B,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,MAAM;AACrB,0BAAQ,YAAY;AAAA;AAEpB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,wBAAQ,QAAQ,MAAM,IAAI,KAAK,SAAS,MAAM,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,GAAG,QAAQ,KAAK;AACnH;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,iBAAS,aAAa,SAAS,QAAQ;AACnC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,SAAS,WAAW;AAgCzB,cAAMC,SAAQ,SAAU,YAAY;AAChC,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,QAAAA,OAAM,UAAU,OAAO;AAQvB,QAAAA,OAAM,UAAU,MAAM;AAQtB,QAAAA,OAAM,UAAU,UAAU;AAc1B,QAAAA,OAAM,SAAS,SAAS,YAAY;AAChC,iBAAO,IAAIA,OAAM,UAAU;AAAA,QAC/B;AAWA,QAAAA,OAAM,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAC9C,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,IAAI;AAChE,cAAI,QAAQ,OAAO,QAAQ,QAAQ,eAAe,KAAK,SAAS,KAAK,KAAK,QAAQ,QAAQ;AACtF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,GAAG;AAC/D,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,CAAC,QAAQ,GAAG,QAAQ,SAAS,CAAC;AAC5G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACnE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,QAAAA,OAAM,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC5D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,MAAM,GAAG;AAC9H,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,MAAM;AAAA;AAEd,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,QAAAA,OAAM,aAAa,SAAS,QAAQ;AAChC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAOA;AAAA,MACX,GAAG;AAEH,eAAS,gBAAgB,WAAW;AA8BhC,cAAM,eAAe,SAAU,YAAY;AACvC,eAAK,aAAa,CAAC;AACnB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,qBAAa,UAAU,aAAa,MAAM;AAc1C,qBAAa,SAAS,SAAS,YAAY;AACvC,iBAAO,IAAI,aAAa,UAAU;AAAA,QACtC;AAWA,qBAAa,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACrD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,cAAc,QAAQ,QAAQ,WAAW;AACjD,qBAAS,IAAI,GAAG,IAAI,QAAQ,WAAW,QAAQ,EAAE;AAC7C,oBAAM,IAAI,KAAK,SAAS,SAAS,OAAO,QAAQ,WAAW,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC3I,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,qBAAa,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACnE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,aAAa;AAClI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,cAAc,QAAQ,WAAW;AAC3C,0BAAQ,aAAa,CAAC;AAC1B,wBAAQ,WAAW,KAAK,MAAM,IAAI,KAAK,SAAS,SAAS,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AAChH;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,qBAAa,aAAa,SAAS,QAAQ;AACvC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,aAAO;AAAA,IACX,GAAG;AAEH,SAAK,YAAY,WAAW;AAOxB,YAAM,WAAW,CAAC;AAElB,eAAS,YAAY,WAAW;AAyD5B,cAAM,WAAW,SAAU,YAAY;AACnC,eAAK,QAAQ,CAAC;AACd,eAAK,SAAS,CAAC;AACf,eAAK,iBAAiB,CAAC;AACvB,eAAK,QAAQ,CAAC;AACd,eAAK,gBAAgB,CAAC;AACtB,eAAK,aAAa,CAAC;AACnB,eAAK,OAAO,CAAC;AACb,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,iBAAS,UAAU,aAAa;AAQhC,iBAAS,UAAU,aAAa;AAQhC,iBAAS,UAAU,OAAO;AAQ1B,iBAAS,UAAU,OAAO;AAQ1B,iBAAS,UAAU,cAAc;AAQjC,iBAAS,UAAU,SAAS;AAQ5B,iBAAS,UAAU,YAAY;AAQ/B,iBAAS,UAAU,SAAS;AAQ5B,iBAAS,UAAU,YAAY;AAQ/B,iBAAS,UAAU,UAAU;AAQ7B,iBAAS,UAAU,QAAQ,MAAM;AAQjC,iBAAS,UAAU,SAAS,MAAM;AAQlC,iBAAS,UAAU,iBAAiB,MAAM;AAQ1C,iBAAS,UAAU,QAAQ,MAAM;AAQjC,iBAAS,UAAU,gBAAgB,MAAM;AAQzC,iBAAS,UAAU,iCAAiC;AAQpD,iBAAS,UAAU,aAAa,MAAM;AAQtC,iBAAS,UAAU,YAAY;AAQ/B,iBAAS,UAAU,OAAO,MAAM;AAQhC,iBAAS,UAAU,UAAU;AAQ7B,iBAAS,UAAU,SAAS;AAQ5B,iBAAS,UAAU,OAAO;AAQ1B,iBAAS,UAAU,OAAO;AAQ1B,iBAAS,UAAU,cAAc;AAQjC,iBAAS,UAAU,WAAW;AAQ9B,iBAAS,UAAU,UAAU;AAQ7B,iBAAS,UAAU,YAAY;AAQ/B,iBAAS,UAAU,OAAO;AAc1B,iBAAS,SAAS,SAAS,YAAY;AACnC,iBAAO,IAAI,SAAS,UAAU;AAAA,QAClC;AAWA,iBAAS,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACjD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,QAAQ,eAAe;AAC3G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,UAAU;AACtE,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,QAAQ,eAAe;AAC3G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,UAAU;AACtE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,IAAI;AAChE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,IAAI;AAChE,cAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAK,SAAS,aAAa,KAAK,QAAQ,gBAAgB;AAC9G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,WAAW;AACvE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW,KAAK,QAAQ,cAAc;AACxG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,SAAS;AACrE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,KAAK,QAAQ,MAAM;AAChE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW,KAAK,QAAQ,cAAc;AACxG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,MAAM,QAAQ,SAAS;AACpE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACpE,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO;AACrE,qBAAS,OAAO,QAAQ,KAAK,QAAQ,KAAK,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AACnE,qBAAO;AAAA;AAAA,gBAA+B;AAAA,cAAE,EAAE,KAAK,EAAE;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,QAAQ,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO;AACnL,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ;AACvE,qBAAS,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AACpE,qBAAO;AAAA;AAAA,gBAA+B;AAAA,cAAE,EAAE,KAAK,EAAE;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO;AACpL,cAAI,QAAQ,kBAAkB,QAAQ,QAAQ,eAAe;AACzD,qBAAS,IAAI,GAAG,IAAI,QAAQ,eAAe,QAAQ,EAAE;AACjD,oBAAM,IAAI,KAAK,SAAS,cAAc,OAAO,QAAQ,eAAe,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA+B;AAAA,cAAG,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AACtJ,cAAI,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AACvC,qBAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,QAAQ,EAAE;AACxC,oBAAM,IAAI,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA+B;AAAA,cAAG,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AACpI,cAAI,QAAQ,iBAAiB,QAAQ,QAAQ,cAAc;AACvD,qBAAS,IAAI,GAAG,IAAI,QAAQ,cAAc,QAAQ,EAAE;AAChD,oBAAM,IAAI,KAAK,SAAS,aAAa,OAAO,QAAQ,cAAc,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA+B;AAAA,cAAG,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AACpJ,cAAI,QAAQ,kCAAkC,QAAQ,QAAQ,eAAe,KAAK,SAAS,gCAAgC,KAAK,QAAQ,mCAAmC;AACvK,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,KAAK,QAAQ,8BAA8B;AAC1F,cAAI,QAAQ,cAAc,QAAQ,QAAQ,WAAW;AACjD,qBAAS,IAAI,GAAG,IAAI,QAAQ,WAAW,QAAQ,EAAE;AAC7C,qBAAO;AAAA;AAAA,gBAA+B;AAAA,cAAG,EAAE,OAAO,QAAQ,WAAW,CAAC,CAAC;AAC/E,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW,KAAK,QAAQ,cAAc;AACxG,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,OAAO,QAAQ,SAAS;AACvE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,KAAK;AACrC,qBAAS,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,EAAE;AACvC,qBAAO;AAAA;AAAA,gBAA+B;AAAA,cAAG,EAAE,OAAO,QAAQ,KAAK,CAAC,CAAC;AACzE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,OAAO,QAAQ,OAAO;AACrE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,OAAO,QAAQ,MAAM;AACpE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,OAAO,QAAQ,IAAI;AAClE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM;AACnE,kBAAM,IAAI,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,OAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC5H,cAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAK,SAAS,aAAa,KAAK,QAAQ,gBAAgB;AAC9G,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,KAAK,QAAQ,WAAW;AACvE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,QAAQ,aAAa;AACrG,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,KAAK,QAAQ,QAAQ;AACpE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,MAAM,QAAQ,OAAO;AACpE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,kBAAM,IAAI,KAAK,SAAS,UAAU,OAAO,QAAQ,WAAW,OAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AACtI,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA+B;AAAA,YAAG,EAAE,OAAO,QAAQ,IAAI;AAClE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,iBAAS,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC/D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,SAAS,GAAG,KAAK;AACtI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,cAAc;AAAA;AAEtB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,YAAY;AAAA;AAEpB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,MAAM;AACrB,0BAAQ,YAAY;AAAA;AAEpB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,UAAU,MAAM;AACxB,0BAAQ,QAAQ,CAAC;AACrB,oBAAI,OAAO,OAAO,OAAO,IAAI,OAAO;AACpC,sBAAM;AACN,wBAAQ;AACR,uBAAO,OAAO,MAAM,MAAM;AACtB,sBAAI,OAAO,OAAO,IAAI;AACtB,6BAAW,OAAO;AAClB,0BAAQ,UAAU,GAAG;AAAA,oBACrB,KAAK;AACD,0BAAI,aAAa;AACb;AACJ,4BAAM,OAAO,aAAa;AAC1B;AAAA,oBACJ,KAAK;AACD,0BAAI,aAAa;AACb;AACJ,8BAAQ,OAAO,aAAa;AAC5B;AAAA,kBACJ;AACA,yBAAO,SAAS,UAAU,QAAQ,IAAI;AAAA,gBAC1C;AACA,oBAAI,QAAQ;AACR,wBAAM,SAAS,QAAQ,OAAO,GAAG;AACrC,wBAAQ,MAAM,GAAG,IAAI;AACrB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,WAAW,MAAM;AACzB,0BAAQ,SAAS,CAAC;AACtB,oBAAI,OAAO,OAAO,OAAO,IAAI,OAAO;AACpC,sBAAM;AACN,wBAAQ;AACR,uBAAO,OAAO,MAAM,MAAM;AACtB,sBAAI,OAAO,OAAO,IAAI;AACtB,6BAAW,OAAO;AAClB,0BAAQ,UAAU,GAAG;AAAA,oBACrB,KAAK;AACD,0BAAI,aAAa;AACb;AACJ,4BAAM,OAAO,aAAa;AAC1B;AAAA,oBACJ,KAAK;AACD,0BAAI,aAAa;AACb;AACJ,8BAAQ,OAAO,aAAa;AAC5B;AAAA,kBACJ;AACA,yBAAO,SAAS,UAAU,QAAQ,IAAI;AAAA,gBAC1C;AACA,oBAAI,QAAQ;AACR,wBAAM,SAAS,QAAQ,QAAQ,GAAG;AACtC,wBAAQ,OAAO,GAAG,IAAI;AACtB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,kBAAkB,QAAQ,eAAe;AACnD,0BAAQ,iBAAiB,CAAC;AAC9B,wBAAQ,eAAe,KAAK,MAAM,IAAI,KAAK,SAAS,cAAc,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AACzH;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,SAAS,QAAQ,MAAM;AACjC,0BAAQ,QAAQ,CAAC;AACrB,wBAAQ,MAAM,KAAK,MAAM,IAAI,KAAK,SAAS,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AACvG;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,iBAAiB,QAAQ,cAAc;AACjD,0BAAQ,gBAAgB,CAAC;AAC7B,wBAAQ,cAAc,KAAK,MAAM,IAAI,KAAK,SAAS,aAAa,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AACvH;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,iCAAiC;AAAA;AAEzC,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,cAAc,QAAQ,WAAW;AAC3C,0BAAQ,aAAa,CAAC;AAC1B,wBAAQ,WAAW,KAAK,OAAO,aAAa,CAAC;AAC7C;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,YAAY;AAAA;AAEpB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,QAAQ,QAAQ,KAAK;AAC/B,0BAAQ,OAAO,CAAC;AACpB,wBAAQ,KAAK,KAAK,OAAO,aAAa,CAAC;AACvC;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,wBAAQ,OAAO,MAAM,IAAI,KAAK,SAAS,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,GAAG,QAAQ,IAAI;AAChH;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,cAAc;AAAA;AAEtB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,MAAM;AACrB,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,wBAAQ,YAAY,MAAM,IAAI,KAAK,SAAS,UAAU,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,GAAG,QAAQ,SAAS;AAC/H;AAAA,cACJ;AAAA,cACJ,KAAK,IAAI;AACD,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,iBAAS,aAAa,SAAS,QAAQ;AACnC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,QAAQ,WAAW;AA+BxB,cAAM,OAAO,SAAU,YAAY;AAC/B,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,aAAK,UAAU,SAAS;AAQxB,aAAK,UAAU,WAAW;AAc1B,aAAK,SAAS,SAAS,YAAY;AAC/B,iBAAO,IAAI,KAAK,UAAU;AAAA,QAC9B;AAWA,aAAK,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAC7C,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,QAAQ,aAAa;AACrG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,QAAQ;AACpE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,aAAK,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC3D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,KAAK,GAAG;AAC7H,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,aAAK,aAAa,SAAS,QAAQ;AAC/B,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,QAAQ,WAAW;AA+BxB,cAAM,OAAO,SAAU,YAAY;AAC/B,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,aAAK,UAAU,MAAM;AAQrB,aAAK,UAAU,QAAQ;AAcvB,aAAK,SAAS,SAAS,YAAY;AAC/B,iBAAO,IAAI,KAAK,UAAU;AAAA,QAC9B;AAWA,aAAK,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAC7C,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,OAAO,QAAQ,QAAQ,eAAe,KAAK,SAAS,KAAK,KAAK,QAAQ,QAAQ;AACtF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,GAAG;AAC/D,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,QAAQ,UAAU;AAC5F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,aAAK,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC3D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,KAAK,GAAG;AAC7H,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,MAAM;AAAA;AAEd,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,aAAK,aAAa,SAAS,QAAQ;AAC/B,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,gBAAgB,WAAW;AA+BhC,cAAM,eAAe,SAAU,YAAY;AACvC,eAAK,WAAW,CAAC;AACjB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,qBAAa,UAAU,QAAQ;AAQ/B,qBAAa,UAAU,WAAW,MAAM;AAcxC,qBAAa,SAAS,SAAS,YAAY;AACvC,iBAAO,IAAI,aAAa,UAAU;AAAA,QACtC;AAWA,qBAAa,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACrD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,QAAQ,UAAU;AAC5F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,SAAS;AAC7C,qBAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,EAAE;AAC3C,qBAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,QAAQ,SAAS,CAAC,CAAC;AAC3E,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,qBAAa,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACnE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,aAAa,GAAG;AACrI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,YAAY,QAAQ,SAAS;AACvC,0BAAQ,WAAW,CAAC;AACxB,wBAAQ,SAAS,KAAK,OAAO,aAAa,CAAC;AAC3C;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,qBAAa,aAAa,SAAS,QAAQ;AACvC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,iBAAiB,WAAW;AAgCjC,cAAM,gBAAgB,SAAU,YAAY;AACxC,eAAK,YAAY,CAAC;AAClB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,sBAAc,UAAU,QAAQ;AAQhC,sBAAc,UAAU,SAAS;AAQjC,sBAAc,UAAU,YAAY,MAAM;AAc1C,sBAAc,SAAS,SAAS,YAAY;AACxC,iBAAO,IAAI,cAAc,UAAU;AAAA,QACvC;AAWA,sBAAc,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACtD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,QAAQ,UAAU;AAC5F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,UAAU;AAC/C,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,QAAQ,UAAU,CAAC,CAAC;AAC5E,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,sBAAc,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACpE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,cAAc,GAAG;AACtI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,aAAa,QAAQ,UAAU;AACzC,0BAAQ,YAAY,CAAC;AACzB,wBAAQ,UAAU,KAAK,OAAO,aAAa,CAAC;AAC5C;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,sBAAc,aAAa,SAAS,QAAQ;AACxC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,aAAa,WAAW;AAkC7B,cAAM,YAAY,SAAU,YAAY;AACpC,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,kBAAU,UAAU,YAAY;AAQhC,kBAAU,UAAU,QAAQ;AAQ5B,kBAAU,UAAU,WAAW;AAQ/B,kBAAU,UAAU,gBAAgB;AAQpC,kBAAU,UAAU,aAAa;AAcjC,kBAAU,SAAS,SAAS,YAAY;AACpC,iBAAO,IAAI,UAAU,UAAU;AAAA,QACnC;AAWA,kBAAU,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAClD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW,KAAK,QAAQ,cAAc;AACxG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,SAAS;AACrE,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,CAAC,QAAQ,GAAG,QAAQ,OAAO,CAAC;AACtG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,CAAC,QAAQ,GAAG,QAAQ,UAAU,CAAC;AAC/G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,QAAQ;AACpE,cAAI,QAAQ,iBAAiB,QAAQ,QAAQ,eAAe,KAAK,SAAS,eAAe,KAAK,CAAC,QAAQ,GAAG,QAAQ,eAAe,CAAC;AAC9H,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,aAAa;AACzE,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,CAAC,QAAQ,GAAG,QAAQ,YAAY,CAAC;AACrH,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,UAAU;AACtE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,kBAAU,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAChE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,UAAU,GAAG;AAClI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,YAAY;AAAA;AAEpB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,gBAAgB;AAAA;AAExB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,kBAAU,aAAa,SAAS,QAAQ;AACpC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,eAAS,gBAAgB,WAAW;AA8BhC,cAAM,eAAe,SAAU,YAAY;AACvC,eAAK,YAAY,CAAC;AAClB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,qBAAa,UAAU,YAAY,MAAM;AAczC,qBAAa,SAAS,SAAS,YAAY;AACvC,iBAAO,IAAI,aAAa,UAAU;AAAA,QACtC;AAWA,qBAAa,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACrD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,aAAa,QAAQ,QAAQ,UAAU;AAC/C,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,oBAAM,IAAI,KAAK,SAAS,SAAS,OAAO,QAAQ,UAAU,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC1I,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,qBAAa,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACnE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,SAAS,aAAa;AAClI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,aAAa,QAAQ,UAAU;AACzC,0BAAQ,YAAY,CAAC;AACzB,wBAAQ,UAAU,KAAK,MAAM,IAAI,KAAK,SAAS,SAAS,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AAC/G;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,qBAAa,aAAa,SAAS,QAAQ;AACvC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,aAAO;AAAA,IACX,GAAG;AAEH,SAAK,cAAc,WAAW;AAO1B,YAAM,aAAa,CAAC;AAEpB,iBAAW,aAAa,WAAW;AAqC/B,cAAM,YAAY,SAAU,YAAY;AACpC,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,kBAAU,UAAU,KAAK;AAQzB,kBAAU,UAAU,SAAS;AAQ7B,kBAAU,UAAU,SAAS;AAQ7B,kBAAU,UAAU,gBAAgB;AAQpC,kBAAU,UAAU,QAAQ;AAQ5B,kBAAU,UAAU,WAAW;AAQ/B,kBAAU,UAAU,WAAW;AAQ/B,kBAAU,UAAU,QAAQ;AAc5B,kBAAU,SAAS,SAAS,YAAY;AACpC,iBAAO,IAAI,UAAU,UAAU;AAAA,QACnC;AAWA,kBAAU,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAClD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,MAAM,QAAQ,QAAQ,eAAe,KAAK,SAAS,IAAI,KAAK,QAAQ,OAAO;AACnF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,EAAE;AAC9D,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,iBAAiB,QAAQ,QAAQ,eAAe,KAAK,SAAS,eAAe,KAAK,QAAQ,kBAAkB;AACpH,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,aAAa;AACzE,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,CAAC,QAAQ,GAAG,QAAQ,OAAO,CAAC;AACtG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,CAAC,QAAQ,GAAG,QAAQ,UAAU,CAAC;AAC/G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,QAAQ;AACpE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,CAAC,QAAQ,GAAG,QAAQ,UAAU,CAAC;AAC/G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,QAAQ;AACpE,cAAI,QAAQ,SAAS,QAAQ,QAAQ,eAAe,KAAK,SAAS,OAAO,KAAK,CAAC,QAAQ,GAAG,QAAQ,OAAO,CAAC;AACtG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,KAAK;AACjE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,kBAAU,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAChE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,WAAW,UAAU,GAAG;AACpI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,KAAK;AAAA;AAEb,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,gBAAgB;AAAA;AAExB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,QAAQ;AAAA;AAEhB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,kBAAU,aAAa,SAAS,QAAQ;AACpC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,iBAAW,kBAAkB,WAAW;AA8BpC,cAAM,iBAAiB,SAAU,YAAY;AACzC,eAAK,aAAa,CAAC;AACnB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,uBAAe,UAAU,aAAa,MAAM;AAc5C,uBAAe,SAAS,SAAS,YAAY;AACzC,iBAAO,IAAI,eAAe,UAAU;AAAA,QACxC;AAWA,uBAAe,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACvD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,cAAc,QAAQ,QAAQ,WAAW;AACjD,qBAAS,IAAI,GAAG,IAAI,QAAQ,WAAW,QAAQ,EAAE;AAC7C,oBAAM,IAAI,KAAK,WAAW,UAAU,OAAO,QAAQ,WAAW,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC9I,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,uBAAe,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACrE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,WAAW,eAAe;AACtI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,cAAc,QAAQ,WAAW;AAC3C,0BAAQ,aAAa,CAAC;AAC1B,wBAAQ,WAAW,KAAK,MAAM,IAAI,KAAK,WAAW,UAAU,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AACnH;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,uBAAe,aAAa,SAAS,QAAQ;AACzC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,aAAO;AAAA,IACX,GAAG;AAEH,SAAK,QAAQ,WAAW;AAOpB,YAAM,OAAO,CAAC;AAEd,WAAK,QAAQ,WAAW;AAoCpB,cAAM,OAAO,SAAU,YAAY;AAC/B,eAAK,WAAW,CAAC;AACjB,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,aAAK,UAAU,SAAS;AAQxB,aAAK,UAAU,MAAM;AAQrB,aAAK,UAAU,MAAM;AAQrB,aAAK,UAAU,aAAa;AAQ5B,aAAK,UAAU,UAAU;AAQzB,aAAK,UAAU,WAAW,MAAM;AAQhC,aAAK,UAAU,cAAc;AAc7B,aAAK,SAAS,SAAS,YAAY;AAC/B,iBAAO,IAAI,KAAK,UAAU;AAAA,QAC9B;AAWA,aAAK,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAC7C,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,OAAO,QAAQ,QAAQ,eAAe,KAAK,SAAS,KAAK,KAAK,CAAC,QAAQ,GAAG,QAAQ,KAAK,CAAC;AAChG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,GAAG;AAC/D,cAAI,QAAQ,OAAO,QAAQ,QAAQ,eAAe,KAAK,SAAS,KAAK,KAAK,CAAC,QAAQ,GAAG,QAAQ,KAAK,CAAC;AAChG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,GAAG;AAC/D,cAAI,QAAQ,cAAc,QAAQ,QAAQ,eAAe,KAAK,SAAS,YAAY,KAAK,QAAQ,eAAe;AAC3G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,KAAK,QAAQ,UAAU;AACpE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACnE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,SAAS;AAC7C,qBAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,EAAE;AAC3C,qBAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,OAAO,QAAQ,SAAS,CAAC,CAAC;AAC3E,cAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAK,SAAS,aAAa,KAAK,QAAQ,gBAAgB;AAC9G,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,KAAK,QAAQ,WAAW;AACrE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,aAAK,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC3D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,KAAK,KAAK,GAAG;AACzH,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,MAAM;AAAA;AAEd,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,CAAC,QAAQ,GAAG,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC,0BAAQ,MAAM;AAAA;AAEd,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,aAAa;AAAA;AAErB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,YAAY,QAAQ,SAAS;AACvC,0BAAQ,WAAW,CAAC;AACxB,wBAAQ,SAAS,KAAK,OAAO,aAAa,CAAC;AAC3C;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,QAAQ,OAAO,KAAK;AACpB,0BAAQ,cAAc;AAAA;AAEtB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,aAAK,aAAa,SAAS,QAAQ;AAC/B,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,WAAK,YAAY,WAAW;AA8BxB,cAAM,WAAW,SAAU,YAAY;AACnC,eAAK,QAAQ,CAAC;AACd,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,iBAAS,UAAU,QAAQ,MAAM;AAcjC,iBAAS,SAAS,SAAS,YAAY;AACnC,iBAAO,IAAI,SAAS,UAAU;AAAA,QAClC;AAWA,iBAAS,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACjD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AACvC,qBAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,QAAQ,EAAE;AACxC,oBAAM,IAAI,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AAC9H,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,iBAAS,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAC/D,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,KAAK,SAAS;AAC1H,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,SAAS,QAAQ,MAAM;AACjC,0BAAQ,QAAQ,CAAC;AACrB,wBAAQ,MAAM,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AACnG;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,iBAAS,aAAa,SAAS,QAAQ;AACnC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,aAAO;AAAA,IACX,GAAG;AAEH,SAAK,aAAa,WAAW;AAOzB,YAAM,YAAY,CAAC;AAEnB,gBAAU,aAAa,WAAW;AAmC9B,cAAM,YAAY,SAAU,YAAY;AACpC,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,kBAAU,UAAU,UAAU;AAQ9B,kBAAU,UAAU,WAAW;AAQ/B,kBAAU,UAAU,OAAO;AAQ3B,kBAAU,UAAU,UAAU;AAQ9B,kBAAU,UAAU,SAAS;AAQ7B,kBAAU,UAAU,UAAU;AAc9B,kBAAU,SAAS,SAAS,YAAY;AACpC,iBAAO,IAAI,UAAU,UAAU;AAAA,QACnC;AAWA,kBAAU,SAAS,SAAU,SAAS,QAAQ,QAAQ;AAClD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACnE,cAAI,QAAQ,YAAY,QAAQ,QAAQ,eAAe,KAAK,SAAS,UAAU,KAAK,QAAQ,aAAa;AACrG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,QAAQ;AACpE,cAAI,QAAQ,QAAQ,QAAQ,QAAQ,eAAe,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS;AACzF,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,IAAI;AAChE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACnE,cAAI,QAAQ,UAAU,QAAQ,QAAQ,eAAe,KAAK,SAAS,QAAQ,KAAK,QAAQ,WAAW;AAC/F,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,MAAM;AAClE,cAAI,QAAQ,WAAW,QAAQ,QAAQ,eAAe,KAAK,SAAS,SAAS,KAAK,QAAQ,YAAY;AAClG,mBAAO;AAAA;AAAA,cAA8B;AAAA,YAAE,EAAE,OAAO,QAAQ,OAAO;AACnE,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,kBAAU,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAChE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,UAAU,UAAU,GAAG;AACnI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,WAAW;AAAA;AAEnB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,OAAO;AAAA;AAEf,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,SAAS;AAAA;AAEjB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,cACJ,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,qBAAK,QAAQ,OAAO,aAAa,GAAG;AAChC,0BAAQ,UAAU;AAAA;AAElB,yBAAO,QAAQ;AACnB;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,kBAAU,aAAa,SAAS,QAAQ;AACpC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,gBAAU,iBAAiB,WAAW;AA8BlC,cAAM,gBAAgB,SAAU,YAAY;AACxC,eAAK,SAAS,CAAC;AACf,cAAI;AACA,qBAAS,OAAO,QAAQ,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,KAAK,QAAQ,EAAE;AAChE,kBAAI,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ,KAAK,CAAC,MAAM;AAC3C,qBAAK,KAAK,CAAC,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA;AAAA,QAClD;AAQA,sBAAc,UAAU,SAAS,MAAM;AAcvC,sBAAc,SAAS,SAAS,YAAY;AACxC,iBAAO,IAAI,cAAc,UAAU;AAAA,QACvC;AAWA,sBAAc,SAAS,SAAU,SAAS,QAAQ,QAAQ;AACtD,cAAI,CAAC;AACD,qBAAS,QAAQ,OAAO;AAC5B,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,MAAM;AACf,kBAAM,OAAO,oBAAoB;AACrC,cAAI,QAAQ,UAAU,QAAQ,QAAQ,OAAO;AACzC,qBAAS,IAAI,GAAG,IAAI,QAAQ,OAAO,QAAQ,EAAE;AACzC,oBAAM,IAAI,KAAK,UAAU,UAAU,OAAO,QAAQ,OAAO,CAAC,GAAG,OAAO;AAAA;AAAA,gBAA8B;AAAA,cAAE,EAAE,KAAK,GAAG,SAAS,CAAC,EAAE,OAAO;AACzI,cAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KAAK,SAAS,WAAW;AAC7E,qBAAS,IAAI,GAAG,IAAI,QAAQ,UAAU,QAAQ,EAAE;AAC5C,qBAAO,IAAI,QAAQ,UAAU,CAAC,CAAC;AACvC,iBAAO;AAAA,QACX;AAaA,sBAAc,SAAS,SAAU,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AACpE,cAAI,EAAE,kBAAkB;AACpB,qBAAS,QAAQ,OAAO,MAAM;AAClC,cAAI,WAAW;AACX,qBAAS;AACb,cAAI,SAAS,QAAQ;AACjB,kBAAM,OAAO,oBAAoB;AACrC,cAAI,MAAM,WAAW,aAAa,OAAO,MAAM,OAAO,MAAM,QAAQ,UAAU,WAAW,IAAI,MAAM,IAAI,KAAK,UAAU,cAAc;AACpI,iBAAO,OAAO,MAAM,KAAK;AACrB,gBAAI,QAAQ,OAAO;AACnB,gBAAI,MAAM,OAAO,IAAI;AACrB,gBAAI,QAAQ,MAAM;AACd,qBAAO;AACP;AAAA,YACJ;AACA,gBAAI,WAAW,MAAM;AACrB,oBAAQ,SAAS,GAAG;AAAA,cACpB,KAAK,GAAG;AACA,oBAAI,aAAa;AACb;AACJ,oBAAI,EAAE,QAAQ,UAAU,QAAQ,OAAO;AACnC,0BAAQ,SAAS,CAAC;AACtB,wBAAQ,OAAO,KAAK,MAAM,IAAI,KAAK,UAAU,UAAU,OAAO,QAAQ,OAAO,OAAO,GAAG,YAAY,SAAS,CAAC,CAAC;AAC9G;AAAA,cACJ;AAAA,YACJ;AACA,mBAAO,SAAS,UAAU,QAAQ,GAAG;AACrC,gBAAI,CAAC,OAAO,gBAAgB;AACxB,oBAAM,SAAS,SAAS,aAAa,KAAK;AAC1C,eAAC,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,YACtF;AAAA,UACJ;AACA,cAAI,SAAS;AACT,kBAAM,OAAO,mBAAmB;AACpC,iBAAO;AAAA,QACX;AAUA,sBAAc,aAAa,SAAS,QAAQ;AACxC,cAAI,WAAW;AACX,qBAAS;AACb,iBAAO,SAAS;AAAA,QACpB;AAEA,eAAO;AAAA,MACX,GAAG;AAEH,aAAO;AAAA,IACX,GAAG;AAEH,WAAO;AAAA,EACX,GAAG;AAEH,SAAOD;AACX,GAAG;;;AChtHH,IAAM,qBAAqB;AAC3B,IAAM,cAAc;AASb,IAAM,YAAN,cAAwB,MAAM;AAAA,EAEnC,YAAY,QAAgB,KAAa;AACvC,UAAM,iBAAiB,OAAO,MAAM,CAAC,QAAQ,GAAG,EAAE;AAClD,SAAK,SAAS;AAAA,EAChB;AACF;AAEA,SAAS,cAAc,QAAmC;AACxD,QAAM,UAAU,YAAY,QAAQ,kBAAkB;AACtD,SAAO,SAAS,YAAY,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI;AACvD;AAEA,eAAe,QAAQ,SAAgC;AACrD,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,QAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,OAAO,MAAM,CAAC;AACnE;AAEA,eAAe,QAAQ,KAAa,SAAyC;AAC3E,MAAI;AACJ,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,QAAI,QAAQ,QAAQ,SAAS;AAC3B,YAAM,qBAAqB,QAAQ,YAAY,IAAI,aAAa,WAAW,YAAY;AAAA,IACzF;AACA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ,QAAQ,UAAU;AAAA,QAC1B,SAAS;AAAA,UACP,GAAI,QAAQ,SAAS,SAAY,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,UAC3E,GAAG,QAAQ;AAAA,QACb;AAAA,QACA,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,QAC3E,QAAQ,cAAc,QAAQ,MAAM;AAAA,MACtC,CAAC;AACD,UAAI,SAAS,UAAU,KAAK;AAC1B,oBAAY,IAAI,UAAU,SAAS,QAAQ,GAAG;AAC9C,cAAM,QAAQ,OAAO;AACrB;AAAA,MACF;AACA,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,SAAS,QAAQ,GAAG;AAC1D,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,UAAW,OAAM;AACpC,UAAI,QAAQ,QAAQ,QAAS,OAAM;AACnC,kBAAY;AACZ,UAAI,UAAU,YAAa,OAAM,QAAQ,OAAO;AAAA,IAClD;AAAA,EACF;AACA,QAAM,qBAAqB,QAAQ,YAAY,IAAI,MAAM,yBAAyB;AACpF;AAEA,eAAsB,UAAa,KAAa,UAAuB,CAAC,GAAe;AACrF,QAAM,WAAW,MAAM,QAAQ,KAAK,OAAO;AAC3C,SAAQ,MAAM,SAAS,KAAK;AAC9B;AAEA,eAAsB,YAAY,KAAa,UAAuB,CAAC,GAAwB;AAC7F,QAAM,WAAW,MAAM,QAAQ,KAAK,OAAO;AAC3C,SAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AACpD;;;ACVA,IAAM,kBAAuD;AAAA,EAC3D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AACR;AAUA,SAAS,kBACP,UAC2D;AAC3D,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,QAAQ;AAOlC,UAAM,WAAW,OAAO,SAAS,YAAY,OAAO,WAAW;AAC/D,QAAI,eAAyC;AAC7C,QAAI,UAAU,SAAS,aAAa,MAAM,QAAQ,SAAS,WAAW,GAAG;AACvE,qBAAe;AAAA,QACb,MAAM;AAAA,QACN,aAAa,SAAS;AAAA,MACxB;AAAA,IACF,WAAW,UAAU,SAAS,gBAAgB,MAAM,QAAQ,SAAS,WAAW,GAAG;AAEjF,qBAAe;AAAA,QACb,MAAM;AAAA,QACN,aAAa,SAAS;AAAA,MACxB;AAAA,IACF;AACA,QAAI,CAAC,aAAc,QAAO;AAC1B,UAAM,QAAQ,OAAO,SAAS,YAAY,OAAO,YAAY,kBAAkB;AAC/E,UAAM,QAAoB,CAAC;AAC3B,QAAI,OAAO,OAAO,WAAW,SAAU,OAAM,SAAS,MAAM;AAC5D,QAAI,OAAO,OAAO,UAAU,SAAU,OAAM,QAAQ,MAAM;AAC1D,QAAI,OAAO,OAAO,cAAc,SAAU,OAAM,YAAY,MAAM;AAClE,QAAI,OAAO,OAAO,YAAY,SAAU,OAAM,UAAU,MAAM;AAC9D,QAAI,OAAO,OAAO,OAAO,aAAa,SAAU,OAAM,YAAY,MAAM,MAAM;AAC9E,QAAI,OAAO,OAAO,OAAO,iBAAiB,SAAU,OAAM,gBAAgB,MAAM,MAAM;AACtF,WAAO,EAAE,UAAU,cAAc,MAAM;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAzHA;AAiIO,IAAM,oBAAN,MAAiD;AAAA,EAGtD,YAAY,SAAmC;AAF/C;AAGE,uBAAK,UAAW;AAAA,EAClB;AAAA,EAEA,MAAM,WAAW,QAA0C;AACzD,UAAM,EAAE,SAAS,QAAQ,UAAU,aAAa,IAAI,mBAAK;AACzD,UAAM,cAAc,SAAS,EAAE,OAAO,IAAI,CAAC;AAG3C,UAAM,OAAO,MAAM,UAAwB,GAAG,OAAO,mCAAmC;AAAA,MACtF,QAAQ;AAAA,MACR,MAAM,EAAE,UAAU,aAAa;AAAA,MAC/B,GAAG;AAAA,IACL,CAAC;AACD,UAAM,SAAS;AAAA,MACb,SAAS,EAAE,eAAe,UAAU,KAAK,WAAW,GAAG;AAAA,MACvD,GAAG;AAAA,IACL;AAGA,UAAM,OAAO,MAAM,UAAwB,GAAG,OAAO,oBAAoB,MAAM,IAAI,MAAM;AAMzF,UAAM,CAAC,YAAY,UAAU,UAAU,aAAa,aAAa,cAAc,aAAa,OAAO,IACjG,MAAM,QAAQ,IAAI;AAAA,MAChB,QAAQ;AAAA,QACN,KAAK,UAAU;AAAA,UAAI,CAAC,MAClB,UAA2B,GAAG,OAAO,qBAAqB,MAAM,IAAI,EAAE,UAAU,IAAI,MAAM;AAAA,QAC5F;AAAA,MACF;AAAA,MACA,YAAY,KAAK,UAAU,OAAO,WAAW;AAAA,MAC7C,YAAY,KAAK,UAAU,OAAO,WAAW;AAAA,MAC7C,YAAY,KAAK,UAAU,UAAU,WAAW;AAAA,MAChD,YAAY,KAAK,UAAU,UAAU,WAAW;AAAA,MAChD,YAAY,KAAK,UAAU,YAAY,WAAW;AAAA,MAClD,UAAgC,GAAG,OAAO,0BAA0B,MAAM,IAAI,MAAM;AAAA;AAAA;AAAA,MAGpF,UAAkC,GAAG,OAAO,8BAA8B,MAAM,EAAE;AAAA,QAChF,OAA+B,CAAC;AAAA,MAClC;AAAA,IACF,CAAC;AAGH,UAAM,YAA2B,KAAK,UAAU,IAAI,CAAC,GAAG,OAAO;AAAA,MAC7D,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,SAAS,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,QACxC,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MAChB,EAAE;AAAA,IACJ,EAAE;AAEF,UAAM,QAAmB,IAAI,KAAK,KAAK,SAAS,OAAO,QAAQ,EAAE,MAAM,IAAI,CAAC,OAAO;AAAA,MACjF,IAAI,EAAE,UAAU;AAAA,MAChB,KAAK,EAAE,OAAO;AAAA,MACd,KAAK,EAAE,OAAO;AAAA,MACd,SAAS,EAAE,WAAW;AAAA;AAAA;AAAA,MAGtB,YAAY;AAAA,MACZ,aAAa,EAAE,eAAe;AAAA,MAC9B,UAAU,CAAC,GAAI,EAAE,YAAY,CAAC,CAAE;AAAA,IAClC,EAAE;AAEF,UAAM,SAAqB,CAAC;AAC5B,eAAW,KAAK,IAAI,KAAK,UAAU,cAAc,OAAO,QAAQ,EAAE,QAAQ;AACxE,YAAM,SAAS,kBAAkB,EAAE,YAAY,EAAE;AACjD,UAAI,CAAC,OAAQ;AACb,aAAO,KAAK;AAAA,QACV,IAAI,EAAE,WAAW;AAAA,QACjB,SAAS,EAAE,WAAW;AAAA,QACtB,SAAS,EAAE,WAAW;AAAA,QACtB,MAAM,EAAE,QAAQ;AAAA,QAChB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,UAAM,YAA2B,IAAI,KAAK,SAAS,aAAa,OAAO,WAAW,EAAE,UAAU;AAAA,MAC5F,CAAC,MAAM;AACL,cAAM,MAAmB;AAAA,UACvB,IAAI,EAAE,cAAc;AAAA,UACpB,MAAM,EAAE,QAAQ;AAAA,UAChB,MAAM,EAAE,QAAQ;AAAA,UAChB,aAAa,CAAC,GAAI,EAAE,cAAc,CAAC,CAAE;AAAA,UACrC,QAAQ,EAAE,UAAU;AAAA,UACpB,WAAW,EAAE,aAAa;AAAA,QAC5B;AACA,YAAI,EAAE,YAAa,KAAI,cAAc,EAAE;AACvC,YAAI,EAAE,OAAQ,KAAI,SAAS,EAAE;AAC7B,YAAI,EAAE,UAAW,KAAI,UAAU,EAAE;AACjC,YAAI,EAAE,QAAS,KAAI,UAAU,EAAE;AAC/B,YAAI,EAAE,KAAM,KAAI,UAAU,EAAE;AAC5B,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,aAA4B,IAAI,KAAK,SAAS,aAAa,OAAO,WAAW,EAAE,WAAW;AAAA,MAC9F,CAAC,MAAM;AACL,cAAM,MAAmB,EAAE,IAAI,EAAE,cAAc,IAAI,MAAM,EAAE,QAAQ,IAAI,WAAW,EAAE,aAAa,EAAE;AAEnG,YAAI,EAAE,qBAAqB;AACzB,gBAAM,MAAM,QAAQ,EAAE,mBAAmB;AACzC,cAAI,IAAK,KAAI,OAAO;AAAA,QACtB;AACA,YAAI,EAAE,OAAO,IAAK,KAAI,WAAW,EAAE,MAAM;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,aAA6B,IAAI,KAAK,WAAW,eAAe;AAAA,MACpE;AAAA,IACF,EAAE,WAAW,IAAI,CAAC,OAAO;AAAA,MACvB,IAAI,EAAE,MAAM;AAAA,MACZ,QAAQ,EAAE,UAAU;AAAA,MACpB,UAAU,EAAE,iBAAiB;AAAA,MAC7B,OAAO,EAAE,SAAS;AAAA,MAClB,UAAU,EAAE,YAAY;AAAA,MACxB,UAAU,EAAE,YAAY;AAAA,MACxB,OAAO,EAAE,SAAS;AAAA,IACpB,EAAE;AAEF,UAAM,mBAAyC,CAAC;AAChD,eAAW,KAAK,aAAa;AAC3B,YAAM,CAAC,aAAa,SAAS,IAAI,EAAE;AACnC,UAAI,CAAC,eAAe,CAAC,UAAW;AAChC,uBAAiB,KAAK;AAAA,QACpB,IAAI,EAAE;AAAA,QACN,MAAM,gBAAgB,EAAE,IAAI,KAAK;AAAA,QACjC,MAAM,EAAE;AAAA,QACR,YAAY,EAAE;AAAA,QACd,QAAQ,EAAE;AAAA,QACV,YAAY,EAAE;AAAA,QACd,WACE,EAAE,cAAc,iBAAiB,eAAe,EAAE,cAAc,iBAAiB,eAAe;AAAA,QAClG;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,MAAM,EAAE,IAAI,KAAK,QAAQ,MAAM,KAAK,UAAU,QAAQ,CAAC,KAAK,WAAW,KAAK,QAAQ,EAAE;AAAA,MACtF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAhKE;","names":["maplibregl","THREE","maplibregl","levelAxis","pointInRing","THREE","bearingDeg","THREE","THIN_STRIP_M","bearingDeg","THREE","THREE","THREE","THREE","bearingDeg","_frame","_map","_root","maplibregl","_venue","_map","_repaint","_map","_venue","_selected","maplibregl","M_PER_DEG_LAT","com","Color"]}
|