waygo-maps 1.1.82 → 1.1.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bundle.js +1 -1
  2. package/package.json +1 -1
package/dist/bundle.js CHANGED
@@ -614,7 +614,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
614
614
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
615
615
 
616
616
  "use strict";
617
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var webpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webpack */ \"./node_modules/webpack/lib/index.js\");\n/* harmony import */ var webpack__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webpack__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _core_Control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/Control */ \"./src/core/Control.js\");\n/* harmony import */ var _utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/coordinateSystems */ \"./src/utils/coordinateSystems.js\");\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\nfunction _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _iterableToArray(r) { if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r); }\nfunction _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }\nfunction _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }\nfunction _possibleConstructorReturn(t, e) { if (e && (\"object\" == _typeof(e) || \"function\" == typeof e)) return e; if (void 0 !== e) throw new TypeError(\"Derived constructors may only return object or undefined\"); return _assertThisInitialized(t); }\nfunction _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e; }\nfunction _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }\nfunction _superPropGet(t, e, r, o) { var p = _get(_getPrototypeOf(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; }\nfunction _get() { return _get = \"undefined\" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); }\nfunction _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; }\nfunction _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }\nfunction _inherits(t, e) { if (\"function\" != typeof e && null !== e) throw new TypeError(\"Super expression must either be null or a function\"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, \"prototype\", { writable: !1 }), e && _setPrototypeOf(t, e); }\nfunction _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }\n\n\n\nvar InteractionControl = /*#__PURE__*/function (_Control) {\n function InteractionControl() {\n var _this;\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _classCallCheck(this, InteractionControl);\n _this = _callSuper(this, InteractionControl, [options]);\n _this.map = null;\n _this.previouslySelectedFeature = null;\n _this.previouslySelectedIcon = null;\n _this.previouslySelectedTextColor = null;\n _this.previouslySelectedTextOffset = null;\n _this.previouslyHoveredFeature = null;\n _this.originalTextColor = null;\n _this.textColorReference = {};\n _this.currentView = null; // Can be set to 'desktop' or 'mobile'\n\n _this.selectedTextColor = '#BE2E28';\n _this.interactionEnabled = true;\n _this.selectionCriteria = null;\n _this.originalPaintProperties = {}; // Store original paint properties for selection state\n _this.selectionModeExpressions = {}; // Store selection mode color expressions for hover persistence\n _this.selectionHoverColor = '#4A90E2'; // Color for hover highlighting in selection mode\n _this.currentHoveredLayerId = null; // Track currently hovered layer in selection mode\n _this.currentHoveredFeatureId = null; // Track currently hovered feature in selection mode\n _this.selectionHoverHandler = null; // Reference to mousemove handler for selection mode\n return _this;\n }\n _inherits(InteractionControl, _Control);\n return _createClass(InteractionControl, [{\n key: \"onAdd\",\n value: function onAdd(map) {\n this.map = map;\n this.container = document.createElement('div');\n this.container.className = 'interaction-control-container';\n this.initializeEventListeners();\n this._attachResizeListener();\n this._initialize();\n this.createHighlightedContentLayer();\n this.createSelectedContentLayer();\n this.storeTextColorReferences();\n // this.applyHoverEffectToAllSymbolLayers();\n\n return this.container;\n }\n }, {\n key: \"_initialize\",\n value: function _initialize() {\n var containerWidth = this.map.mapContainer.offsetWidth;\n this._configureView(containerWidth);\n }\n }, {\n key: \"onRemove\",\n value: function onRemove() {\n _superPropGet(InteractionControl, \"onRemove\", this, 3)([]);\n }\n\n // _attachResizeListener() {\n // window.addEventListener('resize', () => {\n // const newWidth = this.map.mapContainer.offsetWidth;\n // this._configureView(newWidth);\n // });\n // }\n }, {\n key: \"_configureView\",\n value: function _configureView(width) {\n if (width > 767) {\n this._setViewForDesktop();\n } else {\n this._setViewForMobile();\n }\n }\n }, {\n key: \"_setViewForDesktop\",\n value: function _setViewForDesktop() {\n this.currentView = 'desktop';\n }\n }, {\n key: \"_setViewForMobile\",\n value: function _setViewForMobile() {\n this.currentView = 'mobile';\n }\n }, {\n key: \"initializeEventListeners\",\n value: function initializeEventListeners() {\n var _this2 = this;\n this.map.map.on('styleimagemissing', function (e) {\n var missingImage = e.id;\n console.warn(\"Image \\\"\".concat(missingImage, \"\\\" could not be loaded.\"));\n });\n this.map.map.on('click', function (e) {\n _this2._handleClick(e);\n });\n this.map.on('state:default', this._handleDefaultState.bind(this));\n this.map.on('state:search', this._handleSearchState.bind(this));\n this.map.on('state:selectedContent', this._handleSelectedContentState.bind(this));\n this.map.on('state:directions', this._handleDirectionsState.bind(this));\n this.map.on('state:setup', this._handleSetupState.bind(this));\n this.map.on('state:selection', this._handleSelectionState.bind(this));\n this.map.on('additionalSearchResults', this._handleAdditionalSearch.bind(this));\n this.map.on('hoverSearchResult', this._handleHoverSearchResult.bind(this));\n this.map.on('hoverEndSearchResult', this._handleHoverEndSearchResult.bind(this));\n }\n }, {\n key: \"storeTextColorReferences\",\n value: function storeTextColorReferences() {\n var _this3 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var textColor = _this3.map.map.getPaintProperty(layer.id, 'text-color');\n if (textColor !== undefined) {\n _this3.textColorReference[layer.id] = textColor; // Store the text color reference using the layer ID as the key\n }\n }\n });\n }\n }, {\n key: \"createSelectedContentLayer\",\n value: function createSelectedContentLayer() {\n this.map.map.addSource('selected-content', {\n 'type': 'geojson',\n 'data': {\n 'type': 'FeatureCollection',\n 'features': [] // Initially empty, you will add features dynamically\n }\n });\n\n // Add a layer that references this GeoJSON source and matches the styling in your Mapbox Studio project\n this.map.map.addLayer({\n 'id': 'selected-content-layer',\n 'type': 'symbol',\n // Or 'fill', 'line', etc. based on your needs\n 'source': 'selected-content',\n 'layout': {\n 'text-field': ['get', 'name'],\n 'text-font': ['Inter Medium'],\n 'text-size': 14,\n 'text-justify': 'left',\n 'text-anchor': 'bottom-left',\n 'text-offset': [1.3, -1],\n 'icon-image': 'selected-pin',\n 'icon-size': 0.5,\n 'icon-offset': [0, -5],\n 'icon-anchor': 'bottom',\n 'symbol-z-elevate': true,\n 'text-padding': 10,\n 'icon-padding': 5\n },\n 'paint': {\n 'text-color': '#BE2E28',\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1\n }\n });\n }\n }, {\n key: \"createHighlightedContentLayer\",\n value: function createHighlightedContentLayer() {\n this.map.map.addSource('highlighted-content', {\n 'type': 'geojson',\n 'data': {\n 'type': 'FeatureCollection',\n 'features': []\n }\n });\n this.map.map.addLayer({\n 'id': 'highlighted-content-layer',\n 'type': 'symbol',\n 'source': 'highlighted-content',\n 'layout': {\n 'text-field': ['get', 'name'],\n 'text-font': ['Inter Medium'],\n 'text-size': 14,\n 'text-justify': 'left',\n 'text-anchor': 'bottom-left',\n 'text-offset': [1.2, -0.6],\n 'icon-image': 'highlightedPin',\n 'icon-size': 0.5,\n 'icon-offset': [0, -5],\n 'icon-anchor': 'bottom',\n 'symbol-z-elevate': true,\n 'text-padding': 5,\n 'icon-padding': 5\n },\n 'paint': {\n 'text-color': '#1E1E1E',\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1\n }\n });\n }\n\n // clearSelectedContentLayer() {\n // this.map.map.getSource('selected-content').setData({\n // 'type': 'FeatureCollection',\n // 'features': []\n // });\n // }\n\n // clearHighlightedContentLayer() {\n // this.map.map.getSource('highlighted-content').setData({\n // 'type': 'FeatureCollection',\n // 'features': []\n // });\n // }\n\n // addSelectedFeature(coordinates, properties) {\n // const source = this.map.map.getSource('selected-content');\n // const currentData = source._data;\n // const newFeature = {\n // 'type': 'Feature',\n // 'geometry': {\n // 'type': 'Point',\n // 'coordinates': coordinates\n // },\n // 'properties': properties\n // };\n // currentData.features.push(newFeature);\n // source.setData(currentData);\n // }\n\n // addHighlightedFeature(coordinates, properties) {\n // const source = this.map.map.getSource('highlighted-content');\n // const currentData = source._data;\n // const newFeature = {\n // 'type': 'Feature',\n // 'geometry': {\n // 'type': 'Point',\n // 'coordinates': coordinates\n // },\n // 'properties': properties\n // };\n // currentData.features.push(newFeature);\n // source.setData(currentData);\n\n // return newFeature;\n // }\n }, {\n key: \"_handleDefaultState\",\n value: function _handleDefaultState() {\n this.interactionEnabled = true;\n\n // Remove any selection state visuals\n this.removeSelectionVisuals();\n this.selectionCriteria = null;\n this.applyHoverEffectToAllSymbolLayers();\n this.map.clearHighlightedContentLayer();\n this.map.clearSelectedContentLayer();\n this.showSymbolLayers();\n\n // this.removeSelectionVisuals();\n // this.selectionCriteria = null;\n\n // // Ensure symbol layers are visible before applying hover effects\n // this.showSymbolLayers();\n\n // // Apply hover effects to all symbol layers\n // this.applyHoverEffectToAllSymbolLayers();\n\n // this.map.clearHighlightedContentLayer();\n // this.map.clearSelectedContentLayer();\n }\n }, {\n key: \"_handleSearchState\",\n value: function _handleSearchState(data) {\n var query = data.query,\n results = data.results;\n this.interactionEnabled = true;\n this.applyHoverEffectToAllSymbolLayers();\n this.hideSymbolLayers();\n this.map.clearSelectedContentLayer();\n\n // Find the floor with the most results\n var floorCounts = results.reduce(function (acc, result) {\n acc[result.floor] = (acc[result.floor] || 0) + 1;\n return acc;\n }, {});\n\n // Get the floor with the highest count\n var bestFloor = Object.entries(floorCounts).reduce(function (a, b) {\n return b[1] > a[1] ? b : a;\n }, [0, 0])[0];\n\n // Only switch floors if none of the results are on the current floor\n var currentFloor = this.map.getCurrentFloor();\n var hasResultsOnCurrentFloor = results.some(function (result) {\n return result.floor === currentFloor;\n });\n var chosenFloor = currentFloor;\n if (!hasResultsOnCurrentFloor) {\n chosenFloor = bestFloor;\n this.map.updateFloor(parseInt(chosenFloor));\n }\n chosenFloor = parseInt(chosenFloor);\n this.updateLabelsForSearchResults(results, true, chosenFloor);\n }\n }, {\n key: \"_handleAdditionalSearch\",\n value: function _handleAdditionalSearch(data) {\n var results = data.results;\n this.updateLabelsForSearchResults(results, true);\n }\n }, {\n key: \"_handleHoverSearchResult\",\n value: function _handleHoverSearchResult(data) {\n var result = data.result;\n this.updateLabelForSelectedContentPlacement(result, false);\n }\n }, {\n key: \"_handleHoverEndSearchResult\",\n value: function _handleHoverEndSearchResult() {\n if (this.map.getCurrentState() === 'search') {\n this.map.clearSelectedContentLayer();\n }\n }\n }, {\n key: \"_handleSelectedContentState\",\n value: function _handleSelectedContentState(data) {\n var contentPlacementIds = data.contentPlacementIds,\n selectedContentPlacement = data.selectedContentPlacement;\n this.interactionEnabled = true;\n this.applyHoverEffectToAllSymbolLayers();\n this.showSymbolLayers();\n this.updateLabelForSelectedContentPlacement(selectedContentPlacement);\n }\n }, {\n key: \"_handleDirectionsState\",\n value: function _handleDirectionsState(data) {\n var endContentPlacement = data.endContentPlacement;\n // if (endContentPlacement) {\n // // this.updateLabelForSelectedContentPlacement(endContentPlacement);\n // }\n this.interactionEnabled = false;\n this.removeHoverEffects();\n this.showSymbolLayers();\n return;\n }\n }, {\n key: \"_handleSetupState\",\n value: function _handleSetupState() {\n this.interactionEnabled = false;\n this.removeHoverEffects();\n }\n }, {\n key: \"_handleSelectionState\",\n value: function _handleSelectionState(data) {\n var criteria = data.criteria,\n geojson = data.geojson;\n this.selectionCriteria = criteria;\n this.interactionEnabled = true;\n\n // Grey out existing\n this.applySelectionModeVisuals(criteria);\n\n // Remove matching features from existing layers to avoid duplication\n this.map.removeMatchingFeaturesFromExistingLayers(criteria);\n\n // Create layers - PASS THE GEOJSON\n this.map.createSelectableContentLayers(geojson);\n\n // NOW process any pending extrusion features (after sources are created)\n this.processPendingExtrusionFeatures();\n this.processPendingSymbolFeatures();\n\n // Hover effects\n this.applySelectableHoverEffects();\n }\n }, {\n key: \"hideSymbolLayers\",\n value: function hideSymbolLayers() {\n var _this4 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol' && layer.id !== 'selected-content-layer' && layer.id !== 'highlighted-content-layer') {\n _this4.map.map.setLayoutProperty(layer.id, 'visibility', 'none');\n }\n });\n }\n }, {\n key: \"showSymbolLayers\",\n value: function showSymbolLayers() {\n var _this5 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n _this5.map.map.setLayoutProperty(layer.id, 'visibility', 'visible');\n }\n });\n }\n }, {\n key: \"updateLabelsForSearchResults\",\n value: function updateLabelsForSearchResults(results) {\n var _this6 = this;\n var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var floor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n if (floor === null) {\n floor = this.map.getCurrentFloor();\n }\n this.map.clearHighlightedContentLayer();\n var features = [];\n var featuresOnFloor = [];\n results.forEach(function (result) {\n result._floor = result.floor;\n var coordinates = (0,_utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__.convertVerticesToCoordinates)([result.location], null, 30.0);\n var coordinate = coordinates[0];\n var titleKey = result.catalog.content_title_key;\n result.name = result.content.data[titleKey];\n var feature = _this6.map.addHighlightedFeature(coordinate, result);\n features.push(feature);\n if (result.floor === floor) {\n featuresOnFloor.push(feature);\n }\n });\n if (featuresOnFloor.length && animate) {\n var bounds = new mapboxgl.LngLatBounds();\n featuresOnFloor.forEach(function (feature) {\n bounds.extend(feature.geometry.coordinates);\n });\n if (this.currentView === 'desktop') {\n this.map.map.fitBounds(bounds, {\n padding: {\n top: 50,\n bottom: 50,\n left: 350,\n right: 50\n },\n maxZoom: 15,\n pitch: 45,\n bearing: -37,\n duration: 1000\n });\n } else if (this.currentView === 'mobile') {\n var mapHeight = this.map.mapContainer.offsetHeight;\n var mapWidth = this.map.mapContainer.offsetWidth;\n var bottomPaddingPercent = 45;\n var sidePaddingPercent = 8;\n var bottomPaddingInPixels = mapHeight * (bottomPaddingPercent / 100);\n var sidePaddingInPixels = mapWidth * (sidePaddingPercent / 100);\n this.map.map.fitBounds(bounds, {\n padding: {\n top: 150,\n bottom: bottomPaddingInPixels,\n left: sidePaddingInPixels,\n right: sidePaddingInPixels + 95\n },\n maxZoom: 16,\n pitch: 45,\n bearing: -37,\n duration: 1000\n });\n }\n }\n }\n\n // _getSimplifiedSelectedFeatures() {\n // const confirmedFeatures = this.map.getConfirmedSelectionFeatures();\n // return confirmedFeatures.map(feature => ({\n // feature_id: feature.properties.feature_id,\n // name: feature.properties.name || 'Unnamed Feature'\n // }));\n // }\n }, {\n key: \"_getSelectionFeaturesProperties\",\n value: function _getSelectionFeaturesProperties() {\n var confirmedFeatures = this.map.getConfirmedSelectionFeatures();\n return confirmedFeatures.map(function (feature) {\n return feature.properties;\n });\n }\n }, {\n key: \"updateLabelForSelectedContentPlacement\",\n value: function updateLabelForSelectedContentPlacement(result) {\n var _this$map$mapData;\n var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n this.map.clearSelectedContentLayer();\n var mapId = ((_this$map$mapData = this.map.mapData) === null || _this$map$mapData === void 0 ? void 0 : _this$map$mapData.map_id) || null;\n console.log('🔵 InteractionControl: mapId:', mapId);\n var coordinate;\n if (mapId === 'outdoor-cities-demo') {\n coordinate = result.location;\n } else {\n var coordinates = (0,_utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__.convertVerticesToCoordinates)([result.location], null, 30.0);\n coordinate = coordinates[0];\n }\n\n // const coordinates = convertVerticesToCoordinates([result.location], null, 30.0);\n // const coordinate = coordinates[0];\n result._floor = result.floor;\n if (!result.name) {\n if (result.content && result.catalog) {\n var title_key = result.catalog.content_title_key;\n var title = result.content.data[title_key];\n result.name = title;\n }\n }\n this.map.addSelectedFeature(coordinate, result);\n if (animate) {\n if (this.currentView === 'desktop') {\n this.map.map.easeTo({\n center: coordinate,\n padding: {\n top: 0,\n bottom: 0,\n left: 330,\n right: 0\n },\n duration: 1000\n });\n } else if (this.currentView === 'mobile') {\n var mapHeight = this.map.mapContainer.offsetHeight;\n var bottomPaddingPercent = 35;\n var bottomPaddingInPixels = mapHeight * (bottomPaddingPercent / 100);\n this.map.map.easeTo({\n center: coordinate,\n padding: {\n top: 0,\n bottom: bottomPaddingInPixels,\n left: 0,\n right: 0\n },\n duration: 1000\n });\n }\n }\n }\n }, {\n key: \"applyHoverEffectToAllSymbolLayers\",\n value: function applyHoverEffectToAllSymbolLayers() {\n var _this7 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var layerId = layer.id;\n var defaultTextColor = _this7.textColorReference[layerId];\n _this7.map.map.on('mouseenter', layerId, function (e) {\n var feature = e.features[0];\n var placementId = feature.properties.placement_id;\n if (!_this7.previouslySelectedFeature || _this7.previouslySelectedFeature.layer.id !== feature.layer.id) {\n _this7.originalTextColor = _this7.map.map.getPaintProperty(layerId, 'text-color');\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], placementId], '#4B90F7', defaultTextColor]);\n } else {\n _this7.originalTextColor = _this7.previouslySelectedTextColor;\n var previouslySelectedPlacementId = _this7.previouslySelectedFeature.properties.placement_id;\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], placementId], '#4B90F7', ['==', ['get', 'placement_id'], previouslySelectedPlacementId], _this7.selectedTextColor, defaultTextColor]);\n }\n _this7.map.map.getCanvas().style.cursor = 'pointer';\n });\n _this7.map.map.on('mouseleave', layerId, function () {\n if (!_this7.previouslySelectedFeature) {\n _this7.map.map.setPaintProperty(layerId, 'text-color', defaultTextColor);\n } else {\n // If a feature is selected, maintain its selected color\n var previouslySelectedPlacementId = _this7.previouslySelectedFeature.properties.placement_id;\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], previouslySelectedPlacementId], _this7.selectedTextColor, defaultTextColor]);\n }\n _this7.map.map.getCanvas().style.cursor = 'default';\n });\n }\n });\n }\n }, {\n key: \"removeHoverEffects\",\n value: function removeHoverEffects() {\n var _this8 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var layerId = layer.id;\n // Reset to default text color\n var defaultTextColor = _this8.textColorReference[layerId];\n _this8.map.map.setPaintProperty(layerId, 'text-color', defaultTextColor);\n\n // Remove event listeners\n _this8.map.map.off('mouseenter', layerId);\n _this8.map.map.off('mouseleave', layerId);\n }\n });\n this.map.map.getCanvas().style.cursor = 'default';\n }\n }, {\n key: \"applySelectionModeVisuals\",\n value: function applySelectionModeVisuals(criteria) {\n var _this9 = this;\n var layers = this.map.map.getStyle().layers;\n\n // Clear any previous stored properties\n this.originalPaintProperties = {};\n layers.forEach(function (layer) {\n if (layer.type === 'background') {\n var layerId = layer.id;\n\n // Store original background color\n if (!_this9.originalPaintProperties[layerId]) {\n _this9.originalPaintProperties[layerId] = {};\n }\n _this9.originalPaintProperties[layerId]['background-color'] = _this9.map.map.getPaintProperty(layerId, 'background-color');\n\n // Set new background color for selection mode\n _this9.map.map.setPaintProperty(layerId, 'background-color', '#f5f5f5');\n return; // Skip the rest of the loop for background layers\n }\n if (layer.type !== 'raster' && layer.type !== 'heatmap') {\n var _layerId = layer.id;\n\n // Skip our own selectable layers - they should not be greyed out\n if (_layerId.includes('selectable-')) {\n return;\n }\n\n // Initialize storage for this layer\n if (!_this9.originalPaintProperties[_layerId]) {\n _this9.originalPaintProperties[_layerId] = {};\n }\n\n // Apply grey styling to all layer types\n // In applySelectionModeVisuals(), replace the symbol layer section (lines 593-606) with:\n\n if (layer.type === 'symbol') {\n // Skip our own selectable/booked layers\n if (_layerId.includes('selectable-') || _layerId.includes('booked-') || _layerId.includes('confirmed-selection')) {\n return;\n }\n\n // Get the layer info BEFORE hiding it\n var symbolLayer = _this9.map.map.getLayer(_layerId);\n var sourceId = symbolLayer.source;\n var sourceLayer = symbolLayer.sourceLayer;\n var filter = symbolLayer.filter;\n\n // GET FEATURES BEFORE HIDING THE LAYER\n var features = [];\n try {\n var source = _this9.map.map.getSource(sourceId);\n if (source && source.type === 'vector' && sourceLayer) {\n features = _this9.map.map.querySourceFeatures(sourceId, {\n sourceLayer: sourceLayer,\n filter: filter\n });\n } else if (source && source.type === 'geojson') {\n features = source._data.features || [];\n }\n } catch (error) {\n console.error('❌ Error getting symbol features before layer hiding:', error);\n }\n\n // Store the layer info for restoration\n _this9.originalPaintProperties[_layerId] = {\n 'text-opacity': _this9.map.map.getPaintProperty(_layerId, 'text-opacity'),\n 'icon-opacity': _this9.map.map.getPaintProperty(_layerId, 'icon-opacity'),\n 'text-color': _this9.map.map.getPaintProperty(_layerId, 'text-color'),\n 'source': sourceId,\n 'source-layer': sourceLayer,\n 'filter': filter,\n 'features': features // Store the features we got before hiding\n };\n\n // COMPLETELY HIDE the symbol layer\n _this9.map.map.setLayoutProperty(_layerId, 'visibility', 'none');\n\n // Store features to add later (don't add them now)\n if (!_this9.pendingSymbolFeatures) {\n _this9.pendingSymbolFeatures = [];\n }\n _this9.pendingSymbolFeatures.push({\n layerId: _layerId,\n features: features\n });\n } else if (layer.type === 'fill') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['fill-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'fill-opacity');\n _this9.originalPaintProperties[_layerId]['fill-color'] = _this9.map.map.getPaintProperty(_layerId, 'fill-color');\n\n // Apply grey styling - light grey color with reduced opacity but preserve floors\n var fillOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['fill-opacity'],\n // Keep original opacity\n 0.5 // Reduce other fills to 0.5 for layering effect\n ];\n var fillColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['fill-color'],\n // Keep original color\n '#f7f7f8' // Light grey for non-floor fills\n ];\n _this9.map.map.setPaintProperty(_layerId, 'fill-color', fillColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'fill-opacity', fillOpacityExpression);\n } else if (layer.type === 'line') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['line-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'line-opacity');\n _this9.originalPaintProperties[_layerId]['line-color'] = _this9.map.map.getPaintProperty(_layerId, 'line-color');\n\n // Apply grey styling - grey color with 0.6 opacity but preserve floors\n var lineOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['line-opacity'],\n // Keep original opacity\n 0.6 // Reduce other lines to 0.6\n ];\n var lineColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['line-color'],\n // Keep original color\n '#AAAAAA' // Grey for non-floor lines\n ];\n _this9.map.map.setPaintProperty(_layerId, 'line-color', lineColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'line-opacity', lineOpacityExpression);\n } else if (layer.type === 'circle') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['circle-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'circle-opacity');\n _this9.originalPaintProperties[_layerId]['circle-color'] = _this9.map.map.getPaintProperty(_layerId, 'circle-color');\n\n // Apply grey styling - grey color with 0.5 opacity but preserve floors\n var circleOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['circle-opacity'] || 1.0,\n // Keep original opacity\n 0.5 // Reduce other circles to 0.5\n ];\n var circleColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['circle-color'],\n // Keep original color\n '#CCCCCC' // Grey for non-floor circles\n ];\n _this9.map.map.setPaintProperty(_layerId, 'circle-color', circleColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'circle-opacity', circleOpacityExpression);\n } else if (layer.type === 'fill-extrusion') {\n // Get the layer info BEFORE removing it\n var extrusionLayer = _this9.map.map.getLayer(_layerId);\n var _sourceId = extrusionLayer.source;\n var _sourceLayer = extrusionLayer.sourceLayer;\n var _filter = extrusionLayer.filter;\n\n // GET FEATURES BEFORE REMOVING THE LAYER\n var _features = [];\n try {\n var _source = _this9.map.map.getSource(_sourceId);\n if (_source && _source.type === 'vector' && _sourceLayer) {\n _features = _this9.map.map.querySourceFeatures(_sourceId, {\n sourceLayer: _sourceLayer,\n filter: _filter\n });\n } else if (_source && _source.type === 'geojson') {\n _features = _source._data.features || [];\n }\n } catch (error) {\n console.error('❌ Error getting features before layer removal:', error);\n }\n\n // Store the layer info for restoration\n _this9.originalPaintProperties[_layerId] = {\n 'fill-extrusion-color': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-color'),\n 'fill-extrusion-height': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-height'),\n 'fill-extrusion-opacity': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-opacity'),\n 'source': _sourceId,\n 'source-layer': _sourceLayer,\n 'filter': _filter,\n 'features': _features // Store the features we got before removal\n };\n\n // COMPLETELY REMOVE the extrusion layer\n _this9.map.map.removeLayer(_layerId);\n\n // Store features to add later (don't add them now)\n if (!_this9.pendingExtrusionFeatures) {\n _this9.pendingExtrusionFeatures = [];\n }\n _this9.pendingExtrusionFeatures.push({\n layerId: _layerId,\n features: _features\n });\n }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Get the layer info BEFORE removing it\n // const extrusionLayer = this.map.map.getLayer(layerId);\n // const sourceId = extrusionLayer.source;\n // const sourceLayer = extrusionLayer.sourceLayer;\n // const filter = extrusionLayer.filter;\n\n // console.log('🔵 Extrusion layer source:', sourceId, 'source-layer:', sourceLayer);\n // // GET FEATURES BEFORE REMOVING THE LAYER\n // let features = [];\n // try {\n // const source = this.map.map.getSource(sourceId);\n // console.log('SOURCE TYPE:', source.type);\n // console.log('SOURCE', source);\n // console.log('EXTRUSION LAYER:', extrusionLayer);\n // if (source && source.type === 'vector' && sourceLayer) {\n // features = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n // console.log('🔵 Found', features.length, 'features BEFORE removing layer');\n // } else if (source && source.type === 'geojson') {\n // features = source._data.features || [];\n // console.log('🔵 Found', features.length, 'GeoJSON features BEFORE removing layer');\n // }\n // } catch (error) {\n // console.error('❌ Error getting features before layer removal:', error);\n // }\n\n // console.log('🔵 FOUND EXTRUSION FEATURES:', features);\n\n // // Store the layer info for restoration\n // this.originalPaintProperties[layerId] = {\n // 'fill-extrusion-color': this.map.map.getPaintProperty(layerId, 'fill-extrusion-color'),\n // 'fill-extrusion-height': this.map.map.getPaintProperty(layerId, 'fill-extrusion-height'),\n // 'fill-extrusion-opacity': this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity'),\n // 'source': sourceId,\n // 'source-layer': sourceLayer,\n // 'filter': filter,\n // 'features': features // Store the features we got before removal\n // };\n\n // // COMPLETELY REMOVE the extrusion layer\n // console.log('🔵 Removing extrusion layer:', layerId);\n // this.map.map.removeLayer(layerId);\n\n // // Add the features to booked-content\n // this.addFeaturesToBookedContent(features, layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Get the layer info BEFORE removing it\n // const extrusionLayer = this.map.map.getLayer(layerId);\n // const sourceId = extrusionLayer.source;\n\n // console.log('🔵 Extrusion layer source:', sourceId);\n\n // // Store the layer info for restoration\n // this.originalPaintProperties[layerId] = {\n // 'fill-extrusion-color': this.map.map.getPaintProperty(layerId, 'fill-extrusion-color'),\n // 'fill-extrusion-height': this.map.map.getPaintProperty(layerId, 'fill-extrusion-height'),\n // 'fill-extrusion-opacity': this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity')\n // };\n\n // // Store the source info for the fill layer creation\n // this.originalPaintProperties[layerId]['source'] = sourceId;\n // this.originalPaintProperties[layerId]['source-layer'] = extrusionLayer['source-layer'];\n // this.originalPaintProperties[layerId]['filter'] = extrusionLayer.filter;\n\n // // COMPLETELY REMOVE the extrusion layer\n // console.log('🔵 Removing extrusion layer:', layerId);\n // this.map.map.removeLayer(layerId);\n\n // // Create a fill layer with the same data\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // const originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // const originalHeight = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n // const originalVisibility = this.map.map.getLayoutProperty(layerId, 'visibility');\n\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = originalColor;\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = originalHeight;\n\n // // Store layout properties\n // if (!this.originalLayoutProperties) {\n // this.originalLayoutProperties = {};\n // }\n // this.originalLayoutProperties[layerId] = this.originalLayoutProperties[layerId] || {};\n // this.originalLayoutProperties[layerId]['visibility'] = originalVisibility;\n\n // console.log('🔵 Original extrusion visibility:', originalVisibility);\n\n // // COMPLETELY HIDE extrusions for non-floor features\n // const visibilityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // 'visible', // Keep floors visible\n // 'none' // Hide all other extrusions completely\n // ];\n\n // console.log('🔵 Setting visibility expression:', visibilityExpression);\n // this.map.map.setLayoutProperty(layerId, 'visibility', visibilityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // const originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // const originalHeight = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = originalColor;\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = originalHeight;\n\n // console.log('🔵 Original extrusion height:', originalHeight);\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // originalHeight || 0, // Use original height or 0 if undefined\n // 0 // Set height to 0 for non-floor extrusions\n // ];\n\n // console.log('🔵 Setting height expression:', heightExpression);\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-height'], // Keep original height\n // 0 // Set height to 0 for non-floor extrusions\n // ];\n\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity');\n\n // console.log('🔵 Original extrusion opacity:', this.originalPaintProperties[layerId]['fill-extrusion-opacity']);\n\n // // Hide extrusions completely for non-floor features\n // const opacityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'], // Keep original opacity\n // 0 // Hide non-floor extrusions completely\n // ];\n\n // console.log('🔵 Setting opacity expression:', opacityExpression);\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-opacity', opacityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity');\n\n // // Hide extrusions completely for non-floor features\n // const opacityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'], // Keep original opacity\n // 0 // Hide non-floor extrusions completely\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-opacity', opacityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n\n // // Apply light grey styling but preserve floors at original color\n // const lightGreyExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-color'], // Keep original\n // '#e6e6e6' // Much lighter grey for non-floor extrusions\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', lightGreyExpression);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-height'], // Keep original height\n // 0 // Set height to 0 for non-floor extrusions (effectively hiding them)\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n\n // // Apply light grey styling but preserve floors at original color\n // const lightGreyExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-color'], // Keep original\n // '#e6e6e6' // Much lighter grey for non-floor extrusions\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', lightGreyExpression);\n // }\n }\n });\n\n // Note: We no longer apply hover effects to existing layers in selection mode\n // The selectable features will have their own hover effects\n }\n }, {\n key: \"processPendingSymbolFeatures\",\n value: function processPendingSymbolFeatures() {\n var _this10 = this;\n if (!this.pendingSymbolFeatures || this.pendingSymbolFeatures.length === 0) {\n return;\n }\n\n // Process each group\n this.pendingSymbolFeatures.forEach(function (_ref) {\n var layerId = _ref.layerId,\n features = _ref.features;\n _this10.addSymbolFeaturesToBookedLabels(features, layerId);\n });\n\n // Clear the pending features\n this.pendingSymbolFeatures = [];\n }\n }, {\n key: \"addSymbolFeaturesToBookedLabels\",\n value: function addSymbolFeaturesToBookedLabels(features, symbolLayerId) {\n if (features.length === 0) {\n return;\n }\n try {\n // Get the current booked-labels source\n var bookedLabelsSource = this.map.map.getSource('booked-labels');\n if (!bookedLabelsSource) {\n console.error('❌ booked-labels source not found');\n return;\n }\n\n // Get current booked label features\n var currentBookedLabelsData = bookedLabelsSource._data;\n var currentBookedLabelFeatures = currentBookedLabelsData.features || [];\n\n // Convert symbol features to label features\n var labelFeatures = features.map(function (feature) {\n // Use feature.properties.title for existing symbol layers\n var title = feature.properties.title || feature.properties.name || 'Untitled';\n return {\n type: 'Feature',\n geometry: feature.geometry,\n properties: _objectSpread(_objectSpread({}, feature.properties), {}, {\n name: title // Ensure 'name' property exists for the text-field\n })\n };\n });\n\n // Add symbol features to booked label features\n var updatedBookedLabelFeatures = [].concat(_toConsumableArray(currentBookedLabelFeatures), _toConsumableArray(labelFeatures));\n\n // Update the booked-labels source\n bookedLabelsSource.setData({\n type: 'FeatureCollection',\n features: updatedBookedLabelFeatures\n });\n\n // Verify the update worked\n var verifySource = this.map.map.getSource('booked-labels');\n var verifyFeatures = verifySource._data.features || [];\n } catch (error) {\n console.error('❌ Error adding symbol features to booked-labels:', error);\n }\n }\n }, {\n key: \"addFeaturesToBookedContent\",\n value: function addFeaturesToBookedContent(features, extrusionLayerId) {\n if (features.length === 0) {\n return;\n }\n try {\n // Get the current booked-content source\n var bookedSource = this.map.map.getSource('booked-content');\n if (!bookedSource) {\n console.error('❌ booked-content source not found');\n return;\n }\n\n // Get current booked features\n var currentBookedData = bookedSource._data;\n var currentBookedFeatures = currentBookedData.features || [];\n\n // Use the features directly (no high-precision processing for now)\n var updatedBookedFeatures = [].concat(_toConsumableArray(currentBookedFeatures), _toConsumableArray(features));\n\n // Update the booked-content source\n bookedSource.setData({\n type: 'FeatureCollection',\n features: updatedBookedFeatures\n });\n\n // Verify the update worked\n var verifySource = this.map.map.getSource('booked-content');\n var verifyFeatures = verifySource._data.features || [];\n } catch (error) {\n console.error('❌ Error adding features to booked-content:', error);\n }\n }\n }, {\n key: \"processPendingExtrusionFeatures\",\n value: function processPendingExtrusionFeatures() {\n var _this11 = this;\n if (!this.pendingExtrusionFeatures || this.pendingExtrusionFeatures.length === 0) {\n return;\n }\n\n // Process each group\n this.pendingExtrusionFeatures.forEach(function (_ref2) {\n var layerId = _ref2.layerId,\n features = _ref2.features;\n _this11.addFeaturesToBookedContent(features, layerId);\n });\n\n // Clear the pending features\n this.pendingExtrusionFeatures = [];\n }\n\n // getHighPrecisionFeatures(features, extrusionLayerId) {\n // console.log('🔵 Using original features for', features.length, 'features');\n\n // // For now, just return the original features\n // // The issue might not be with precision but with how we're handling them\n // return features;\n // }\n }, {\n key: \"getHighPrecisionFeatures\",\n value: function getHighPrecisionFeatures(features, extrusionLayerId) {\n // Get the stored layer info\n var layerInfo = this.originalPaintProperties[extrusionLayerId];\n if (!layerInfo) {\n console.warn('⚠️ No layer info found, using original features');\n return features;\n }\n var sourceId = layerInfo.source;\n var sourceLayer = layerInfo['source-layer'];\n var filter = layerInfo.filter;\n try {\n // Get the source first\n var source = this.map.map.getSource(sourceId);\n if (!source) {\n console.error('❌ Source not found:', sourceId);\n return features;\n }\n\n // Try querying without changing zoom - just use current view\n var currentFeatures = this.map.map.querySourceFeatures(sourceId, {\n sourceLayer: sourceLayer,\n filter: filter\n });\n\n // If we got the same or more features, use them\n if (currentFeatures.length >= features.length) {\n return currentFeatures;\n } else {\n return features;\n }\n } catch (error) {\n console.error('❌ Error getting high-precision features:', error);\n return features;\n }\n }\n\n // async getHighPrecisionFeatures(features, extrusionLayerId) {\n // console.log('🔵 Getting high-precision geometries for', features.length, 'features');\n\n // // Get the stored layer info\n // const layerInfo = this.originalPaintProperties[extrusionLayerId];\n // if (!layerInfo) {\n // console.warn('⚠️ No layer info found, using original features');\n // return features;\n // }\n\n // const sourceId = layerInfo.source;\n // const sourceLayer = layerInfo['source-layer']; // Fixed: use bracket notation for hyphenated property\n // const filter = layerInfo.filter;\n\n // try {\n // // Get the source first\n // const source = this.map.map.getSource(sourceId);\n // if (!source) {\n // console.error('❌ Source not found:', sourceId);\n // return features;\n // }\n\n // // Temporarily zoom to max zoom to force high-res tile loading\n // const currentZoom = this.map.map.getZoom();\n // const currentCenter = this.map.map.getCenter();\n\n // // Zoom to max zoom briefly to load high-res tiles\n // this.map.map.setZoom(22);\n\n // // Wait a bit for tiles to load\n // await new Promise(resolve => setTimeout(resolve, 100));\n\n // // Query at max zoom\n // const highPrecisionFeatures = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n\n // // Restore original zoom\n // this.map.map.setZoom(currentZoom);\n // this.map.map.setCenter(currentCenter);\n\n // console.log('🔵 Retrieved', highPrecisionFeatures.length, 'high-precision features');\n\n // return highPrecisionFeatures.length > 0 ? highPrecisionFeatures : features;\n\n // } catch (error) {\n // console.error('❌ Error getting high-precision features:', error);\n // console.log('🔵 Falling back to original features');\n // return features;\n // }\n // }\n\n // createGreyFillLayerForExtrusion(extrusionLayerId) {\n // console.log('🔵 Adding extrusion features to booked-content source:', extrusionLayerId);\n\n // // Get the source info from the stored properties\n // const sourceId = this.originalPaintProperties[extrusionLayerId]['source'];\n // const sourceLayer = this.originalPaintProperties[extrusionLayerId]['source-layer'];\n // const filter = this.originalPaintProperties[extrusionLayerId]['filter'];\n\n // console.log('🔵 Using source:', sourceId, 'source-layer:', sourceLayer);\n\n // if (!sourceId) {\n // console.error('❌ Source ID not found for:', extrusionLayerId);\n // return;\n // }\n\n // try {\n // // Get the source\n // const source = this.map.map.getSource(sourceId);\n // if (!source) {\n // console.error('❌ Source not found:', sourceId);\n // return;\n // }\n\n // // Get features based on source type\n // let features = [];\n\n // if (source.type === 'geojson') {\n // // For GeoJSON sources, use _data\n // features = source._data.features || [];\n // } else if (source.type === 'vector') {\n // // For vector sources, use querySourceFeatures\n // if (sourceLayer) {\n // features = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n // } else {\n // console.warn('⚠️ No source-layer specified for vector source:', sourceId);\n // return;\n // }\n // }\n\n // console.log('🔵 Found', features.length, 'features in extrusion source');\n\n // if (features.length === 0) {\n // console.log('⚠️ No features found, skipping');\n // return;\n // }\n\n // // Get the current booked-content source\n // const bookedSource = this.map.map.getSource('booked-content');\n // if (!bookedSource) {\n // console.error('❌ booked-content source not found');\n // return;\n // }\n\n // // Get current booked features\n // const currentBookedData = bookedSource._data;\n // const currentBookedFeatures = currentBookedData.features || [];\n\n // // Add extrusion features to booked features\n // const updatedBookedFeatures = [...currentBookedFeatures, ...features];\n\n // // Update the booked-content source\n // bookedSource.setData({\n // type: 'FeatureCollection',\n // features: updatedBookedFeatures\n // });\n\n // console.log('✅ Added', features.length, 'extrusion features to booked-content. Total booked features:', updatedBookedFeatures.length);\n\n // } catch (error) {\n // console.error('❌ Error adding extrusion features to booked-content:', error);\n // }\n // }\n }, {\n key: \"removeGreyFillLayers\",\n value: function removeGreyFillLayers() {\n var _this12 = this;\n if (this.greyFillLayers) {\n this.greyFillLayers.forEach(function (layerId) {\n if (_this12.map.map.getLayer(layerId)) {\n _this12.map.map.removeLayer(layerId);\n }\n });\n this.greyFillLayers = [];\n }\n }\n }, {\n key: \"applySelectableHoverEffects\",\n value: function applySelectableHoverEffects() {\n var _this13 = this;\n // Remove any existing selection hover handler\n if (this.selectionHoverHandler) {\n this.map.map.off('mousemove', this.selectionHoverHandler);\n }\n\n // Create new hover handler for selectable features\n this.selectionHoverHandler = function (e) {\n if (!_this13.interactionEnabled || !_this13.selectionCriteria) return;\n\n // Query selectable fill layer\n var features = _this13.map.map.queryRenderedFeatures(e.point, {\n layers: ['selectable-fill-layer']\n });\n\n // Reset previous hover\n if (_this13.currentHoveredFeatureId) {\n _this13.map.map.setFeatureState({\n source: 'selectable-content',\n id: _this13.currentHoveredFeatureId\n }, {\n hover: false\n });\n }\n\n // Apply hover to new feature\n if (features.length > 0) {\n var feature = features[0];\n _this13.currentHoveredFeatureId = feature.properties.feature_id;\n _this13.map.map.setFeatureState({\n source: 'selectable-content',\n id: _this13.currentHoveredFeatureId\n }, {\n hover: true\n });\n _this13.map.map.getCanvas().style.cursor = 'pointer';\n } else {\n _this13.currentHoveredFeatureId = null;\n _this13.map.map.getCanvas().style.cursor = 'default';\n }\n };\n\n // Add the hover handler\n this.map.map.on('mousemove', this.selectionHoverHandler);\n\n // Update fill layer paint to respond to hover state\n this.map.map.setPaintProperty('selectable-fill-layer', 'fill-color', ['case', ['boolean', ['feature-state', 'hover'], false], this.selectionHoverColor,\n // #4A90E2\n '#FFFFFF' // Default white\n ]);\n }\n }, {\n key: \"createSelectionOpacityExpression\",\n value: function createSelectionOpacityExpression(criteria) {\n // Start with a base case for non-matching features (very low opacity)\n var expression = 0.1;\n\n // First check if feature type is 'floor' - always keep at full opacity\n expression = ['case', ['==', ['get', 'type'], 'floor'], 1.0, expression];\n\n // Build conditions for matching features (full opacity)\n var _loop = function _loop() {\n var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),\n property = _Object$entries$_i[0],\n value = _Object$entries$_i[1];\n if (Array.isArray(value)) {\n // Handle multiple values (e.g., size: ['10x10', '20x10'])\n var conditions = value.map(function (v) {\n return ['==', ['get', property], v];\n });\n var anyMatch = ['any'].concat(_toConsumableArray(conditions));\n expression = ['case', anyMatch, 1.0, expression];\n } else {\n // Handle single value\n expression = ['case', ['==', ['get', property], value], 1.0, expression];\n }\n };\n for (var _i = 0, _Object$entries = Object.entries(criteria); _i < _Object$entries.length; _i++) {\n _loop();\n }\n return expression;\n }\n }, {\n key: \"createSelectionColorOpacityExpression\",\n value: function createSelectionColorOpacityExpression(criteria, layerId) {\n // Get the original color\n var originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n if (!originalColor) return null;\n\n // Create an expression that sets non-selectable extrusions to solid color #2A2A2A\n // For floor type, keep original color\n var expression = ['case', ['==', ['get', 'type'], 'floor'], originalColor // Keep original color for floors\n ];\n\n // Add criteria matching - keep original color\n var _loop2 = function _loop2() {\n var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),\n property = _Object$entries2$_i[0],\n value = _Object$entries2$_i[1];\n if (Array.isArray(value)) {\n var conditions = value.map(function (v) {\n return ['==', ['get', property], v];\n });\n var anyMatch = ['any'].concat(_toConsumableArray(conditions));\n expression.push(anyMatch, originalColor);\n } else {\n expression.push(['==', ['get', property], value], originalColor);\n }\n };\n for (var _i2 = 0, _Object$entries2 = Object.entries(criteria); _i2 < _Object$entries2.length; _i2++) {\n _loop2();\n }\n\n // For non-matching features, set to solid color #2A2A2A\n expression.push('#2A2A2A');\n return expression;\n }\n }, {\n key: \"restoreLayerToSelectionMode\",\n value: function restoreLayerToSelectionMode(layerId) {\n // Helper method to restore a layer to its selection mode colors\n var layer = this.map.map.getStyle().layers.find(function (l) {\n return l.id === layerId;\n });\n if (!layer) return;\n if (layer.type === 'fill') {\n var originalColor = this.originalPaintProperties[layerId]['fill-color'];\n if (originalColor) {\n this.map.map.setPaintProperty(layerId, 'fill-color', originalColor);\n }\n } else if (layer.type === 'fill-extrusion') {\n // Use selection mode expression if available, otherwise fall back to original\n var colorToRestore = this.selectionModeExpressions[layerId] || this.originalPaintProperties[layerId]['fill-extrusion-color'];\n if (colorToRestore) {\n this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', colorToRestore);\n }\n }\n }\n }, {\n key: \"applyHoverToFeature\",\n value: function applyHoverToFeature(layerId, featureId, layerType) {\n // Helper method to apply hover color to a specific feature\n if (layerType === 'fill') {\n this.map.map.setPaintProperty(layerId, 'fill-color', ['case', ['==', ['id'], featureId], this.selectionHoverColor, this.originalPaintProperties[layerId]['fill-color'] || ['get', 'color'] || 0]);\n } else if (layerType === 'fill-extrusion') {\n this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', ['case', ['==', ['id'], featureId], this.selectionHoverColor, this.selectionModeExpressions[layerId] || this.originalPaintProperties[layerId]['fill-extrusion-color'] || ['get', 'color'] || 0]);\n }\n }\n }, {\n key: \"applySelectionHoverEffects\",\n value: function applySelectionHoverEffects(criteria) {\n var _this14 = this;\n // Use a single global mousemove handler instead of per-layer mouseenter/mouseleave\n // This approach continuously validates what's under the cursor and immediately invalidates stale hovers\n this.selectionHoverHandler = function (e) {\n if (!_this14.interactionEnabled || !_this14.selectionCriteria) return;\n\n // Query ALL features under the cursor\n var features = _this14.map.map.queryRenderedFeatures(e.point);\n\n // Find the first fill or fill-extrusion feature\n var fillFeature = features.find(function (f) {\n return f.layer.type === 'fill' || f.layer.type === 'fill-extrusion';\n });\n if (fillFeature) {\n var layerId = fillFeature.layer.id;\n var featureId = fillFeature.id;\n\n // Check if this is a different feature than currently hovered\n if (_this14.currentHoveredLayerId !== layerId || _this14.currentHoveredFeatureId !== featureId) {\n // INVALIDATE old hover if exists\n if (_this14.currentHoveredLayerId) {\n _this14.restoreLayerToSelectionMode(_this14.currentHoveredLayerId);\n }\n\n // Check if new feature is selectable\n if (_this14.featureMatchesCriteria(fillFeature.properties, _this14.selectionCriteria)) {\n // Apply hover to new selectable feature\n _this14.currentHoveredLayerId = layerId;\n _this14.currentHoveredFeatureId = featureId;\n _this14.applyHoverToFeature(layerId, featureId, fillFeature.layer.type);\n _this14.map.map.getCanvas().style.cursor = 'pointer';\n } else {\n // Non-selectable feature\n _this14.currentHoveredLayerId = null;\n _this14.currentHoveredFeatureId = null;\n _this14.map.map.getCanvas().style.cursor = 'default';\n }\n }\n } else {\n // No fill/extrusion features under cursor - clear any hover\n if (_this14.currentHoveredLayerId) {\n _this14.restoreLayerToSelectionMode(_this14.currentHoveredLayerId);\n _this14.currentHoveredLayerId = null;\n _this14.currentHoveredFeatureId = null;\n }\n _this14.map.map.getCanvas().style.cursor = 'default';\n }\n };\n\n // Add the single mousemove handler to the map\n this.map.map.on('mousemove', this.selectionHoverHandler);\n }\n }, {\n key: \"removeSelectionVisuals\",\n value: function removeSelectionVisuals() {\n var _this15 = this;\n // Restore all original paint properties\n for (var _i3 = 0, _Object$entries3 = Object.entries(this.originalPaintProperties); _i3 < _Object$entries3.length; _i3++) {\n var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i3], 2),\n layerId = _Object$entries3$_i[0],\n properties = _Object$entries3$_i[1];\n for (var _i4 = 0, _Object$entries4 = Object.entries(properties); _i4 < _Object$entries4.length; _i4++) {\n var _Object$entries4$_i = _slicedToArray(_Object$entries4[_i4], 2),\n property = _Object$entries4$_i[0],\n value = _Object$entries4$_i[1];\n if (property === 'source' || property === 'source-layer' || property === 'filter' || property === 'features') {\n // Skip non-paint properties\n continue;\n }\n if (value !== undefined) {\n this.map.map.setPaintProperty(layerId, property, value);\n }\n }\n\n // Restore visibility for symbol layers\n if (properties.source) {\n // This indicates it was a symbol layer we hid\n this.map.map.setLayoutProperty(layerId, 'visibility', 'visible');\n }\n }\n\n // Restore original filters for all layers AND reapply floor filtering\n var layers = this.map.map.getStyle().layers;\n var currentFloor = this.map.getCurrentFloor(); // Get current floor\n\n layers.forEach(function (layer) {\n if (layer.type !== 'background' && layer.type !== 'raster' && layer.type !== 'heatmap') {\n var _layerId2 = layer.id;\n\n // Skip our own selectable layers\n if (_layerId2.includes('selectable-')) {\n return;\n }\n\n // Restore original filter\n var originalFilter = _this15.map.map.getFilter(_layerId2);\n if (originalFilter) {\n // Check if this layer had an original filter stored\n var storedOriginalFilter = _this15.map.originalFilters[_layerId2];\n if (storedOriginalFilter !== undefined) {\n // Restore the original filter\n _this15.map.map.setFilter(_layerId2, storedOriginalFilter);\n\n // IMPORTANT: Reapply floor filtering after restoring original filter\n var floorFilter = ['==', ['get', '_floor'], currentFloor];\n if (storedOriginalFilter) {\n var combinedFilter = ['all', floorFilter, storedOriginalFilter];\n _this15.map.map.setFilter(_layerId2, combinedFilter);\n } else {\n _this15.map.map.setFilter(_layerId2, floorFilter);\n }\n }\n } else {\n // If no original filter, just apply floor filter\n var _floorFilter = ['==', ['get', '_floor'], currentFloor];\n _this15.map.map.setFilter(_layerId2, _floorFilter);\n }\n }\n });\n\n // Clear stored properties\n this.originalPaintProperties = {};\n this.selectionModeExpressions = {};\n\n // Remove selectable content layers\n this.map.removeSelectableContentLayers();\n\n // Remove grey fill layers\n this.removeGreyFillLayers();\n\n // Clear hover tracking\n this.currentHoveredLayerId = null;\n this.currentHoveredFeatureId = null;\n\n // Remove the global mousemove handler\n if (this.selectionHoverHandler) {\n this.map.map.off('mousemove', this.selectionHoverHandler);\n this.selectionHoverHandler = null;\n }\n this.pendingSymbolFeatures = [];\n this.pendingExtrusionFeatures = [];\n\n // Reset cursor\n this.map.map.getCanvas().style.cursor = 'default';\n }\n }, {\n key: \"_handleClick\",\n value: function _handleClick(e) {\n var _this16 = this;\n if (!this.interactionEnabled) return;\n var currentState = this.map.getCurrentState();\n if (currentState === 'selection') {\n // First check if clicking on confirmed selection features (for deselection)\n var confirmedFeatures = this.map.map.queryRenderedFeatures(e.point, {\n layers: ['confirmed-selection-fill-layer', 'confirmed-selection-outline-layer', 'confirmed-selection-icon-layer']\n });\n if (confirmedFeatures.length > 0) {\n var feature = confirmedFeatures[0];\n var featureId = feature.properties.feature_id; // Use feature_id consistently\n\n // Remove from confirmed selection layers using feature_id\n this.map.removeConfirmedSelectionFeature(featureId);\n\n // Fire deselection event\n this.map.fire('selection:featureDeselected', {\n feature: feature,\n placementId: feature.properties.placement_id || featureId // Keep placementId for UI compatibility\n });\n this.map.fire('selection:changed', {\n selectedContent: this._getSelectionFeaturesProperties(),\n selectionCount: this.map.getConfirmedSelectionFeatures().length\n });\n return;\n }\n\n // Then check for selectable features (for selection)\n var selectableFeatures = this.map.map.queryRenderedFeatures(e.point, {\n layers: ['selectable-fill-layer']\n });\n if (selectableFeatures.length > 0) {\n var _feature = selectableFeatures[0];\n var placementId = _feature.properties.placement_id;\n var _featureId = _feature.properties.feature_id; // Get feature_id for consistency\n\n // SINGLE-SELECT MODE: Optimistically remove previous selection\n if (!this.map.multiSelect) {\n var currentConfirmedFeatures = this.map.getConfirmedSelectionFeatures();\n if (currentConfirmedFeatures.length > 0) {\n var previousFeature = currentConfirmedFeatures[0];\n var previousFeatureId = previousFeature.properties.feature_id; // Use feature_id\n\n // Fire optimistic deselection event for previous feature\n this.map.fire('selection:featureDeselectedOptimistic', {\n placementId: previousFeature.properties.placement_id || previousFeatureId\n });\n }\n }\n\n // OPTIMISTIC SELECTION: Add to confirmed layers immediately for instant feedback\n this.map.addConfirmedSelectionFeature(_feature, !this.map.multiSelect);\n\n // Fire optimistic selection event immediately\n this.map.fire('selection:featureSelectedOptimistic', {\n feature: _feature\n });\n\n // Check if placement_id exists before attempting to fetch\n if (placementId && placementId !== 'unknown' && placementId !== '') {\n // Set loading state for content placement details\n this.map._stateCoordinator.setLoading(true, 'content');\n\n // Fetch content placement details and update selection context\n this.map.getContentPlacementDetails(placementId).then(function (details) {\n // Success - fire the full selection event to update the UI\n _this16.map.fire('selection:featureSelected', {\n feature: _feature,\n contentPlacement: details\n });\n _this16.map.fire('selection:changed', {\n selectedContent: _this16._getSelectionFeaturesProperties(),\n selectionCount: _this16.map.getConfirmedSelectionFeatures().length\n });\n })[\"catch\"](function (error) {\n console.error('❌ Error fetching content placement details:', error);\n\n // FAILURE - Remove from confirmed selection and show error\n _this16.map.removeConfirmedSelectionFeature(_featureId); // Use feature_id\n\n // Fire optimistic removal event\n _this16.map.fire('selection:featureDeselectedOptimistic', {\n placementId: placementId || _featureId\n });\n })[\"finally\"](function () {\n // Reset loading state\n _this16.map._stateCoordinator.setLoading(false, 'content');\n });\n } else {\n // Create a simple fallback content placement object\n var fallbackContentPlacement = _objectSpread({\n placement_id: _featureId,\n // Use feature_id as fallback\n name: _feature.properties.name || 'Unknown Feature',\n type: _feature.properties.type || 'unknown'\n }, _feature.properties);\n\n // Fire selection event with the simple fallback object\n this.map.fire('selection:featureSelected', {\n feature: _feature,\n contentPlacement: fallbackContentPlacement\n });\n this.map.fire('selection:changed', {\n selectedContent: this._getSelectionFeaturesProperties(),\n selectionCount: this.map.getConfirmedSelectionFeatures().length\n });\n }\n return;\n }\n } else {\n // Default behavior for other states\n var features = this.map.map.queryRenderedFeatures(e.point);\n var symbolFeatures = features.filter(function (feature) {\n return feature.layer.type === 'symbol';\n });\n if (symbolFeatures.length > 0) {\n var _feature2 = symbolFeatures[0];\n var _placementId = _feature2.properties.placement_id;\n\n // Check if placement_id exists before attempting to navigate\n if (_placementId && _placementId !== 'unknown' && _placementId !== '') {\n this.map.setToSelectedContentState([_placementId]);\n }\n }\n }\n }\n }, {\n key: \"featureMatchesCriteria\",\n value: function featureMatchesCriteria(properties, criteria) {\n for (var _i5 = 0, _Object$entries5 = Object.entries(criteria); _i5 < _Object$entries5.length; _i5++) {\n var _Object$entries5$_i = _slicedToArray(_Object$entries5[_i5], 2),\n property = _Object$entries5$_i[0],\n value = _Object$entries5$_i[1];\n var featureValue = properties[property];\n if (Array.isArray(value)) {\n // Check if feature value is in the array of allowed values\n if (!value.includes(featureValue)) {\n return false;\n }\n } else {\n // Check if feature value matches the single required value\n if (featureValue !== value) {\n return false;\n }\n }\n }\n return true;\n }\n }, {\n key: \"_setupCursorHandling\",\n value: function _setupCursorHandling() {\n var _this17 = this;\n // Method 1: Using mouseenter/mouseleave events (recommended)\n this.map.map.on('mouseenter', 'confirmed-selection-fill-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-fill-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n this.map.map.on('mouseenter', 'confirmed-selection-outline-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-outline-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n this.map.map.on('mouseenter', 'confirmed-selection-icon-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-icon-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n }\n }]);\n}(_core_Control__WEBPACK_IMPORTED_MODULE_1__[\"default\"]);\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (InteractionControl);\n\n//# sourceURL=webpack://waygomaps/./src/Controls/InteractionControl.js?");
617
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var webpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webpack */ \"./node_modules/webpack/lib/index.js\");\n/* harmony import */ var webpack__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webpack__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _core_Control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../core/Control */ \"./src/core/Control.js\");\n/* harmony import */ var _utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/coordinateSystems */ \"./src/utils/coordinateSystems.js\");\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\nfunction _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _iterableToArray(r) { if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r); }\nfunction _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }\nfunction _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError(\"Cannot call a class as a function\"); }\nfunction _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, \"value\" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }\nfunction _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, \"prototype\", { writable: !1 }), e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }\nfunction _possibleConstructorReturn(t, e) { if (e && (\"object\" == _typeof(e) || \"function\" == typeof e)) return e; if (void 0 !== e) throw new TypeError(\"Derived constructors may only return object or undefined\"); return _assertThisInitialized(t); }\nfunction _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e; }\nfunction _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }\nfunction _superPropGet(t, e, r, o) { var p = _get(_getPrototypeOf(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; }\nfunction _get() { return _get = \"undefined\" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); }\nfunction _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; }\nfunction _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }\nfunction _inherits(t, e) { if (\"function\" != typeof e && null !== e) throw new TypeError(\"Super expression must either be null or a function\"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, \"prototype\", { writable: !1 }), e && _setPrototypeOf(t, e); }\nfunction _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }\n\n\n\nvar InteractionControl = /*#__PURE__*/function (_Control) {\n function InteractionControl() {\n var _this;\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _classCallCheck(this, InteractionControl);\n _this = _callSuper(this, InteractionControl, [options]);\n _this.map = null;\n _this.previouslySelectedFeature = null;\n _this.previouslySelectedIcon = null;\n _this.previouslySelectedTextColor = null;\n _this.previouslySelectedTextOffset = null;\n _this.previouslyHoveredFeature = null;\n _this.originalTextColor = null;\n _this.textColorReference = {};\n _this.currentView = null; // Can be set to 'desktop' or 'mobile'\n\n _this.selectedTextColor = '#BE2E28';\n _this.interactionEnabled = true;\n _this.selectionCriteria = null;\n _this.originalPaintProperties = {}; // Store original paint properties for selection state\n _this.selectionModeExpressions = {}; // Store selection mode color expressions for hover persistence\n _this.selectionHoverColor = '#4A90E2'; // Color for hover highlighting in selection mode\n _this.currentHoveredLayerId = null; // Track currently hovered layer in selection mode\n _this.currentHoveredFeatureId = null; // Track currently hovered feature in selection mode\n _this.selectionHoverHandler = null; // Reference to mousemove handler for selection mode\n return _this;\n }\n _inherits(InteractionControl, _Control);\n return _createClass(InteractionControl, [{\n key: \"onAdd\",\n value: function onAdd(map) {\n this.map = map;\n this.container = document.createElement('div');\n this.container.className = 'interaction-control-container';\n this.initializeEventListeners();\n this._attachResizeListener();\n this._initialize();\n this.createHighlightedContentLayer();\n this.createSelectedContentLayer();\n this.storeTextColorReferences();\n // this.applyHoverEffectToAllSymbolLayers();\n\n return this.container;\n }\n }, {\n key: \"_initialize\",\n value: function _initialize() {\n var containerWidth = this.map.mapContainer.offsetWidth;\n this._configureView(containerWidth);\n }\n }, {\n key: \"onRemove\",\n value: function onRemove() {\n _superPropGet(InteractionControl, \"onRemove\", this, 3)([]);\n }\n\n // _attachResizeListener() {\n // window.addEventListener('resize', () => {\n // const newWidth = this.map.mapContainer.offsetWidth;\n // this._configureView(newWidth);\n // });\n // }\n }, {\n key: \"_configureView\",\n value: function _configureView(width) {\n if (width > 767) {\n this._setViewForDesktop();\n } else {\n this._setViewForMobile();\n }\n }\n }, {\n key: \"_setViewForDesktop\",\n value: function _setViewForDesktop() {\n this.currentView = 'desktop';\n }\n }, {\n key: \"_setViewForMobile\",\n value: function _setViewForMobile() {\n this.currentView = 'mobile';\n }\n }, {\n key: \"initializeEventListeners\",\n value: function initializeEventListeners() {\n var _this2 = this;\n this.map.map.on('styleimagemissing', function (e) {\n var missingImage = e.id;\n console.warn(\"Image \\\"\".concat(missingImage, \"\\\" could not be loaded.\"));\n });\n this.map.map.on('click', function (e) {\n _this2._handleClick(e);\n });\n this.map.on('state:default', this._handleDefaultState.bind(this));\n this.map.on('state:search', this._handleSearchState.bind(this));\n this.map.on('state:selectedContent', this._handleSelectedContentState.bind(this));\n this.map.on('state:directions', this._handleDirectionsState.bind(this));\n this.map.on('state:setup', this._handleSetupState.bind(this));\n this.map.on('state:selection', this._handleSelectionState.bind(this));\n this.map.on('additionalSearchResults', this._handleAdditionalSearch.bind(this));\n this.map.on('hoverSearchResult', this._handleHoverSearchResult.bind(this));\n this.map.on('hoverEndSearchResult', this._handleHoverEndSearchResult.bind(this));\n }\n }, {\n key: \"storeTextColorReferences\",\n value: function storeTextColorReferences() {\n var _this3 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var textColor = _this3.map.map.getPaintProperty(layer.id, 'text-color');\n if (textColor !== undefined) {\n _this3.textColorReference[layer.id] = textColor; // Store the text color reference using the layer ID as the key\n }\n }\n });\n }\n }, {\n key: \"createSelectedContentLayer\",\n value: function createSelectedContentLayer() {\n this.map.map.addSource('selected-content', {\n 'type': 'geojson',\n 'data': {\n 'type': 'FeatureCollection',\n 'features': [] // Initially empty, you will add features dynamically\n }\n });\n\n // Add a layer that references this GeoJSON source and matches the styling in your Mapbox Studio project\n this.map.map.addLayer({\n 'id': 'selected-content-layer',\n 'type': 'symbol',\n // Or 'fill', 'line', etc. based on your needs\n 'source': 'selected-content',\n 'layout': {\n 'text-field': ['get', 'name'],\n 'text-font': ['Inter Medium'],\n 'text-size': 14,\n 'text-justify': 'left',\n 'text-anchor': 'bottom-left',\n 'text-offset': [1.3, -1],\n 'icon-image': 'selected-pin',\n 'icon-size': 0.5,\n 'icon-offset': [0, -5],\n 'icon-anchor': 'bottom',\n 'symbol-z-elevate': true,\n 'text-padding': 10,\n 'icon-padding': 5\n },\n 'paint': {\n 'text-color': '#BE2E28',\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1\n }\n });\n }\n }, {\n key: \"createHighlightedContentLayer\",\n value: function createHighlightedContentLayer() {\n this.map.map.addSource('highlighted-content', {\n 'type': 'geojson',\n 'data': {\n 'type': 'FeatureCollection',\n 'features': []\n }\n });\n this.map.map.addLayer({\n 'id': 'highlighted-content-layer',\n 'type': 'symbol',\n 'source': 'highlighted-content',\n 'layout': {\n 'text-field': ['get', 'name'],\n 'text-font': ['Inter Medium'],\n 'text-size': 14,\n 'text-justify': 'left',\n 'text-anchor': 'bottom-left',\n 'text-offset': [1.2, -0.6],\n 'icon-image': 'highlightedPin',\n 'icon-size': 0.5,\n 'icon-offset': [0, -5],\n 'icon-anchor': 'bottom',\n 'symbol-z-elevate': true,\n 'text-padding': 5,\n 'icon-padding': 5\n },\n 'paint': {\n 'text-color': '#1E1E1E',\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1\n }\n });\n }\n\n // clearSelectedContentLayer() {\n // this.map.map.getSource('selected-content').setData({\n // 'type': 'FeatureCollection',\n // 'features': []\n // });\n // }\n\n // clearHighlightedContentLayer() {\n // this.map.map.getSource('highlighted-content').setData({\n // 'type': 'FeatureCollection',\n // 'features': []\n // });\n // }\n\n // addSelectedFeature(coordinates, properties) {\n // const source = this.map.map.getSource('selected-content');\n // const currentData = source._data;\n // const newFeature = {\n // 'type': 'Feature',\n // 'geometry': {\n // 'type': 'Point',\n // 'coordinates': coordinates\n // },\n // 'properties': properties\n // };\n // currentData.features.push(newFeature);\n // source.setData(currentData);\n // }\n\n // addHighlightedFeature(coordinates, properties) {\n // const source = this.map.map.getSource('highlighted-content');\n // const currentData = source._data;\n // const newFeature = {\n // 'type': 'Feature',\n // 'geometry': {\n // 'type': 'Point',\n // 'coordinates': coordinates\n // },\n // 'properties': properties\n // };\n // currentData.features.push(newFeature);\n // source.setData(currentData);\n\n // return newFeature;\n // }\n }, {\n key: \"_handleDefaultState\",\n value: function _handleDefaultState() {\n this.interactionEnabled = true;\n\n // Remove any selection state visuals\n this.removeSelectionVisuals();\n this.selectionCriteria = null;\n this.applyHoverEffectToAllSymbolLayers();\n this.map.clearHighlightedContentLayer();\n this.map.clearSelectedContentLayer();\n this.showSymbolLayers();\n\n // this.removeSelectionVisuals();\n // this.selectionCriteria = null;\n\n // // Ensure symbol layers are visible before applying hover effects\n // this.showSymbolLayers();\n\n // // Apply hover effects to all symbol layers\n // this.applyHoverEffectToAllSymbolLayers();\n\n // this.map.clearHighlightedContentLayer();\n // this.map.clearSelectedContentLayer();\n }\n }, {\n key: \"_handleSearchState\",\n value: function _handleSearchState(data) {\n var query = data.query,\n results = data.results;\n this.interactionEnabled = true;\n this.applyHoverEffectToAllSymbolLayers();\n this.hideSymbolLayers();\n this.map.clearSelectedContentLayer();\n\n // Find the floor with the most results\n var floorCounts = results.reduce(function (acc, result) {\n acc[result.floor] = (acc[result.floor] || 0) + 1;\n return acc;\n }, {});\n\n // Get the floor with the highest count\n var bestFloor = Object.entries(floorCounts).reduce(function (a, b) {\n return b[1] > a[1] ? b : a;\n }, [0, 0])[0];\n\n // Only switch floors if none of the results are on the current floor\n var currentFloor = this.map.getCurrentFloor();\n var hasResultsOnCurrentFloor = results.some(function (result) {\n return result.floor === currentFloor;\n });\n var chosenFloor = currentFloor;\n if (!hasResultsOnCurrentFloor) {\n chosenFloor = bestFloor;\n this.map.updateFloor(parseInt(chosenFloor));\n }\n chosenFloor = parseInt(chosenFloor);\n this.updateLabelsForSearchResults(results, true, chosenFloor);\n }\n }, {\n key: \"_handleAdditionalSearch\",\n value: function _handleAdditionalSearch(data) {\n var results = data.results;\n this.updateLabelsForSearchResults(results, true);\n }\n }, {\n key: \"_handleHoverSearchResult\",\n value: function _handleHoverSearchResult(data) {\n var result = data.result;\n this.updateLabelForSelectedContentPlacement(result, false);\n }\n }, {\n key: \"_handleHoverEndSearchResult\",\n value: function _handleHoverEndSearchResult() {\n if (this.map.getCurrentState() === 'search') {\n this.map.clearSelectedContentLayer();\n }\n }\n }, {\n key: \"_handleSelectedContentState\",\n value: function _handleSelectedContentState(data) {\n var contentPlacementIds = data.contentPlacementIds,\n selectedContentPlacement = data.selectedContentPlacement;\n this.interactionEnabled = true;\n this.applyHoverEffectToAllSymbolLayers();\n this.showSymbolLayers();\n this.updateLabelForSelectedContentPlacement(selectedContentPlacement);\n }\n }, {\n key: \"_handleDirectionsState\",\n value: function _handleDirectionsState(data) {\n var endContentPlacement = data.endContentPlacement;\n // if (endContentPlacement) {\n // // this.updateLabelForSelectedContentPlacement(endContentPlacement);\n // }\n this.interactionEnabled = false;\n this.removeHoverEffects();\n this.showSymbolLayers();\n return;\n }\n }, {\n key: \"_handleSetupState\",\n value: function _handleSetupState() {\n this.interactionEnabled = false;\n this.removeHoverEffects();\n }\n }, {\n key: \"_handleSelectionState\",\n value: function _handleSelectionState(data) {\n var criteria = data.criteria,\n geojson = data.geojson;\n this.selectionCriteria = criteria;\n this.interactionEnabled = true;\n\n // Grey out existing\n this.applySelectionModeVisuals(criteria);\n\n // Remove matching features from existing layers to avoid duplication\n this.map.removeMatchingFeaturesFromExistingLayers(criteria);\n\n // Create layers - PASS THE GEOJSON\n this.map.createSelectableContentLayers(geojson);\n\n // NOW process any pending extrusion features (after sources are created)\n this.processPendingExtrusionFeatures();\n this.processPendingSymbolFeatures();\n\n // Hover effects\n this.applySelectableHoverEffects();\n }\n }, {\n key: \"hideSymbolLayers\",\n value: function hideSymbolLayers() {\n var _this4 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol' && layer.id !== 'selected-content-layer' && layer.id !== 'highlighted-content-layer') {\n _this4.map.map.setLayoutProperty(layer.id, 'visibility', 'none');\n }\n });\n }\n }, {\n key: \"showSymbolLayers\",\n value: function showSymbolLayers() {\n var _this5 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n _this5.map.map.setLayoutProperty(layer.id, 'visibility', 'visible');\n }\n });\n }\n }, {\n key: \"updateLabelsForSearchResults\",\n value: function updateLabelsForSearchResults(results) {\n var _this6 = this;\n var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var floor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n if (floor === null) {\n floor = this.map.getCurrentFloor();\n }\n this.map.clearHighlightedContentLayer();\n var features = [];\n var featuresOnFloor = [];\n results.forEach(function (result) {\n var _this6$map$mapData;\n result._floor = result.floor;\n var mapId = ((_this6$map$mapData = _this6.map.mapData) === null || _this6$map$mapData === void 0 ? void 0 : _this6$map$mapData.map_id) || null;\n console.log('🔵 InteractionControl: mapId:', mapId);\n var coordinate;\n if (mapId === 'outdoor-cities-demo') {\n coordinate = result.location;\n } else {\n var coordinates = (0,_utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__.convertVerticesToCoordinates)([result.location], null, 30.0);\n coordinate = coordinates[0];\n }\n // const coordinates = convertVerticesToCoordinates([result.location], null, 30.0);\n // const coordinate = coordinates[0];\n var titleKey = result.catalog.content_title_key;\n result.name = result.content.data[titleKey];\n var feature = _this6.map.addHighlightedFeature(coordinate, result);\n features.push(feature);\n if (result.floor === floor) {\n featuresOnFloor.push(feature);\n }\n });\n if (featuresOnFloor.length && animate) {\n var bounds = new mapboxgl.LngLatBounds();\n featuresOnFloor.forEach(function (feature) {\n bounds.extend(feature.geometry.coordinates);\n });\n if (this.currentView === 'desktop') {\n this.map.map.fitBounds(bounds, {\n padding: {\n top: 50,\n bottom: 50,\n left: 350,\n right: 50\n },\n maxZoom: 15,\n pitch: 45,\n bearing: -37,\n duration: 1000\n });\n } else if (this.currentView === 'mobile') {\n var mapHeight = this.map.mapContainer.offsetHeight;\n var mapWidth = this.map.mapContainer.offsetWidth;\n var bottomPaddingPercent = 45;\n var sidePaddingPercent = 8;\n var bottomPaddingInPixels = mapHeight * (bottomPaddingPercent / 100);\n var sidePaddingInPixels = mapWidth * (sidePaddingPercent / 100);\n this.map.map.fitBounds(bounds, {\n padding: {\n top: 150,\n bottom: bottomPaddingInPixels,\n left: sidePaddingInPixels,\n right: sidePaddingInPixels + 95\n },\n maxZoom: 16,\n pitch: 45,\n bearing: -37,\n duration: 1000\n });\n }\n }\n }\n\n // _getSimplifiedSelectedFeatures() {\n // const confirmedFeatures = this.map.getConfirmedSelectionFeatures();\n // return confirmedFeatures.map(feature => ({\n // feature_id: feature.properties.feature_id,\n // name: feature.properties.name || 'Unnamed Feature'\n // }));\n // }\n }, {\n key: \"_getSelectionFeaturesProperties\",\n value: function _getSelectionFeaturesProperties() {\n var confirmedFeatures = this.map.getConfirmedSelectionFeatures();\n return confirmedFeatures.map(function (feature) {\n return feature.properties;\n });\n }\n }, {\n key: \"updateLabelForSelectedContentPlacement\",\n value: function updateLabelForSelectedContentPlacement(result) {\n var _this$map$mapData;\n var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n this.map.clearSelectedContentLayer();\n var mapId = ((_this$map$mapData = this.map.mapData) === null || _this$map$mapData === void 0 ? void 0 : _this$map$mapData.map_id) || null;\n console.log('🔵 InteractionControl: mapId:', mapId);\n var coordinate;\n if (mapId === 'outdoor-cities-demo') {\n coordinate = result.location;\n } else {\n var coordinates = (0,_utils_coordinateSystems__WEBPACK_IMPORTED_MODULE_2__.convertVerticesToCoordinates)([result.location], null, 30.0);\n coordinate = coordinates[0];\n }\n\n // const coordinates = convertVerticesToCoordinates([result.location], null, 30.0);\n // const coordinate = coordinates[0];\n result._floor = result.floor;\n if (!result.name) {\n if (result.content && result.catalog) {\n var title_key = result.catalog.content_title_key;\n var title = result.content.data[title_key];\n result.name = title;\n }\n }\n this.map.addSelectedFeature(coordinate, result);\n if (animate) {\n if (this.currentView === 'desktop') {\n this.map.map.easeTo({\n center: coordinate,\n padding: {\n top: 0,\n bottom: 0,\n left: 330,\n right: 0\n },\n duration: 1000\n });\n } else if (this.currentView === 'mobile') {\n var mapHeight = this.map.mapContainer.offsetHeight;\n var bottomPaddingPercent = 35;\n var bottomPaddingInPixels = mapHeight * (bottomPaddingPercent / 100);\n this.map.map.easeTo({\n center: coordinate,\n padding: {\n top: 0,\n bottom: bottomPaddingInPixels,\n left: 0,\n right: 0\n },\n duration: 1000\n });\n }\n }\n }\n }, {\n key: \"applyHoverEffectToAllSymbolLayers\",\n value: function applyHoverEffectToAllSymbolLayers() {\n var _this7 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var layerId = layer.id;\n var defaultTextColor = _this7.textColorReference[layerId];\n _this7.map.map.on('mouseenter', layerId, function (e) {\n var feature = e.features[0];\n var placementId = feature.properties.placement_id;\n if (!_this7.previouslySelectedFeature || _this7.previouslySelectedFeature.layer.id !== feature.layer.id) {\n _this7.originalTextColor = _this7.map.map.getPaintProperty(layerId, 'text-color');\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], placementId], '#4B90F7', defaultTextColor]);\n } else {\n _this7.originalTextColor = _this7.previouslySelectedTextColor;\n var previouslySelectedPlacementId = _this7.previouslySelectedFeature.properties.placement_id;\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], placementId], '#4B90F7', ['==', ['get', 'placement_id'], previouslySelectedPlacementId], _this7.selectedTextColor, defaultTextColor]);\n }\n _this7.map.map.getCanvas().style.cursor = 'pointer';\n });\n _this7.map.map.on('mouseleave', layerId, function () {\n if (!_this7.previouslySelectedFeature) {\n _this7.map.map.setPaintProperty(layerId, 'text-color', defaultTextColor);\n } else {\n // If a feature is selected, maintain its selected color\n var previouslySelectedPlacementId = _this7.previouslySelectedFeature.properties.placement_id;\n _this7.map.map.setPaintProperty(layerId, 'text-color', ['case', ['==', ['get', 'placement_id'], previouslySelectedPlacementId], _this7.selectedTextColor, defaultTextColor]);\n }\n _this7.map.map.getCanvas().style.cursor = 'default';\n });\n }\n });\n }\n }, {\n key: \"removeHoverEffects\",\n value: function removeHoverEffects() {\n var _this8 = this;\n var layers = this.map.map.getStyle().layers;\n layers.forEach(function (layer) {\n if (layer.type === 'symbol') {\n var layerId = layer.id;\n // Reset to default text color\n var defaultTextColor = _this8.textColorReference[layerId];\n _this8.map.map.setPaintProperty(layerId, 'text-color', defaultTextColor);\n\n // Remove event listeners\n _this8.map.map.off('mouseenter', layerId);\n _this8.map.map.off('mouseleave', layerId);\n }\n });\n this.map.map.getCanvas().style.cursor = 'default';\n }\n }, {\n key: \"applySelectionModeVisuals\",\n value: function applySelectionModeVisuals(criteria) {\n var _this9 = this;\n var layers = this.map.map.getStyle().layers;\n\n // Clear any previous stored properties\n this.originalPaintProperties = {};\n layers.forEach(function (layer) {\n if (layer.type === 'background') {\n var layerId = layer.id;\n\n // Store original background color\n if (!_this9.originalPaintProperties[layerId]) {\n _this9.originalPaintProperties[layerId] = {};\n }\n _this9.originalPaintProperties[layerId]['background-color'] = _this9.map.map.getPaintProperty(layerId, 'background-color');\n\n // Set new background color for selection mode\n _this9.map.map.setPaintProperty(layerId, 'background-color', '#f5f5f5');\n return; // Skip the rest of the loop for background layers\n }\n if (layer.type !== 'raster' && layer.type !== 'heatmap') {\n var _layerId = layer.id;\n\n // Skip our own selectable layers - they should not be greyed out\n if (_layerId.includes('selectable-')) {\n return;\n }\n\n // Initialize storage for this layer\n if (!_this9.originalPaintProperties[_layerId]) {\n _this9.originalPaintProperties[_layerId] = {};\n }\n\n // Apply grey styling to all layer types\n // In applySelectionModeVisuals(), replace the symbol layer section (lines 593-606) with:\n\n if (layer.type === 'symbol') {\n // Skip our own selectable/booked layers\n if (_layerId.includes('selectable-') || _layerId.includes('booked-') || _layerId.includes('confirmed-selection')) {\n return;\n }\n\n // Get the layer info BEFORE hiding it\n var symbolLayer = _this9.map.map.getLayer(_layerId);\n var sourceId = symbolLayer.source;\n var sourceLayer = symbolLayer.sourceLayer;\n var filter = symbolLayer.filter;\n\n // GET FEATURES BEFORE HIDING THE LAYER\n var features = [];\n try {\n var source = _this9.map.map.getSource(sourceId);\n if (source && source.type === 'vector' && sourceLayer) {\n features = _this9.map.map.querySourceFeatures(sourceId, {\n sourceLayer: sourceLayer,\n filter: filter\n });\n } else if (source && source.type === 'geojson') {\n features = source._data.features || [];\n }\n } catch (error) {\n console.error('❌ Error getting symbol features before layer hiding:', error);\n }\n\n // Store the layer info for restoration\n _this9.originalPaintProperties[_layerId] = {\n 'text-opacity': _this9.map.map.getPaintProperty(_layerId, 'text-opacity'),\n 'icon-opacity': _this9.map.map.getPaintProperty(_layerId, 'icon-opacity'),\n 'text-color': _this9.map.map.getPaintProperty(_layerId, 'text-color'),\n 'source': sourceId,\n 'source-layer': sourceLayer,\n 'filter': filter,\n 'features': features // Store the features we got before hiding\n };\n\n // COMPLETELY HIDE the symbol layer\n _this9.map.map.setLayoutProperty(_layerId, 'visibility', 'none');\n\n // Store features to add later (don't add them now)\n if (!_this9.pendingSymbolFeatures) {\n _this9.pendingSymbolFeatures = [];\n }\n _this9.pendingSymbolFeatures.push({\n layerId: _layerId,\n features: features\n });\n } else if (layer.type === 'fill') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['fill-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'fill-opacity');\n _this9.originalPaintProperties[_layerId]['fill-color'] = _this9.map.map.getPaintProperty(_layerId, 'fill-color');\n\n // Apply grey styling - light grey color with reduced opacity but preserve floors\n var fillOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['fill-opacity'],\n // Keep original opacity\n 0.5 // Reduce other fills to 0.5 for layering effect\n ];\n var fillColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['fill-color'],\n // Keep original color\n '#f7f7f8' // Light grey for non-floor fills\n ];\n _this9.map.map.setPaintProperty(_layerId, 'fill-color', fillColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'fill-opacity', fillOpacityExpression);\n } else if (layer.type === 'line') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['line-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'line-opacity');\n _this9.originalPaintProperties[_layerId]['line-color'] = _this9.map.map.getPaintProperty(_layerId, 'line-color');\n\n // Apply grey styling - grey color with 0.6 opacity but preserve floors\n var lineOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['line-opacity'],\n // Keep original opacity\n 0.6 // Reduce other lines to 0.6\n ];\n var lineColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['line-color'],\n // Keep original color\n '#AAAAAA' // Grey for non-floor lines\n ];\n _this9.map.map.setPaintProperty(_layerId, 'line-color', lineColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'line-opacity', lineOpacityExpression);\n } else if (layer.type === 'circle') {\n // Store original values\n _this9.originalPaintProperties[_layerId]['circle-opacity'] = _this9.map.map.getPaintProperty(_layerId, 'circle-opacity');\n _this9.originalPaintProperties[_layerId]['circle-color'] = _this9.map.map.getPaintProperty(_layerId, 'circle-color');\n\n // Apply grey styling - grey color with 0.5 opacity but preserve floors\n var circleOpacityExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['circle-opacity'] || 1.0,\n // Keep original opacity\n 0.5 // Reduce other circles to 0.5\n ];\n var circleColorExpression = ['case', ['==', ['get', 'type'], 'floor'], _this9.originalPaintProperties[_layerId]['circle-color'],\n // Keep original color\n '#CCCCCC' // Grey for non-floor circles\n ];\n _this9.map.map.setPaintProperty(_layerId, 'circle-color', circleColorExpression);\n _this9.map.map.setPaintProperty(_layerId, 'circle-opacity', circleOpacityExpression);\n } else if (layer.type === 'fill-extrusion') {\n // Get the layer info BEFORE removing it\n var extrusionLayer = _this9.map.map.getLayer(_layerId);\n var _sourceId = extrusionLayer.source;\n var _sourceLayer = extrusionLayer.sourceLayer;\n var _filter = extrusionLayer.filter;\n\n // GET FEATURES BEFORE REMOVING THE LAYER\n var _features = [];\n try {\n var _source = _this9.map.map.getSource(_sourceId);\n if (_source && _source.type === 'vector' && _sourceLayer) {\n _features = _this9.map.map.querySourceFeatures(_sourceId, {\n sourceLayer: _sourceLayer,\n filter: _filter\n });\n } else if (_source && _source.type === 'geojson') {\n _features = _source._data.features || [];\n }\n } catch (error) {\n console.error('❌ Error getting features before layer removal:', error);\n }\n\n // Store the layer info for restoration\n _this9.originalPaintProperties[_layerId] = {\n 'fill-extrusion-color': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-color'),\n 'fill-extrusion-height': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-height'),\n 'fill-extrusion-opacity': _this9.map.map.getPaintProperty(_layerId, 'fill-extrusion-opacity'),\n 'source': _sourceId,\n 'source-layer': _sourceLayer,\n 'filter': _filter,\n 'features': _features // Store the features we got before removal\n };\n\n // COMPLETELY REMOVE the extrusion layer\n _this9.map.map.removeLayer(_layerId);\n\n // Store features to add later (don't add them now)\n if (!_this9.pendingExtrusionFeatures) {\n _this9.pendingExtrusionFeatures = [];\n }\n _this9.pendingExtrusionFeatures.push({\n layerId: _layerId,\n features: _features\n });\n }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Get the layer info BEFORE removing it\n // const extrusionLayer = this.map.map.getLayer(layerId);\n // const sourceId = extrusionLayer.source;\n // const sourceLayer = extrusionLayer.sourceLayer;\n // const filter = extrusionLayer.filter;\n\n // console.log('🔵 Extrusion layer source:', sourceId, 'source-layer:', sourceLayer);\n // // GET FEATURES BEFORE REMOVING THE LAYER\n // let features = [];\n // try {\n // const source = this.map.map.getSource(sourceId);\n // console.log('SOURCE TYPE:', source.type);\n // console.log('SOURCE', source);\n // console.log('EXTRUSION LAYER:', extrusionLayer);\n // if (source && source.type === 'vector' && sourceLayer) {\n // features = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n // console.log('🔵 Found', features.length, 'features BEFORE removing layer');\n // } else if (source && source.type === 'geojson') {\n // features = source._data.features || [];\n // console.log('🔵 Found', features.length, 'GeoJSON features BEFORE removing layer');\n // }\n // } catch (error) {\n // console.error('❌ Error getting features before layer removal:', error);\n // }\n\n // console.log('🔵 FOUND EXTRUSION FEATURES:', features);\n\n // // Store the layer info for restoration\n // this.originalPaintProperties[layerId] = {\n // 'fill-extrusion-color': this.map.map.getPaintProperty(layerId, 'fill-extrusion-color'),\n // 'fill-extrusion-height': this.map.map.getPaintProperty(layerId, 'fill-extrusion-height'),\n // 'fill-extrusion-opacity': this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity'),\n // 'source': sourceId,\n // 'source-layer': sourceLayer,\n // 'filter': filter,\n // 'features': features // Store the features we got before removal\n // };\n\n // // COMPLETELY REMOVE the extrusion layer\n // console.log('🔵 Removing extrusion layer:', layerId);\n // this.map.map.removeLayer(layerId);\n\n // // Add the features to booked-content\n // this.addFeaturesToBookedContent(features, layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Get the layer info BEFORE removing it\n // const extrusionLayer = this.map.map.getLayer(layerId);\n // const sourceId = extrusionLayer.source;\n\n // console.log('🔵 Extrusion layer source:', sourceId);\n\n // // Store the layer info for restoration\n // this.originalPaintProperties[layerId] = {\n // 'fill-extrusion-color': this.map.map.getPaintProperty(layerId, 'fill-extrusion-color'),\n // 'fill-extrusion-height': this.map.map.getPaintProperty(layerId, 'fill-extrusion-height'),\n // 'fill-extrusion-opacity': this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity')\n // };\n\n // // Store the source info for the fill layer creation\n // this.originalPaintProperties[layerId]['source'] = sourceId;\n // this.originalPaintProperties[layerId]['source-layer'] = extrusionLayer['source-layer'];\n // this.originalPaintProperties[layerId]['filter'] = extrusionLayer.filter;\n\n // // COMPLETELY REMOVE the extrusion layer\n // console.log('🔵 Removing extrusion layer:', layerId);\n // this.map.map.removeLayer(layerId);\n\n // // Create a fill layer with the same data\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // const originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // const originalHeight = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n // const originalVisibility = this.map.map.getLayoutProperty(layerId, 'visibility');\n\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = originalColor;\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = originalHeight;\n\n // // Store layout properties\n // if (!this.originalLayoutProperties) {\n // this.originalLayoutProperties = {};\n // }\n // this.originalLayoutProperties[layerId] = this.originalLayoutProperties[layerId] || {};\n // this.originalLayoutProperties[layerId]['visibility'] = originalVisibility;\n\n // console.log('🔵 Original extrusion visibility:', originalVisibility);\n\n // // COMPLETELY HIDE extrusions for non-floor features\n // const visibilityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // 'visible', // Keep floors visible\n // 'none' // Hide all other extrusions completely\n // ];\n\n // console.log('🔵 Setting visibility expression:', visibilityExpression);\n // this.map.map.setLayoutProperty(layerId, 'visibility', visibilityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // const originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // const originalHeight = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = originalColor;\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = originalHeight;\n\n // console.log('🔵 Original extrusion height:', originalHeight);\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // originalHeight || 0, // Use original height or 0 if undefined\n // 0 // Set height to 0 for non-floor extrusions\n // ];\n\n // console.log('🔵 Setting height expression:', heightExpression);\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-height'], // Keep original height\n // 0 // Set height to 0 for non-floor extrusions\n // ];\n\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // console.log('🔵 Processing fill-extrusion layer:', layerId);\n\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity');\n\n // console.log('🔵 Original extrusion opacity:', this.originalPaintProperties[layerId]['fill-extrusion-opacity']);\n\n // // Hide extrusions completely for non-floor features\n // const opacityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'], // Keep original opacity\n // 0 // Hide non-floor extrusions completely\n // ];\n\n // console.log('🔵 Setting opacity expression:', opacityExpression);\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-opacity', opacityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-opacity');\n\n // // Hide extrusions completely for non-floor features\n // const opacityExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-opacity'], // Keep original opacity\n // 0 // Hide non-floor extrusions completely\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-opacity', opacityExpression);\n\n // // Create corresponding 2D fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n\n // // Apply light grey styling but preserve floors at original color\n // const lightGreyExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-color'], // Keep original\n // '#e6e6e6' // Much lighter grey for non-floor extrusions\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', lightGreyExpression);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n // this.originalPaintProperties[layerId]['fill-extrusion-height'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-height');\n\n // // Hide extrusions by setting height to 0 for non-floor features\n // const heightExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-height'], // Keep original height\n // 0 // Set height to 0 for non-floor extrusions (effectively hiding them)\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-height', heightExpression);\n\n // // Create corresponding fill layers for the same features\n // this.createGreyFillLayerForExtrusion(layerId);\n // }\n // } else if (layer.type === 'fill-extrusion') {\n // // Store original values for extrusions\n // this.originalPaintProperties[layerId]['fill-extrusion-color'] = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n\n // // Apply light grey styling but preserve floors at original color\n // const lightGreyExpression = [\n // 'case',\n // ['==', ['get', 'type'], 'floor'],\n // this.originalPaintProperties[layerId]['fill-extrusion-color'], // Keep original\n // '#e6e6e6' // Much lighter grey for non-floor extrusions\n // ];\n // this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', lightGreyExpression);\n // }\n }\n });\n\n // Note: We no longer apply hover effects to existing layers in selection mode\n // The selectable features will have their own hover effects\n }\n }, {\n key: \"processPendingSymbolFeatures\",\n value: function processPendingSymbolFeatures() {\n var _this10 = this;\n if (!this.pendingSymbolFeatures || this.pendingSymbolFeatures.length === 0) {\n return;\n }\n\n // Process each group\n this.pendingSymbolFeatures.forEach(function (_ref) {\n var layerId = _ref.layerId,\n features = _ref.features;\n _this10.addSymbolFeaturesToBookedLabels(features, layerId);\n });\n\n // Clear the pending features\n this.pendingSymbolFeatures = [];\n }\n }, {\n key: \"addSymbolFeaturesToBookedLabels\",\n value: function addSymbolFeaturesToBookedLabels(features, symbolLayerId) {\n if (features.length === 0) {\n return;\n }\n try {\n // Get the current booked-labels source\n var bookedLabelsSource = this.map.map.getSource('booked-labels');\n if (!bookedLabelsSource) {\n console.error('❌ booked-labels source not found');\n return;\n }\n\n // Get current booked label features\n var currentBookedLabelsData = bookedLabelsSource._data;\n var currentBookedLabelFeatures = currentBookedLabelsData.features || [];\n\n // Convert symbol features to label features\n var labelFeatures = features.map(function (feature) {\n // Use feature.properties.title for existing symbol layers\n var title = feature.properties.title || feature.properties.name || 'Untitled';\n return {\n type: 'Feature',\n geometry: feature.geometry,\n properties: _objectSpread(_objectSpread({}, feature.properties), {}, {\n name: title // Ensure 'name' property exists for the text-field\n })\n };\n });\n\n // Add symbol features to booked label features\n var updatedBookedLabelFeatures = [].concat(_toConsumableArray(currentBookedLabelFeatures), _toConsumableArray(labelFeatures));\n\n // Update the booked-labels source\n bookedLabelsSource.setData({\n type: 'FeatureCollection',\n features: updatedBookedLabelFeatures\n });\n\n // Verify the update worked\n var verifySource = this.map.map.getSource('booked-labels');\n var verifyFeatures = verifySource._data.features || [];\n } catch (error) {\n console.error('❌ Error adding symbol features to booked-labels:', error);\n }\n }\n }, {\n key: \"addFeaturesToBookedContent\",\n value: function addFeaturesToBookedContent(features, extrusionLayerId) {\n if (features.length === 0) {\n return;\n }\n try {\n // Get the current booked-content source\n var bookedSource = this.map.map.getSource('booked-content');\n if (!bookedSource) {\n console.error('❌ booked-content source not found');\n return;\n }\n\n // Get current booked features\n var currentBookedData = bookedSource._data;\n var currentBookedFeatures = currentBookedData.features || [];\n\n // Use the features directly (no high-precision processing for now)\n var updatedBookedFeatures = [].concat(_toConsumableArray(currentBookedFeatures), _toConsumableArray(features));\n\n // Update the booked-content source\n bookedSource.setData({\n type: 'FeatureCollection',\n features: updatedBookedFeatures\n });\n\n // Verify the update worked\n var verifySource = this.map.map.getSource('booked-content');\n var verifyFeatures = verifySource._data.features || [];\n } catch (error) {\n console.error('❌ Error adding features to booked-content:', error);\n }\n }\n }, {\n key: \"processPendingExtrusionFeatures\",\n value: function processPendingExtrusionFeatures() {\n var _this11 = this;\n if (!this.pendingExtrusionFeatures || this.pendingExtrusionFeatures.length === 0) {\n return;\n }\n\n // Process each group\n this.pendingExtrusionFeatures.forEach(function (_ref2) {\n var layerId = _ref2.layerId,\n features = _ref2.features;\n _this11.addFeaturesToBookedContent(features, layerId);\n });\n\n // Clear the pending features\n this.pendingExtrusionFeatures = [];\n }\n\n // getHighPrecisionFeatures(features, extrusionLayerId) {\n // console.log('🔵 Using original features for', features.length, 'features');\n\n // // For now, just return the original features\n // // The issue might not be with precision but with how we're handling them\n // return features;\n // }\n }, {\n key: \"getHighPrecisionFeatures\",\n value: function getHighPrecisionFeatures(features, extrusionLayerId) {\n // Get the stored layer info\n var layerInfo = this.originalPaintProperties[extrusionLayerId];\n if (!layerInfo) {\n console.warn('⚠️ No layer info found, using original features');\n return features;\n }\n var sourceId = layerInfo.source;\n var sourceLayer = layerInfo['source-layer'];\n var filter = layerInfo.filter;\n try {\n // Get the source first\n var source = this.map.map.getSource(sourceId);\n if (!source) {\n console.error('❌ Source not found:', sourceId);\n return features;\n }\n\n // Try querying without changing zoom - just use current view\n var currentFeatures = this.map.map.querySourceFeatures(sourceId, {\n sourceLayer: sourceLayer,\n filter: filter\n });\n\n // If we got the same or more features, use them\n if (currentFeatures.length >= features.length) {\n return currentFeatures;\n } else {\n return features;\n }\n } catch (error) {\n console.error('❌ Error getting high-precision features:', error);\n return features;\n }\n }\n\n // async getHighPrecisionFeatures(features, extrusionLayerId) {\n // console.log('🔵 Getting high-precision geometries for', features.length, 'features');\n\n // // Get the stored layer info\n // const layerInfo = this.originalPaintProperties[extrusionLayerId];\n // if (!layerInfo) {\n // console.warn('⚠️ No layer info found, using original features');\n // return features;\n // }\n\n // const sourceId = layerInfo.source;\n // const sourceLayer = layerInfo['source-layer']; // Fixed: use bracket notation for hyphenated property\n // const filter = layerInfo.filter;\n\n // try {\n // // Get the source first\n // const source = this.map.map.getSource(sourceId);\n // if (!source) {\n // console.error('❌ Source not found:', sourceId);\n // return features;\n // }\n\n // // Temporarily zoom to max zoom to force high-res tile loading\n // const currentZoom = this.map.map.getZoom();\n // const currentCenter = this.map.map.getCenter();\n\n // // Zoom to max zoom briefly to load high-res tiles\n // this.map.map.setZoom(22);\n\n // // Wait a bit for tiles to load\n // await new Promise(resolve => setTimeout(resolve, 100));\n\n // // Query at max zoom\n // const highPrecisionFeatures = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n\n // // Restore original zoom\n // this.map.map.setZoom(currentZoom);\n // this.map.map.setCenter(currentCenter);\n\n // console.log('🔵 Retrieved', highPrecisionFeatures.length, 'high-precision features');\n\n // return highPrecisionFeatures.length > 0 ? highPrecisionFeatures : features;\n\n // } catch (error) {\n // console.error('❌ Error getting high-precision features:', error);\n // console.log('🔵 Falling back to original features');\n // return features;\n // }\n // }\n\n // createGreyFillLayerForExtrusion(extrusionLayerId) {\n // console.log('🔵 Adding extrusion features to booked-content source:', extrusionLayerId);\n\n // // Get the source info from the stored properties\n // const sourceId = this.originalPaintProperties[extrusionLayerId]['source'];\n // const sourceLayer = this.originalPaintProperties[extrusionLayerId]['source-layer'];\n // const filter = this.originalPaintProperties[extrusionLayerId]['filter'];\n\n // console.log('🔵 Using source:', sourceId, 'source-layer:', sourceLayer);\n\n // if (!sourceId) {\n // console.error('❌ Source ID not found for:', extrusionLayerId);\n // return;\n // }\n\n // try {\n // // Get the source\n // const source = this.map.map.getSource(sourceId);\n // if (!source) {\n // console.error('❌ Source not found:', sourceId);\n // return;\n // }\n\n // // Get features based on source type\n // let features = [];\n\n // if (source.type === 'geojson') {\n // // For GeoJSON sources, use _data\n // features = source._data.features || [];\n // } else if (source.type === 'vector') {\n // // For vector sources, use querySourceFeatures\n // if (sourceLayer) {\n // features = this.map.map.querySourceFeatures(sourceId, {\n // sourceLayer: sourceLayer,\n // filter: filter\n // });\n // } else {\n // console.warn('⚠️ No source-layer specified for vector source:', sourceId);\n // return;\n // }\n // }\n\n // console.log('🔵 Found', features.length, 'features in extrusion source');\n\n // if (features.length === 0) {\n // console.log('⚠️ No features found, skipping');\n // return;\n // }\n\n // // Get the current booked-content source\n // const bookedSource = this.map.map.getSource('booked-content');\n // if (!bookedSource) {\n // console.error('❌ booked-content source not found');\n // return;\n // }\n\n // // Get current booked features\n // const currentBookedData = bookedSource._data;\n // const currentBookedFeatures = currentBookedData.features || [];\n\n // // Add extrusion features to booked features\n // const updatedBookedFeatures = [...currentBookedFeatures, ...features];\n\n // // Update the booked-content source\n // bookedSource.setData({\n // type: 'FeatureCollection',\n // features: updatedBookedFeatures\n // });\n\n // console.log('✅ Added', features.length, 'extrusion features to booked-content. Total booked features:', updatedBookedFeatures.length);\n\n // } catch (error) {\n // console.error('❌ Error adding extrusion features to booked-content:', error);\n // }\n // }\n }, {\n key: \"removeGreyFillLayers\",\n value: function removeGreyFillLayers() {\n var _this12 = this;\n if (this.greyFillLayers) {\n this.greyFillLayers.forEach(function (layerId) {\n if (_this12.map.map.getLayer(layerId)) {\n _this12.map.map.removeLayer(layerId);\n }\n });\n this.greyFillLayers = [];\n }\n }\n }, {\n key: \"applySelectableHoverEffects\",\n value: function applySelectableHoverEffects() {\n var _this13 = this;\n // Remove any existing selection hover handler\n if (this.selectionHoverHandler) {\n this.map.map.off('mousemove', this.selectionHoverHandler);\n }\n\n // Create new hover handler for selectable features\n this.selectionHoverHandler = function (e) {\n if (!_this13.interactionEnabled || !_this13.selectionCriteria) return;\n\n // Query selectable fill layer\n var features = _this13.map.map.queryRenderedFeatures(e.point, {\n layers: ['selectable-fill-layer']\n });\n\n // Reset previous hover\n if (_this13.currentHoveredFeatureId) {\n _this13.map.map.setFeatureState({\n source: 'selectable-content',\n id: _this13.currentHoveredFeatureId\n }, {\n hover: false\n });\n }\n\n // Apply hover to new feature\n if (features.length > 0) {\n var feature = features[0];\n _this13.currentHoveredFeatureId = feature.properties.feature_id;\n _this13.map.map.setFeatureState({\n source: 'selectable-content',\n id: _this13.currentHoveredFeatureId\n }, {\n hover: true\n });\n _this13.map.map.getCanvas().style.cursor = 'pointer';\n } else {\n _this13.currentHoveredFeatureId = null;\n _this13.map.map.getCanvas().style.cursor = 'default';\n }\n };\n\n // Add the hover handler\n this.map.map.on('mousemove', this.selectionHoverHandler);\n\n // Update fill layer paint to respond to hover state\n this.map.map.setPaintProperty('selectable-fill-layer', 'fill-color', ['case', ['boolean', ['feature-state', 'hover'], false], this.selectionHoverColor,\n // #4A90E2\n '#FFFFFF' // Default white\n ]);\n }\n }, {\n key: \"createSelectionOpacityExpression\",\n value: function createSelectionOpacityExpression(criteria) {\n // Start with a base case for non-matching features (very low opacity)\n var expression = 0.1;\n\n // First check if feature type is 'floor' - always keep at full opacity\n expression = ['case', ['==', ['get', 'type'], 'floor'], 1.0, expression];\n\n // Build conditions for matching features (full opacity)\n var _loop = function _loop() {\n var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),\n property = _Object$entries$_i[0],\n value = _Object$entries$_i[1];\n if (Array.isArray(value)) {\n // Handle multiple values (e.g., size: ['10x10', '20x10'])\n var conditions = value.map(function (v) {\n return ['==', ['get', property], v];\n });\n var anyMatch = ['any'].concat(_toConsumableArray(conditions));\n expression = ['case', anyMatch, 1.0, expression];\n } else {\n // Handle single value\n expression = ['case', ['==', ['get', property], value], 1.0, expression];\n }\n };\n for (var _i = 0, _Object$entries = Object.entries(criteria); _i < _Object$entries.length; _i++) {\n _loop();\n }\n return expression;\n }\n }, {\n key: \"createSelectionColorOpacityExpression\",\n value: function createSelectionColorOpacityExpression(criteria, layerId) {\n // Get the original color\n var originalColor = this.map.map.getPaintProperty(layerId, 'fill-extrusion-color');\n if (!originalColor) return null;\n\n // Create an expression that sets non-selectable extrusions to solid color #2A2A2A\n // For floor type, keep original color\n var expression = ['case', ['==', ['get', 'type'], 'floor'], originalColor // Keep original color for floors\n ];\n\n // Add criteria matching - keep original color\n var _loop2 = function _loop2() {\n var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),\n property = _Object$entries2$_i[0],\n value = _Object$entries2$_i[1];\n if (Array.isArray(value)) {\n var conditions = value.map(function (v) {\n return ['==', ['get', property], v];\n });\n var anyMatch = ['any'].concat(_toConsumableArray(conditions));\n expression.push(anyMatch, originalColor);\n } else {\n expression.push(['==', ['get', property], value], originalColor);\n }\n };\n for (var _i2 = 0, _Object$entries2 = Object.entries(criteria); _i2 < _Object$entries2.length; _i2++) {\n _loop2();\n }\n\n // For non-matching features, set to solid color #2A2A2A\n expression.push('#2A2A2A');\n return expression;\n }\n }, {\n key: \"restoreLayerToSelectionMode\",\n value: function restoreLayerToSelectionMode(layerId) {\n // Helper method to restore a layer to its selection mode colors\n var layer = this.map.map.getStyle().layers.find(function (l) {\n return l.id === layerId;\n });\n if (!layer) return;\n if (layer.type === 'fill') {\n var originalColor = this.originalPaintProperties[layerId]['fill-color'];\n if (originalColor) {\n this.map.map.setPaintProperty(layerId, 'fill-color', originalColor);\n }\n } else if (layer.type === 'fill-extrusion') {\n // Use selection mode expression if available, otherwise fall back to original\n var colorToRestore = this.selectionModeExpressions[layerId] || this.originalPaintProperties[layerId]['fill-extrusion-color'];\n if (colorToRestore) {\n this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', colorToRestore);\n }\n }\n }\n }, {\n key: \"applyHoverToFeature\",\n value: function applyHoverToFeature(layerId, featureId, layerType) {\n // Helper method to apply hover color to a specific feature\n if (layerType === 'fill') {\n this.map.map.setPaintProperty(layerId, 'fill-color', ['case', ['==', ['id'], featureId], this.selectionHoverColor, this.originalPaintProperties[layerId]['fill-color'] || ['get', 'color'] || 0]);\n } else if (layerType === 'fill-extrusion') {\n this.map.map.setPaintProperty(layerId, 'fill-extrusion-color', ['case', ['==', ['id'], featureId], this.selectionHoverColor, this.selectionModeExpressions[layerId] || this.originalPaintProperties[layerId]['fill-extrusion-color'] || ['get', 'color'] || 0]);\n }\n }\n }, {\n key: \"applySelectionHoverEffects\",\n value: function applySelectionHoverEffects(criteria) {\n var _this14 = this;\n // Use a single global mousemove handler instead of per-layer mouseenter/mouseleave\n // This approach continuously validates what's under the cursor and immediately invalidates stale hovers\n this.selectionHoverHandler = function (e) {\n if (!_this14.interactionEnabled || !_this14.selectionCriteria) return;\n\n // Query ALL features under the cursor\n var features = _this14.map.map.queryRenderedFeatures(e.point);\n\n // Find the first fill or fill-extrusion feature\n var fillFeature = features.find(function (f) {\n return f.layer.type === 'fill' || f.layer.type === 'fill-extrusion';\n });\n if (fillFeature) {\n var layerId = fillFeature.layer.id;\n var featureId = fillFeature.id;\n\n // Check if this is a different feature than currently hovered\n if (_this14.currentHoveredLayerId !== layerId || _this14.currentHoveredFeatureId !== featureId) {\n // INVALIDATE old hover if exists\n if (_this14.currentHoveredLayerId) {\n _this14.restoreLayerToSelectionMode(_this14.currentHoveredLayerId);\n }\n\n // Check if new feature is selectable\n if (_this14.featureMatchesCriteria(fillFeature.properties, _this14.selectionCriteria)) {\n // Apply hover to new selectable feature\n _this14.currentHoveredLayerId = layerId;\n _this14.currentHoveredFeatureId = featureId;\n _this14.applyHoverToFeature(layerId, featureId, fillFeature.layer.type);\n _this14.map.map.getCanvas().style.cursor = 'pointer';\n } else {\n // Non-selectable feature\n _this14.currentHoveredLayerId = null;\n _this14.currentHoveredFeatureId = null;\n _this14.map.map.getCanvas().style.cursor = 'default';\n }\n }\n } else {\n // No fill/extrusion features under cursor - clear any hover\n if (_this14.currentHoveredLayerId) {\n _this14.restoreLayerToSelectionMode(_this14.currentHoveredLayerId);\n _this14.currentHoveredLayerId = null;\n _this14.currentHoveredFeatureId = null;\n }\n _this14.map.map.getCanvas().style.cursor = 'default';\n }\n };\n\n // Add the single mousemove handler to the map\n this.map.map.on('mousemove', this.selectionHoverHandler);\n }\n }, {\n key: \"removeSelectionVisuals\",\n value: function removeSelectionVisuals() {\n var _this15 = this;\n // Restore all original paint properties\n for (var _i3 = 0, _Object$entries3 = Object.entries(this.originalPaintProperties); _i3 < _Object$entries3.length; _i3++) {\n var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i3], 2),\n layerId = _Object$entries3$_i[0],\n properties = _Object$entries3$_i[1];\n for (var _i4 = 0, _Object$entries4 = Object.entries(properties); _i4 < _Object$entries4.length; _i4++) {\n var _Object$entries4$_i = _slicedToArray(_Object$entries4[_i4], 2),\n property = _Object$entries4$_i[0],\n value = _Object$entries4$_i[1];\n if (property === 'source' || property === 'source-layer' || property === 'filter' || property === 'features') {\n // Skip non-paint properties\n continue;\n }\n if (value !== undefined) {\n this.map.map.setPaintProperty(layerId, property, value);\n }\n }\n\n // Restore visibility for symbol layers\n if (properties.source) {\n // This indicates it was a symbol layer we hid\n this.map.map.setLayoutProperty(layerId, 'visibility', 'visible');\n }\n }\n\n // Restore original filters for all layers AND reapply floor filtering\n var layers = this.map.map.getStyle().layers;\n var currentFloor = this.map.getCurrentFloor(); // Get current floor\n\n layers.forEach(function (layer) {\n if (layer.type !== 'background' && layer.type !== 'raster' && layer.type !== 'heatmap') {\n var _layerId2 = layer.id;\n\n // Skip our own selectable layers\n if (_layerId2.includes('selectable-')) {\n return;\n }\n\n // Restore original filter\n var originalFilter = _this15.map.map.getFilter(_layerId2);\n if (originalFilter) {\n // Check if this layer had an original filter stored\n var storedOriginalFilter = _this15.map.originalFilters[_layerId2];\n if (storedOriginalFilter !== undefined) {\n // Restore the original filter\n _this15.map.map.setFilter(_layerId2, storedOriginalFilter);\n\n // IMPORTANT: Reapply floor filtering after restoring original filter\n var floorFilter = ['==', ['get', '_floor'], currentFloor];\n if (storedOriginalFilter) {\n var combinedFilter = ['all', floorFilter, storedOriginalFilter];\n _this15.map.map.setFilter(_layerId2, combinedFilter);\n } else {\n _this15.map.map.setFilter(_layerId2, floorFilter);\n }\n }\n } else {\n // If no original filter, just apply floor filter\n var _floorFilter = ['==', ['get', '_floor'], currentFloor];\n _this15.map.map.setFilter(_layerId2, _floorFilter);\n }\n }\n });\n\n // Clear stored properties\n this.originalPaintProperties = {};\n this.selectionModeExpressions = {};\n\n // Remove selectable content layers\n this.map.removeSelectableContentLayers();\n\n // Remove grey fill layers\n this.removeGreyFillLayers();\n\n // Clear hover tracking\n this.currentHoveredLayerId = null;\n this.currentHoveredFeatureId = null;\n\n // Remove the global mousemove handler\n if (this.selectionHoverHandler) {\n this.map.map.off('mousemove', this.selectionHoverHandler);\n this.selectionHoverHandler = null;\n }\n this.pendingSymbolFeatures = [];\n this.pendingExtrusionFeatures = [];\n\n // Reset cursor\n this.map.map.getCanvas().style.cursor = 'default';\n }\n }, {\n key: \"_handleClick\",\n value: function _handleClick(e) {\n var _this16 = this;\n if (!this.interactionEnabled) return;\n var currentState = this.map.getCurrentState();\n if (currentState === 'selection') {\n // First check if clicking on confirmed selection features (for deselection)\n var confirmedFeatures = this.map.map.queryRenderedFeatures(e.point, {\n layers: ['confirmed-selection-fill-layer', 'confirmed-selection-outline-layer', 'confirmed-selection-icon-layer']\n });\n if (confirmedFeatures.length > 0) {\n var feature = confirmedFeatures[0];\n var featureId = feature.properties.feature_id; // Use feature_id consistently\n\n // Remove from confirmed selection layers using feature_id\n this.map.removeConfirmedSelectionFeature(featureId);\n\n // Fire deselection event\n this.map.fire('selection:featureDeselected', {\n feature: feature,\n placementId: feature.properties.placement_id || featureId // Keep placementId for UI compatibility\n });\n this.map.fire('selection:changed', {\n selectedContent: this._getSelectionFeaturesProperties(),\n selectionCount: this.map.getConfirmedSelectionFeatures().length\n });\n return;\n }\n\n // Then check for selectable features (for selection)\n var selectableFeatures = this.map.map.queryRenderedFeatures(e.point, {\n layers: ['selectable-fill-layer']\n });\n if (selectableFeatures.length > 0) {\n var _feature = selectableFeatures[0];\n var placementId = _feature.properties.placement_id;\n var _featureId = _feature.properties.feature_id; // Get feature_id for consistency\n\n // SINGLE-SELECT MODE: Optimistically remove previous selection\n if (!this.map.multiSelect) {\n var currentConfirmedFeatures = this.map.getConfirmedSelectionFeatures();\n if (currentConfirmedFeatures.length > 0) {\n var previousFeature = currentConfirmedFeatures[0];\n var previousFeatureId = previousFeature.properties.feature_id; // Use feature_id\n\n // Fire optimistic deselection event for previous feature\n this.map.fire('selection:featureDeselectedOptimistic', {\n placementId: previousFeature.properties.placement_id || previousFeatureId\n });\n }\n }\n\n // OPTIMISTIC SELECTION: Add to confirmed layers immediately for instant feedback\n this.map.addConfirmedSelectionFeature(_feature, !this.map.multiSelect);\n\n // Fire optimistic selection event immediately\n this.map.fire('selection:featureSelectedOptimistic', {\n feature: _feature\n });\n\n // Check if placement_id exists before attempting to fetch\n if (placementId && placementId !== 'unknown' && placementId !== '') {\n // Set loading state for content placement details\n this.map._stateCoordinator.setLoading(true, 'content');\n\n // Fetch content placement details and update selection context\n this.map.getContentPlacementDetails(placementId).then(function (details) {\n // Success - fire the full selection event to update the UI\n _this16.map.fire('selection:featureSelected', {\n feature: _feature,\n contentPlacement: details\n });\n _this16.map.fire('selection:changed', {\n selectedContent: _this16._getSelectionFeaturesProperties(),\n selectionCount: _this16.map.getConfirmedSelectionFeatures().length\n });\n })[\"catch\"](function (error) {\n console.error('❌ Error fetching content placement details:', error);\n\n // FAILURE - Remove from confirmed selection and show error\n _this16.map.removeConfirmedSelectionFeature(_featureId); // Use feature_id\n\n // Fire optimistic removal event\n _this16.map.fire('selection:featureDeselectedOptimistic', {\n placementId: placementId || _featureId\n });\n })[\"finally\"](function () {\n // Reset loading state\n _this16.map._stateCoordinator.setLoading(false, 'content');\n });\n } else {\n // Create a simple fallback content placement object\n var fallbackContentPlacement = _objectSpread({\n placement_id: _featureId,\n // Use feature_id as fallback\n name: _feature.properties.name || 'Unknown Feature',\n type: _feature.properties.type || 'unknown'\n }, _feature.properties);\n\n // Fire selection event with the simple fallback object\n this.map.fire('selection:featureSelected', {\n feature: _feature,\n contentPlacement: fallbackContentPlacement\n });\n this.map.fire('selection:changed', {\n selectedContent: this._getSelectionFeaturesProperties(),\n selectionCount: this.map.getConfirmedSelectionFeatures().length\n });\n }\n return;\n }\n } else {\n // Default behavior for other states\n var features = this.map.map.queryRenderedFeatures(e.point);\n var symbolFeatures = features.filter(function (feature) {\n return feature.layer.type === 'symbol';\n });\n if (symbolFeatures.length > 0) {\n var _feature2 = symbolFeatures[0];\n var _placementId = _feature2.properties.placement_id;\n\n // Check if placement_id exists before attempting to navigate\n if (_placementId && _placementId !== 'unknown' && _placementId !== '') {\n this.map.setToSelectedContentState([_placementId]);\n }\n }\n }\n }\n }, {\n key: \"featureMatchesCriteria\",\n value: function featureMatchesCriteria(properties, criteria) {\n for (var _i5 = 0, _Object$entries5 = Object.entries(criteria); _i5 < _Object$entries5.length; _i5++) {\n var _Object$entries5$_i = _slicedToArray(_Object$entries5[_i5], 2),\n property = _Object$entries5$_i[0],\n value = _Object$entries5$_i[1];\n var featureValue = properties[property];\n if (Array.isArray(value)) {\n // Check if feature value is in the array of allowed values\n if (!value.includes(featureValue)) {\n return false;\n }\n } else {\n // Check if feature value matches the single required value\n if (featureValue !== value) {\n return false;\n }\n }\n }\n return true;\n }\n }, {\n key: \"_setupCursorHandling\",\n value: function _setupCursorHandling() {\n var _this17 = this;\n // Method 1: Using mouseenter/mouseleave events (recommended)\n this.map.map.on('mouseenter', 'confirmed-selection-fill-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-fill-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n this.map.map.on('mouseenter', 'confirmed-selection-outline-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-outline-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n this.map.map.on('mouseenter', 'confirmed-selection-icon-layer', function () {\n _this17.map.map.getCanvas().style.cursor = 'pointer';\n });\n this.map.map.on('mouseleave', 'confirmed-selection-icon-layer', function () {\n _this17.map.map.getCanvas().style.cursor = '';\n });\n }\n }]);\n}(_core_Control__WEBPACK_IMPORTED_MODULE_1__[\"default\"]);\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (InteractionControl);\n\n//# sourceURL=webpack://waygomaps/./src/Controls/InteractionControl.js?");
618
618
 
619
619
  /***/ }),
620
620
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygo-maps",
3
- "version": "1.1.82",
3
+ "version": "1.1.83",
4
4
  "main": "dist/bundle.js",
5
5
  "files": [
6
6
  "dist/bundle.js",