@mappedin/dynamic-focus 6.0.1-beta.58 → 6.0.1-beta.60
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/lib/dynamic-focus.iife.js.map +3 -3
- package/lib/esm/{chunk-MIOCMA37.js → chunk-FHYN5MAH.js} +31 -79
- package/lib/esm/chunk-FHYN5MAH.js.map +7 -0
- package/lib/esm/index.d.ts +35803 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/react/index.d.ts +35803 -1
- package/lib/esm/react/index.js +1 -1
- package/lib/rn/index-rn.js +2 -2
- package/lib/rn/types.d.ts +13 -1
- package/package.json +5 -4
- package/lib/esm/chunk-MIOCMA37.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/dynamic-focus.ts", "../../packages/common/array-utils.ts", "../../packages/common/pubsub.ts", "../src/building.ts", "../src/dynamic-focus-scene.ts", "../src/types.ts", "../src/validation.ts", "../../packages/common/Mappedin.Logger.ts", "../../packages/common/math-utils.ts", "../src/logger.ts", "../src/outdoors.ts", "../src/constants.ts"],
|
|
4
|
-
"sourcesContent": ["export { DynamicFocus } from './dynamic-focus';\nexport type {\n\tDynamicFocusState,\n\tDynamicFocusMode,\n\tDynamicFocusAnimationOptions,\n\tDynamicFocusEvents,\n\tDynamicFocusEventPayload,\n} from './types';\n", "import type {\n\tCameraTransform,\n\tFacade,\n\tFloorStack,\n\tMapData,\n\tMapView,\n\tTEvents,\n\tTFloorState,\n} from '@mappedin/mappedin-js';\nimport { Floor } from '@mappedin/mappedin-js';\nimport { arraysEqual } from '@packages/internal/common/array-utils';\nimport { PubSub } from '@packages/internal/common/pubsub';\nimport { Building } from './building';\nimport {\n\tgetFloorToShow,\n\tshouldShowIndoor,\n\tgetBuildingAnimationType,\n\tgetZoomState,\n\tgetOutdoorOpacity,\n\tgetSetFloorTargetFromZoomState,\n\tgetBuildingStates,\n\tshouldDeferSetFloor,\n} from './dynamic-focus-scene';\nimport { DYNAMIC_FOCUS_MODES } from './types';\nimport type {\n\tViewState,\n\tZoomState,\n\tBuildingFacadeState,\n\tDynamicFocusEventPayload,\n\tDynamicFocusEvents,\n\tDynamicFocusMode,\n\tDynamicFocusState,\n\tBuildingFloorStackState,\n\tInternalDynamicFocusEvents,\n} from './types';\nimport { validateFloorForStack, validateZoomThreshold } from './validation';\nimport { getOutdoorFloorStack, Outdoors } from './outdoors';\nimport { Logger } from './logger';\nimport MappedinJSLogger from '../../packages/common/Mappedin.Logger';\nimport { DEFAULT_STATE } from './constants';\nimport type { MapViewExtension } from '@packages/internal/common/extensions';\n\n/**\n * Dynamic Focus is a MapView scene manager that maintains the visibility of the outdoors\n * while fading in and out building interiors as the camera pans.\n */\nexport class DynamicFocus implements MapViewExtension<DynamicFocusState> {\n\t#pubsub: PubSub<DynamicFocusEvents & InternalDynamicFocusEvents>;\n\t#mapView: MapView;\n\t#mapData: MapData;\n\t#state: Required<DynamicFocusState> = DEFAULT_STATE;\n\t/**\n\t * The buildings that are currently in view, sorted by the order they are in the facades-in-view-change event.\n\t * While these will be within the camera view, these may not be in focus or showIndoor depending on the mode.\n\t */\n\t#sortedBuildingsInView: Building[] = [];\n\t/**\n\t * The buildings that are currently in view, as a set of building ids.\n\t */\n\t#buildingIdsInViewSet = new Set<string>();\n\t#buildings = new Map<string, Building>();\n\t#outdoors: Outdoors;\n\t#userInteracting = false;\n\t#pendingFacadeUpdate = false;\n\t#floorElevation = 0;\n\t#cameraElevation = 0;\n\t/**\n\t * Tracks the current zoom state based on camera zoom level:\n\t * - 'in-range': Camera is zoomed in enough to show indoor details (>= indoorZoomThreshold)\n\t * - 'out-of-range': Camera is zoomed out to show outdoor context (<= outdoorZoomThreshold)\n\t * - 'transition': Camera is between the two thresholds (no floor changes occur)\n\t */\n\t#zoomState: ZoomState = 'transition';\n\t#viewState: ViewState = 'outdoor';\n\t/**\n\t * The facades that are actually focused and shown (filtered by showIndoor logic)\n\t */\n\t#facadesInFocus: Facade[] = [];\n\t#enabled = false;\n\n\t/**\n\t * @internal\n\t * Used to await the current scene update before starting a new one, or when the scene is updated asynchronously by an event.\n\t */\n\tprivate sceneUpdateQueue: Promise<void> = Promise.resolve();\n\n\t/**\n\t * Creates a new instance of the Dynamic Focus controller.\n\t *\n\t * @param mapView - The {@link MapView} to attach Dynamic Focus to.\n\t * @param options - Options for configuring Dynamic Focus.\n\t *\n\t * @example\n\t * ```ts\n\t * const mapView = show3dMap(...);\n\t * const df = new DynamicFocus(mapView);\n\t * df.enable({ autoFocus: true });\n\t *\n\t * // pause the listener\n\t * df.updateState({ autoFocus: false });\n\t *\n\t * // manually trigger a focus\n\t * df.focus();\n\t * ```\n\t */\n\tconstructor(mapView: MapView) {\n\t\tthis.#pubsub = new PubSub<DynamicFocusEvents & InternalDynamicFocusEvents>();\n\t\tthis.#mapView = mapView;\n\t\tLogger.setLevel(MappedinJSLogger.logState);\n\t\tthis.#mapData = this.#mapView.getMapData();\n\t\tthis.#floorElevation = this.#mapView.currentFloor.elevation;\n\t\tthis.#cameraElevation = this.#mapView.Camera.elevation;\n\t\t// initialize the buildings\n\t\tfor (const facade of this.#mapData.getByType('facade')) {\n\t\t\tthis.#buildings.set(facade.floorStack.id, new Building(facade.floorStack, this.#mapView));\n\t\t}\n\t\tthis.#outdoors = new Outdoors(\n\t\t\tgetOutdoorFloorStack(this.#mapData.getByType('floor-stack'), this.#buildings),\n\t\t\tthis.#mapView,\n\t\t);\n\t\tthis.#mapView.on('floor-change-start', this.#handleFloorChangeStart);\n\t\tthis.#mapView.on('camera-change', this.#handleCameraChange);\n\t\tthis.#mapView.on('facades-in-view-change', this.#handleFacadesInViewChange);\n\t\tthis.#mapView.on('user-interaction-start', this.#handleUserInteractionStart);\n\t\tthis.#mapView.on('user-interaction-end', this.#handleUserInteractionEnd);\n\t}\n\n\t/**\n\t * Enables Dynamic Focus with the given options.\n\t * @param options - The options to enable Dynamic Focus with.\n\t */\n\tenable(options?: Partial<DynamicFocusState>): void {\n\t\tif (this.#enabled) {\n\t\t\tLogger.warn('enable() called on an already enabled Dynamic Focus instance.');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#enabled = true;\n\t\tthis.#mapView.manualFloorVisibility = true;\n\t\tthis.#outdoors.show();\n\t\tthis.updateState({ ...this.#state, ...options });\n\t\t// fire the camera change event to set the initial state\n\t\tthis.#handleCameraChange({\n\t\t\tzoomLevel: this.#mapView.Camera.zoomLevel,\n\t\t\tcenter: this.#mapView.Camera.center,\n\t\t\tbearing: this.#mapView.Camera.bearing,\n\t\t\tpitch: this.#mapView.Camera.pitch,\n\t\t} as CameraTransform);\n\t\t// fire dynamic focus change to set initial state of facades\n\t\tthis.#mapView.Camera.updateFacadesInView();\n\t}\n\t/**\n\t * Disables Dynamic Focus and returns the MapView to it's previous state.\n\t */\n\tdisable(): void {\n\t\tif (!this.#enabled) {\n\t\t\tLogger.warn('disable() called on an already disabled Dynamic Focus instance.');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#enabled = false;\n\t\tthis.#mapView.manualFloorVisibility = false;\n\t}\n\n\t/**\n\t * Returns true if Dynamic Focus is enabled.\n\t */\n\tget isEnabled(): boolean {\n\t\treturn this.#enabled;\n\t}\n\n\t/**\n\t * Returns true if the current view state is indoor.\n\t */\n\tget isIndoor() {\n\t\treturn this.#viewState === 'indoor';\n\t}\n\n\t/**\n\t * Returns true if the current view state is outdoor.\n\t */\n\tget isOutdoor() {\n\t\treturn this.#viewState === 'outdoor';\n\t}\n\n\t/**\n\t * Sets the view state to indoor, regardless of the current zoom level.\n\t */\n\tsetIndoor() {\n\t\tthis.#viewState = 'indoor';\n\t\tthis.#zoomState = 'in-range';\n\n\t\tthis.#handleViewStateChange();\n\t}\n\n\t/**\n\t * Sets the view state to outdoor, regardless of the current zoom level.\n\t */\n\tsetOutdoor() {\n\t\tthis.#viewState = 'outdoor';\n\t\tthis.#zoomState = 'out-of-range';\n\n\t\tthis.#handleViewStateChange();\n\t}\n\n\t#handleViewStateChange() {\n\t\tif (this.#state.autoFocus) {\n\t\t\t// Only set the floor if setFloorOnFocus is true and the view state changed due to a user interaction\n\t\t\t// Camera animations will not trigger a focus change until they settle.\n\t\t\tif (this.#userInteracting) {\n\t\t\t\tthis.focus();\n\t\t\t} else {\n\t\t\t\tthis.#pendingFacadeUpdate = true;\n\t\t\t}\n\t\t}\n\t\tthis.#pubsub.publish('state-change');\n\t}\n\n\t#preloadFloors(mode: DynamicFocusMode) {\n\t\tthis.#mapView.preloadFloors(\n\t\t\tthis.#mapData\n\t\t\t\t.getByType('facade')\n\t\t\t\t.map(facade => getFloorToShow(this.#buildings.get(facade.floorStack.id)!, mode, this.#floorElevation))\n\t\t\t\t.filter(f => f != null && Floor.is(f)),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the facades that are currently in focus.\n\t */\n\tget focusedFacades() {\n\t\treturn [...this.#facadesInFocus];\n\t}\n\n\t/**\n\t * Subscribe to a Dynamic Focus event.\n\t */\n\ton = <EventName extends keyof DynamicFocusEvents>(\n\t\teventName: EventName,\n\t\tfn: (payload: DynamicFocusEventPayload<EventName>) => void,\n\t) => {\n\t\tthis.#pubsub.on(eventName, fn);\n\t};\n\n\t/**\n\t * Unsubscribe from a Dynamic Focus event.\n\t */\n\toff = <EventName extends keyof DynamicFocusEvents>(\n\t\teventName: EventName,\n\t\tfn: (payload: DynamicFocusEventPayload<EventName>) => void,\n\t) => {\n\t\tthis.#pubsub.off(eventName, fn);\n\t};\n\n\t/**\n\t * Returns the current state of the Dynamic Focus controller.\n\t */\n\tgetState(): DynamicFocusState {\n\t\treturn { ...this.#state };\n\t}\n\n\t/**\n\t * Updates the state of the Dynamic Focus controller.\n\t * @param state - The state to update.\n\t */\n\tupdateState(state: Partial<DynamicFocusState>) {\n\t\tlet shouldReapplyBuildingStates = false;\n\n\t\tif (state.indoorZoomThreshold != null) {\n\t\t\tstate.indoorZoomThreshold = validateZoomThreshold(\n\t\t\t\tstate.indoorZoomThreshold,\n\t\t\t\tthis.#state.outdoorZoomThreshold,\n\t\t\t\tthis.#mapView.Camera.maxZoomLevel,\n\t\t\t\t'indoorZoomThreshold',\n\t\t\t);\n\t\t}\n\t\tif (state.outdoorZoomThreshold != null) {\n\t\t\tstate.outdoorZoomThreshold = validateZoomThreshold(\n\t\t\t\tstate.outdoorZoomThreshold,\n\t\t\t\tthis.#mapView.Camera.minZoomLevel,\n\t\t\t\tthis.#state.indoorZoomThreshold,\n\t\t\t\t'outdoorZoomThreshold',\n\t\t\t);\n\t\t}\n\n\t\tif (state.mode != null) {\n\t\t\tstate.mode = DYNAMIC_FOCUS_MODES.includes(state.mode) ? state.mode : 'default-floor';\n\t\t}\n\n\t\tif (state.autoAdjustFacadeHeights != null) {\n\t\t\tthis.#state.autoAdjustFacadeHeights = state.autoAdjustFacadeHeights;\n\t\t\tthis.#buildings.forEach(building => {\n\t\t\t\tif (this.#state.autoAdjustFacadeHeights) {\n\t\t\t\t\tbuilding.expandFacade();\n\t\t\t\t} else {\n\t\t\t\t\tbuilding.collapseFacade();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\tstate.dynamicBuildingInteriors != null &&\n\t\t\tstate.dynamicBuildingInteriors !== this.#state.dynamicBuildingInteriors\n\t\t) {\n\t\t\tshouldReapplyBuildingStates = true;\n\t\t}\n\n\t\t// assign state and ignore undefined values\n\t\tthis.#state = Object.assign(\n\t\t\t{},\n\t\t\tthis.#state,\n\t\t\tObject.fromEntries(Object.entries(state).filter(([, value]) => value != null)),\n\t\t);\n\n\t\t// preload the initial floors that will be included in the mode\n\t\tif (state.mode != null && state.preloadFloors) {\n\t\t\tthis.#preloadFloors(state.mode);\n\t\t}\n\n\t\tif (shouldReapplyBuildingStates) {\n\t\t\tthis.#applyBuildingStates();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the Dynamic Focus instance and unsubscribes all MapView event listeners.\n\t */\n\tdestroy() {\n\t\tthis.disable();\n\t\tthis.#mapView.off('facades-in-view-change', this.#handleFacadesInViewChange);\n\t\tthis.#mapView.off('floor-change-start', this.#handleFloorChangeStart);\n\t\tthis.#mapView.off('camera-change', this.#handleCameraChange);\n\t\tthis.#mapView.off('user-interaction-start', this.#handleUserInteractionStart);\n\t\tthis.#mapView.off('user-interaction-end', this.#handleUserInteractionEnd);\n\t\tthis.#buildings.forEach(building => building.destroy());\n\t\tthis.#outdoors.destroy();\n\t\tthis.#pubsub.destroy();\n\t}\n\n\t/**\n\t * Perform a manual visual update of the focused facades, and optionally set the floor.\n\t * @param setFloor - Whether to set the floor. This will default to the current state of setFloorOnFocus.\n\t */\n\tasync focus(setFloor = this.#state.setFloorOnFocus) {\n\t\tif (setFloor) {\n\t\t\tif (shouldDeferSetFloor(this.#cameraElevation, this.#mapView.Camera.elevation, this.#userInteracting)) {\n\t\t\t\tthis.#cameraElevation = this.#mapView.Camera.elevation;\n\t\t\t\tthis.#pendingFacadeUpdate = true;\n\t\t\t} else {\n\t\t\t\tconst target = getSetFloorTargetFromZoomState(this.#sortedBuildingsInView, this.#outdoors, this.#zoomState);\n\n\t\t\t\tconst floor = target ? getFloorToShow(target, this.#state.mode, this.#floorElevation) : undefined;\n\n\t\t\t\tif (floor && floor.id !== this.#mapView.currentFloor.id) {\n\t\t\t\t\tthis.#mapView.setFloor(floor, { context: 'dynamic-focus' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait this.#applyBuildingStates();\n\t\t// must publish after the scene is updated to ensure the focusedFacades array is up to date\n\t\tthis.#pubsub.publish('focus', { facades: this.focusedFacades });\n\t}\n\n\t/**\n\t * Preloads the initial floors for each building to improve performance when rendering the building for the first time. See {@link DynamicFocusState.preloadFloors}.\n\t */\n\tpreloadFloors() {\n\t\tthis.#preloadFloors(this.#state.mode);\n\t}\n\n\t/**\n\t * Sets the default floor for a floor stack. This is the floor that will be shown when focusing on a facade if there is no currently active floor in the stack.\n\t * See {@link resetDefaultFloorForStack} to reset the default floor.\n\t * @param floorStack - The floor stack to set the default floor for.\n\t * @param floor - The floor to set as the default floor.\n\t */\n\tsetDefaultFloorForStack(floorStack: FloorStack, floor: Floor) {\n\t\tif (!validateFloorForStack(floor, floorStack)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.defaultFloor = floor;\n\t\t}\n\t}\n\n\t/**\n\t * Resets the default floor for a floor stack to it's initial value.\n\t * @param floorStack - The floor stack to reset the default floor for.\n\t */\n\tresetDefaultFloorForStack(floorStack: FloorStack) {\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.defaultFloor = floorStack.defaultFloor;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the current default floor for a floor stack.\n\t * @param floorStack - The floor stack to get the default floor for.\n\t * @returns The current default floor for the floor stack.\n\t */\n\tgetDefaultFloorForStack(floorStack: FloorStack) {\n\t\treturn this.#buildings.get(floorStack.id)?.defaultFloor || floorStack.defaultFloor || floorStack.floors[0];\n\t}\n\n\t/**\n\t * Sets the current floor for a floor stack. If the floor stack is currently focused, this floor will become visible.\n\t * @param floorStack - The floor stack to set the current floor for.\n\t */\n\tsetCurrentFloorForStack(floorStack: FloorStack, floor: Floor) {\n\t\tif (!validateFloorForStack(floor, floorStack)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.activeFloor = floor;\n\t\t\tthis.#applyBuildingStates();\n\t\t}\n\t}\n\n\t/**\n\t * Excludes a floor stack from visibility changes.\n\t * @param excluded - The floor stack or stacks to exclude.\n\t */\n\texclude(excluded: FloorStack | FloorStack[]) {\n\t\tconst excludedFloorStacks = Array.isArray(excluded) ? excluded : [excluded];\n\t\tfor (const floorStack of excludedFloorStacks) {\n\t\t\tconst building = this.#buildings.get(floorStack.id);\n\t\t\tif (building) {\n\t\t\t\tbuilding.excluded = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Includes a floor stack in visibility changes.\n\t * @param included - The floor stack or stacks to include.\n\t */\n\tinclude(included: FloorStack | FloorStack[]) {\n\t\tconst includedFloorStacks = Array.isArray(included) ? included : [included];\n\t\tfor (const floorStack of includedFloorStacks) {\n\t\t\tconst building = this.#buildings.get(floorStack.id);\n\t\t\tif (building) {\n\t\t\t\tbuilding.excluded = false;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the current floor for a floor stack.\n\t * @param floorStack - The floor stack to get the current floor for.\n\t * @returns The current floor for the floor stack.\n\t */\n\tgetCurrentFloorForStack(floorStack: FloorStack) {\n\t\treturn this.#buildings.get(floorStack.id)?.activeFloor || this.getDefaultFloorForStack(floorStack);\n\t}\n\n\t/**\n\t * Handles management of focused facades but doesn't trigger view updates unless enabled.\n\t * @see {@link focus} to manually trigger a view update.\n\t */\n\t#handleFacadesInViewChange = (event: TEvents['facades-in-view-change']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { facades } = event;\n\n\t\t// if the facades are the same, or we're in between outdoor/indoor, don't do anything unless we're pending a facade update\n\t\tif (arraysEqual(facades, this.focusedFacades) && this.#viewState === 'transition' && !this.#pendingFacadeUpdate) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#pendingFacadeUpdate = false;\n\n\t\tthis.#sortedBuildingsInView = [];\n\t\tthis.#buildingIdsInViewSet.clear();\n\t\tif (facades.length > 0) {\n\t\t\tfor (const facade of facades) {\n\t\t\t\tconst building = this.#buildings.get(facade.floorStack.id);\n\t\t\t\tif (building) {\n\t\t\t\t\tthis.#buildingIdsInViewSet.add(building.id);\n\t\t\t\t\tthis.#sortedBuildingsInView.push(building);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.#state.autoFocus) {\n\t\t\tthis.focus();\n\t\t}\n\t};\n\t/**\n\t * Handles floor and facade visibility when the floor changes.\n\t */\n\t#handleFloorChangeStart = async (event: TEvents['floor-change-start']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { floor: newFloor } = event;\n\t\tconst building = this.#buildings.get(newFloor.floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.activeFloor = newFloor;\n\t\t}\n\t\t// Don't update elevation when switching to outdoor floor stack\n\t\tif (building?.excluded === false && !this.#outdoors.matchesFloorStack(newFloor.floorStack)) {\n\t\t\tthis.#floorElevation = newFloor.elevation;\n\t\t}\n\n\t\tif (this.#mapView.manualFloorVisibility === true) {\n\t\t\tif (event.reason !== 'dynamic-focus') {\n\t\t\t\tawait this.#applyBuildingStates(newFloor);\n\t\t\t\t// Despite this not really being a focus event, we've changed the focused facades, so we need to publish it\n\t\t\t\tthis.#pubsub.publish('focus', { facades: this.focusedFacades });\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tthis.#mapView.options.multiFloorView != null &&\n\t\t\t\tthis.#mapView.options.multiFloorView?.enabled &&\n\t\t\t\tthis.#mapView.options.multiFloorView?.updateCameraElevationOnFloorChange &&\n\t\t\t\tthis.#mapView.Camera.elevation !== this.#floorElevation * (this.#mapView.options.multiFloorView.floorGap ?? 0)\n\t\t\t) {\n\t\t\t\tthis.#mapView.Camera.animateElevation(\n\t\t\t\t\tthis.#floorElevation * (this.#mapView.options.multiFloorView.floorGap ?? 0),\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: 750,\n\t\t\t\t\t\teasing: 'ease-in-out',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\t#handleUserInteractionStart = () => {\n\t\tthis.#userInteracting = true;\n\t};\n\t#handleUserInteractionEnd = () => {\n\t\tthis.#userInteracting = false;\n\t};\n\n\t/**\n\t * Handles camera moving in and out of zoom range and fires a focus event if the camera is in range.\n\t */\n\t#handleCameraChange = (event: TEvents['camera-change']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { zoomLevel } = event;\n\t\tconst newZoomState = getZoomState(zoomLevel, this.#state.indoorZoomThreshold, this.#state.outdoorZoomThreshold);\n\n\t\tif (this.#zoomState !== newZoomState) {\n\t\t\tthis.#zoomState = newZoomState;\n\n\t\t\tif (newZoomState === 'in-range') {\n\t\t\t\tthis.setIndoor();\n\t\t\t} else if (newZoomState === 'out-of-range') {\n\t\t\t\tthis.setOutdoor();\n\t\t\t}\n\t\t}\n\t};\n\n\t#updateFloorVisibility(floorStates: BuildingFloorStackState['floorStates'], shouldShow: boolean, inFocus?: boolean) {\n\t\tfloorStates.forEach(floorState => {\n\t\t\tif (floorState.floor) {\n\t\t\t\tif (shouldShow) {\n\t\t\t\t\tconst state =\n\t\t\t\t\t\tinFocus !== undefined\n\t\t\t\t\t\t\t? ({\n\t\t\t\t\t\t\t\t\t...floorState.state,\n\t\t\t\t\t\t\t\t\tlabels: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.labels,\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.labels.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tmarkers: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.markers,\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.markers.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tocclusion: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.occlusion,\n\t\t\t\t\t\t\t\t\t\t// We don't want this floor to occlude if it's not in focus\n\t\t\t\t\t\t\t\t\t\t// Allows us to show a label above this floor while it's not active\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.occlusion.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t } satisfies TFloorState)\n\t\t\t\t\t\t\t: floorState.state;\n\n\t\t\t\t\tthis.#mapView.updateState(floorState.floor, state);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#mapView.updateState(floorState.floor, { visible: false });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tasync #animateIndoorSequence(\n\t\tbuilding: Building,\n\t\tfloorStackState: BuildingFloorStackState,\n\t\tfacadeState: BuildingFacadeState,\n\t\tinFocus: boolean,\n\t) {\n\t\t// show floor first then fade in the facade\n\t\tthis.#updateFloorVisibility(floorStackState.floorStates, true, inFocus);\n\n\t\treturn building.animateFacade(facadeState.state, this.#state.indoorAnimationOptions);\n\t}\n\n\tasync #animateOutdoorSequence(\n\t\tbuilding: Building,\n\t\tfloorStackState: BuildingFloorStackState,\n\t\tfacadeState: BuildingFacadeState,\n\t\tfloorStackIdsInNavigation: string[],\n\t) {\n\t\t// fade in facade then hide floors when complete\n\t\tconst result = await building.animateFacade(facadeState.state, this.#state.outdoorAnimationOptions);\n\n\t\tif (result.result === 'completed') {\n\t\t\t// Re-check if we should still show indoor after animation completes\n\t\t\tthis.#updateFloorVisibility(\n\t\t\t\tfloorStackState.floorStates,\n\t\t\t\tshouldShowIndoor(\n\t\t\t\t\tbuilding,\n\t\t\t\t\tthis.#mapView.currentFloor,\n\t\t\t\t\tthis.#zoomState === 'in-range',\n\t\t\t\t\tthis.#buildingIdsInViewSet.has(building.id),\n\t\t\t\t\tthis.#state.mode,\n\t\t\t\t\tthis.#floorElevation,\n\t\t\t\t\tfloorStackIdsInNavigation.includes(building.floorStack.id),\n\t\t\t\t\tthis.#state.dynamicBuildingInteriors,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t#applyBuildingStates = async (newFloor?: Floor) => {\n\t\tif (this.#mapView.manualFloorVisibility !== true || !this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentFloor = newFloor || this.#mapView.currentFloor;\n\t\tconst multiFloorView = this.#mapView.options.multiFloorView;\n\t\tconst floorIdsInNavigation = this.#mapView.Navigation?.floors?.map(f => f.id) || [];\n\t\tconst floorStackIdsInNavigation = this.#mapView.Navigation?.floorStacks.map(fs => fs.id) || [];\n\n\t\t// Create a new promise for this update\n\t\tconst updatePromise = new Promise<void>(async resolve => {\n\t\t\t// Wait for the previous update to complete\n\t\t\tawait this.sceneUpdateQueue;\n\n\t\t\tconst buildingStates = getBuildingStates(\n\t\t\t\tArray.from(this.#buildings.values()),\n\t\t\t\tthis.#buildingIdsInViewSet,\n\t\t\t\tcurrentFloor,\n\t\t\t\tthis.#zoomState,\n\t\t\t\tthis.#state.mode,\n\t\t\t\tthis.#floorElevation,\n\t\t\t\tfloorIdsInNavigation,\n\t\t\t\tfloorStackIdsInNavigation,\n\t\t\t\tmultiFloorView,\n\t\t\t\tthis.#state.dynamicBuildingInteriors,\n\t\t\t);\n\n\t\t\tconst floorStackStates: BuildingFloorStackState[] = [];\n\t\t\tawait Promise.all(\n\t\t\t\tArray.from(buildingStates.values()).map(async buildingState => {\n\t\t\t\t\tconst { building, showIndoor, floorStackState, facadeState, inFocus } = buildingState;\n\n\t\t\t\t\tfloorStackStates.push(floorStackState);\n\n\t\t\t\t\tconst animation = getBuildingAnimationType(building, showIndoor);\n\n\t\t\t\t\tif (animation === 'indoor') {\n\t\t\t\t\t\treturn this.#animateIndoorSequence(building, floorStackState, facadeState, inFocus);\n\t\t\t\t\t} else if (animation === 'outdoor') {\n\t\t\t\t\t\treturn this.#animateOutdoorSequence(building, floorStackState, facadeState, floorStackIdsInNavigation);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tthis.#mapView.Outdoor.setOpacity(getOutdoorOpacity(floorStackStates, this.#state.mode));\n\n\t\t\t// Filter #facadesInFocus to maintain sort order, keeping only buildings with showIndoor true\n\t\t\tthis.#facadesInFocus = this.#sortedBuildingsInView\n\t\t\t\t.filter(building => buildingStates.get(building.id)?.showIndoor === true)\n\t\t\t\t.map(building => building.facade);\n\n\t\t\tthis.#pubsub.publish('focus', { facades: this.#facadesInFocus });\n\n\t\t\tresolve();\n\t\t});\n\n\t\t// Update the queue with the new promise\n\t\tthis.sceneUpdateQueue = updatePromise;\n\n\t\treturn updatePromise;\n\t};\n}\n", "/**\n * Compare two arrays for equality\n */\nexport function arraysEqual(arr1: any[] | null | undefined, arr2: any[] | null | undefined) {\n\tif (arr1 == null || arr2 == null) {\n\t\treturn arr1 === arr2;\n\t}\n\n\tif (arr1.length !== arr2.length) {\n\t\treturn false;\n\t}\n\n\tfor (let i = 0; i < arr1.length; i++) {\n\t\tif (arr1[i] !== arr2[i]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n", "/**\n * Generic PubSub class implementing the Publish-Subscribe pattern for event handling.\n *\n * @template EVENT_PAYLOAD - The type of the event payload.\n * @template EVENT - The type of the event.\n */\nexport class PubSub<EVENT_PAYLOAD, EVENT extends keyof EVENT_PAYLOAD = keyof EVENT_PAYLOAD> {\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tprivate _subscribers: any = {};\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tprivate _destroyed = false;\n\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tpublish<EVENT_NAME extends EVENT>(eventName: EVENT_NAME, data?: EVENT_PAYLOAD[EVENT_NAME]) {\n\t\tif (!this._subscribers || !this._subscribers[eventName] || this._destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._subscribers[eventName]!.forEach(function (fn) {\n\t\t\tif (typeof fn !== 'function') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfn(data);\n\t\t});\n\t}\n\n\t/**\n\t * Subscribe a function to an event.\n\t *\n\t * @param eventName An event name which, when fired, will call the provided\n\t * function.\n\t * @param fn A callback that gets called when the corresponding event is fired. The\n\t * callback will get passed an argument with a type that's one of event payloads.\n\t * @example\n\t * // Subscribe to the 'click' event\n\t * const handler = (event) => {\n\t * const { coordinate } = event;\n\t * const { latitude, longitude } = coordinate;\n\t * \tconsole.log(`Map was clicked at ${latitude}, ${longitude}`);\n\t * };\n\t * map.on('click', handler);\n\t */\n\ton<EVENT_NAME extends EVENT>(\n\t\teventName: EVENT_NAME,\n\t\tfn: (\n\t\t\tpayload: EVENT_PAYLOAD[EVENT_NAME] extends {\n\t\t\t\tdata: null;\n\t\t\t}\n\t\t\t\t? EVENT_PAYLOAD[EVENT_NAME]['data']\n\t\t\t\t: EVENT_PAYLOAD[EVENT_NAME],\n\t\t) => void,\n\t) {\n\t\tif (!this._subscribers || this._destroyed) {\n\t\t\tthis._subscribers = {};\n\t\t}\n\t\tthis._subscribers[eventName] = this._subscribers[eventName] || [];\n\t\tthis._subscribers[eventName]!.push(fn);\n\t}\n\n\t/**\n\t * Unsubscribe a function previously subscribed with {@link on}\n\t *\n\t * @param eventName An event name to which the provided function was previously\n\t * subscribed.\n\t * @param fn A function that was previously passed to {@link on}. The function must\n\t * have the same reference as the function that was subscribed.\n\t * @example\n\t * // Unsubscribe from the 'click' event\n\t * const handler = (event) => {\n\t * \tconsole.log('Map was clicked', event);\n\t * };\n\t * map.off('click', handler);\n\t */\n\toff<EVENT_NAME extends EVENT>(\n\t\teventName: EVENT_NAME,\n\t\tfn: (\n\t\t\tpayload: EVENT_PAYLOAD[EVENT_NAME] extends {\n\t\t\t\tdata: null;\n\t\t\t}\n\t\t\t\t? EVENT_PAYLOAD[EVENT_NAME]['data']\n\t\t\t\t: EVENT_PAYLOAD[EVENT_NAME],\n\t\t) => void,\n\t) {\n\t\tif (!this._subscribers || this._subscribers[eventName] == null || this._destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tconst itemIdx = this._subscribers[eventName]!.indexOf(fn);\n\n\t\tif (itemIdx !== -1) {\n\t\t\tthis._subscribers[eventName]!.splice(itemIdx, 1);\n\t\t}\n\t}\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tdestroy() {\n\t\tthis._destroyed = true;\n\t\tthis._subscribers = {};\n\t}\n}\n", "import type { MapView, Space, TAnimateStateResult, TFacadeState } from '@mappedin/mappedin-js';\nimport { Facade, Floor, FloorStack } from '@mappedin/mappedin-js';\nimport type { DynamicFocusAnimationOptions } from './types';\n\nexport class Building {\n\t__type = 'building';\n\t#floorStack: FloorStack;\n\t#floorsById = new Map<string, Floor>();\n\t#floorsByElevation = new Map<number, Floor>();\n\t#floorsByElevationSorted: Floor[] = [];\n\t#mapView: MapView;\n\t#spacesByAltitude?: Map<number, { space: Space; originalAltitude: number; originalHeight: number }[]>;\n\t#animationInProgress: { state: TFacadeState; animation: ReturnType<MapView['animateState']> } | undefined;\n\n\tdefaultFloor: Floor;\n\tactiveFloor: Floor;\n\texcluded = false;\n\n\tconstructor(floorStack: FloorStack, mapView: MapView) {\n\t\tthis.#floorStack = floorStack;\n\t\tthis.#floorsById = new Map(floorStack.floors.map(floor => [floor.id, floor]));\n\t\tthis.#floorsByElevation = new Map(floorStack.floors.map(floor => [floor.elevation, floor]));\n\t\tthis.#floorsByElevationSorted = Array.from(this.#floorsByElevation.values()).sort(\n\t\t\t(a, b) => a.elevation - b.elevation,\n\t\t);\n\t\tthis.defaultFloor = floorStack.defaultFloor;\n\t\tthis.activeFloor = this.defaultFloor;\n\t\tthis.#mapView = mapView;\n\t}\n\n\tget id() {\n\t\treturn this.#floorStack.id;\n\t}\n\n\tget name() {\n\t\treturn this.#floorStack.name;\n\t}\n\n\tget floors() {\n\t\treturn this.#floorStack.floors;\n\t}\n\n\tget floorStack() {\n\t\treturn this.#floorStack;\n\t}\n\n\tget facade() {\n\t\t// the floorstack must have a facade if we created a building for it\n\t\treturn this.#floorStack.facade!;\n\t}\n\n\tget isCurrentFloorStack() {\n\t\treturn this.id === this.#mapView.currentFloorStack.id;\n\t}\n\n\tget isIndoor() {\n\t\tconst state = this.#mapView.getState(this.facade);\n\n\t\treturn this.isCurrentFloorStack || (state?.visible === false && state?.opacity === 0);\n\t}\n\n\tget canSetFloor() {\n\t\treturn this.isIndoor || !this.excluded;\n\t}\n\n\t#maxElevation: number | undefined;\n\tget maxElevation() {\n\t\tif (this.#maxElevation == null) {\n\t\t\tthis.#maxElevation = Math.max(...this.#floorsByElevation.keys());\n\t\t}\n\n\t\treturn this.#maxElevation;\n\t}\n\n\t#minElevation: number | undefined;\n\tget minElevation() {\n\t\tif (this.#minElevation == null) {\n\t\t\tthis.#minElevation = Math.min(...this.#floorsByElevation.keys());\n\t\t}\n\n\t\treturn this.#minElevation;\n\t}\n\n\thas(f: Floor | FloorStack | Facade) {\n\t\tif (Floor.is(f)) {\n\t\t\treturn this.#floorsById.has(f.id);\n\t\t}\n\n\t\tif (FloorStack.is(f)) {\n\t\t\treturn f.id === this.#floorStack.id;\n\t\t}\n\n\t\tif (Facade.is(f)) {\n\t\t\treturn f.id === this.facade.id;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tget aboveGroundFloors() {\n\t\treturn this.#floorsByElevationSorted.filter(floor => floor.elevation >= 0);\n\t}\n\n\texpandFacade() {\n\t\tif (\n\t\t\t!this.#mapView.options.multiFloorView?.enabled ||\n\t\t\t!this.facade ||\n\t\t\tthis.facade.__type !== 'facade' ||\n\t\t\tthis.facade.spaces.length < 1\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst footprintHeight = this.#mapView.options.multiFloorView.floorGap ?? 10;\n\n\t\t// Store original states and grouping\n\t\tif (!this.#spacesByAltitude) {\n\t\t\tthis.#spacesByAltitude = new Map();\n\t\t\tfor (const space of this.facade.spaces) {\n\t\t\t\tconst state = this.#mapView.getState(space);\n\t\t\t\tconst altitude = state?.altitude ?? 0;\n\t\t\t\tconst height = state?.height ?? 0;\n\n\t\t\t\tif (!this.#spacesByAltitude.has(altitude)) {\n\t\t\t\t\tthis.#spacesByAltitude.set(altitude, []);\n\t\t\t\t}\n\n\t\t\t\tthis.#spacesByAltitude.get(altitude)!.push({\n\t\t\t\t\tspace,\n\t\t\t\t\toriginalAltitude: altitude,\n\t\t\t\t\toriginalHeight: height,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Assign each altitude group to represent actual floor heights\n\t\tconst altitudeKeys = Array.from(this.#spacesByAltitude.keys()).sort((a, b) => a - b);\n\t\tconst isSingleAltitude = altitudeKeys.length === 1;\n\n\t\t// If there's only one altitude, set the height to represent the entire building\n\t\tconst heightToUse = isSingleAltitude ? footprintHeight * (this.aboveGroundFloors.length - 1) : footprintHeight;\n\n\t\tlet currentAltitude = 0;\n\t\taltitudeKeys.forEach(originalAltitude => {\n\t\t\tconst spaceData = this.#spacesByAltitude!.get(originalAltitude)!;\n\n\t\t\t// All spaces that were at the same original altitude get the same new altitude and height\n\t\t\tfor (const { space } of spaceData) {\n\t\t\t\tthis.#mapView.updateState(space, {\n\t\t\t\t\theight: isSingleAltitude ? heightToUse : footprintHeight,\n\t\t\t\t\taltitude: currentAltitude,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!isSingleAltitude) {\n\t\t\t\tcurrentAltitude += footprintHeight;\n\t\t\t}\n\t\t});\n\t}\n\n\tcollapseFacade() {\n\t\tif (!this.#spacesByAltitude) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Restore original states\n\t\tfor (const spaceDataArray of this.#spacesByAltitude.values()) {\n\t\t\tfor (const { space, originalAltitude, originalHeight } of spaceDataArray) {\n\t\t\t\tthis.#mapView.updateState(space, {\n\t\t\t\t\theight: originalHeight,\n\t\t\t\t\taltitude: originalAltitude,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.#spacesByAltitude = undefined;\n\t}\n\n\tgetFloorByElevation(elevation: number) {\n\t\treturn this.#floorsByElevation.get(elevation);\n\t}\n\n\tgetNearestFloorByElevation(targetElevation: number): Floor | undefined {\n\t\tconst exactMatch = this.getFloorByElevation(targetElevation);\n\t\tif (exactMatch) {\n\t\t\treturn exactMatch;\n\t\t}\n\n\t\tif (targetElevation >= 0) {\n\t\t\t// For positive elevations, return highest floor if target is above max\n\t\t\tif (targetElevation > this.maxElevation) {\n\t\t\t\treturn this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];\n\t\t\t}\n\n\t\t\t// Search backwards from the end\n\t\t\tfor (let i = this.#floorsByElevationSorted.length - 1; i >= 0; i--) {\n\t\t\t\tconst floor = this.#floorsByElevationSorted[i];\n\t\t\t\tif (floor.elevation <= targetElevation) {\n\t\t\t\t\treturn floor;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// For negative elevations (basements), return the lowest floor if target is below min\n\t\t\tif (targetElevation < this.minElevation) {\n\t\t\t\treturn this.#floorsByElevationSorted[0];\n\t\t\t}\n\n\t\t\t// Search forwards from the start\n\t\t\tfor (const floor of this.#floorsByElevationSorted) {\n\t\t\t\tif (floor.elevation >= targetElevation) {\n\t\t\t\t\treturn floor;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgetHighestFloor(): Floor {\n\t\treturn this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];\n\t}\n\n\tcancelAnimation() {\n\t\tif (this.#animationInProgress) {\n\t\t\tthis.#animationInProgress.animation.cancel();\n\t\t\tthis.#animationInProgress = undefined;\n\t\t}\n\t}\n\n\tasync animateFacade(\n\t\tnewState: TFacadeState,\n\t\toptions: DynamicFocusAnimationOptions = { duration: 150 },\n\t): Promise<TAnimateStateResult> {\n\t\tconst currentState = this.#animationInProgress?.state || this.#mapView.getState(this.facade);\n\t\tif (\n\t\t\t!currentState ||\n\t\t\t!newState ||\n\t\t\t(currentState?.opacity === newState.opacity && currentState?.visible === newState.visible)\n\t\t) {\n\t\t\t// nothing to do\n\t\t\treturn { result: 'completed' };\n\t\t}\n\n\t\tthis.cancelAnimation();\n\t\tconst { opacity, visible } = newState;\n\n\t\t// always set facade visible so it can be seen during animation\n\t\tthis.#mapView.updateState(this.facade, {\n\t\t\tvisible: true,\n\t\t});\n\n\t\tif (opacity !== undefined) {\n\t\t\tthis.#animationInProgress = {\n\t\t\t\tanimation: this.#mapView.animateState(\n\t\t\t\t\tthis.facade,\n\t\t\t\t\t{\n\t\t\t\t\t\topacity,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: options.duration,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tstate: newState,\n\t\t\t};\n\t\t\tconst result = await this.#animationInProgress.animation;\n\n\t\t\tthis.#animationInProgress = undefined;\n\n\t\t\tif (result.result === 'cancelled') {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tif (visible === false) {\n\t\t\tthis.#mapView.updateState(this.facade, {\n\t\t\t\tvisible,\n\t\t\t});\n\t\t}\n\n\t\treturn { result: 'completed' };\n\t}\n\n\tdestroy() {\n\t\tthis.cancelAnimation();\n\t\t// Hide all floors except current floor\n\t\tthis.#floorStack.floors.forEach(floor => {\n\t\t\tthis.#mapView.updateState(floor, {\n\t\t\t\tvisible: floor.id === this.#mapView.currentFloor.id,\n\t\t\t});\n\t\t});\n\t\t// Show the facade if the current floor is not in this building\n\t\tif (!this.has(this.#mapView.currentFloor)) {\n\t\t\tthis.#mapView.updateState(this.facade, {\n\t\t\t\tvisible: true,\n\t\t\t\topacity: 1,\n\t\t\t});\n\t\t}\n\t}\n}\n", "import type { Facade, Floor, FloorStack, TFloorState } from '@mappedin/mappedin-js';\nimport { getMultiFloorState } from '@mappedin/mappedin-js';\nimport type { Building } from './building';\nimport type {\n\tBuildingAnimation,\n\tBuildingFacadeState,\n\tBuildingFloorStackState,\n\tDynamicFocusMode,\n\tZoomState,\n} from './types';\nimport type { Outdoors } from './outdoors';\n\n/**\n * Calculates the zoom state based on camera zoom level and thresholds.\n */\nexport function getZoomState(zoomLevel: number, indoorThreshold: number, outdoorThreshold: number): ZoomState {\n\tif (zoomLevel >= indoorThreshold) {\n\t\treturn 'in-range';\n\t}\n\tif (zoomLevel <= outdoorThreshold) {\n\t\treturn 'out-of-range';\n\t}\n\n\treturn 'transition';\n}\n\nexport function getFloorToShow(\n\ttarget: Building | Outdoors,\n\tmode: DynamicFocusMode,\n\televation: number,\n): Floor | undefined {\n\tif (target.__type === 'outdoors' && 'floor' in target) {\n\t\treturn target.floor;\n\t}\n\n\tconst building = target as Building;\n\tif (building.excluded) {\n\t\treturn building.activeFloor;\n\t}\n\n\tswitch (mode) {\n\t\tcase 'lock-elevation':\n\t\t\treturn building.getFloorByElevation(elevation);\n\t\tcase 'nearest-elevation':\n\t\t\treturn building.getNearestFloorByElevation(elevation);\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\t// if the building is already showing, don't switch to the default floor\n\treturn building.isIndoor ? building.activeFloor : building.defaultFloor;\n}\n\nexport function getFacadeState(facade: Facade, inFocus: boolean): BuildingFacadeState {\n\treturn {\n\t\tfacade,\n\t\tstate: {\n\t\t\ttype: 'facade',\n\t\t\tvisible: !inFocus,\n\t\t\topacity: inFocus ? 0 : 1,\n\t\t},\n\t};\n}\n\nexport function getSingleBuildingState(\n\tfloorStack: FloorStack,\n\tcurrentFloor: Floor,\n\tinFocus: boolean,\n): BuildingFloorStackState {\n\treturn {\n\t\toutdoorOpacity: 1,\n\t\tfloorStates: floorStack.floors.map(f => {\n\t\t\tconst visible = f.id === currentFloor.id && inFocus;\n\n\t\t\treturn {\n\t\t\t\tfloor: f,\n\t\t\t\tstate: {\n\t\t\t\t\ttype: 'floor',\n\t\t\t\t\tvisible: visible,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\tvisible: visible,\n\t\t\t\t\t},\n\t\t\t\t\tlabels: {\n\t\t\t\t\t\tenabled: visible,\n\t\t\t\t\t},\n\t\t\t\t\tmarkers: {\n\t\t\t\t\t\tenabled: visible,\n\t\t\t\t\t},\n\t\t\t\t\tfootprint: {\n\t\t\t\t\t\tvisible: false,\n\t\t\t\t\t},\n\t\t\t\t\tocclusion: {\n\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t},\n\t\t\t\t} as Required<TFloorState>,\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Calculates the outdoor opacity based on floor stack states and mode.\n */\nexport function getOutdoorOpacity(floorStackStates: BuildingFloorStackState[], mode: DynamicFocusMode): number {\n\tif (!mode.includes('lock-elevation')) {\n\t\treturn 1;\n\t}\n\n\tfor (const state of floorStackStates) {\n\t\tif (state.outdoorOpacity >= 0 && state.outdoorOpacity <= 1) {\n\t\t\treturn state.outdoorOpacity;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nexport function getSetFloorTargetFromZoomState(\n\tbuildings: Building[],\n\toutdoors: Outdoors,\n\tzoomState: ZoomState,\n): Building | Outdoors | undefined {\n\tswitch (zoomState) {\n\t\tcase 'in-range':\n\t\t\treturn buildings[0]?.canSetFloor ? buildings[0] : undefined;\n\t\tcase 'out-of-range':\n\t\t\treturn outdoors;\n\t\tcase 'transition':\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the building states for all buildings.\n */\nexport function getBuildingStates(\n\tbuildings: Building[],\n\tinViewSet: Set<string>,\n\tcurrentFloor: Floor,\n\tzoomState: ZoomState,\n\tmode: DynamicFocusMode,\n\televation: number,\n\tfloorIdsInNavigation: string[],\n\tfloorStackIdsInNavigation: string[],\n\tmultiFloorView: any,\n\tdynamicBuildingInteriors: boolean,\n): Map<\n\tstring,\n\t{\n\t\tbuilding: Building;\n\t\tshowIndoor: boolean;\n\t\tfloorStackState: BuildingFloorStackState;\n\t\tfacadeState: BuildingFacadeState;\n\t\tinFocus: boolean;\n\t\tfloorToShow: Floor | undefined;\n\t}\n> {\n\tconst buildingStates = new Map();\n\n\tfor (const building of buildings) {\n\t\tconst inCameraView = inViewSet.has(building.id);\n\t\tconst showIndoor = shouldShowIndoor(\n\t\t\tbuilding,\n\t\t\tcurrentFloor,\n\t\t\tzoomState === 'in-range',\n\t\t\tinCameraView,\n\t\t\tmode,\n\t\t\televation,\n\t\t\tfloorStackIdsInNavigation.includes(building.id),\n\t\t\tdynamicBuildingInteriors,\n\t\t);\n\n\t\tconst floorToShow =\n\t\t\tcurrentFloor.floorStack.id === building.id ? building.activeFloor : getFloorToShow(building, mode, elevation);\n\n\t\tconst floorStackState = multiFloorView.enabled\n\t\t\t? getMultiFloorState(\n\t\t\t\t\tbuilding.floors,\n\t\t\t\t\tfloorToShow || building.activeFloor,\n\t\t\t\t\tmultiFloorView.floorGap,\n\t\t\t\t\tfloorIdsInNavigation,\n\t\t\t )\n\t\t\t: getSingleBuildingState(building.floorStack, floorToShow || building.activeFloor, showIndoor);\n\n\t\tconst facadeState = getFacadeState(building.facade, showIndoor);\n\n\t\tbuildingStates.set(building.id, {\n\t\t\tbuilding,\n\t\t\tshowIndoor,\n\t\t\tfloorStackState,\n\t\t\tfacadeState,\n\t\t\tinFocus: inCameraView,\n\t\t\tfloorToShow,\n\t\t});\n\t}\n\n\treturn buildingStates;\n}\n\nexport function getBuildingAnimationType(building: Building, showIndoor: boolean): BuildingAnimation {\n\tif (building.excluded) {\n\t\treturn 'none';\n\t}\n\n\tif (showIndoor) {\n\t\treturn 'indoor';\n\t}\n\n\treturn 'outdoor';\n}\n\n/**\n * Determines if a building's indoor floors should be shown through a number of different state checks.\n */\nexport function shouldShowIndoor(\n\tbuilding: Building,\n\tcurrentFloor: Floor,\n\tinRange: boolean,\n\tinFocus: boolean,\n\tmode: DynamicFocusMode,\n\televation: number,\n\tinNavigation: boolean,\n\tdynamicBuildingInteriors: boolean,\n): boolean {\n\t// always show the current floor regardless of any other states\n\tif (building.id === currentFloor.floorStack.id) {\n\t\treturn true;\n\t}\n\n\t// if the building is excluded, we don't control the visibility, so don't show it\n\tif (building.excluded) {\n\t\treturn false;\n\t}\n\n\t// if it's not excluded, always show the navigation\n\tif (inNavigation === true) {\n\t\treturn true;\n\t}\n\n\t// Without dynamic building interiors, we only rely on whether the current floor is indoor or outdoor\n\tif (!dynamicBuildingInteriors) {\n\t\treturn currentFloor.floorStack.type !== 'Outdoor';\n\t}\n\n\t// the following cases rely on the camera being in range\n\tif (!inRange) {\n\t\treturn false;\n\t}\n\n\t// the following cases rely on the building being in focus\n\tif (!inFocus) {\n\t\treturn false;\n\t}\n\n\tswitch (mode) {\n\t\tcase 'lock-elevation':\n\t\t\treturn building.getFloorByElevation(elevation) != null;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nexport function shouldDeferSetFloor(\n\ttrackedCameraElevation: number,\n\tcurrentCameraElevation: number,\n\tuserInteracting: boolean,\n): boolean {\n\treturn trackedCameraElevation !== currentCameraElevation && !userInteracting;\n}\n", "import type { Facade, TFacadeState, VisibilityState as BuildingFloorStackState } from '@mappedin/mappedin-js';\n\nexport type DynamicFocusAnimationOptions = {\n\t/**\n\t * The duration of the animation in milliseconds.\n\t * @default 150\n\t */\n\tduration: number;\n};\n\n/**\n * Array of valid dynamic focus modes for runtime validation.\n */\nexport const DYNAMIC_FOCUS_MODES = ['default-floor', 'lock-elevation', 'nearest-elevation'] as const;\n\n/**\n * The mode which determines the indoor floor to reveal when the camera focuses on a facade.\n * - 'default-floor' - Show the default floor of the floor stack.\n * - 'lock-elevation' - Show the floor at the current elevation, if possible.\n * When a floor stack does not have a floor at the current elevation, no indoor floor will be shown.\n * - 'nearest-elevation' - Show the floor at the current elevation, if possible.\n * When a floor stack does not have a floor at the current elevation, show the indoor floor at the nearest lower elevation.\n */\nexport type DynamicFocusMode = (typeof DYNAMIC_FOCUS_MODES)[number];\n\n/**\n * State of the Dynamic Focus controller.\n */\nexport type DynamicFocusState = {\n\t/**\n\t * Whether to automatically focus on the outdoors when the camera moves in range.\n\t * @default true\n\t */\n\tautoFocus: boolean;\n\t/**\n\t * The zoom level at which the camera will fade out the facades and fade in the indoor floors.\n\t * @default 18\n\t */\n\tindoorZoomThreshold: number;\n\t/**\n\t * The zoom level at which the camera will fade in the facades and fade out the indoor floors.\n\t * @default 17\n\t */\n\toutdoorZoomThreshold: number;\n\t/**\n\t * Whether to set the floor to the outdoors when the camera moves in range.\n\t * @default true\n\t */\n\tsetFloorOnFocus: boolean;\n\t/**\n\t * Options for the animation when fading out the facade to reveal the interior.\n\t */\n\tindoorAnimationOptions: DynamicFocusAnimationOptions;\n\t/**\n\t * Options for the animation when fading in the facade to hide the interior.\n\t */\n\toutdoorAnimationOptions: DynamicFocusAnimationOptions;\n\t/**\n\t * The mode of the Dynamic Focus controller.\n\t * @default 'default-floor'\n\t */\n\tmode: DynamicFocusMode;\n\t/**\n\t * Whether to automatically adjust facade heights to align with floor boundaries in multi-floor buildings.\n\t * @default false\n\t */\n\tautoAdjustFacadeHeights: boolean;\n\t/**\n\t * Whether to automatically hide the indoors of buildings not in or near the camera's view.\n\t * @default true\n\t */\n\tdynamicBuildingInteriors: boolean;\n\t/**\n\t * Whether to preload the geometry of the initial floors in each building. Improves performance when rendering the building for the first time.\n\t * @default true\n\t */\n\tpreloadFloors: boolean;\n};\n\n/**\n * Internal events emitted for updating React state.\n */\nexport type InternalDynamicFocusEvents = {\n\t'state-change': undefined;\n};\n\n/**\n * Events emitted by the Dynamic Focus controller.\n */\nexport type DynamicFocusEvents = {\n\t/**\n\t * Emitted when the Dynamic Focus controller triggers a focus update either from a camera change or manually calling `focus()`.\n\t */\n\tfocus: {\n\t\tfacades: Facade[];\n\t};\n};\n\nexport type DynamicFocusEventPayload<EventName extends keyof DynamicFocusEvents> =\n\tDynamicFocusEvents[EventName] extends { data: null }\n\t\t? DynamicFocusEvents[EventName]['data']\n\t\t: DynamicFocusEvents[EventName];\n\nexport type BuildingFacadeState = {\n\tfacade: Facade;\n\tstate: TFacadeState;\n};\n\nexport type BuildingState = BuildingFloorStackState & {\n\tfacadeState: BuildingFacadeState;\n};\n\nexport type ZoomState = 'in-range' | 'out-of-range' | 'transition';\nexport type ViewState = 'indoor' | 'outdoor' | 'transition';\n\nexport type BuildingAnimation = 'indoor' | 'outdoor' | 'none';\n\nexport type { BuildingFloorStackState };\n", "import { Floor, FloorStack } from '@mappedin/mappedin-js';\nimport { clampWithWarning } from '@packages/internal/common/math-utils';\nimport Logger from '@packages/internal/common/Mappedin.Logger';\n\n/**\n * Validates that a floor belongs to the specified floor stack.\n */\nexport function validateFloorForStack(floor: Floor, floorStack: FloorStack): boolean {\n\tif (!Floor.is(floor) || floor?.floorStack == null || !FloorStack.is(floorStack)) {\n\t\treturn false;\n\t}\n\n\tif (floor.floorStack.id !== floorStack.id) {\n\t\tLogger.warn(`Floor (${floor.id}) does not belong to floor stack (${floorStack.id}).`);\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Validates and clamps zoom threshold values.\n */\nexport function validateZoomThreshold(value: number, min: number, max: number, name: string): number {\n\treturn clampWithWarning(value, min, max, `${name} must be between ${min} and ${max}.`);\n}\n", "/* eslint-disable no-console*/\nexport const MI_DEBUG_KEY = 'mi-debug';\nexport const MI_ERROR_LABEL = '[MappedinJS]';\n\nexport enum E_SDK_LOG_LEVEL {\n\tLOG,\n\tWARN,\n\tERROR,\n\tSILENT,\n}\n\nexport function createLogger(name = '', { prefix = MI_ERROR_LABEL } = {}) {\n\tconst label = `${prefix}${name ? `-${name}` : ''}`;\n\n\tconst rnDebug = (type: 'log' | 'warn' | 'error', args: any[]) => {\n\t\tif (typeof window !== 'undefined' && (window as any).rnDebug) {\n\t\t\tconst processed = args.map(arg => {\n\t\t\t\tif (arg instanceof Error && arg.stack) {\n\t\t\t\t\treturn `${arg.message}\\n${arg.stack}`;\n\t\t\t\t}\n\n\t\t\t\treturn arg;\n\t\t\t});\n\t\t\t(window as any).rnDebug(`${name} ${type}: ${processed.join(' ')}`);\n\t\t}\n\t};\n\n\treturn {\n\t\tlogState: process.env.NODE_ENV === 'test' ? E_SDK_LOG_LEVEL.SILENT : E_SDK_LOG_LEVEL.LOG,\n\n\t\tlog(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.LOG) {\n\t\t\t\tconsole.log(label, ...args);\n\t\t\t\trnDebug('log', args);\n\t\t\t}\n\t\t},\n\n\t\twarn(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.WARN) {\n\t\t\t\tconsole.warn(label, ...args);\n\t\t\t\trnDebug('warn', args);\n\t\t\t}\n\t\t},\n\n\t\terror(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.ERROR) {\n\t\t\t\tconsole.error(label, ...args);\n\n\t\t\t\trnDebug('error', args);\n\t\t\t}\n\t\t},\n\n\t\t// It's a bit tricky to prepend [MappedinJs] to assert and time because of how the output is structured in the console, so it is left out for simplicity\n\t\tassert(...args: any[]) {\n\t\t\tconsole.assert(...args);\n\t\t},\n\n\t\ttime(label: string) {\n\t\t\tconsole.time(label);\n\t\t},\n\n\t\ttimeEnd(label: string) {\n\t\t\tconsole.timeEnd(label);\n\t\t},\n\t\tsetLevel(level: E_SDK_LOG_LEVEL) {\n\t\t\tif (E_SDK_LOG_LEVEL.LOG <= level && level <= E_SDK_LOG_LEVEL.SILENT) {\n\t\t\t\tthis.logState = level;\n\t\t\t}\n\t\t},\n\t};\n}\n\nconst Logger = createLogger();\nexport function setLoggerLevel(level: E_SDK_LOG_LEVEL) {\n\tif (E_SDK_LOG_LEVEL.LOG <= level && level <= E_SDK_LOG_LEVEL.SILENT) {\n\t\tLogger.logState = level;\n\t}\n}\n\nexport default Logger;\n", "import Logger from './Mappedin.Logger';\n\n/**\n * Clamp a number between lower and upper bounds with a warning\n */\nexport function clampWithWarning(x: number, lower: number, upper: number, warning: string) {\n\tif (x < lower || x > upper) {\n\t\tLogger.warn(warning);\n\t}\n\n\treturn Math.min(upper, Math.max(lower, x));\n}\n", "import { createLogger } from '../../packages/common/Mappedin.Logger';\n\nexport const Logger = createLogger('', { prefix: '[DynamicFocus]' });\n", "import type { FloorStack, MapView } from '@mappedin/mappedin-js';\nimport { Logger } from './logger';\nimport type { Building } from './building';\n\nexport class Outdoors {\n\t__type = 'outdoors';\n\t#floorStack: FloorStack;\n\t#mapView: MapView;\n\n\tconstructor(floorStack: FloorStack, mapView: MapView) {\n\t\tthis.#floorStack = floorStack;\n\t\tthis.#mapView = mapView;\n\t}\n\n\tget id() {\n\t\treturn this.#floorStack.id;\n\t}\n\n\tget floorStack() {\n\t\treturn this.#floorStack;\n\t}\n\n\tget floor() {\n\t\t// outdoors should only have 1 floor\n\t\treturn this.#floorStack.defaultFloor;\n\t}\n\n\tmatchesFloorStack(floorStack: FloorStack | string) {\n\t\treturn floorStack === this.#floorStack || floorStack === this.#floorStack.id;\n\t}\n\n\t#setVisible(visible: boolean) {\n\t\tfor (const floor of this.#floorStack.floors) {\n\t\t\tthis.#mapView.updateState(floor, {\n\t\t\t\tvisible,\n\t\t\t});\n\t\t}\n\t}\n\n\tshow() {\n\t\tthis.#setVisible(true);\n\t}\n\n\thide() {\n\t\tthis.#setVisible(false);\n\t}\n\n\tdestroy() {\n\t\tif (!this.matchesFloorStack(this.#mapView.currentFloorStack)) {\n\t\t\tthis.hide();\n\t\t}\n\t}\n}\n\nexport function getOutdoorFloorStack(floorStacks: FloorStack[], buildingsSet: Map<string, Building>): FloorStack {\n\tconst outdoorFloorStack = floorStacks.find(floorStack => floorStack.type?.toLowerCase() === 'outdoor');\n\n\tif (outdoorFloorStack) {\n\t\treturn outdoorFloorStack;\n\t}\n\n\t// If no outdoor type found, find the first floor stack that does not have a facade or is already in the buildings set\n\tconst likelyOutdoorFloorStack = floorStacks.find(\n\t\tfloorStack => floorStack.facade == null && !buildingsSet.has(floorStack.id),\n\t);\n\n\tif (likelyOutdoorFloorStack) {\n\t\treturn likelyOutdoorFloorStack;\n\t}\n\n\tLogger.warn('No good candidate for the outdoor floor stack was found. Using the first floor stack.');\n\n\treturn floorStacks[0];\n}\n", "import type { RequiredDeep } from 'type-fest';\nimport type { DynamicFocusState } from './types';\n\nexport const DEFAULT_STATE: RequiredDeep<DynamicFocusState> = {\n\tindoorZoomThreshold: 18,\n\toutdoorZoomThreshold: 17,\n\tsetFloorOnFocus: true,\n\tautoFocus: false,\n\tindoorAnimationOptions: {\n\t\tduration: 150,\n\t},\n\toutdoorAnimationOptions: {\n\t\tduration: 150,\n\t},\n\tautoAdjustFacadeHeights: false,\n\tmode: 'default-floor',\n\tpreloadFloors: true,\n\tdynamicBuildingInteriors: true,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["index_exports", "__export", "DynamicFocus", "import_mappedin_js", "arraysEqual", "arr1", "arr2", "i", "__name", "_PubSub", "__publicField", "eventName", "data", "fn", "itemIdx", "__name", "PubSub", "import_mappedin_js", "_floorStack", "_floorsById", "_floorsByElevation", "_floorsByElevationSorted", "_mapView", "
|
|
4
|
+
"sourcesContent": ["export { DynamicFocus } from './dynamic-focus';\nexport type {\n\tDynamicFocusState,\n\tDynamicFocusMode,\n\tDynamicFocusAnimationOptions,\n\tDynamicFocusEvents,\n\tDynamicFocusEventPayload,\n} from './types';\n", "import type {\n\tCameraTransform,\n\tFacade,\n\tFloorStack,\n\tMapData,\n\tMapView,\n\tTEvents,\n\tTFloorState,\n} from '@mappedin/mappedin-js';\nimport { Floor, getMultiFloorState } from '@mappedin/mappedin-js';\nimport { arraysEqual } from '@packages/internal/common/array-utils';\nimport { PubSub } from '@packages/internal/common/pubsub';\nimport { Building } from './building';\nimport {\n\tgetFloorToShow,\n\tshouldShowIndoor,\n\tgetBuildingAnimationType,\n\tgetZoomState,\n\tgetOutdoorOpacity,\n\tgetSetFloorTargetFromZoomState,\n\tgetBuildingStates,\n\tshouldDeferSetFloor,\n} from './dynamic-focus-scene';\nimport { DYNAMIC_FOCUS_MODES } from './types';\nimport type {\n\tViewState,\n\tZoomState,\n\tBuildingFacadeState,\n\tDynamicFocusEventPayload,\n\tDynamicFocusEvents,\n\tDynamicFocusMode,\n\tDynamicFocusState,\n\tBuildingFloorStackState,\n\tInternalDynamicFocusEvents,\n} from './types';\nimport { validateFloorForStack, validateZoomThreshold } from './validation';\nimport { getOutdoorFloorStack, Outdoors } from './outdoors';\nimport { Logger } from './logger';\nimport MappedinJSLogger from '../../packages/common/Mappedin.Logger';\nimport { DEFAULT_STATE } from './constants';\nimport type { MapViewExtension } from '@packages/internal/common/extensions';\n\n/**\n * Dynamic Focus is a MapView scene manager that maintains the visibility of the outdoors\n * while fading in and out building interiors as the camera pans.\n */\nexport class DynamicFocus implements MapViewExtension<DynamicFocusState> {\n\t#pubsub: PubSub<DynamicFocusEvents & InternalDynamicFocusEvents>;\n\t#mapView: MapView;\n\t#mapData: MapData;\n\t#state: Required<DynamicFocusState> = DEFAULT_STATE;\n\t/**\n\t * The buildings that are currently in view, sorted by the order they are in the facades-in-view-change event.\n\t * While these will be within the camera view, these may not be in focus or showIndoor depending on the mode.\n\t */\n\t#sortedBuildingsInView: Building[] = [];\n\t/**\n\t * The buildings that are currently in view, as a set of building ids.\n\t */\n\t#buildingIdsInViewSet = new Set<string>();\n\t#buildings = new Map<string, Building>();\n\t#outdoors: Outdoors;\n\t#userInteracting = false;\n\t#pendingFacadeUpdate = false;\n\t#floorElevation = 0;\n\t#cameraElevation = 0;\n\t/**\n\t * Tracks the current zoom state based on camera zoom level:\n\t * - 'in-range': Camera is zoomed in enough to show indoor details (>= indoorZoomThreshold)\n\t * - 'out-of-range': Camera is zoomed out to show outdoor context (<= outdoorZoomThreshold)\n\t * - 'transition': Camera is between the two thresholds (no floor changes occur)\n\t */\n\t#zoomState: ZoomState = 'transition';\n\t#viewState: ViewState = 'outdoor';\n\t/**\n\t * The facades that are actually focused and shown (filtered by showIndoor logic)\n\t */\n\t#facadesInFocus: Facade[] = [];\n\t#enabled = false;\n\n\t/**\n\t * @internal\n\t * Used to await the current scene update before starting a new one, or when the scene is updated asynchronously by an event.\n\t */\n\tprivate sceneUpdateQueue: Promise<void> = Promise.resolve();\n\n\t/**\n\t * Creates a new instance of the Dynamic Focus controller.\n\t *\n\t * @param mapView - The {@link MapView} to attach Dynamic Focus to.\n\t * @param options - Options for configuring Dynamic Focus.\n\t *\n\t * @example\n\t * ```ts\n\t * const mapView = show3dMap(...);\n\t * const df = new DynamicFocus(mapView);\n\t * df.enable({ autoFocus: true });\n\t *\n\t * // pause the listener\n\t * df.updateState({ autoFocus: false });\n\t *\n\t * // manually trigger a focus\n\t * df.focus();\n\t * ```\n\t */\n\tconstructor(mapView: MapView) {\n\t\tthis.#pubsub = new PubSub<DynamicFocusEvents & InternalDynamicFocusEvents>();\n\t\tthis.#mapView = mapView;\n\t\tLogger.setLevel(MappedinJSLogger.logState);\n\t\tthis.#mapData = this.#mapView.getMapData();\n\t\tthis.#floorElevation = this.#mapView.currentFloor.elevation;\n\t\tthis.#cameraElevation = this.#mapView.Camera.elevation;\n\t\t// initialize the buildings\n\t\tfor (const facade of this.#mapData.getByType('facade')) {\n\t\t\tthis.#buildings.set(facade.floorStack.id, new Building(facade.floorStack, this.#mapView));\n\t\t}\n\t\tthis.#outdoors = new Outdoors(\n\t\t\tgetOutdoorFloorStack(this.#mapData.getByType('floor-stack'), this.#buildings),\n\t\t\tthis.#mapView,\n\t\t);\n\t\tthis.#mapView.on('floor-change-start', this.#handleFloorChangeStart);\n\t\tthis.#mapView.on('camera-change', this.#handleCameraChange);\n\t\tthis.#mapView.on('facades-in-view-change', this.#handleFacadesInViewChange);\n\t\tthis.#mapView.on('user-interaction-start', this.#handleUserInteractionStart);\n\t\tthis.#mapView.on('user-interaction-end', this.#handleUserInteractionEnd);\n\t}\n\n\t/**\n\t * Enables Dynamic Focus with the given options.\n\t * @param options - The options to enable Dynamic Focus with.\n\t */\n\tenable(options?: Partial<DynamicFocusState>): void {\n\t\tif (this.#enabled) {\n\t\t\tLogger.warn('enable() called on an already enabled Dynamic Focus instance.');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#enabled = true;\n\t\tthis.#mapView.manualFloorVisibility = true;\n\t\tthis.#outdoors.show();\n\t\tthis.updateState({ ...this.#state, ...options });\n\t\t// fire the camera change event to set the initial state\n\t\tthis.#handleCameraChange({\n\t\t\tzoomLevel: this.#mapView.Camera.zoomLevel,\n\t\t\tcenter: this.#mapView.Camera.center,\n\t\t\tbearing: this.#mapView.Camera.bearing,\n\t\t\tpitch: this.#mapView.Camera.pitch,\n\t\t} as CameraTransform);\n\t\t// fire dynamic focus change to set initial state of facades\n\t\tthis.#mapView.Camera.updateFacadesInView();\n\t}\n\t/**\n\t * Disables Dynamic Focus and returns the MapView to it's previous state.\n\t */\n\tdisable(): void {\n\t\tif (!this.#enabled) {\n\t\t\tLogger.warn('disable() called on an already disabled Dynamic Focus instance.');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#enabled = false;\n\t\tthis.#mapView.manualFloorVisibility = false;\n\t}\n\n\t/**\n\t * Returns true if Dynamic Focus is enabled.\n\t */\n\tget isEnabled(): boolean {\n\t\treturn this.#enabled;\n\t}\n\n\t/**\n\t * Returns true if the current view state is indoor.\n\t */\n\tget isIndoor() {\n\t\treturn this.#viewState === 'indoor';\n\t}\n\n\t/**\n\t * Returns true if the current view state is outdoor.\n\t */\n\tget isOutdoor() {\n\t\treturn this.#viewState === 'outdoor';\n\t}\n\n\t/**\n\t * Sets the view state to indoor, regardless of the current zoom level.\n\t */\n\tsetIndoor() {\n\t\tthis.#viewState = 'indoor';\n\t\tthis.#zoomState = 'in-range';\n\n\t\tthis.#handleViewStateChange();\n\t}\n\n\t/**\n\t * Sets the view state to outdoor, regardless of the current zoom level.\n\t */\n\tsetOutdoor() {\n\t\tthis.#viewState = 'outdoor';\n\t\tthis.#zoomState = 'out-of-range';\n\n\t\tthis.#handleViewStateChange();\n\t}\n\n\t#handleViewStateChange() {\n\t\tif (this.#state.autoFocus) {\n\t\t\t// Only set the floor if setFloorOnFocus is true and the view state changed due to a user interaction\n\t\t\t// Camera animations will not trigger a focus change until they settle.\n\t\t\tif (this.#userInteracting) {\n\t\t\t\tthis.focus();\n\t\t\t} else {\n\t\t\t\tthis.#pendingFacadeUpdate = true;\n\t\t\t}\n\t\t}\n\t\tthis.#pubsub.publish('state-change');\n\t}\n\n\t#preloadFloors(mode: DynamicFocusMode) {\n\t\tthis.#mapView.preloadFloors(\n\t\t\tthis.#mapData\n\t\t\t\t.getByType('facade')\n\t\t\t\t.map(facade => getFloorToShow(this.#buildings.get(facade.floorStack.id)!, mode, this.#floorElevation))\n\t\t\t\t.filter(f => f != null && Floor.is(f)),\n\t\t);\n\t}\n\n\t/**\n\t * Returns the facades that are currently in focus.\n\t */\n\tget focusedFacades() {\n\t\treturn [...this.#facadesInFocus];\n\t}\n\n\t/**\n\t * Subscribe to a Dynamic Focus event.\n\t */\n\ton = <EventName extends keyof DynamicFocusEvents>(\n\t\teventName: EventName,\n\t\tfn: (payload: DynamicFocusEventPayload<EventName>) => void,\n\t) => {\n\t\tthis.#pubsub.on(eventName, fn);\n\t};\n\n\t/**\n\t * Unsubscribe from a Dynamic Focus event.\n\t */\n\toff = <EventName extends keyof DynamicFocusEvents>(\n\t\teventName: EventName,\n\t\tfn: (payload: DynamicFocusEventPayload<EventName>) => void,\n\t) => {\n\t\tthis.#pubsub.off(eventName, fn);\n\t};\n\n\t/**\n\t * Returns the current state of the Dynamic Focus controller.\n\t */\n\tgetState(): DynamicFocusState {\n\t\treturn { ...this.#state };\n\t}\n\n\t/**\n\t * Updates the state of the Dynamic Focus controller.\n\t * @param state - The state to update.\n\t */\n\tupdateState(state: Partial<DynamicFocusState>) {\n\t\tlet shouldReapplyBuildingStates = false;\n\n\t\tif (state.indoorZoomThreshold != null) {\n\t\t\tstate.indoorZoomThreshold = validateZoomThreshold(\n\t\t\t\tstate.indoorZoomThreshold,\n\t\t\t\tthis.#state.outdoorZoomThreshold,\n\t\t\t\tthis.#mapView.Camera.maxZoomLevel,\n\t\t\t\t'indoorZoomThreshold',\n\t\t\t);\n\t\t}\n\t\tif (state.outdoorZoomThreshold != null) {\n\t\t\tstate.outdoorZoomThreshold = validateZoomThreshold(\n\t\t\t\tstate.outdoorZoomThreshold,\n\t\t\t\tthis.#mapView.Camera.minZoomLevel,\n\t\t\t\tthis.#state.indoorZoomThreshold,\n\t\t\t\t'outdoorZoomThreshold',\n\t\t\t);\n\t\t}\n\n\t\tif (state.mode != null) {\n\t\t\tstate.mode = DYNAMIC_FOCUS_MODES.includes(state.mode) ? state.mode : 'default-floor';\n\t\t}\n\n\t\tif (state.autoAdjustFacadeHeights != null) {\n\t\t\tthis.#state.autoAdjustFacadeHeights = state.autoAdjustFacadeHeights;\n\t\t}\n\n\t\tif (\n\t\t\tstate.dynamicBuildingInteriors != null &&\n\t\t\tstate.dynamicBuildingInteriors !== this.#state.dynamicBuildingInteriors\n\t\t) {\n\t\t\tshouldReapplyBuildingStates = true;\n\t\t}\n\n\t\t// assign state and ignore undefined values\n\t\tthis.#state = Object.assign(\n\t\t\t{},\n\t\t\tthis.#state,\n\t\t\tObject.fromEntries(Object.entries(state).filter(([, value]) => value != null)),\n\t\t);\n\n\t\t// preload the initial floors that will be included in the mode\n\t\tif (state.mode != null && state.preloadFloors) {\n\t\t\tthis.#preloadFloors(state.mode);\n\t\t}\n\n\t\tif (shouldReapplyBuildingStates) {\n\t\t\tthis.#applyBuildingStates();\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the Dynamic Focus instance and unsubscribes all MapView event listeners.\n\t */\n\tdestroy() {\n\t\tthis.disable();\n\t\tthis.#mapView.off('facades-in-view-change', this.#handleFacadesInViewChange);\n\t\tthis.#mapView.off('floor-change-start', this.#handleFloorChangeStart);\n\t\tthis.#mapView.off('camera-change', this.#handleCameraChange);\n\t\tthis.#mapView.off('user-interaction-start', this.#handleUserInteractionStart);\n\t\tthis.#mapView.off('user-interaction-end', this.#handleUserInteractionEnd);\n\t\tthis.#buildings.forEach(building => building.destroy());\n\t\tthis.#outdoors.destroy();\n\t\tthis.#pubsub.destroy();\n\t}\n\n\t/**\n\t * Perform a manual visual update of the focused facades, and optionally set the floor.\n\t * @param setFloor - Whether to set the floor. This will default to the current state of setFloorOnFocus.\n\t */\n\tasync focus(setFloor = this.#state.setFloorOnFocus) {\n\t\tif (setFloor) {\n\t\t\tif (shouldDeferSetFloor(this.#cameraElevation, this.#mapView.Camera.elevation, this.#userInteracting)) {\n\t\t\t\tthis.#cameraElevation = this.#mapView.Camera.elevation;\n\t\t\t\tthis.#pendingFacadeUpdate = true;\n\t\t\t} else {\n\t\t\t\tconst target = getSetFloorTargetFromZoomState(this.#sortedBuildingsInView, this.#outdoors, this.#zoomState);\n\n\t\t\t\tconst floor = target ? getFloorToShow(target, this.#state.mode, this.#floorElevation) : undefined;\n\n\t\t\t\tif (floor && floor.id !== this.#mapView.currentFloor.id) {\n\t\t\t\t\tthis.#mapView.setFloor(floor, { context: 'dynamic-focus' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait this.#applyBuildingStates();\n\t\t// must publish after the scene is updated to ensure the focusedFacades array is up to date\n\t\tthis.#pubsub.publish('focus', { facades: this.focusedFacades });\n\t}\n\n\t/**\n\t * Preloads the initial floors for each building to improve performance when rendering the building for the first time. See {@link DynamicFocusState.preloadFloors}.\n\t */\n\tpreloadFloors() {\n\t\tthis.#preloadFloors(this.#state.mode);\n\t}\n\n\t/**\n\t * Sets the default floor for a floor stack. This is the floor that will be shown when focusing on a facade if there is no currently active floor in the stack.\n\t * See {@link resetDefaultFloorForStack} to reset the default floor.\n\t * @param floorStack - The floor stack to set the default floor for.\n\t * @param floor - The floor to set as the default floor.\n\t */\n\tsetDefaultFloorForStack(floorStack: FloorStack, floor: Floor) {\n\t\tif (!validateFloorForStack(floor, floorStack)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.defaultFloor = floor;\n\t\t}\n\t}\n\n\t/**\n\t * Resets the default floor for a floor stack to it's initial value.\n\t * @param floorStack - The floor stack to reset the default floor for.\n\t */\n\tresetDefaultFloorForStack(floorStack: FloorStack) {\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.defaultFloor = floorStack.defaultFloor;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the current default floor for a floor stack.\n\t * @param floorStack - The floor stack to get the default floor for.\n\t * @returns The current default floor for the floor stack.\n\t */\n\tgetDefaultFloorForStack(floorStack: FloorStack) {\n\t\treturn this.#buildings.get(floorStack.id)?.defaultFloor || floorStack.defaultFloor || floorStack.floors[0];\n\t}\n\n\t/**\n\t * Sets the current floor for a floor stack. If the floor stack is currently focused, this floor will become visible.\n\t * @param floorStack - The floor stack to set the current floor for.\n\t */\n\tsetCurrentFloorForStack(floorStack: FloorStack, floor: Floor) {\n\t\tif (!validateFloorForStack(floor, floorStack)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst building = this.#buildings.get(floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.activeFloor = floor;\n\t\t\tthis.#applyBuildingStates();\n\t\t}\n\t}\n\n\t/**\n\t * Excludes a floor stack from visibility changes.\n\t * @param excluded - The floor stack or stacks to exclude.\n\t */\n\texclude(excluded: FloorStack | FloorStack[]) {\n\t\tconst excludedFloorStacks = Array.isArray(excluded) ? excluded : [excluded];\n\t\tfor (const floorStack of excludedFloorStacks) {\n\t\t\tconst building = this.#buildings.get(floorStack.id);\n\t\t\tif (building) {\n\t\t\t\tbuilding.excluded = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Includes a floor stack in visibility changes.\n\t * @param included - The floor stack or stacks to include.\n\t */\n\tinclude(included: FloorStack | FloorStack[]) {\n\t\tconst includedFloorStacks = Array.isArray(included) ? included : [included];\n\t\tfor (const floorStack of includedFloorStacks) {\n\t\t\tconst building = this.#buildings.get(floorStack.id);\n\t\t\tif (building) {\n\t\t\t\tbuilding.excluded = false;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the current floor for a floor stack.\n\t * @param floorStack - The floor stack to get the current floor for.\n\t * @returns The current floor for the floor stack.\n\t */\n\tgetCurrentFloorForStack(floorStack: FloorStack) {\n\t\treturn this.#buildings.get(floorStack.id)?.activeFloor || this.getDefaultFloorForStack(floorStack);\n\t}\n\n\t/**\n\t * Handles management of focused facades but doesn't trigger view updates unless enabled.\n\t * @see {@link focus} to manually trigger a view update.\n\t */\n\t#handleFacadesInViewChange = (event: TEvents['facades-in-view-change']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { facades } = event;\n\n\t\t// if the facades are the same, or we're in between outdoor/indoor, don't do anything unless we're pending a facade update\n\t\tif (arraysEqual(facades, this.focusedFacades) && this.#viewState === 'transition' && !this.#pendingFacadeUpdate) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#pendingFacadeUpdate = false;\n\n\t\tthis.#sortedBuildingsInView = [];\n\t\tthis.#buildingIdsInViewSet.clear();\n\t\tif (facades.length > 0) {\n\t\t\tfor (const facade of facades) {\n\t\t\t\tconst building = this.#buildings.get(facade.floorStack.id);\n\t\t\t\tif (building) {\n\t\t\t\t\tthis.#buildingIdsInViewSet.add(building.id);\n\t\t\t\t\tthis.#sortedBuildingsInView.push(building);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.#state.autoFocus) {\n\t\t\tthis.focus();\n\t\t}\n\t};\n\t/**\n\t * Handles floor and facade visibility when the floor changes.\n\t */\n\t#handleFloorChangeStart = async (event: TEvents['floor-change-start']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { floor: newFloor } = event;\n\t\tconst building = this.#buildings.get(newFloor.floorStack.id);\n\t\tif (building) {\n\t\t\tbuilding.activeFloor = newFloor;\n\t\t}\n\t\t// Don't update elevation when switching to outdoor floor stack\n\t\tif (building?.excluded === false && !this.#outdoors.matchesFloorStack(newFloor.floorStack)) {\n\t\t\tthis.#floorElevation = newFloor.elevation;\n\t\t}\n\n\t\tif (this.#mapView.manualFloorVisibility === true) {\n\t\t\tif (event.reason !== 'dynamic-focus') {\n\t\t\t\tawait this.#applyBuildingStates(newFloor);\n\t\t\t\t// Despite this not really being a focus event, we've changed the focused facades, so we need to publish it\n\t\t\t\tthis.#pubsub.publish('focus', { facades: this.focusedFacades });\n\t\t\t}\n\n\t\t\tconst altitude = building?.floorsAltitudesMap.get(newFloor.elevation)?.altitude ?? 0;\n\t\t\tif (\n\t\t\t\tthis.#mapView.options.multiFloorView != null &&\n\t\t\t\tthis.#mapView.options.multiFloorView?.enabled &&\n\t\t\t\tthis.#mapView.options.multiFloorView?.updateCameraElevationOnFloorChange &&\n\t\t\t\tthis.#mapView.Camera.elevation !== altitude\n\t\t\t) {\n\t\t\t\tthis.#mapView.Camera.animateElevation(altitude, {\n\t\t\t\t\tduration: 750,\n\t\t\t\t\teasing: 'ease-in-out',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\t#handleUserInteractionStart = () => {\n\t\tthis.#userInteracting = true;\n\t};\n\t#handleUserInteractionEnd = () => {\n\t\tthis.#userInteracting = false;\n\t};\n\n\t/**\n\t * Handles camera moving in and out of zoom range and fires a focus event if the camera is in range.\n\t */\n\t#handleCameraChange = (event: TEvents['camera-change']) => {\n\t\tif (!this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { zoomLevel } = event;\n\t\tconst newZoomState = getZoomState(zoomLevel, this.#state.indoorZoomThreshold, this.#state.outdoorZoomThreshold);\n\n\t\tif (this.#zoomState !== newZoomState) {\n\t\t\tthis.#zoomState = newZoomState;\n\n\t\t\tif (newZoomState === 'in-range') {\n\t\t\t\tthis.setIndoor();\n\t\t\t} else if (newZoomState === 'out-of-range') {\n\t\t\t\tthis.setOutdoor();\n\t\t\t}\n\t\t}\n\t};\n\n\t#updateFloorVisibility(floorStates: BuildingFloorStackState['floorStates'], shouldShow: boolean, inFocus?: boolean) {\n\t\tfloorStates.forEach(floorState => {\n\t\t\tif (floorState.floor) {\n\t\t\t\tif (shouldShow) {\n\t\t\t\t\tconst state =\n\t\t\t\t\t\tinFocus !== undefined\n\t\t\t\t\t\t\t? ({\n\t\t\t\t\t\t\t\t\t...floorState.state,\n\t\t\t\t\t\t\t\t\tlabels: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.labels,\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.labels.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tmarkers: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.markers,\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.markers.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tocclusion: {\n\t\t\t\t\t\t\t\t\t\t...floorState.state.occlusion,\n\t\t\t\t\t\t\t\t\t\t// We don't want this floor to occlude if it's not in focus\n\t\t\t\t\t\t\t\t\t\t// Allows us to show a label above this floor while it's not active\n\t\t\t\t\t\t\t\t\t\tenabled: floorState.state.occlusion.enabled && inFocus,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t } satisfies TFloorState)\n\t\t\t\t\t\t\t: floorState.state;\n\n\t\t\t\t\tthis.#mapView.updateState(floorState.floor, state);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#mapView.updateState(floorState.floor, { visible: false });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tasync #animateIndoorSequence(\n\t\tbuilding: Building,\n\t\tfloorStackState: BuildingFloorStackState,\n\t\tfacadeState: BuildingFacadeState,\n\t\tinFocus: boolean,\n\t) {\n\t\t// show floor first then fade in the facade\n\t\tthis.#updateFloorVisibility(floorStackState.floorStates, true, inFocus);\n\n\t\treturn building.animateFacade(facadeState.state, this.#state.indoorAnimationOptions);\n\t}\n\n\tasync #animateOutdoorSequence(\n\t\tbuilding: Building,\n\t\tfloorStackState: BuildingFloorStackState,\n\t\tfacadeState: BuildingFacadeState,\n\t\tfloorStackIdsInNavigation: string[],\n\t) {\n\t\t// fade in facade then hide floors when complete\n\t\tconst result = await building.animateFacade(facadeState.state, this.#state.outdoorAnimationOptions);\n\n\t\tif (result.result === 'completed') {\n\t\t\t// Re-check if we should still show indoor after animation completes\n\t\t\tthis.#updateFloorVisibility(\n\t\t\t\tfloorStackState.floorStates,\n\t\t\t\tshouldShowIndoor(\n\t\t\t\t\tbuilding,\n\t\t\t\t\tthis.#mapView.currentFloor,\n\t\t\t\t\tthis.#zoomState === 'in-range',\n\t\t\t\t\tthis.#buildingIdsInViewSet.has(building.id),\n\t\t\t\t\tthis.#state.mode,\n\t\t\t\t\tthis.#floorElevation,\n\t\t\t\t\tfloorStackIdsInNavigation.includes(building.floorStack.id),\n\t\t\t\t\tthis.#state.dynamicBuildingInteriors,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t#applyBuildingStates = async (newFloor?: Floor) => {\n\t\tif (this.#mapView.manualFloorVisibility !== true || !this.isEnabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentFloor = newFloor || this.#mapView.currentFloor;\n\t\tconst multiFloorView = this.#mapView.options.multiFloorView;\n\t\tconst floorIdsInNavigation = this.#mapView.Navigation?.floors?.map(f => f.id) || [];\n\t\tconst floorStackIdsInNavigation = this.#mapView.Navigation?.floorStacks.map(fs => fs.id) || [];\n\n\t\t// Create a new promise for this update\n\t\tconst updatePromise = new Promise<void>(async resolve => {\n\t\t\t// Wait for the previous update to complete\n\t\t\tawait this.sceneUpdateQueue;\n\n\t\t\tconst buildingStates = getBuildingStates(\n\t\t\t\tArray.from(this.#buildings.values()),\n\t\t\t\tthis.#buildingIdsInViewSet,\n\t\t\t\tcurrentFloor,\n\t\t\t\tthis.#zoomState,\n\t\t\t\tthis.#state.mode,\n\t\t\t\tthis.#floorElevation,\n\t\t\t\tfloorIdsInNavigation,\n\t\t\t\tfloorStackIdsInNavigation,\n\t\t\t\tmultiFloorView,\n\t\t\t\tthis.#state.customMultiFloorVisibilityState ?? getMultiFloorState,\n\t\t\t\tthis.#state.dynamicBuildingInteriors,\n\t\t\t);\n\n\t\t\tconst floorStackStates: BuildingFloorStackState[] = [];\n\t\t\tawait Promise.all(\n\t\t\t\tArray.from(buildingStates.values()).map(async buildingState => {\n\t\t\t\t\tconst { building, showIndoor, floorStackState, facadeState, inFocus } = buildingState;\n\n\t\t\t\t\tfloorStackStates.push(floorStackState);\n\n\t\t\t\t\tconst animation = getBuildingAnimationType(building, showIndoor);\n\n\t\t\t\t\tif (animation === 'indoor') {\n\t\t\t\t\t\treturn this.#animateIndoorSequence(building, floorStackState, facadeState, inFocus);\n\t\t\t\t\t} else if (animation === 'outdoor') {\n\t\t\t\t\t\treturn this.#animateOutdoorSequence(building, floorStackState, facadeState, floorStackIdsInNavigation);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tthis.#mapView.Outdoor.setOpacity(getOutdoorOpacity(floorStackStates, this.#state.mode));\n\n\t\t\t// Filter #facadesInFocus to maintain sort order, keeping only buildings with showIndoor true\n\t\t\tthis.#facadesInFocus = this.#sortedBuildingsInView\n\t\t\t\t.filter(building => buildingStates.get(building.id)?.showIndoor === true)\n\t\t\t\t.map(building => building.facade);\n\n\t\t\tthis.#pubsub.publish('focus', { facades: this.#facadesInFocus });\n\n\t\t\tresolve();\n\t\t});\n\n\t\t// Update the queue with the new promise\n\t\tthis.sceneUpdateQueue = updatePromise;\n\n\t\treturn updatePromise;\n\t};\n}\n", "/**\n * Compare two arrays for equality\n */\nexport function arraysEqual(arr1: any[] | null | undefined, arr2: any[] | null | undefined) {\n\tif (arr1 == null || arr2 == null) {\n\t\treturn arr1 === arr2;\n\t}\n\n\tif (arr1.length !== arr2.length) {\n\t\treturn false;\n\t}\n\n\tfor (let i = 0; i < arr1.length; i++) {\n\t\tif (arr1[i] !== arr2[i]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n", "/**\n * Generic PubSub class implementing the Publish-Subscribe pattern for event handling.\n *\n * @template EVENT_PAYLOAD - The type of the event payload.\n * @template EVENT - The type of the event.\n */\nexport class PubSub<EVENT_PAYLOAD, EVENT extends keyof EVENT_PAYLOAD = keyof EVENT_PAYLOAD> {\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tprivate _subscribers: any = {};\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tprivate _destroyed = false;\n\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tpublish<EVENT_NAME extends EVENT>(eventName: EVENT_NAME, data?: EVENT_PAYLOAD[EVENT_NAME]) {\n\t\tif (!this._subscribers || !this._subscribers[eventName] || this._destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._subscribers[eventName]!.forEach(function (fn) {\n\t\t\tif (typeof fn !== 'function') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfn(data);\n\t\t});\n\t}\n\n\t/**\n\t * Subscribe a function to an event.\n\t *\n\t * @param eventName An event name which, when fired, will call the provided\n\t * function.\n\t * @param fn A callback that gets called when the corresponding event is fired. The\n\t * callback will get passed an argument with a type that's one of event payloads.\n\t * @example\n\t * // Subscribe to the 'click' event\n\t * const handler = (event) => {\n\t * const { coordinate } = event;\n\t * const { latitude, longitude } = coordinate;\n\t * \tconsole.log(`Map was clicked at ${latitude}, ${longitude}`);\n\t * };\n\t * map.on('click', handler);\n\t */\n\ton<EVENT_NAME extends EVENT>(\n\t\teventName: EVENT_NAME,\n\t\tfn: (\n\t\t\tpayload: EVENT_PAYLOAD[EVENT_NAME] extends {\n\t\t\t\tdata: null;\n\t\t\t}\n\t\t\t\t? EVENT_PAYLOAD[EVENT_NAME]['data']\n\t\t\t\t: EVENT_PAYLOAD[EVENT_NAME],\n\t\t) => void,\n\t) {\n\t\tif (!this._subscribers || this._destroyed) {\n\t\t\tthis._subscribers = {};\n\t\t}\n\t\tthis._subscribers[eventName] = this._subscribers[eventName] || [];\n\t\tthis._subscribers[eventName]!.push(fn);\n\t}\n\n\t/**\n\t * Unsubscribe a function previously subscribed with {@link on}\n\t *\n\t * @param eventName An event name to which the provided function was previously\n\t * subscribed.\n\t * @param fn A function that was previously passed to {@link on}. The function must\n\t * have the same reference as the function that was subscribed.\n\t * @example\n\t * // Unsubscribe from the 'click' event\n\t * const handler = (event) => {\n\t * \tconsole.log('Map was clicked', event);\n\t * };\n\t * map.off('click', handler);\n\t */\n\toff<EVENT_NAME extends EVENT>(\n\t\teventName: EVENT_NAME,\n\t\tfn: (\n\t\t\tpayload: EVENT_PAYLOAD[EVENT_NAME] extends {\n\t\t\t\tdata: null;\n\t\t\t}\n\t\t\t\t? EVENT_PAYLOAD[EVENT_NAME]['data']\n\t\t\t\t: EVENT_PAYLOAD[EVENT_NAME],\n\t\t) => void,\n\t) {\n\t\tif (!this._subscribers || this._subscribers[eventName] == null || this._destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tconst itemIdx = this._subscribers[eventName]!.indexOf(fn);\n\n\t\tif (itemIdx !== -1) {\n\t\t\tthis._subscribers[eventName]!.splice(itemIdx, 1);\n\t\t}\n\t}\n\t/**\n\t * @private\n\t * @internal\n\t */\n\tdestroy() {\n\t\tthis._destroyed = true;\n\t\tthis._subscribers = {};\n\t}\n}\n", "import type { MapView, TAnimateStateResult, TFacadeState } from '@mappedin/mappedin-js';\nimport { Facade, Floor, FloorStack } from '@mappedin/mappedin-js';\nimport type { DynamicFocusAnimationOptions } from './types';\n\nexport class Building {\n\t__type = 'building';\n\t#floorStack: FloorStack;\n\t#floorsById = new Map<string, Floor>();\n\t#floorsByElevation = new Map<number, Floor>();\n\t#floorsByElevationSorted: Floor[] = [];\n\t#mapView: MapView;\n\t#animationInProgress: { state: TFacadeState; animation: ReturnType<MapView['animateState']> } | undefined;\n\n\tdefaultFloor: Floor;\n\tactiveFloor: Floor;\n\texcluded = false;\n\tfloorsAltitudesMap: Map<number, { altitude: number; effectiveHeight: number }> = new Map();\n\taboveGroundFloors: Floor[] = [];\n\n\tconstructor(floorStack: FloorStack, mapView: MapView) {\n\t\tthis.#floorStack = floorStack;\n\t\tthis.#floorsById = new Map(floorStack.floors.map(floor => [floor.id, floor]));\n\t\tthis.#floorsByElevation = new Map(floorStack.floors.map(floor => [floor.elevation, floor]));\n\t\tthis.#floorsByElevationSorted = Array.from(this.#floorsByElevation.values()).sort(\n\t\t\t(a, b) => a.elevation - b.elevation,\n\t\t);\n\t\tthis.defaultFloor = floorStack.defaultFloor;\n\t\tthis.activeFloor = this.defaultFloor;\n\t\tthis.#mapView = mapView;\n\t\tthis.aboveGroundFloors = this.#floorsByElevationSorted.filter(floor => floor.elevation >= 0);\n\n\t\tconst sortedSpaces = floorStack.facade?.spaces\n\t\t\t.map(space => this.#mapView.getState(space))\n\t\t\t.sort((a, b) => a.altitude - b.altitude);\n\t\tif (sortedSpaces && sortedSpaces.length === this.aboveGroundFloors.length) {\n\t\t\tfor (const idx in this.aboveGroundFloors) {\n\t\t\t\tconst floor = this.aboveGroundFloors[idx];\n\t\t\t\tconst space = sortedSpaces[idx];\n\t\t\t\tthis.floorsAltitudesMap.set(floor.elevation, {\n\t\t\t\t\taltitude: space.altitude,\n\t\t\t\t\teffectiveHeight: space.height,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tget id() {\n\t\treturn this.#floorStack.id;\n\t}\n\n\tget name() {\n\t\treturn this.#floorStack.name;\n\t}\n\n\tget floors() {\n\t\treturn this.#floorStack.floors;\n\t}\n\n\tget floorStack() {\n\t\treturn this.#floorStack;\n\t}\n\n\tget facade() {\n\t\t// the floorstack must have a facade if we created a building for it\n\t\treturn this.#floorStack.facade!;\n\t}\n\n\tget isCurrentFloorStack() {\n\t\treturn this.id === this.#mapView.currentFloorStack.id;\n\t}\n\n\tget isIndoor() {\n\t\tconst state = this.#mapView.getState(this.facade);\n\n\t\treturn this.isCurrentFloorStack || (state?.visible === false && state?.opacity === 0);\n\t}\n\n\tget canSetFloor() {\n\t\treturn this.isIndoor || !this.excluded;\n\t}\n\n\t#maxElevation: number | undefined;\n\tget maxElevation() {\n\t\tif (this.#maxElevation == null) {\n\t\t\tthis.#maxElevation = Math.max(...this.#floorsByElevation.keys());\n\t\t}\n\n\t\treturn this.#maxElevation;\n\t}\n\n\t#minElevation: number | undefined;\n\tget minElevation() {\n\t\tif (this.#minElevation == null) {\n\t\t\tthis.#minElevation = Math.min(...this.#floorsByElevation.keys());\n\t\t}\n\n\t\treturn this.#minElevation;\n\t}\n\n\thas(f: Floor | FloorStack | Facade) {\n\t\tif (Floor.is(f)) {\n\t\t\treturn this.#floorsById.has(f.id);\n\t\t}\n\n\t\tif (FloorStack.is(f)) {\n\t\t\treturn f.id === this.#floorStack.id;\n\t\t}\n\n\t\tif (Facade.is(f)) {\n\t\t\treturn f.id === this.facade.id;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tgetFloorByElevation(elevation: number) {\n\t\treturn this.#floorsByElevation.get(elevation);\n\t}\n\n\tgetNearestFloorByElevation(targetElevation: number): Floor | undefined {\n\t\tconst exactMatch = this.getFloorByElevation(targetElevation);\n\t\tif (exactMatch) {\n\t\t\treturn exactMatch;\n\t\t}\n\n\t\tif (targetElevation >= 0) {\n\t\t\t// For positive elevations, return highest floor if target is above max\n\t\t\tif (targetElevation > this.maxElevation) {\n\t\t\t\treturn this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];\n\t\t\t}\n\n\t\t\t// Search backwards from the end\n\t\t\tfor (let i = this.#floorsByElevationSorted.length - 1; i >= 0; i--) {\n\t\t\t\tconst floor = this.#floorsByElevationSorted[i];\n\t\t\t\tif (floor.elevation <= targetElevation) {\n\t\t\t\t\treturn floor;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// For negative elevations (basements), return the lowest floor if target is below min\n\t\t\tif (targetElevation < this.minElevation) {\n\t\t\t\treturn this.#floorsByElevationSorted[0];\n\t\t\t}\n\n\t\t\t// Search forwards from the start\n\t\t\tfor (const floor of this.#floorsByElevationSorted) {\n\t\t\t\tif (floor.elevation >= targetElevation) {\n\t\t\t\t\treturn floor;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgetHighestFloor(): Floor {\n\t\treturn this.#floorsByElevationSorted[this.#floorsByElevationSorted.length - 1];\n\t}\n\n\tcancelAnimation() {\n\t\tif (this.#animationInProgress) {\n\t\t\tthis.#animationInProgress.animation.cancel();\n\t\t\tthis.#animationInProgress = undefined;\n\t\t}\n\t}\n\n\tasync animateFacade(\n\t\tnewState: TFacadeState,\n\t\toptions: DynamicFocusAnimationOptions = { duration: 150 },\n\t): Promise<TAnimateStateResult> {\n\t\tconst currentState = this.#animationInProgress?.state || this.#mapView.getState(this.facade);\n\t\tif (\n\t\t\t!currentState ||\n\t\t\t!newState ||\n\t\t\t(currentState?.opacity === newState.opacity && currentState?.visible === newState.visible)\n\t\t) {\n\t\t\t// nothing to do\n\t\t\treturn { result: 'completed' };\n\t\t}\n\n\t\tthis.cancelAnimation();\n\t\tconst { opacity, visible } = newState;\n\n\t\t// always set facade visible so it can be seen during animation\n\t\tthis.#mapView.updateState(this.facade, {\n\t\t\tvisible: true,\n\t\t});\n\n\t\tif (opacity !== undefined) {\n\t\t\tthis.#animationInProgress = {\n\t\t\t\tanimation: this.#mapView.animateState(\n\t\t\t\t\tthis.facade,\n\t\t\t\t\t{\n\t\t\t\t\t\topacity,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: options.duration,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tstate: newState,\n\t\t\t};\n\t\t\tconst result = await this.#animationInProgress.animation;\n\n\t\t\tthis.#animationInProgress = undefined;\n\n\t\t\tif (result.result === 'cancelled') {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tif (visible === false) {\n\t\t\tthis.#mapView.updateState(this.facade, {\n\t\t\t\tvisible,\n\t\t\t});\n\t\t}\n\n\t\treturn { result: 'completed' };\n\t}\n\n\tdestroy() {\n\t\tthis.cancelAnimation();\n\t\t// Hide all floors except current floor\n\t\tthis.#floorStack.floors.forEach(floor => {\n\t\t\tthis.#mapView.updateState(floor, {\n\t\t\t\tvisible: floor.id === this.#mapView.currentFloor.id,\n\t\t\t});\n\t\t});\n\t\t// Show the facade if the current floor is not in this building\n\t\tif (!this.has(this.#mapView.currentFloor)) {\n\t\t\tthis.#mapView.updateState(this.facade, {\n\t\t\t\tvisible: true,\n\t\t\t\topacity: 1,\n\t\t\t});\n\t\t}\n\t}\n}\n", "import type { Facade, Floor, FloorStack, TFloorState } from '@mappedin/mappedin-js';\nimport type { Building } from './building';\nimport type {\n\tBuildingAnimation,\n\tBuildingFacadeState,\n\tBuildingFloorStackState,\n\tDynamicFocusMode,\n\tMultiFloorVisibilityState,\n\tZoomState,\n} from './types';\nimport type { Outdoors } from './outdoors';\n\n/**\n * Calculates the zoom state based on camera zoom level and thresholds.\n */\nexport function getZoomState(zoomLevel: number, indoorThreshold: number, outdoorThreshold: number): ZoomState {\n\tif (zoomLevel >= indoorThreshold) {\n\t\treturn 'in-range';\n\t}\n\tif (zoomLevel <= outdoorThreshold) {\n\t\treturn 'out-of-range';\n\t}\n\n\treturn 'transition';\n}\n\nexport function getFloorToShow(\n\ttarget: Building | Outdoors,\n\tmode: DynamicFocusMode,\n\televation: number,\n): Floor | undefined {\n\tif (target.__type === 'outdoors' && 'floor' in target) {\n\t\treturn target.floor;\n\t}\n\n\tconst building = target as Building;\n\tif (building.excluded) {\n\t\treturn building.activeFloor;\n\t}\n\n\tswitch (mode) {\n\t\tcase 'lock-elevation':\n\t\t\treturn building.getFloorByElevation(elevation);\n\t\tcase 'nearest-elevation':\n\t\t\treturn building.getNearestFloorByElevation(elevation);\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\t// if the building is already showing, don't switch to the default floor\n\treturn building.isIndoor ? building.activeFloor : building.defaultFloor;\n}\n\nexport function getFacadeState(facade: Facade, inFocus: boolean): BuildingFacadeState {\n\treturn {\n\t\tfacade,\n\t\tstate: {\n\t\t\ttype: 'facade',\n\t\t\tvisible: !inFocus,\n\t\t\topacity: inFocus ? 0 : 1,\n\t\t},\n\t};\n}\n\nexport function getSingleBuildingState(\n\tfloorStack: FloorStack,\n\tcurrentFloor: Floor,\n\tinFocus: boolean,\n): BuildingFloorStackState {\n\treturn {\n\t\toutdoorOpacity: 1,\n\t\tfloorStates: floorStack.floors.map(f => {\n\t\t\tconst visible = f.id === currentFloor.id && inFocus;\n\n\t\t\treturn {\n\t\t\t\tfloor: f,\n\t\t\t\tstate: {\n\t\t\t\t\ttype: 'floor',\n\t\t\t\t\tvisible: visible,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\tvisible: visible,\n\t\t\t\t\t},\n\t\t\t\t\tlabels: {\n\t\t\t\t\t\tenabled: visible,\n\t\t\t\t\t},\n\t\t\t\t\tmarkers: {\n\t\t\t\t\t\tenabled: visible,\n\t\t\t\t\t},\n\t\t\t\t\tfootprint: {\n\t\t\t\t\t\tvisible: false,\n\t\t\t\t\t},\n\t\t\t\t\tocclusion: {\n\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t},\n\t\t\t\t} as Required<TFloorState>,\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Calculates the outdoor opacity based on floor stack states and mode.\n */\nexport function getOutdoorOpacity(floorStackStates: BuildingFloorStackState[], mode: DynamicFocusMode): number {\n\tif (!mode.includes('lock-elevation')) {\n\t\treturn 1;\n\t}\n\n\tfor (const state of floorStackStates) {\n\t\tif (state.outdoorOpacity >= 0 && state.outdoorOpacity <= 1) {\n\t\t\treturn state.outdoorOpacity;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nexport function getSetFloorTargetFromZoomState(\n\tbuildings: Building[],\n\toutdoors: Outdoors,\n\tzoomState: ZoomState,\n): Building | Outdoors | undefined {\n\tswitch (zoomState) {\n\t\tcase 'in-range':\n\t\t\treturn buildings[0]?.canSetFloor ? buildings[0] : undefined;\n\t\tcase 'out-of-range':\n\t\t\treturn outdoors;\n\t\tcase 'transition':\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Gets the building states for all buildings.\n */\nexport function getBuildingStates(\n\tbuildings: Building[],\n\tinViewSet: Set<string>,\n\tcurrentFloor: Floor,\n\tzoomState: ZoomState,\n\tmode: DynamicFocusMode,\n\televation: number,\n\tfloorIdsInNavigation: string[],\n\tfloorStackIdsInNavigation: string[],\n\tmultiFloorView: any,\n\tgetMultiFloorState: MultiFloorVisibilityState,\n\tdynamicBuildingInteriors: boolean,\n): Map<\n\tstring,\n\t{\n\t\tbuilding: Building;\n\t\tshowIndoor: boolean;\n\t\tfloorStackState: BuildingFloorStackState;\n\t\tfacadeState: BuildingFacadeState;\n\t\tinFocus: boolean;\n\t\tfloorToShow: Floor | undefined;\n\t}\n> {\n\tconst buildingStates = new Map();\n\n\tfor (const building of buildings) {\n\t\tconst inCameraView = inViewSet.has(building.id);\n\t\tconst showIndoor = shouldShowIndoor(\n\t\t\tbuilding,\n\t\t\tcurrentFloor,\n\t\t\tzoomState === 'in-range',\n\t\t\tinCameraView,\n\t\t\tmode,\n\t\t\televation,\n\t\t\tfloorStackIdsInNavigation.includes(building.id),\n\t\t\tdynamicBuildingInteriors,\n\t\t);\n\n\t\tconst floorToShow =\n\t\t\tcurrentFloor.floorStack.id === building.id ? building.activeFloor : getFloorToShow(building, mode, elevation);\n\n\t\tconst floorStackState = multiFloorView.enabled\n\t\t\t? getMultiFloorState(\n\t\t\t\t\tbuilding.floors,\n\t\t\t\t\tfloorToShow || building.activeFloor,\n\t\t\t\t\tmultiFloorView?.floorGap,\n\t\t\t\t\tfloorIdsInNavigation,\n\t\t\t\t\tbuilding.floorsAltitudesMap,\n\t\t\t )\n\t\t\t: getSingleBuildingState(building.floorStack, floorToShow || building.activeFloor, showIndoor);\n\n\t\tconst facadeState = getFacadeState(building.facade, showIndoor);\n\t\tbuildingStates.set(building.id, {\n\t\t\tbuilding,\n\t\t\tshowIndoor,\n\t\t\tfloorStackState,\n\t\t\tfacadeState,\n\t\t\tinFocus: inCameraView,\n\t\t\tfloorToShow,\n\t\t});\n\t}\n\n\treturn buildingStates;\n}\n\nexport function getBuildingAnimationType(building: Building, showIndoor: boolean): BuildingAnimation {\n\tif (building.excluded) {\n\t\treturn 'none';\n\t}\n\n\tif (showIndoor) {\n\t\treturn 'indoor';\n\t}\n\n\treturn 'outdoor';\n}\n\n/**\n * Determines if a building's indoor floors should be shown through a number of different state checks.\n */\nexport function shouldShowIndoor(\n\tbuilding: Building,\n\tcurrentFloor: Floor,\n\tinRange: boolean,\n\tinFocus: boolean,\n\tmode: DynamicFocusMode,\n\televation: number,\n\tinNavigation: boolean,\n\tdynamicBuildingInteriors: boolean,\n): boolean {\n\t// always show the current floor regardless of any other states\n\tif (building.id === currentFloor.floorStack.id) {\n\t\treturn true;\n\t}\n\n\t// if the building is excluded, we don't control the visibility, so don't show it\n\tif (building.excluded) {\n\t\treturn false;\n\t}\n\n\t// if it's not excluded, always show the navigation\n\tif (inNavigation === true) {\n\t\treturn true;\n\t}\n\n\t// Without dynamic building interiors, we only rely on whether the current floor is indoor or outdoor\n\tif (!dynamicBuildingInteriors) {\n\t\treturn currentFloor.floorStack.type !== 'Outdoor';\n\t}\n\n\t// the following cases rely on the camera being in range\n\tif (!inRange) {\n\t\treturn false;\n\t}\n\n\t// the following cases rely on the building being in focus\n\tif (!inFocus) {\n\t\treturn false;\n\t}\n\n\tswitch (mode) {\n\t\tcase 'lock-elevation':\n\t\t\treturn building.getFloorByElevation(elevation) != null;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn true;\n}\n\nexport function shouldDeferSetFloor(\n\ttrackedCameraElevation: number,\n\tcurrentCameraElevation: number,\n\tuserInteracting: boolean,\n): boolean {\n\treturn trackedCameraElevation !== currentCameraElevation && !userInteracting;\n}\n", "import type { Facade, Floor, TFacadeState } from '@mappedin/mappedin-js';\nimport type { VisibilityState as BuildingFloorStackState } from '../../mappedin-js/src/api-geojson/multi-floor';\n\nexport type MultiFloorVisibilityState = (\n\tfloors: Floor[],\n\tcurrentFloor: Floor,\n\tfloorGap: number,\n\tfloorIdsInNavigation: Floor['id'][],\n\tfloorsVisualHeightMap?: Map<number, { altitude: number; effectiveHeight: number }>,\n) => BuildingFloorStackState;\n\nexport type DynamicFocusAnimationOptions = {\n\t/**\n\t * The duration of the animation in milliseconds.\n\t * @default 150\n\t */\n\tduration: number;\n};\n\n/**\n * Array of valid dynamic focus modes for runtime validation.\n */\nexport const DYNAMIC_FOCUS_MODES = ['default-floor', 'lock-elevation', 'nearest-elevation'] as const;\n\n/**\n * The mode which determines the indoor floor to reveal when the camera focuses on a facade.\n * - 'default-floor' - Show the default floor of the floor stack.\n * - 'lock-elevation' - Show the floor at the current elevation, if possible.\n * When a floor stack does not have a floor at the current elevation, no indoor floor will be shown.\n * - 'nearest-elevation' - Show the floor at the current elevation, if possible.\n * When a floor stack does not have a floor at the current elevation, show the indoor floor at the nearest lower elevation.\n */\nexport type DynamicFocusMode = (typeof DYNAMIC_FOCUS_MODES)[number];\n\n/**\n * State of the Dynamic Focus controller.\n */\nexport type DynamicFocusState = {\n\t/**\n\t * Whether to automatically focus on the outdoors when the camera moves in range.\n\t * @default true\n\t */\n\tautoFocus: boolean;\n\t/**\n\t * The zoom level at which the camera will fade out the facades and fade in the indoor floors.\n\t * @default 18\n\t */\n\tindoorZoomThreshold: number;\n\t/**\n\t * The zoom level at which the camera will fade in the facades and fade out the indoor floors.\n\t * @default 17\n\t */\n\toutdoorZoomThreshold: number;\n\t/**\n\t * Whether to set the floor to the outdoors when the camera moves in range.\n\t * @default true\n\t */\n\tsetFloorOnFocus: boolean;\n\t/**\n\t * Options for the animation when fading out the facade to reveal the interior.\n\t */\n\tindoorAnimationOptions: DynamicFocusAnimationOptions;\n\t/**\n\t * Options for the animation when fading in the facade to hide the interior.\n\t */\n\toutdoorAnimationOptions: DynamicFocusAnimationOptions;\n\t/**\n\t * The mode of the Dynamic Focus controller.\n\t * @default 'default-floor'\n\t */\n\tmode: DynamicFocusMode;\n\t/**\n\t * Whether to automatically adjust facade heights to align with floor boundaries in multi-floor buildings.\n\t * @default false\n\t */\n\tautoAdjustFacadeHeights: boolean;\n\t/**\n\t * Whether to automatically hide the indoors of buildings not in or near the camera's view.\n\t * @default true\n\t */\n\tdynamicBuildingInteriors: boolean;\n\t/**\n\t * Whether to preload the geometry of the initial floors in each building. Improves performance when rendering the building for the first time.\n\t * @default true\n\t */\n\tpreloadFloors: boolean;\n\n\t/**\n\t * @experimental\n\t * @internal\n\t * A custom function to override the default floor visibility state.\n\t * This is useful for customizing the floor visibility state for a specific building.\n\t */\n\tcustomMultiFloorVisibilityState?: MultiFloorVisibilityState;\n};\n\n/**\n * Internal events emitted for updating React state.\n */\nexport type InternalDynamicFocusEvents = {\n\t'state-change': undefined;\n};\n\n/**\n * Events emitted by the Dynamic Focus controller.\n */\nexport type DynamicFocusEvents = {\n\t/**\n\t * Emitted when the Dynamic Focus controller triggers a focus update either from a camera change or manually calling `focus()`.\n\t */\n\tfocus: {\n\t\tfacades: Facade[];\n\t};\n};\n\nexport type DynamicFocusEventPayload<EventName extends keyof DynamicFocusEvents> =\n\tDynamicFocusEvents[EventName] extends { data: null }\n\t\t? DynamicFocusEvents[EventName]['data']\n\t\t: DynamicFocusEvents[EventName];\n\nexport type BuildingFacadeState = {\n\tfacade: Facade;\n\tstate: TFacadeState;\n};\n\nexport type BuildingState = BuildingFloorStackState & {\n\tfacadeState: BuildingFacadeState;\n};\n\nexport type ZoomState = 'in-range' | 'out-of-range' | 'transition';\nexport type ViewState = 'indoor' | 'outdoor' | 'transition';\n\nexport type BuildingAnimation = 'indoor' | 'outdoor' | 'none';\n\nexport type { BuildingFloorStackState };\n", "import { Floor, FloorStack } from '@mappedin/mappedin-js';\nimport { clampWithWarning } from '@packages/internal/common/math-utils';\nimport Logger from '@packages/internal/common/Mappedin.Logger';\n\n/**\n * Validates that a floor belongs to the specified floor stack.\n */\nexport function validateFloorForStack(floor: Floor, floorStack: FloorStack): boolean {\n\tif (!Floor.is(floor) || floor?.floorStack == null || !FloorStack.is(floorStack)) {\n\t\treturn false;\n\t}\n\n\tif (floor.floorStack.id !== floorStack.id) {\n\t\tLogger.warn(`Floor (${floor.id}) does not belong to floor stack (${floorStack.id}).`);\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Validates and clamps zoom threshold values.\n */\nexport function validateZoomThreshold(value: number, min: number, max: number, name: string): number {\n\treturn clampWithWarning(value, min, max, `${name} must be between ${min} and ${max}.`);\n}\n", "/* eslint-disable no-console*/\nexport const MI_DEBUG_KEY = 'mi-debug';\nexport const MI_ERROR_LABEL = '[MappedinJS]';\n\nexport enum E_SDK_LOG_LEVEL {\n\tLOG,\n\tWARN,\n\tERROR,\n\tSILENT,\n}\n\nexport function createLogger(name = '', { prefix = MI_ERROR_LABEL } = {}) {\n\tconst label = `${prefix}${name ? `-${name}` : ''}`;\n\n\tconst rnDebug = (type: 'log' | 'warn' | 'error', args: any[]) => {\n\t\tif (typeof window !== 'undefined' && (window as any).rnDebug) {\n\t\t\tconst processed = args.map(arg => {\n\t\t\t\tif (arg instanceof Error && arg.stack) {\n\t\t\t\t\treturn `${arg.message}\\n${arg.stack}`;\n\t\t\t\t}\n\n\t\t\t\treturn arg;\n\t\t\t});\n\t\t\t(window as any).rnDebug(`${name} ${type}: ${processed.join(' ')}`);\n\t\t}\n\t};\n\n\treturn {\n\t\tlogState: process.env.NODE_ENV === 'test' ? E_SDK_LOG_LEVEL.SILENT : E_SDK_LOG_LEVEL.LOG,\n\n\t\tlog(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.LOG) {\n\t\t\t\tconsole.log(label, ...args);\n\t\t\t\trnDebug('log', args);\n\t\t\t}\n\t\t},\n\n\t\twarn(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.WARN) {\n\t\t\t\tconsole.warn(label, ...args);\n\t\t\t\trnDebug('warn', args);\n\t\t\t}\n\t\t},\n\n\t\terror(...args: any[]) {\n\t\t\tif (this.logState <= E_SDK_LOG_LEVEL.ERROR) {\n\t\t\t\tconsole.error(label, ...args);\n\n\t\t\t\trnDebug('error', args);\n\t\t\t}\n\t\t},\n\n\t\t// It's a bit tricky to prepend [MappedinJs] to assert and time because of how the output is structured in the console, so it is left out for simplicity\n\t\tassert(...args: any[]) {\n\t\t\tconsole.assert(...args);\n\t\t},\n\n\t\ttime(label: string) {\n\t\t\tconsole.time(label);\n\t\t},\n\n\t\ttimeEnd(label: string) {\n\t\t\tconsole.timeEnd(label);\n\t\t},\n\t\tsetLevel(level: E_SDK_LOG_LEVEL) {\n\t\t\tif (E_SDK_LOG_LEVEL.LOG <= level && level <= E_SDK_LOG_LEVEL.SILENT) {\n\t\t\t\tthis.logState = level;\n\t\t\t}\n\t\t},\n\t};\n}\n\nconst Logger = createLogger();\nexport function setLoggerLevel(level: E_SDK_LOG_LEVEL) {\n\tif (E_SDK_LOG_LEVEL.LOG <= level && level <= E_SDK_LOG_LEVEL.SILENT) {\n\t\tLogger.logState = level;\n\t}\n}\n\nexport default Logger;\n", "import Logger from './Mappedin.Logger';\n\n/**\n * Clamp a number between lower and upper bounds with a warning\n */\nexport function clampWithWarning(x: number, lower: number, upper: number, warning: string) {\n\tif (x < lower || x > upper) {\n\t\tLogger.warn(warning);\n\t}\n\n\treturn Math.min(upper, Math.max(lower, x));\n}\n", "import { createLogger } from '../../packages/common/Mappedin.Logger';\n\nexport const Logger = createLogger('', { prefix: '[DynamicFocus]' });\n", "import type { FloorStack, MapView } from '@mappedin/mappedin-js';\nimport { Logger } from './logger';\nimport type { Building } from './building';\n\nexport class Outdoors {\n\t__type = 'outdoors';\n\t#floorStack: FloorStack;\n\t#mapView: MapView;\n\n\tconstructor(floorStack: FloorStack, mapView: MapView) {\n\t\tthis.#floorStack = floorStack;\n\t\tthis.#mapView = mapView;\n\t}\n\n\tget id() {\n\t\treturn this.#floorStack.id;\n\t}\n\n\tget floorStack() {\n\t\treturn this.#floorStack;\n\t}\n\n\tget floor() {\n\t\t// outdoors should only have 1 floor\n\t\treturn this.#floorStack.defaultFloor;\n\t}\n\n\tmatchesFloorStack(floorStack: FloorStack | string) {\n\t\treturn floorStack === this.#floorStack || floorStack === this.#floorStack.id;\n\t}\n\n\t#setVisible(visible: boolean) {\n\t\tfor (const floor of this.#floorStack.floors) {\n\t\t\tthis.#mapView.updateState(floor, {\n\t\t\t\tvisible,\n\t\t\t});\n\t\t}\n\t}\n\n\tshow() {\n\t\tthis.#setVisible(true);\n\t}\n\n\thide() {\n\t\tthis.#setVisible(false);\n\t}\n\n\tdestroy() {\n\t\tif (!this.matchesFloorStack(this.#mapView.currentFloorStack)) {\n\t\t\tthis.hide();\n\t\t}\n\t}\n}\n\nexport function getOutdoorFloorStack(floorStacks: FloorStack[], buildingsSet: Map<string, Building>): FloorStack {\n\tconst outdoorFloorStack = floorStacks.find(floorStack => floorStack.type?.toLowerCase() === 'outdoor');\n\n\tif (outdoorFloorStack) {\n\t\treturn outdoorFloorStack;\n\t}\n\n\t// If no outdoor type found, find the first floor stack that does not have a facade or is already in the buildings set\n\tconst likelyOutdoorFloorStack = floorStacks.find(\n\t\tfloorStack => floorStack.facade == null && !buildingsSet.has(floorStack.id),\n\t);\n\n\tif (likelyOutdoorFloorStack) {\n\t\treturn likelyOutdoorFloorStack;\n\t}\n\n\tLogger.warn('No good candidate for the outdoor floor stack was found. Using the first floor stack.');\n\n\treturn floorStacks[0];\n}\n", "import { getMultiFloorState } from '@mappedin/mappedin-js';\nimport type { RequiredDeep } from 'type-fest';\nimport type { DynamicFocusState } from './types';\n\nexport const DEFAULT_STATE: RequiredDeep<DynamicFocusState> = {\n\tindoorZoomThreshold: 18,\n\toutdoorZoomThreshold: 17,\n\tsetFloorOnFocus: true,\n\tautoFocus: false,\n\tindoorAnimationOptions: {\n\t\tduration: 150,\n\t},\n\toutdoorAnimationOptions: {\n\t\tduration: 150,\n\t},\n\tautoAdjustFacadeHeights: false,\n\tmode: 'default-floor',\n\tpreloadFloors: true,\n\tcustomMultiFloorVisibilityState: getMultiFloorState,\n\tdynamicBuildingInteriors: true,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "DynamicFocus", "import_mappedin_js", "arraysEqual", "arr1", "arr2", "i", "__name", "_PubSub", "__publicField", "eventName", "data", "fn", "itemIdx", "__name", "PubSub", "import_mappedin_js", "_floorStack", "_floorsById", "_floorsByElevation", "_floorsByElevationSorted", "_mapView", "_animationInProgress", "_maxElevation", "_minElevation", "_Building", "floorStack", "mapView", "__publicField", "__privateAdd", "__privateSet", "floor", "__privateGet", "a", "b", "sortedSpaces", "space", "idx", "state", "f", "elevation", "targetElevation", "exactMatch", "i", "newState", "options", "currentState", "opacity", "visible", "result", "__name", "Building", "getZoomState", "zoomLevel", "indoorThreshold", "outdoorThreshold", "__name", "getFloorToShow", "target", "mode", "elevation", "building", "getFacadeState", "facade", "inFocus", "getSingleBuildingState", "floorStack", "currentFloor", "f", "visible", "getOutdoorOpacity", "floorStackStates", "state", "getSetFloorTargetFromZoomState", "buildings", "outdoors", "zoomState", "getBuildingStates", "inViewSet", "floorIdsInNavigation", "floorStackIdsInNavigation", "multiFloorView", "getMultiFloorState", "dynamicBuildingInteriors", "buildingStates", "inCameraView", "showIndoor", "shouldShowIndoor", "floorToShow", "floorStackState", "facadeState", "getBuildingAnimationType", "inRange", "inNavigation", "shouldDeferSetFloor", "trackedCameraElevation", "currentCameraElevation", "userInteracting", "DYNAMIC_FOCUS_MODES", "import_mappedin_js", "MI_ERROR_LABEL", "createLogger", "name", "prefix", "MI_ERROR_LABEL", "label", "rnDebug", "__name", "type", "args", "processed", "arg", "level", "Logger", "Mappedin_Logger_default", "Logger", "clampWithWarning", "x", "lower", "upper", "warning", "Mappedin_Logger_default", "__name", "validateFloorForStack", "floor", "floorStack", "Mappedin_Logger_default", "__name", "validateZoomThreshold", "value", "min", "max", "name", "clampWithWarning", "Logger", "createLogger", "_floorStack", "_mapView", "_Outdoors_instances", "setVisible_fn", "_Outdoors", "floorStack", "mapView", "__privateAdd", "__publicField", "__privateSet", "__privateGet", "__privateMethod", "__name", "visible", "floor", "Outdoors", "getOutdoorFloorStack", "floorStacks", "buildingsSet", "outdoorFloorStack", "likelyOutdoorFloorStack", "Logger", "import_mappedin_js", "DEFAULT_STATE", "_pubsub", "_mapView", "_mapData", "_state", "_sortedBuildingsInView", "_buildingIdsInViewSet", "_buildings", "_outdoors", "_userInteracting", "_pendingFacadeUpdate", "_floorElevation", "_cameraElevation", "_zoomState", "_viewState", "_facadesInFocus", "_enabled", "_DynamicFocus_instances", "handleViewStateChange_fn", "preloadFloors_fn", "_handleFacadesInViewChange", "_handleFloorChangeStart", "_handleUserInteractionStart", "_handleUserInteractionEnd", "_handleCameraChange", "updateFloorVisibility_fn", "animateIndoorSequence_fn", "animateOutdoorSequence_fn", "_applyBuildingStates", "_DynamicFocus", "mapView", "__privateAdd", "DEFAULT_STATE", "__publicField", "__name", "eventName", "fn", "__privateGet", "event", "facades", "arraysEqual", "__privateSet", "facade", "building", "newFloor", "altitude", "zoomLevel", "newZoomState", "getZoomState", "currentFloor", "multiFloorView", "floorIdsInNavigation", "f", "floorStackIdsInNavigation", "fs", "updatePromise", "resolve", "buildingStates", "getBuildingStates", "floorStackStates", "buildingState", "showIndoor", "floorStackState", "facadeState", "inFocus", "animation", "getBuildingAnimationType", "__privateMethod", "getOutdoorOpacity", "PubSub", "Logger", "Mappedin_Logger_default", "Building", "Outdoors", "getOutdoorFloorStack", "options", "state", "shouldReapplyBuildingStates", "validateZoomThreshold", "DYNAMIC_FOCUS_MODES", "value", "setFloor", "shouldDeferSetFloor", "target", "getSetFloorTargetFromZoomState", "floor", "getFloorToShow", "floorStack", "validateFloorForStack", "excluded", "excludedFloorStacks", "included", "includedFloorStacks", "mode", "floorStates", "shouldShow", "floorState", "result", "shouldShowIndoor", "DynamicFocus"]
|
|
7
7
|
}
|
|
@@ -2,10 +2,10 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// <define:process>
|
|
5
|
-
var define_process_default = { env: { npm_package_version: "6.0.1-beta.
|
|
5
|
+
var define_process_default = { env: { npm_package_version: "6.0.1-beta.60" } };
|
|
6
6
|
|
|
7
7
|
// src/dynamic-focus.ts
|
|
8
|
-
import { Floor as Floor3 } from "@mappedin/mappedin-js";
|
|
8
|
+
import { Floor as Floor3, getMultiFloorState as getMultiFloorState2 } from "@mappedin/mappedin-js";
|
|
9
9
|
|
|
10
10
|
// ../packages/common/array-utils.ts
|
|
11
11
|
function arraysEqual(arr1, arr2) {
|
|
@@ -122,11 +122,12 @@ var Building = class {
|
|
|
122
122
|
#floorsByElevation = /* @__PURE__ */ new Map();
|
|
123
123
|
#floorsByElevationSorted = [];
|
|
124
124
|
#mapView;
|
|
125
|
-
#spacesByAltitude;
|
|
126
125
|
#animationInProgress;
|
|
127
126
|
defaultFloor;
|
|
128
127
|
activeFloor;
|
|
129
128
|
excluded = false;
|
|
129
|
+
floorsAltitudesMap = /* @__PURE__ */ new Map();
|
|
130
|
+
aboveGroundFloors = [];
|
|
130
131
|
constructor(floorStack, mapView) {
|
|
131
132
|
this.#floorStack = floorStack;
|
|
132
133
|
this.#floorsById = new Map(floorStack.floors.map((floor) => [floor.id, floor]));
|
|
@@ -137,6 +138,18 @@ var Building = class {
|
|
|
137
138
|
this.defaultFloor = floorStack.defaultFloor;
|
|
138
139
|
this.activeFloor = this.defaultFloor;
|
|
139
140
|
this.#mapView = mapView;
|
|
141
|
+
this.aboveGroundFloors = this.#floorsByElevationSorted.filter((floor) => floor.elevation >= 0);
|
|
142
|
+
const sortedSpaces = floorStack.facade?.spaces.map((space) => this.#mapView.getState(space)).sort((a, b) => a.altitude - b.altitude);
|
|
143
|
+
if (sortedSpaces && sortedSpaces.length === this.aboveGroundFloors.length) {
|
|
144
|
+
for (const idx in this.aboveGroundFloors) {
|
|
145
|
+
const floor = this.aboveGroundFloors[idx];
|
|
146
|
+
const space = sortedSpaces[idx];
|
|
147
|
+
this.floorsAltitudesMap.set(floor.elevation, {
|
|
148
|
+
altitude: space.altitude,
|
|
149
|
+
effectiveHeight: space.height
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
140
153
|
}
|
|
141
154
|
get id() {
|
|
142
155
|
return this.#floorStack.id;
|
|
@@ -189,61 +202,6 @@ var Building = class {
|
|
|
189
202
|
}
|
|
190
203
|
return false;
|
|
191
204
|
}
|
|
192
|
-
get aboveGroundFloors() {
|
|
193
|
-
return this.#floorsByElevationSorted.filter((floor) => floor.elevation >= 0);
|
|
194
|
-
}
|
|
195
|
-
expandFacade() {
|
|
196
|
-
if (!this.#mapView.options.multiFloorView?.enabled || !this.facade || this.facade.__type !== "facade" || this.facade.spaces.length < 1) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const footprintHeight = this.#mapView.options.multiFloorView.floorGap ?? 10;
|
|
200
|
-
if (!this.#spacesByAltitude) {
|
|
201
|
-
this.#spacesByAltitude = /* @__PURE__ */ new Map();
|
|
202
|
-
for (const space of this.facade.spaces) {
|
|
203
|
-
const state = this.#mapView.getState(space);
|
|
204
|
-
const altitude = state?.altitude ?? 0;
|
|
205
|
-
const height = state?.height ?? 0;
|
|
206
|
-
if (!this.#spacesByAltitude.has(altitude)) {
|
|
207
|
-
this.#spacesByAltitude.set(altitude, []);
|
|
208
|
-
}
|
|
209
|
-
this.#spacesByAltitude.get(altitude).push({
|
|
210
|
-
space,
|
|
211
|
-
originalAltitude: altitude,
|
|
212
|
-
originalHeight: height
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
const altitudeKeys = Array.from(this.#spacesByAltitude.keys()).sort((a, b) => a - b);
|
|
217
|
-
const isSingleAltitude = altitudeKeys.length === 1;
|
|
218
|
-
const heightToUse = isSingleAltitude ? footprintHeight * (this.aboveGroundFloors.length - 1) : footprintHeight;
|
|
219
|
-
let currentAltitude = 0;
|
|
220
|
-
altitudeKeys.forEach((originalAltitude) => {
|
|
221
|
-
const spaceData = this.#spacesByAltitude.get(originalAltitude);
|
|
222
|
-
for (const { space } of spaceData) {
|
|
223
|
-
this.#mapView.updateState(space, {
|
|
224
|
-
height: isSingleAltitude ? heightToUse : footprintHeight,
|
|
225
|
-
altitude: currentAltitude
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
if (!isSingleAltitude) {
|
|
229
|
-
currentAltitude += footprintHeight;
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
collapseFacade() {
|
|
234
|
-
if (!this.#spacesByAltitude) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
for (const spaceDataArray of this.#spacesByAltitude.values()) {
|
|
238
|
-
for (const { space, originalAltitude, originalHeight } of spaceDataArray) {
|
|
239
|
-
this.#mapView.updateState(space, {
|
|
240
|
-
height: originalHeight,
|
|
241
|
-
altitude: originalAltitude
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
this.#spacesByAltitude = void 0;
|
|
246
|
-
}
|
|
247
205
|
getFloorByElevation(elevation) {
|
|
248
206
|
return this.#floorsByElevation.get(elevation);
|
|
249
207
|
}
|
|
@@ -336,7 +294,6 @@ var Building = class {
|
|
|
336
294
|
};
|
|
337
295
|
|
|
338
296
|
// src/dynamic-focus-scene.ts
|
|
339
|
-
import { getMultiFloorState } from "@mappedin/mappedin-js";
|
|
340
297
|
function getZoomState(zoomLevel, indoorThreshold, outdoorThreshold) {
|
|
341
298
|
if (zoomLevel >= indoorThreshold) {
|
|
342
299
|
return "in-range";
|
|
@@ -432,7 +389,7 @@ function getSetFloorTargetFromZoomState(buildings, outdoors, zoomState) {
|
|
|
432
389
|
}
|
|
433
390
|
}
|
|
434
391
|
__name(getSetFloorTargetFromZoomState, "getSetFloorTargetFromZoomState");
|
|
435
|
-
function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode, elevation, floorIdsInNavigation, floorStackIdsInNavigation, multiFloorView, dynamicBuildingInteriors) {
|
|
392
|
+
function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode, elevation, floorIdsInNavigation, floorStackIdsInNavigation, multiFloorView, getMultiFloorState3, dynamicBuildingInteriors) {
|
|
436
393
|
const buildingStates = /* @__PURE__ */ new Map();
|
|
437
394
|
for (const building of buildings) {
|
|
438
395
|
const inCameraView = inViewSet.has(building.id);
|
|
@@ -447,11 +404,12 @@ function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode,
|
|
|
447
404
|
dynamicBuildingInteriors
|
|
448
405
|
);
|
|
449
406
|
const floorToShow = currentFloor.floorStack.id === building.id ? building.activeFloor : getFloorToShow(building, mode, elevation);
|
|
450
|
-
const floorStackState = multiFloorView.enabled ?
|
|
407
|
+
const floorStackState = multiFloorView.enabled ? getMultiFloorState3(
|
|
451
408
|
building.floors,
|
|
452
409
|
floorToShow || building.activeFloor,
|
|
453
|
-
multiFloorView
|
|
454
|
-
floorIdsInNavigation
|
|
410
|
+
multiFloorView?.floorGap,
|
|
411
|
+
floorIdsInNavigation,
|
|
412
|
+
building.floorsAltitudesMap
|
|
455
413
|
) : getSingleBuildingState(building.floorStack, floorToShow || building.activeFloor, showIndoor);
|
|
456
414
|
const facadeState = getFacadeState(building.facade, showIndoor);
|
|
457
415
|
buildingStates.set(building.id, {
|
|
@@ -661,6 +619,7 @@ function getOutdoorFloorStack(floorStacks, buildingsSet) {
|
|
|
661
619
|
__name(getOutdoorFloorStack, "getOutdoorFloorStack");
|
|
662
620
|
|
|
663
621
|
// src/constants.ts
|
|
622
|
+
import { getMultiFloorState } from "@mappedin/mappedin-js";
|
|
664
623
|
var DEFAULT_STATE = {
|
|
665
624
|
indoorZoomThreshold: 18,
|
|
666
625
|
outdoorZoomThreshold: 17,
|
|
@@ -675,6 +634,7 @@ var DEFAULT_STATE = {
|
|
|
675
634
|
autoAdjustFacadeHeights: false,
|
|
676
635
|
mode: "default-floor",
|
|
677
636
|
preloadFloors: true,
|
|
637
|
+
customMultiFloorVisibilityState: getMultiFloorState,
|
|
678
638
|
dynamicBuildingInteriors: true
|
|
679
639
|
};
|
|
680
640
|
|
|
@@ -891,13 +851,6 @@ var DynamicFocus = class {
|
|
|
891
851
|
}
|
|
892
852
|
if (state.autoAdjustFacadeHeights != null) {
|
|
893
853
|
this.#state.autoAdjustFacadeHeights = state.autoAdjustFacadeHeights;
|
|
894
|
-
this.#buildings.forEach((building) => {
|
|
895
|
-
if (this.#state.autoAdjustFacadeHeights) {
|
|
896
|
-
building.expandFacade();
|
|
897
|
-
} else {
|
|
898
|
-
building.collapseFacade();
|
|
899
|
-
}
|
|
900
|
-
});
|
|
901
854
|
}
|
|
902
855
|
if (state.dynamicBuildingInteriors != null && state.dynamicBuildingInteriors !== this.#state.dynamicBuildingInteriors) {
|
|
903
856
|
shouldReapplyBuildingStates = true;
|
|
@@ -1083,14 +1036,12 @@ var DynamicFocus = class {
|
|
|
1083
1036
|
await this.#applyBuildingStates(newFloor);
|
|
1084
1037
|
this.#pubsub.publish("focus", { facades: this.focusedFacades });
|
|
1085
1038
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
);
|
|
1039
|
+
const altitude = building?.floorsAltitudesMap.get(newFloor.elevation)?.altitude ?? 0;
|
|
1040
|
+
if (this.#mapView.options.multiFloorView != null && this.#mapView.options.multiFloorView?.enabled && this.#mapView.options.multiFloorView?.updateCameraElevationOnFloorChange && this.#mapView.Camera.elevation !== altitude) {
|
|
1041
|
+
this.#mapView.Camera.animateElevation(altitude, {
|
|
1042
|
+
duration: 750,
|
|
1043
|
+
easing: "ease-in-out"
|
|
1044
|
+
});
|
|
1094
1045
|
}
|
|
1095
1046
|
}
|
|
1096
1047
|
}, "#handleFloorChangeStart");
|
|
@@ -1189,6 +1140,7 @@ var DynamicFocus = class {
|
|
|
1189
1140
|
floorIdsInNavigation,
|
|
1190
1141
|
floorStackIdsInNavigation,
|
|
1191
1142
|
multiFloorView,
|
|
1143
|
+
this.#state.customMultiFloorVisibilityState ?? getMultiFloorState2,
|
|
1192
1144
|
this.#state.dynamicBuildingInteriors
|
|
1193
1145
|
);
|
|
1194
1146
|
const floorStackStates = [];
|
|
@@ -1218,4 +1170,4 @@ export {
|
|
|
1218
1170
|
__name,
|
|
1219
1171
|
DynamicFocus
|
|
1220
1172
|
};
|
|
1221
|
-
//# sourceMappingURL=chunk-
|
|
1173
|
+
//# sourceMappingURL=chunk-FHYN5MAH.js.map
|