@mappedin/dynamic-focus 6.0.1-beta.56 → 6.0.1-beta.58

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/README.md CHANGED
@@ -41,7 +41,11 @@ const mapView = await show3dMap(...);
41
41
  /**
42
42
  * Create a new Dynamic Focus controller that automatically updates the MapView scene.
43
43
  */
44
- const df = new DynamicFocus(mapView, { autoFocus: true, setFloorOnFocus: true });
44
+ const df = new DynamicFocus(mapView);
45
+
46
+
47
+ // Enable dynamic-focus extension with options
48
+ df.enable({ autoFocus: true, setFloorOnFocus: true });
45
49
 
46
50
  /**
47
51
  * Disable automatic updates - now you'll need to manually call `focus()` to update the view.
@@ -98,3 +102,86 @@ function DynamicFocusDisplay() {
98
102
  );
99
103
  }
100
104
  ```
105
+
106
+ #### React Native
107
+
108
+ ```tsx
109
+ import React, { useEffect, useCallback } from 'react';
110
+ import { View, Text, TouchableOpacity } from 'react-native';
111
+ import { MapView, useMapData } from '@mappedin/react-native-sdk';
112
+ import { useDynamicFocus, useDynamicFocusEvent } from '@mappedin/dynamic-focus/rn';
113
+
114
+ function MyComponent() {
115
+ const { mapData } = useMapData({
116
+ key: 'your-api-key',
117
+ secret: 'your-api-secret',
118
+ mapId: 'your-map-id',
119
+ });
120
+
121
+ return (
122
+ <MapView mapData={mapData}>
123
+ <DynamicFocusDisplay />
124
+ </MapView>
125
+ );
126
+ }
127
+
128
+ function DynamicFocusDisplay() {
129
+ // All methods are async and return Promises
130
+ const { isReady, isEnabled, focusedFacades, enable, updateState, getState, focus, disable } = useDynamicFocus();
131
+
132
+ // Listen for focus events - similar to React but with separate hook
133
+ useDynamicFocusEvent(
134
+ 'focus',
135
+ useCallback(event => {
136
+ console.log('Focused facades:', event.facades);
137
+ }, []),
138
+ );
139
+
140
+ useEffect(() => {
141
+ if (isReady && !isEnabled) {
142
+ // All methods are async - use await or .then()
143
+ enable({
144
+ autoFocus: true,
145
+ mode: 'lock-elevation',
146
+ indoorZoomThreshold: 18,
147
+ outdoorZoomThreshold: 17,
148
+ });
149
+ }
150
+ }, [isReady, isEnabled, enable]);
151
+
152
+ const handleUpdateSettings = useCallback(async () => {
153
+ try {
154
+ // All state operations are async
155
+ await updateState({
156
+ indoorZoomThreshold: 19,
157
+ outdoorZoomThreshold: 16,
158
+ });
159
+
160
+ // Get current state
161
+ const currentState = await getState();
162
+ console.log('Current state:', currentState);
163
+
164
+ // Manual focus trigger
165
+ await focus(true); // setFloor = true
166
+ } catch (error) {
167
+ console.error('Failed to update settings:', error);
168
+ }
169
+ }, [updateState, getState, focus]);
170
+
171
+ return (
172
+ <View>
173
+ <Text>Is Ready: {isReady ? 'Yes' : 'No'}</Text>
174
+ <Text>Is Enabled: {isEnabled ? 'Yes' : 'No'}</Text>
175
+ <Text>Focused Facades: {focusedFacades.length}</Text>
176
+ <TouchableOpacity onPress={handleUpdateSettings}>
177
+ <Text>Update Settings</Text>
178
+ </TouchableOpacity>
179
+ </View>
180
+ );
181
+ }
182
+ ```
183
+
184
+ **Key Differences from React:**
185
+
186
+ - **All methods are async**: `enable()`, `updateState()`, `getState()`, `focus()`, and `disable()` return Promises
187
+ - **Additional state**: Hook returns `isReady`, `focusedFacades` for real-time updates
@@ -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\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\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\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),\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);\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): 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);\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): 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// the following cases rely on the camera being in range\n\tif (!inRange) {\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\t// the following cases rely on the building being in focus\n\tif (!inFocus) {\n\t\treturn false;\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 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};\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", "_spacesByAltitude", "_animationInProgress", "_maxElevation", "_minElevation", "_Building", "floorStack", "mapView", "__publicField", "__privateAdd", "__privateSet", "floor", "__privateGet", "a", "b", "state", "f", "footprintHeight", "space", "altitude", "height", "altitudeKeys", "isSingleAltitude", "heightToUse", "currentAltitude", "originalAltitude", "spaceData", "spaceDataArray", "originalHeight", "elevation", "targetElevation", "exactMatch", "newState", "options", "currentState", "opacity", "visible", "result", "__name", "Building", "import_mappedin_js", "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", "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", "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", "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", "validateZoomThreshold", "DYNAMIC_FOCUS_MODES", "value", "setFloor", "shouldDeferSetFloor", "target", "getSetFloorTargetFromZoomState", "floor", "getFloorToShow", "floorStack", "validateFloorForStack", "excluded", "excludedFloorStacks", "included", "includedFloorStacks", "mode", "floorStates", "shouldShow", "floorState", "result", "shouldShowIndoor", "DynamicFocus"]
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", "_spacesByAltitude", "_animationInProgress", "_maxElevation", "_minElevation", "_Building", "floorStack", "mapView", "__publicField", "__privateAdd", "__privateSet", "floor", "__privateGet", "a", "b", "state", "f", "footprintHeight", "space", "altitude", "height", "altitudeKeys", "isSingleAltitude", "heightToUse", "currentAltitude", "originalAltitude", "spaceData", "spaceDataArray", "originalHeight", "elevation", "targetElevation", "exactMatch", "newState", "options", "currentState", "opacity", "visible", "result", "__name", "Building", "import_mappedin_js", "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", "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", "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", "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,7 +2,7 @@ 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.56" } };
5
+ var define_process_default = { env: { npm_package_version: "6.0.1-beta.58" } };
6
6
 
7
7
  // src/dynamic-focus.ts
8
8
  import { Floor as Floor3 } from "@mappedin/mappedin-js";
@@ -432,7 +432,7 @@ function getSetFloorTargetFromZoomState(buildings, outdoors, zoomState) {
432
432
  }
433
433
  }
434
434
  __name(getSetFloorTargetFromZoomState, "getSetFloorTargetFromZoomState");
435
- function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode, elevation, floorIdsInNavigation, floorStackIdsInNavigation, multiFloorView) {
435
+ function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode, elevation, floorIdsInNavigation, floorStackIdsInNavigation, multiFloorView, dynamicBuildingInteriors) {
436
436
  const buildingStates = /* @__PURE__ */ new Map();
437
437
  for (const building of buildings) {
438
438
  const inCameraView = inViewSet.has(building.id);
@@ -443,7 +443,8 @@ function getBuildingStates(buildings, inViewSet, currentFloor, zoomState, mode,
443
443
  inCameraView,
444
444
  mode,
445
445
  elevation,
446
- floorStackIdsInNavigation.includes(building.id)
446
+ floorStackIdsInNavigation.includes(building.id),
447
+ dynamicBuildingInteriors
447
448
  );
448
449
  const floorToShow = currentFloor.floorStack.id === building.id ? building.activeFloor : getFloorToShow(building, mode, elevation);
449
450
  const floorStackState = multiFloorView.enabled ? getMultiFloorState(
@@ -475,7 +476,7 @@ function getBuildingAnimationType(building, showIndoor) {
475
476
  return "outdoor";
476
477
  }
477
478
  __name(getBuildingAnimationType, "getBuildingAnimationType");
478
- function shouldShowIndoor(building, currentFloor, inRange, inFocus, mode, elevation, inNavigation) {
479
+ function shouldShowIndoor(building, currentFloor, inRange, inFocus, mode, elevation, inNavigation, dynamicBuildingInteriors) {
479
480
  if (building.id === currentFloor.floorStack.id) {
480
481
  return true;
481
482
  }
@@ -485,18 +486,21 @@ function shouldShowIndoor(building, currentFloor, inRange, inFocus, mode, elevat
485
486
  if (inNavigation === true) {
486
487
  return true;
487
488
  }
489
+ if (!dynamicBuildingInteriors) {
490
+ return currentFloor.floorStack.type !== "Outdoor";
491
+ }
488
492
  if (!inRange) {
489
493
  return false;
490
494
  }
495
+ if (!inFocus) {
496
+ return false;
497
+ }
491
498
  switch (mode) {
492
499
  case "lock-elevation":
493
500
  return building.getFloorByElevation(elevation) != null;
494
501
  default:
495
502
  break;
496
503
  }
497
- if (!inFocus) {
498
- return false;
499
- }
500
504
  return true;
501
505
  }
502
506
  __name(shouldShowIndoor, "shouldShowIndoor");
@@ -670,7 +674,8 @@ var DEFAULT_STATE = {
670
674
  },
671
675
  autoAdjustFacadeHeights: false,
672
676
  mode: "default-floor",
673
- preloadFloors: true
677
+ preloadFloors: true,
678
+ dynamicBuildingInteriors: true
674
679
  };
675
680
 
676
681
  // src/dynamic-focus.ts
@@ -864,6 +869,7 @@ var DynamicFocus = class {
864
869
  * @param state - The state to update.
865
870
  */
866
871
  updateState(state) {
872
+ let shouldReapplyBuildingStates = false;
867
873
  if (state.indoorZoomThreshold != null) {
868
874
  state.indoorZoomThreshold = validateZoomThreshold(
869
875
  state.indoorZoomThreshold,
@@ -893,6 +899,9 @@ var DynamicFocus = class {
893
899
  }
894
900
  });
895
901
  }
902
+ if (state.dynamicBuildingInteriors != null && state.dynamicBuildingInteriors !== this.#state.dynamicBuildingInteriors) {
903
+ shouldReapplyBuildingStates = true;
904
+ }
896
905
  this.#state = Object.assign(
897
906
  {},
898
907
  this.#state,
@@ -901,6 +910,9 @@ var DynamicFocus = class {
901
910
  if (state.mode != null && state.preloadFloors) {
902
911
  this.#preloadFloors(state.mode);
903
912
  }
913
+ if (shouldReapplyBuildingStates) {
914
+ this.#applyBuildingStates();
915
+ }
904
916
  }
905
917
  /**
906
918
  * Destroys the Dynamic Focus instance and unsubscribes all MapView event listeners.
@@ -1150,7 +1162,8 @@ var DynamicFocus = class {
1150
1162
  this.#buildingIdsInViewSet.has(building.id),
1151
1163
  this.#state.mode,
1152
1164
  this.#floorElevation,
1153
- floorStackIdsInNavigation.includes(building.floorStack.id)
1165
+ floorStackIdsInNavigation.includes(building.floorStack.id),
1166
+ this.#state.dynamicBuildingInteriors
1154
1167
  )
1155
1168
  );
1156
1169
  }
@@ -1175,7 +1188,8 @@ var DynamicFocus = class {
1175
1188
  this.#floorElevation,
1176
1189
  floorIdsInNavigation,
1177
1190
  floorStackIdsInNavigation,
1178
- multiFloorView
1191
+ multiFloorView,
1192
+ this.#state.dynamicBuildingInteriors
1179
1193
  );
1180
1194
  const floorStackStates = [];
1181
1195
  await Promise.all(
@@ -1204,4 +1218,4 @@ export {
1204
1218
  __name,
1205
1219
  DynamicFocus
1206
1220
  };
1207
- //# sourceMappingURL=chunk-UUWLLGNN.js.map
1221
+ //# sourceMappingURL=chunk-MIOCMA37.js.map