@tomtom-org/maps-sdk 0.41.1 → 0.41.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.md +6 -6
- package/core/dist/THIRD_PARTY.txt +1 -1
- package/core/dist/core.es.js +1 -1
- package/core/dist/core.es.js.map +1 -1
- package/core/package.json +0 -3
- package/map/dist/THIRD_PARTY.txt +5 -5
- package/map/dist/index.d.ts +156 -10
- package/map/dist/map.es.js +1 -1
- package/map/dist/map.es.js.map +1 -1
- package/map/package.json +2 -4
- package/package.json +7 -5
- package/services/dist/THIRD_PARTY.txt +2 -2
- package/services/dist/services.es.js +1 -1
- package/services/dist/services.es.js.map +1 -1
- package/services/package.json +1 -4
package/map/dist/map.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.es.js","sources":["../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_freeGlobal.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_root.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Symbol.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getRawTag.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_objectToString.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseGetTag.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isObjectLike.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isSymbol.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arrayMap.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseToString.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isObject.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/identity.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isFunction.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_coreJsData.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isMasked.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_toSource.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsNative.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getNative.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getValue.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_WeakMap.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_shortOut.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_defineProperty.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseSetToString.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/constant.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_setToString.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isIndex.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseAssignValue.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/eq.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_assignValue.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_overRest.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isLength.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isArrayLike.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isPrototype.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsArguments.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isArguments.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/stubFalse.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseUnary.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_nodeUtil.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arrayLikeKeys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseTimes.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_overArg.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_nativeKeys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseKeys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/keys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_nativeKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/keysIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isKey.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_nativeCreate.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hashGet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hashHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Hash.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_assocIndexOf.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hashClear.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hashDelete.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hashSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_listCacheDelete.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_ListCache.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_listCacheClear.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_listCacheGet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_listCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_listCacheSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Map.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getMapData.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isKeyable.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_MapCache.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapCacheClear.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapCacheDelete.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapCacheGet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapCacheSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/memoize.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stringToPath.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_memoizeCapped.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_castPath.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/toString.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_toKey.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseGet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arrayPush.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isFlattenable.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/flatten.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseFlatten.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getPrototype.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isPlainObject.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Stack.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stackClear.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stackDelete.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stackGet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stackHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_stackSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/stubArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getSymbols.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arrayFilter.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getSymbolsIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseGetAllKeys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getAllKeys.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getAllKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_DataView.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Promise.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Set.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getTag.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_initCloneArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_Uint8Array.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneArrayBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneRegExp.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneSymbol.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_initCloneByTag.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneDataView.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cloneTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isMap.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsMap.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseClone.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arrayEach.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_SetCache.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_arraySome.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_setCacheAdd.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_setCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_equalArrays.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_cacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_mapToArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_setToArray.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_equalByTag.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_equalObjects.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsEqualDeep.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsEqual.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_isStrictComparable.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_matchesStrictComparable.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseMatches.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_getMatchData.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIsMatch.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseHasIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/hasIn.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_hasPath.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseMatchesProperty.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/get.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/property.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseProperty.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_basePropertyDeep.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseIteratee.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_parent.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseSlice.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isEmpty.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isEqual.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/isNil.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseUnset.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/last.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_customOmitClone.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/omit.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_flatRest.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_apply.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_copyObject.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_baseSet.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/pickBy.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_basePickBy.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/omitBy.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/negate.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/_basePullAt.js","../../node_modules/.pnpm/lodash-es@4.17.22/node_modules/lodash-es/remove.js","../src/shared/errorMessages.ts","../src/shared/imageUtils.ts","../src/shared/resources/index.ts","../src/shared/resources/pin.svg?raw","../src/shared/assertionUtils.ts","../src/shared/TomTomMapSource.ts","../src/shared/SourceWithLayers.ts","../src/shared/mapUtils.ts","../src/shared/AbstractMapModule.ts","../src/shared/EventsModule.ts","../src/shared/AbstractEventProxy.ts","../src/shared/eventUtils.ts","../src/shared/EventsProxy.ts","../src/shared/layers/layerIDs.ts","../src/shared/layers/sourcesIDs.ts","../src/pois/layers/poisLayers.ts","../src/pois/poiCategoryMapping.ts","../src/shared/layers/commonLayerProps.ts","../src/shared/layers/symbolLayers.ts","../src/shared/layers/utils.ts","../src/shared/layers/eventState.ts","../src/places/layers/placesLayers.ts","../src/places/resources/index.ts","../src/places/utils/toPinImageID.ts","../src/places/utils/preparePlacesForDisplay.ts","../src/places/PlacesModule.ts","../src/shared/mapLibreFilterUtils.ts","../src/pois/poiCategoryGroups.ts","../src/pois/POIsModule.ts","../src/base/layerGroups.ts","../src/base/BaseMapModule.ts","../src/base/types/baseMapModuleConfig.ts","../src/geometry/types/geometryDisplayProps.ts","../src/geometry/layers/geometryLayers.ts","../src/geometry/prepareGeometryForDisplay.ts","../src/geometry/GeometriesModule.ts","../src/hillshade/HillshadeModule.ts","../src/init/types/mapInit.ts","../src/routing/layers/shared.ts","../src/routing/layers/chargingStopLayers.ts","../src/routing/layers/guidanceLayers.ts","../src/routing/layers/routeFerrySectionLayers.ts","../src/routing/layers/routeMainLineLayers.ts","../src/routing/layers/routeTollRoadLayers.ts","../src/routing/layers/routeTrafficSectionLayers.ts","../src/routing/layers/routeTunnelSectionLayers.ts","../src/routing/layers/routeVehicleRestrictedLayers.ts","../src/routing/layers/summaryBubbleLayers.ts","../src/routing/types/waypointDisplayProps.ts","../src/routing/layers/waypointLayers.ts","../src/routing/layers/routingLayers.ts","../src/routing/resources/index.ts","../src/routing/resources/instruction-line-arrow.svg?raw","../src/routing/resources/summary-map-bubble.svg?raw","../src/routing/resources/traffic.svg?raw","../src/routing/util/config.ts","../src/routing/util/displayChargingStops.ts","../src/routing/util/displayTrafficSectionProps.ts","../src/routing/util/displayWaypoints.ts","../../node_modules/.pnpm/@turf+helpers@7.3.2/node_modules/@turf/helpers/dist/esm/index.js","../../node_modules/.pnpm/@turf+invariant@7.3.2/node_modules/@turf/invariant/dist/esm/index.js","../../node_modules/.pnpm/@turf+bearing@7.3.2/node_modules/@turf/bearing/dist/esm/index.js","../src/routing/util/guidance.ts","../src/routing/util/routeSections.ts","../src/routing/util/routeSelection.ts","../src/routing/util/routes.ts","../src/routing/RoutingModule.ts","../src/routing/resources/start.svg?raw","../src/routing/resources/circle.svg?raw","../src/routing/resources/finish.svg?raw","../src/init/styleInputBuilder.ts","../src/TomTomMap.ts","../src/init/buildMapOptions.ts","../src/shared/localization.ts","../src/traffic/types/trafficModuleConfig.ts","../src/traffic/filters/trafficFilters.ts","../src/traffic/TrafficFlowModule.ts","../src/traffic/TrafficIncidentsModule.ts","../src/utils/paddedBounds.ts"],"sourcesContent":["/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n","import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","import Symbol from './_Symbol.js';\nimport arrayMap from './_arrayMap.js';\nimport isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","import baseGetTag from './_baseGetTag.js';\nimport isObject from './isObject.js';\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nexport default isFunction;\n","import root from './_root.js';\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nexport default coreJsData;\n","import coreJsData from './_coreJsData.js';\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nexport default isMasked;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","import isFunction from './isFunction.js';\nimport isMasked from './_isMasked.js';\nimport isObject from './isObject.js';\nimport toSource from './_toSource.js';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nexport default baseIsNative;\n","import baseIsNative from './_baseIsNative.js';\nimport getValue from './_getValue.js';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nexport default getNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","import getNative from './_getNative.js';\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nexport default defineProperty;\n","import constant from './constant.js';\nimport defineProperty from './_defineProperty.js';\nimport identity from './identity.js';\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nexport default baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","import baseSetToString from './_baseSetToString.js';\nimport shortOut from './_shortOut.js';\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nexport default setToString;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","import defineProperty from './_defineProperty.js';\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nexport default baseAssignValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nexport default assignValue;\n","import apply from './_apply.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nexport default overRest;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","import isFunction from './isFunction.js';\nimport isLength from './isLength.js';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nexport default isArrayLike;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nexport default baseIsArguments;\n","import baseIsArguments from './_baseIsArguments.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nexport default isArguments;\n","import root from './_root.js';\nimport stubFalse from './stubFalse.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nexport default isBuffer;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","import baseGetTag from './_baseGetTag.js';\nimport isLength from './isLength.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nexport default baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nexport default nodeUtil;\n","import baseIsTypedArray from './_baseIsTypedArray.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nexport default isTypedArray;\n","import baseTimes from './_baseTimes.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isIndex from './_isIndex.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","import overArg from './_overArg.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nexport default nativeKeys;\n","import isPrototype from './_isPrototype.js';\nimport nativeKeys from './_nativeKeys.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeys;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n","import isObject from './isObject.js';\nimport isPrototype from './_isPrototype.js';\nimport nativeKeysIn from './_nativeKeysIn.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeysIn from './_baseKeysIn.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nexport default keysIn;\n","import isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nexport default isKey;\n","import getNative from './_getNative.js';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n","import hashClear from './_hashClear.js';\nimport hashDelete from './_hashDelete.js';\nimport hashGet from './_hashGet.js';\nimport hashHas from './_hashHas.js';\nimport hashSet from './_hashSet.js';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n","import eq from './eq.js';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nexport default assocIndexOf;\n","import nativeCreate from './_nativeCreate.js';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nexport default hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nexport default hashSet;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nexport default listCacheDelete;\n","import listCacheClear from './_listCacheClear.js';\nimport listCacheDelete from './_listCacheDelete.js';\nimport listCacheGet from './_listCacheGet.js';\nimport listCacheHas from './_listCacheHas.js';\nimport listCacheSet from './_listCacheSet.js';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nexport default listCacheSet;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n","import isKeyable from './_isKeyable.js';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nexport default getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","import mapCacheClear from './_mapCacheClear.js';\nimport mapCacheDelete from './_mapCacheDelete.js';\nimport mapCacheGet from './_mapCacheGet.js';\nimport mapCacheHas from './_mapCacheHas.js';\nimport mapCacheSet from './_mapCacheSet.js';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n","import Hash from './_Hash.js';\nimport ListCache from './_ListCache.js';\nimport Map from './_Map.js';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nexport default mapCacheClear;\n","import getMapData from './_getMapData.js';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default mapCacheDelete;\n","import getMapData from './_getMapData.js';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n","import getMapData from './_getMapData.js';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n","import getMapData from './_getMapData.js';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nexport default mapCacheSet;\n","import MapCache from './_MapCache.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nexport default memoize;\n","import memoizeCapped from './_memoizeCapped.js';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nexport default stringToPath;\n","import memoize from './memoize.js';\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nexport default memoizeCapped;\n","import isArray from './isArray.js';\nimport isKey from './_isKey.js';\nimport stringToPath from './_stringToPath.js';\nimport toString from './toString.js';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nexport default castPath;\n","import baseToString from './_baseToString.js';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n","import isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n","import castPath from './_castPath.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","import Symbol from './_Symbol.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nexport default isFlattenable;\n","import baseFlatten from './_baseFlatten.js';\n\n/**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\nfunction flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n}\n\nexport default flatten;\n","import arrayPush from './_arrayPush.js';\nimport isFlattenable from './_isFlattenable.js';\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nexport default baseFlatten;\n","import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n","import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n","import ListCache from './_ListCache.js';\nimport stackClear from './_stackClear.js';\nimport stackDelete from './_stackDelete.js';\nimport stackGet from './_stackGet.js';\nimport stackHas from './_stackHas.js';\nimport stackSet from './_stackSet.js';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n","import ListCache from './_ListCache.js';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nexport default stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","import ListCache from './_ListCache.js';\nimport Map from './_Map.js';\nimport MapCache from './_MapCache.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nexport default stackSet;\n","import root from './_root.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nexport default cloneBuffer;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nexport default getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nexport default getSymbolsIn;\n","import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n","import DataView from './_DataView.js';\nimport Map from './_Map.js';\nimport Promise from './_Promise.js';\nimport Set from './_Set.js';\nimport WeakMap from './_WeakMap.js';\nimport baseGetTag from './_baseGetTag.js';\nimport toSource from './_toSource.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nexport default getTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n","import Uint8Array from './_Uint8Array.js';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nexport default cloneArrayBuffer;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n","import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n","import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n","import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n","import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\nimport keysIn from './keysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n","import MapCache from './_MapCache.js';\nimport setCacheAdd from './_setCacheAdd.js';\nimport setCacheHas from './_setCacheHas.js';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","import SetCache from './_SetCache.js';\nimport arraySome from './_arraySome.js';\nimport cacheHas from './_cacheHas.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nexport default equalArrays;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","import Symbol from './_Symbol.js';\nimport Uint8Array from './_Uint8Array.js';\nimport eq from './eq.js';\nimport equalArrays from './_equalArrays.js';\nimport mapToArray from './_mapToArray.js';\nimport setToArray from './_setToArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nexport default equalByTag;\n","import getAllKeys from './_getAllKeys.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nexport default equalObjects;\n","import Stack from './_Stack.js';\nimport equalArrays from './_equalArrays.js';\nimport equalByTag from './_equalByTag.js';\nimport equalObjects from './_equalObjects.js';\nimport getTag from './_getTag.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nexport default baseIsEqualDeep;\n","import baseIsEqualDeep from './_baseIsEqualDeep.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nexport default baseIsEqual;\n","import isObject from './isObject.js';\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nexport default isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","import baseIsMatch from './_baseIsMatch.js';\nimport getMatchData from './_getMatchData.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nexport default baseMatches;\n","import isStrictComparable from './_isStrictComparable.js';\nimport keys from './keys.js';\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nexport default getMatchData;\n","import Stack from './_Stack.js';\nimport baseIsEqual from './_baseIsEqual.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport default baseIsMatch;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","import baseHasIn from './_baseHasIn.js';\nimport hasPath from './_hasPath.js';\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nexport default hasIn;\n","import castPath from './_castPath.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isIndex from './_isIndex.js';\nimport isLength from './isLength.js';\nimport toKey from './_toKey.js';\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nexport default hasPath;\n","import baseIsEqual from './_baseIsEqual.js';\nimport get from './get.js';\nimport hasIn from './hasIn.js';\nimport isKey from './_isKey.js';\nimport isStrictComparable from './_isStrictComparable.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\nimport toKey from './_toKey.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nexport default baseMatchesProperty;\n","import baseGet from './_baseGet.js';\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nexport default get;\n","import baseProperty from './_baseProperty.js';\nimport basePropertyDeep from './_basePropertyDeep.js';\nimport isKey from './_isKey.js';\nimport toKey from './_toKey.js';\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nexport default property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","import baseGet from './_baseGet.js';\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nexport default basePropertyDeep;\n","import baseMatches from './_baseMatches.js';\nimport baseMatchesProperty from './_baseMatchesProperty.js';\nimport identity from './identity.js';\nimport isArray from './isArray.js';\nimport property from './property.js';\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nexport default baseIteratee;\n","import baseGet from './_baseGet.js';\nimport baseSlice from './_baseSlice.js';\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nexport default parent;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","import baseKeys from './_baseKeys.js';\nimport getTag from './_getTag.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isArrayLike from './isArrayLike.js';\nimport isBuffer from './isBuffer.js';\nimport isPrototype from './_isPrototype.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n setTag = '[object Set]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\nfunction isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArrayLike(value) &&\n (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n return !value.length;\n }\n var tag = getTag(value);\n if (tag == mapTag || tag == setTag) {\n return !value.size;\n }\n if (isPrototype(value)) {\n return !baseKeys(value).length;\n }\n for (var key in value) {\n if (hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport default isEmpty;\n","import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nexport default isEqual;\n","/**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\nfunction isNil(value) {\n return value == null;\n}\n\nexport default isNil;\n","import castPath from './_castPath.js';\nimport last from './last.js';\nimport parent from './_parent.js';\nimport toKey from './_toKey.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\nfunction baseUnset(object, path) {\n path = castPath(path, object);\n\n // Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg\n var index = -1,\n length = path.length;\n\n if (!length) {\n return true;\n }\n\n var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');\n\n while (++index < length) {\n var key = path[index];\n\n // skip non-string keys (e.g., Symbols, numbers)\n if (typeof key !== 'string') {\n continue;\n }\n\n // Always block \"__proto__\" anywhere in the path if it's not expected\n if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {\n return false;\n }\n\n // Block \"constructor.prototype\" chains\n if (key === 'constructor' &&\n (index + 1) < length &&\n typeof path[index + 1] === 'string' &&\n path[index + 1] === 'prototype') {\n\n // Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')\n if (isRootPrimitive && index === 0) {\n continue;\n }\n\n return false;\n }\n }\n\n var obj = parent(object, path);\n return obj == null || delete obj[toKey(last(path))];\n}\n\nexport default baseUnset;\n","/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n","import isPlainObject from './isPlainObject.js';\n\n/**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\nfunction customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n}\n\nexport default customOmitClone;\n","import arrayMap from './_arrayMap.js';\nimport baseClone from './_baseClone.js';\nimport baseUnset from './_baseUnset.js';\nimport castPath from './_castPath.js';\nimport copyObject from './_copyObject.js';\nimport customOmitClone from './_customOmitClone.js';\nimport flatRest from './_flatRest.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\nvar omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n});\n\nexport default omit;\n","import flatten from './flatten.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\nfunction flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n}\n\nexport default flatRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","import assignValue from './_assignValue.js';\nimport baseAssignValue from './_baseAssignValue.js';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nexport default copyObject;\n","import assignValue from './_assignValue.js';\nimport castPath from './_castPath.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return object;\n }\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nexport default baseSet;\n","import arrayMap from './_arrayMap.js';\nimport baseIteratee from './_baseIteratee.js';\nimport basePickBy from './_basePickBy.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\n\n/**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\nfunction pickBy(object, predicate) {\n if (object == null) {\n return {};\n }\n var props = arrayMap(getAllKeysIn(object), function(prop) {\n return [prop];\n });\n predicate = baseIteratee(predicate);\n return basePickBy(object, props, function(value, path) {\n return predicate(value, path[0]);\n });\n}\n\nexport default pickBy;\n","import baseGet from './_baseGet.js';\nimport baseSet from './_baseSet.js';\nimport castPath from './_castPath.js';\n\n/**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\nfunction basePickBy(object, paths, predicate) {\n var index = -1,\n length = paths.length,\n result = {};\n\n while (++index < length) {\n var path = paths[index],\n value = baseGet(object, path);\n\n if (predicate(value, path)) {\n baseSet(result, castPath(path, object), value);\n }\n }\n return result;\n}\n\nexport default basePickBy;\n","import baseIteratee from './_baseIteratee.js';\nimport negate from './negate.js';\nimport pickBy from './pickBy.js';\n\n/**\n * The opposite of `_.pickBy`; this method creates an object composed of\n * the own and inherited enumerable string keyed properties of `object` that\n * `predicate` doesn't return truthy for. The predicate is invoked with two\n * arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omitBy(object, _.isNumber);\n * // => { 'b': '2' }\n */\nfunction omitBy(object, predicate) {\n return pickBy(object, negate(baseIteratee(predicate)));\n}\n\nexport default omitBy;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","import baseUnset from './_baseUnset.js';\nimport isIndex from './_isIndex.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\nfunction basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n } else {\n baseUnset(array, index);\n }\n }\n }\n return array;\n}\n\nexport default basePullAt;\n","import baseIteratee from './_baseIteratee.js';\nimport basePullAt from './_basePullAt.js';\n\n/**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\nfunction remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = baseIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n}\n\nexport default remove;\n","import type { StyleModule } from '../init';\n\n/**\n * @ignore\n */\nexport const notInTheStyle = (actionText: string): Error =>\n new Error(`Trying to ${actionText} while it is not in the map style. Did you exclude it when loading the map?`);\n\n/**\n * @ignore\n */\nexport const cannotAddStyleModuleToCustomStyle = (styleModule: StyleModule): Error =>\n new Error(`Trying to add style module ${styleModule} to the custom style!`);\n","/**\n * @ignore\n */\nexport const isDOMImageSupported = (): boolean =>\n typeof document != 'undefined' && typeof DOMParser != 'undefined' && typeof btoa != 'undefined';\n\n/**\n * @ignore\n */\nexport const svgToImg = (svgDomElement: SVGElement): HTMLImageElement => {\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const img = document.createElement('img');\n img.src = `data:image/svg+xml;base64,${btoa(new XMLSerializer().serializeToString(svgDomElement))}`;\n return img;\n};\n","import { SVGIconStyleOptions } from '../types';\nimport pinSvgRaw from './pin.svg?raw';\n\n/**\n * Helper function to parse SVG string (typically imported from ...svg?raw) to SVGElement\n * @ignore\n */\nexport const parseSvg = (svgString: string): SVGElement =>\n new DOMParser().parseFromString(svgString, 'image/svg+xml').documentElement as unknown as SVGElement;\n\n/**\n * @ignore\n */\nexport const pinSvg = (options: SVGIconStyleOptions | undefined): SVGElement => {\n const element = parseSvg(pinSvgRaw);\n // see pin.svg structure\n if (options?.fillColor) {\n element.querySelector('#background')?.setAttribute('fill', options.fillColor);\n }\n if (options?.outlineColor) {\n element.querySelector('#outline')?.setAttribute('fill', options.outlineColor);\n }\n if (options?.outlineOpacity !== undefined) {\n element.querySelector('#outline')?.setAttribute('fill-opacity', options.outlineOpacity.toString());\n }\n return element;\n};\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path id=\\\"background\\\" d=\\\"M63.95 137.516c6.556-12.737 19.098-21.09 30.828-29.388C110.046 97.324 120 79.603 120 59.574 120 26.671 93.138 0 60 0S0 26.671 0 59.574c0 20.029 9.954 37.75 25.22 48.55 11.734 8.302 24.274 16.652 30.83 29.388 1.706 3.316 6.194 3.316 7.9 0z\\\"\\n fill=\\\"#1988cf\\\"/>\\n <path id=\\\"outline\\\" d=\\\"M91.298 103.272C105.052 93.544 114 77.596 114 59.574c0-29.61-24.176-53.617-54-53.617S6 29.964 6 59.574c0 18.022 8.95 33.97 22.7 43.698l2.27 1.601c10.172 7.153 21.922 15.423 29.03 27.416 7.104-11.993 18.858-20.259 29.03-27.416l2.268-1.601zm1.468 6.274c-11.13 7.845-22.632 15.957-28.816 27.966-1.706 3.316-6.194 3.316-7.9 0-6.182-12.009-17.686-20.121-28.816-27.966l-2.016-1.422C9.954 97.324 0 79.603 0 59.574 0 26.671 26.862 0 60 0s60 26.671 60 59.574c0 20.029-9.954 37.75-25.222 48.55l-2.016 1.422z\\\"\\n fill-opacity=\\\".3\\\"/>\\n</svg>\\n\"","import { isNil } from 'lodash-es';\n\n/**\n * Throws an error if the given value is not defined.\n * @ignore\n */\nexport function assertDefined<T>(value: T | null | undefined): asserts value is T {\n if (isNil(value)) {\n throw new Error(`${value} must not be null/undefined. Something went wrong with its initialization.`);\n }\n}\n\n/**\n * Returns the given value as its defined type, or throws an error if it isn't defined.\n * @ignore\n * @throws\n */\nexport const asDefined = <T>(value: T | null | undefined): T => {\n assertDefined(value);\n return value;\n};\n","import type { Map, Source, SourceSpecification } from 'maplibre-gl';\n\n/**\n * Contains a source relevant for TomTom Maps SDK JS.\n * * The source might already be initialized from the map style, or it might be initialized here.\n * @ignore\n */\nexport class TomTomMapSource<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> {\n constructor(\n readonly id: string,\n readonly spec?: SOURCE_SPEC,\n public runtimeSource?: RUNTIME_SOURCE,\n ) {}\n\n ensureAddedToMap(map: Map) {\n if (!this.runtimeSource) {\n if (!map.getSource(this.id) && this.spec) {\n map.addSource(this.id, this.spec);\n }\n this.runtimeSource = map.getSource(this.id) as RUNTIME_SOURCE;\n }\n }\n}\n","import type { FeatureCollection } from 'geojson';\nimport type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n LayerSpecification,\n Map,\n Source,\n SourceSpecification,\n} from 'maplibre-gl';\nimport { asDefined } from './assertionUtils';\nimport { TomTomMapSource } from './TomTomMapSource';\nimport type {\n ByIdOrIndex,\n CleanEventStateOptions,\n CleanEventStatesOptions,\n LayerSpecFilter,\n LayerSpecWithSource,\n PutEventStateOptions,\n SourceWithLayerIDs,\n SourceWithLayers,\n ToBeAddedLayerSpec,\n ToBeAddedLayerSpecWithoutSource,\n} from './types';\n\n/**\n * Contains a source and the layers to render its data.\n * @ignore\n */\nexport abstract class AbstractSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n LAYER_SPEC extends LayerSpecification = LayerSpecification,\n> {\n readonly _layerSpecs: LAYER_SPEC[];\n private _sourceAndLayerIDs!: SourceWithLayerIDs;\n\n constructor(\n readonly map: Map,\n readonly source: TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>,\n layerSpecs: LAYER_SPEC[],\n ) {\n this._layerSpecs = layerSpecs;\n this._updateSourceAndLayerIDs();\n }\n\n isAnyLayerVisible(filter?: LayerSpecFilter): boolean {\n return this.getLayerSpecs(filter).some((layer) => this.isLayerVisible(layer));\n }\n\n areAllLayersVisible(filter?: LayerSpecFilter): boolean {\n return this.getLayerSpecs(filter).every((layer) => this.isLayerVisible(layer));\n }\n\n private getLayerSpecs(filter?: LayerSpecFilter) {\n return filter ? this._layerSpecs.filter(filter) : this._layerSpecs;\n }\n\n _updateSourceAndLayerIDs(): void {\n this._sourceAndLayerIDs = { sourceID: this.source.id, layerIDs: this._layerSpecs.map((layer) => layer.id) };\n }\n\n private isLayerVisible(layer: LayerSpecification): boolean {\n return this.map.getLayoutProperty(layer.id, 'visibility') !== 'none';\n }\n\n setLayersVisible(visible: boolean, filter?: LayerSpecFilter): void {\n for (const layerSpec of this.getLayerSpecs(filter)) {\n this.map.setLayoutProperty(layerSpec.id, 'visibility', visible ? 'visible' : 'none', { validate: false });\n }\n }\n\n get sourceAndLayerIDs(): SourceWithLayerIDs {\n return this._sourceAndLayerIDs;\n }\n\n equalSourceAndLayerIDs(other: SourceWithLayers): boolean {\n return (\n this.sourceAndLayerIDs.sourceID === other.sourceAndLayerIDs.sourceID &&\n this.sourceAndLayerIDs.layerIDs.length === other.sourceAndLayerIDs.layerIDs.length &&\n this.sourceAndLayerIDs.layerIDs.every((id, index) => id === other.sourceAndLayerIDs.layerIDs[index])\n );\n }\n}\n\n/**\n * @ignore\n * @param loadedMap\n * @param sourceIDs\n */\nexport const filterLayersBySources = (loadedMap: Map, sourceIDs: string[]): LayerSpecWithSource[] =>\n loadedMap\n .getStyle()\n .layers.filter((layer) => sourceIDs.includes((layer as LayerSpecWithSource)?.source)) as LayerSpecWithSource[];\n\n/**\n * Source with layers which are coming from the downloaded TT map style.\n * * Examples are parts of the base map, traffic, pois, and hillshade.\n * @ignore\n */\nexport class StyleSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> extends AbstractSourceWithLayers<SourceSpecification, RUNTIME_SOURCE> {\n constructor(map: Map, runtimeSource: RUNTIME_SOURCE, filter?: LayerSpecFilter) {\n let layers = filterLayersBySources(map, [runtimeSource.id]);\n if (filter) {\n layers = layers.filter(filter);\n }\n super(\n map,\n new TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>(\n runtimeSource.id,\n map.getStyle().sources[runtimeSource.id] as SOURCE_SPEC,\n runtimeSource,\n ),\n layers,\n );\n }\n}\n\n/**\n * Source with layers which originally is not in the map style, but it's to be added after the map is initialized.\n * @ignore\n */\nexport class AddedSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> extends AbstractSourceWithLayers<SOURCE_SPEC, RUNTIME_SOURCE, ToBeAddedLayerSpec> {\n constructor(map: Map, sourceId: string, sourceSpec: SOURCE_SPEC, layerSpecs: ToBeAddedLayerSpecWithoutSource[]) {\n super(\n map,\n new TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>(sourceId, sourceSpec),\n // We ensure the source ID is assigned to the layers:\n layerSpecs.map((layerSpec) => ({ ...layerSpec, source: sourceId }) as ToBeAddedLayerSpec),\n );\n }\n\n private ensureLayersAddedToMap(): void {\n for (const layerSpec of this._layerSpecs) {\n if (!this.map.getLayer(layerSpec.id)) {\n this.map.addLayer(layerSpec, layerSpec.beforeID);\n }\n }\n }\n\n ensureAddedToMapWithVisibility(visible: boolean, addLayersToMap: boolean): void {\n this.source.ensureAddedToMap(this.map);\n if (addLayersToMap) {\n this.ensureLayersAddedToMap();\n this.setLayersVisible(visible);\n }\n }\n}\n\nconst emptyFeatureCollection: FeatureCollection = { type: 'FeatureCollection', features: [] };\n\n/**\n * @ignore\n */\nexport class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<\n GeoJSONSourceSpecification,\n GeoJSONSource\n> {\n shownFeatures: T = emptyFeatureCollection as T;\n\n constructor(map: Map, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap = true) {\n // MapLibre does not reuse the given feature ID. Either we generate it on the fly or use the one from properties via promotedId value.\n // We must generate \"id\" property based on the feature id on the fly on \"prepareForDisplay\" functions.\n super(map, sourceId, { type: 'geojson', data: emptyFeatureCollection, promoteId: 'id' }, layerSpecs);\n this.ensureAddedToMapWithVisibility(false, addLayersToMap);\n }\n\n show(featureCollection: T): void {\n this.shownFeatures = featureCollection;\n asDefined(this.source.runtimeSource).setData(featureCollection);\n this.setLayersVisible(!!featureCollection.features.length);\n }\n\n clear(): void {\n this.show(emptyFeatureCollection as T);\n }\n\n private findFeature(options: ByIdOrIndex) {\n if ('index' in options) {\n return this.shownFeatures.features[options.index];\n } else if ('id' in options) {\n return this.shownFeatures.features.find((f) => f.id === options.id);\n }\n return undefined;\n }\n\n putEventState(options: PutEventStateOptions) {\n const mode = options.mode ?? 'put';\n if (mode === 'put') {\n for (const feature of this.shownFeatures.features) {\n if (feature.properties?.eventState === options.state) {\n delete feature.properties.eventState;\n }\n }\n }\n\n const feature = this.findFeature(options);\n if (feature) {\n feature.properties = { ...feature.properties, eventState: options.state };\n }\n\n if (options.show !== false) {\n this.show(this.shownFeatures);\n }\n }\n\n cleanEventState(options: CleanEventStateOptions) {\n const feature = this.findFeature(options);\n\n if (feature?.properties?.eventState) {\n delete feature?.properties?.eventState;\n if (options?.show !== false) {\n this.show(this.shownFeatures);\n }\n }\n }\n\n cleanEventStates(options?: CleanEventStatesOptions) {\n let changed = false;\n for (const feature of this.shownFeatures.features) {\n if (!options?.states || options.states.includes(feature.properties?.eventState)) {\n delete feature.properties?.eventState;\n changed = true;\n }\n }\n\n if (options?.show !== false && changed) {\n this.show(this.shownFeatures);\n }\n }\n}\n","import type { GlobalConfig } from '@tomtom-org/maps-sdk/core';\nimport { generateTomTomHeaders } from '@tomtom-org/maps-sdk/core';\nimport type {\n FilterSpecification,\n Map,\n MapGeoJSONFeature,\n RequestParameters,\n ResourceType,\n StyleImageMetadata,\n} from 'maplibre-gl';\nimport { InternalTomTomMapParams, StandardStyle, StandardStyleID, StyleInput, StyleModule } from '../init';\nimport type { TomTomMap } from '../TomTomMap';\nimport { cannotAddStyleModuleToCustomStyle } from './errorMessages';\nimport { svgToImg } from './imageUtils';\nimport { parseSvg } from './resources';\nimport { AbstractSourceWithLayers, filterLayersBySources } from './SourceWithLayers';\nimport type { LightDark, ToBeAddedLayerSpec, ToBeAddedLayerSpecWithoutSource } from './types';\n\n/**\n * Wait until the map is ready.\n * @param tomtomMap The TomTomMap instance.\n * @returns {Promise<boolean>} Returns a Promise<boolean>\n */\nexport const waitUntilMapIsReady = async (tomtomMap: TomTomMap): Promise<void> => {\n if (!tomtomMap.mapReady) {\n await tomtomMap.mapLibreMap.once('styledata');\n // Recursively waiting for map to be ready (in case of style changes quickly in succession):\n await waitUntilMapIsReady(tomtomMap);\n }\n};\n\n/**\n * Wait until the source is ready.\n * @param tomtomMap The TomTomMap instance.\n * @param sourceId we want to check for.\n * @returns {Promise<boolean>} Returns a Promise<boolean>\n */\nexport const waitUntilSourceIsLoaded = async (tomtomMap: TomTomMap, sourceId: string): Promise<void> => {\n if (!tomtomMap.mapLibreMap.getSource(sourceId) || !tomtomMap.mapLibreMap.isSourceLoaded(sourceId)) {\n await tomtomMap.mapLibreMap.once('sourcedata');\n }\n};\n\n/**\n * Deserializes the properties from MapLibre features.\n * * Maplibre has a bug where all properties from a feature are stringified.\n * See: {@link} https://github.com/maplibre/maplibre-gl-js/issues/1325\n *\n * @param features An Array with MapGeoJSONFeatures objects\n *\n * @ignore\n */\nexport const deserializeFeatures = (features: MapGeoJSONFeature[]): void => {\n for (const feature of features) {\n if (!feature || !Object.keys(feature.properties).length) {\n continue;\n }\n\n for (const key in feature.properties) {\n if (typeof feature.properties[key] === 'string') {\n try {\n feature.properties[key] = JSON.parse(feature.properties[key]);\n } catch (_e) {\n // We ignore the error if the object can't be parsed and continue.\n // console.debug('Cannot deserialize feature property', key, 'with value', feature.properties[key], e);\n }\n }\n }\n }\n};\n\n/**\n * Inject TomTom custom headers to requests to TomTom.\n *\n * @ignore\n * @param params Global SDK Map configuration\n */\nexport const injectTomTomHeaders =\n (params: Partial<GlobalConfig>) =>\n (url: string, resourceType?: ResourceType): RequestParameters => {\n if (url.includes('tomtom.com')) {\n if (resourceType === 'Image') {\n return { url };\n }\n return { url, headers: { ...generateTomTomHeaders(params) } };\n }\n return { url };\n };\n\n/**\n * Compares two MapLibre features by ID.\n * @ignore\n */\nexport const areBothDefinedAndEqual = (\n featureA: MapGeoJSONFeature | undefined,\n featureB: MapGeoJSONFeature | undefined,\n): boolean => !!featureA && !!featureB && featureA.id === featureB.id;\n\ntype LayerProps = {\n id: string;\n layout?: any;\n paint?: any;\n minzoom?: number;\n maxzoom?: number;\n filter?: FilterSpecification;\n};\n\n/**\n * Applies the layout and paint properties from newLayoutPaint\n * while unsetting (setting as undefined) the ones from previousSpec which no longer exist in newLayoutPaint.\n * * This allows for a quick change of a layer visuals without removing-re-adding the layer.\n * @ignore\n * @param newLayerProps The new layer from which to apply layout/pain props.\n * @param prevLayerProps The previous layer to ensure layout/paint props are removed.\n * @param map\n */\nexport const changeLayerProps = (newLayerProps: LayerProps, prevLayerProps: LayerProps, map: Map) => {\n const layerId = newLayerProps.id;\n if (newLayerProps.maxzoom !== prevLayerProps.maxzoom || newLayerProps.minzoom !== prevLayerProps.minzoom) {\n map.setLayerZoomRange(\n layerId,\n newLayerProps.minzoom ?? map.getMinZoom(),\n newLayerProps.maxzoom ?? map.getMaxZoom(),\n );\n }\n map.setFilter(layerId, newLayerProps.filter, { validate: false });\n for (const property of Object.keys(prevLayerProps.layout ?? [])) {\n if (!newLayerProps.layout?.[property]) {\n map.setLayoutProperty(layerId, property, undefined, { validate: false });\n }\n }\n for (const property of Object.keys(prevLayerProps.paint ?? [])) {\n if (!newLayerProps.paint?.[property]) {\n map.setPaintProperty(layerId, property, undefined, { validate: false });\n }\n }\n for (const [property, value] of Object.entries(newLayerProps.paint ?? [])) {\n map.setPaintProperty(layerId, property, value, { validate: false });\n }\n\n for (const [property, value] of Object.entries(newLayerProps.layout ?? [])) {\n map.setLayoutProperty(layerId, property, value, { validate: false });\n }\n};\n\n/**\n * Applies the layer properties from each layer of newLayoutPaints\n * while unsetting (setting as undefined) the ones from the corresponding layer from prevLayoutPaints\n * which no longer exist in the new one.\n * * The two layer inputs are expected to be parallel arrays.\n * * This allows for quick changes of layer visuals without removing-re-adding the layers.\n * @ignore\n */\nexport const changeLayersProps = (newLayerProps: LayerProps[], prevLayerProps: LayerProps[], map: Map) => {\n newLayerProps.forEach((layoutPaint, index) => changeLayerProps(layoutPaint, prevLayerProps[index], map));\n};\n\n/**\n * Handles new layer specs for the provided source. It will remove layers no longer present,\n * update existing layers and add new one if needed to the source.\n * Adding layers to the map needs to be done correctly, so after calling this method, you should call addLayersInCorrectOrder.\n * If ID of layer to be added already is present on map, MapLibre will through exception.\n * @param newLayersSpecs new layer specification for provided source.\n * @param oldLayersSpecs current layer specification for provided source.\n * @param sourceWithLayers provided source that contains layers.\n * @param map provided map libre map object.\n * @ignore\n */\nexport const updateLayersAndSource = (\n newLayersSpecs: ToBeAddedLayerSpecWithoutSource[],\n oldLayersSpecs: ToBeAddedLayerSpecWithoutSource[],\n sourceWithLayers: AbstractSourceWithLayers,\n map: Map,\n): void => {\n // map layers by id in object for easier access, reduces number of loops\n const newLayersMap: Record<string, ToBeAddedLayerSpecWithoutSource> = newLayersSpecs.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {},\n );\n const oldLayersMap: Record<string, ToBeAddedLayerSpecWithoutSource> = oldLayersSpecs.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {},\n );\n\n // we need to store layers in four arrays, layers to add ID, layers to remove ID and layers to update\n const layersToAdd: string[] = [];\n const layersToRemove: string[] = [];\n const newLayersToUpdate: ToBeAddedLayerSpecWithoutSource[] = [];\n const oldLayersToUpdate: ToBeAddedLayerSpecWithoutSource[] = [];\n Object.keys(newLayersMap).forEach((key) => {\n if (oldLayersMap[key]) {\n newLayersToUpdate.push(newLayersMap[key]);\n oldLayersToUpdate.push(oldLayersMap[key]);\n } else {\n layersToAdd.push(key);\n }\n });\n Object.keys(oldLayersMap).forEach((key) => {\n if (!newLayersMap[key]) {\n layersToRemove.push(key);\n }\n });\n\n // remove the old layers no longer present in new layer specification\n const layerSpecs: ToBeAddedLayerSpec[] = sourceWithLayers._layerSpecs;\n layersToRemove.forEach((layerId) => {\n map.removeLayer(layerId);\n for (let i = 0; i < layerSpecs.length; i++) {\n if (layerSpecs[i].id === layerId) {\n layerSpecs.splice(i, 1);\n break;\n }\n }\n });\n // add new layers\n layersToAdd.forEach((layerId) => {\n // add layer spec and map\n const toBeAddedLayerSpec: ToBeAddedLayerSpec = {\n ...newLayersMap[layerId],\n source: sourceWithLayers.source.id,\n } as ToBeAddedLayerSpec;\n layerSpecs.push(toBeAddedLayerSpec);\n });\n sourceWithLayers._updateSourceAndLayerIDs();\n // update existing layers\n changeLayersProps(newLayersToUpdate, oldLayersToUpdate, map);\n};\n\n/**\n * Adds the given layers to the map ensuring they respect their \"beforeID\" properties.\n * * We need to make sure that layers are added in the correct Z order because one layer may depend on another layer.\n * @param layersToAdd\n * @param map MapLibre map\n * @ignore\n */\nexport const addLayers = (layersToAdd: ToBeAddedLayerSpec[], map: Map): void => {\n const layerIdsAlreadyOnMap = new Set<string>();\n const addLayer = (layer: ToBeAddedLayerSpec): void => {\n // we can safely add this layer\n if (!map.getLayer(layer.id)) {\n map.addLayer({ ...layer, layout: { ...layer.layout, visibility: 'none' } }, layer.beforeID);\n }\n layerIdsAlreadyOnMap.add(layer.id);\n };\n\n const mapIdDependency: Record<string, ToBeAddedLayerSpec[]> = {};\n\n layersToAdd.forEach((layer) => {\n if (layer.beforeID) {\n if (layerIdsAlreadyOnMap.has(layer.beforeID) || map.getLayer(layer.beforeID)) {\n layerIdsAlreadyOnMap.add(layer.beforeID);\n addLayer(layer);\n } else if (mapIdDependency[layer.beforeID]) {\n // we cannot add this layer yet\n mapIdDependency[layer.beforeID].push(layer);\n } else {\n mapIdDependency[layer.beforeID] = [layer];\n }\n } else {\n addLayer(layer);\n }\n });\n\n // try to process the rest of layers\n while (Object.keys(mapIdDependency).length > 0) {\n const idsWeCanProcess = Object.keys(mapIdDependency).filter((id) => layerIdsAlreadyOnMap.has(id));\n if (idsWeCanProcess.length === 0) {\n throw Error(`Circular dependency for before Ids ${JSON.stringify(Object.keys(mapIdDependency))}`);\n }\n idsWeCanProcess.forEach((id) => {\n mapIdDependency[id].forEach((layer) => addLayer(layer));\n delete mapIdDependency[id];\n });\n }\n};\n\n/**\n * Adding a style-based module to the given style input, if possible.\n * * This results in a style input which will include such style-based module (e.g. include traffic layers).\n * @param style which we want to update.\n * @param styleModule module we want to add.\n * @ignore\n */\nexport const updateStyleWithModule = (style: StyleInput | undefined, styleModule: StyleModule): StyleInput => {\n switch (typeof style) {\n case 'undefined':\n return { type: 'standard', include: [styleModule] };\n case 'string':\n // this is a standard style\n return { type: 'standard', id: style, include: [styleModule] };\n default:\n if (style.type === 'standard') {\n if (style.include) {\n return { ...style, include: [...style.include, styleModule] };\n }\n return { ...style, include: [styleModule] };\n }\n throw cannotAddStyleModuleToCustomStyle(styleModule);\n }\n};\n\n/**\n * Checks if the source is missing and try to add it to the map by reloading its style.\n * @param map the TomTom map instance.\n * @param sourceId id of the source.\n * @param styleModule style module of the source.\n * @ignore\n */\nexport const ensureAddedToStyle = async (map: TomTomMap, sourceId: string, styleModule: StyleModule): Promise<void> => {\n if (!map.mapLibreMap.getSource(sourceId)) {\n const mapLibreMap = map.mapLibreMap;\n if (!mapLibreMap.isStyleLoaded()) {\n // we let the map settle before changing its style again, so the previous style/data load goes smoother:\n await mapLibreMap.once('idle');\n }\n map.setStyle(updateStyleWithModule(map.getStyle(), styleModule));\n await waitUntilSourceIsLoaded(map, sourceId);\n\n await mapLibreMap.once('styledata');\n // we're loading a bunch of style layers to the map, and we hide them all by default:\n // see TomTomMap.handleStyleData for similar logic\n for (const layer of filterLayersBySources(mapLibreMap, [sourceId])) {\n mapLibreMap.setLayoutProperty(layer.id, 'visibility', 'none', { validate: false });\n }\n // Since we just changed the style visibility, we ensure to wait until the style data is changed before returning to prevent race conditions:\n await mapLibreMap.once('styledata');\n }\n};\n\n/**\n * Sets the given image on the map (loading it if necessary), either adding or updating it.\n * @ignore\n */\nexport const addOrUpdateImage = async (\n mode: 'if-not-in-sprite' | 'add-or-update',\n imageId: string,\n imageToLoad: string | HTMLImageElement,\n map: Map,\n options?: Partial<StyleImageMetadata>,\n) => {\n // defensive check (should not happen but we cannot let it crash):\n if (!imageToLoad) {\n console.warn(`addOrUpdateImage called with empty image for ID ${imageId}`);\n return;\n }\n\n // Helper function to add or update the image\n const addOrUpdateToMap = (imgElement: HTMLImageElement | ImageData | ImageBitmap) => {\n const imageExists = map.hasImage(imageId);\n if (imageExists && mode == 'add-or-update') {\n map.updateImage(imageId, imgElement);\n } else if (!imageExists) {\n map.addImage(imageId, imgElement, options);\n }\n };\n\n const ensureImageLoaded = (imgElement: HTMLImageElement) => {\n // An image is successfully loaded if it's complete AND has valid dimensions\n // (naturalWidth > 0 ensures the image didn't fail to load)\n if (imgElement.complete) {\n if (imgElement.naturalWidth > 0) {\n addOrUpdateToMap(imgElement);\n } else {\n // Image is complete but failed to load\n console.warn(`Failed to load image for ID ${imageId}`);\n }\n } else {\n imgElement.onload = () => addOrUpdateToMap(imgElement);\n imgElement.onerror = () => console.warn(`Failed to load image for ID ${imageId}`);\n }\n };\n\n if (typeof imageToLoad === 'string') {\n if (imageToLoad.includes('<svg')) {\n // Supporting raw SVGs:\n const imgElement = svgToImg(parseSvg(imageToLoad));\n ensureImageLoaded(imgElement);\n } else {\n // Expecting image URL, so the image needs to be downloaded first:\n addOrUpdateToMap((await map.loadImage(imageToLoad)).data);\n }\n } else {\n // Expecting HTMLImageElement, wait for it to be loaded\n ensureImageLoaded(imageToLoad);\n }\n};\n\n/**\n * Returns the light/dark theme for a known standard style.\n * @param standardStyleID\n */\nconst getStandardStyleTheme = (standardStyleID: StandardStyleID): LightDark => {\n switch (standardStyleID) {\n case 'standardDark':\n case 'drivingDark':\n case 'monoDark':\n case 'satellite':\n return 'dark';\n default:\n return 'light';\n }\n};\n\n/**\n * Returns the light/dark theme for a given style input.\n * * Unknown standard styles and custom styles are considered as 'light' theme.\n * @param styleInput The style input to check. If not provided, 'light' is returned.\n * @ignore\n */\nexport const getStyleLightDarkTheme = (styleInput?: StyleInput): LightDark => {\n if (typeof styleInput === 'string') {\n return getStandardStyleTheme(styleInput);\n }\n const standardStyle = styleInput as StandardStyle;\n if (standardStyle?.id) {\n return getStandardStyleTheme(standardStyle.id);\n }\n return 'light';\n};\n\n/**\n * Adds the large POI sprite to the map style.\n * @ignore\n */\nexport const addPinCategoriesSpriteToStyle = async (mapParams: InternalTomTomMapParams, mapLibreMap: Map) => {\n mapLibreMap.setSprite(\n `${mapParams.commonBaseURL}/maps/orbis/assets/sprites/2.*/sprite?key=${mapParams.apiKey}&poi=poi_${getStyleLightDarkTheme(mapParams.style)}&apiVersion=1&apiChannel=preview`,\n { validate: false },\n );\n};\n","import type { Map } from 'maplibre-gl';\nimport type { TomTomMap } from '../TomTomMap';\nimport type { EventsProxy } from './EventsProxy';\nimport { waitUntilMapIsReady } from './mapUtils';\nimport type { MapModuleCommonConfig, SourcesWithLayers, SourceWithLayerIDs } from './types';\n\n/**\n * Whether a map module is based on a map style or on added GeoJSON data.\n */\ntype MapModuleSource = 'style' | 'geojson';\n\n/**\n * Base class for all Maps SDK map modules.\n *\n * This abstract class provides the foundation for creating map modules that can display\n * and manage various types of data on a TomTom map. It handles module lifecycle management,\n * including initialization, configuration updates, and automatic restoration after map style changes.\n *\n * @remarks\n * All map modules extend this class to ensure consistent behavior across the SDK.\n * The class manages the module's sources, layers, and configuration, automatically\n * handling map style changes by restoring the module's state when needed.\n *\n * @typeParam SOURCES_WITH_LAYERS - The type defining the sources and layers used by this module\n * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed. When defined, must extend MapModuleCommonConfig.\n *\n * @example\n * ```typescript\n * class CustomModule extends AbstractMapModule<MySourcesWithLayers, MyConfig> {\n * constructor(tomtomMap: TomTomMap, config?: MyConfig) {\n * super('geojson', tomtomMap, config);\n * }\n * // Implement abstract methods...\n * }\n * ```\n *\n * @group Shared\n */\nexport abstract class AbstractMapModule<\n SOURCES_WITH_LAYERS extends SourcesWithLayers,\n CFG extends MapModuleCommonConfig | undefined = undefined,\n> {\n private readonly sourceType: MapModuleSource;\n /**\n * @ignore\n */\n protected readonly tomtomMap: TomTomMap;\n /**\n * @ignore\n */\n protected readonly eventsProxy: EventsProxy;\n /**\n * @ignore\n */\n protected readonly mapLibreMap: Map;\n /**\n * @ignore\n */\n protected sourcesWithLayers!: SOURCES_WITH_LAYERS;\n /**\n * @ignore\n */\n protected _sourceAndLayerIDs!: Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;\n /**\n * @ignore\n */\n protected config?: CFG;\n /**\n * @ignore\n */\n protected _initializing = true;\n\n /**\n * Indicates that this module is currently adding its sources and layers to the map, so during this time it might not function properly.\n * @see waitUntilModuleReady\n * @private\n */\n private moduleReady = false;\n\n /**\n * Builds this module based on a given Maps SDK map.\n * @param tomtomMap The map. It may or may not be initialized at this stage,\n * but the module ensures to initialize itself once it is.\n * @param sourceType Whether the module is based on a map style or on added GeoJSON data.\n * @param config Optional configuration to initialize directly as soon as the map is ready.\n */\n protected constructor(sourceType: MapModuleSource, tomtomMap: TomTomMap, config?: CFG) {\n this.sourceType = sourceType;\n this.tomtomMap = tomtomMap;\n this.eventsProxy = tomtomMap._eventsProxy;\n this.mapLibreMap = tomtomMap.mapLibreMap;\n this.initSourcesWithLayers(config);\n this.applyConfig(config);\n this.tomtomMap.addStyleChangeHandler({\n onStyleAboutToChange: () => {\n this.moduleReady = false;\n },\n onStyleChanged: () => this.restoreDataAndConfig(),\n });\n this._initializing = false;\n }\n\n /**\n * Initializes the sources with layers of this module.\n * @param config The optional configuration for the module.\n * @param restore Whether we are restoring an existing module after the map style got reloaded.\n * @protected\n * @ignore\n */\n protected initSourcesWithLayers(config?: CFG, restore?: boolean): void {\n this.moduleReady = false;\n this.sourcesWithLayers = this._initSourcesWithLayers(config, restore);\n this._sourceAndLayerIDs = Object.fromEntries(\n Object.entries(this.sourcesWithLayers).map(([name, sourceWithLayers]) => [\n name,\n sourceWithLayers.sourceAndLayerIDs,\n ]),\n ) as Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;\n if (restore) {\n this.eventsProxy.updateIfRegistered(this.sourcesWithLayers);\n }\n // Only if the map is still ready, we consider that the module is ready.\n // Otherwise, we assume there's a quick style change in progress and expect that'll trigger the module to restore itself again.\n if (this.tomtomMap.mapReady) {\n this.moduleReady = true;\n }\n }\n\n /**\n * Initializes the sources with layers for the specific module.\n * @protected\n * @ignore\n */\n protected abstract _initSourcesWithLayers(config?: CFG, restore?: boolean): SOURCES_WITH_LAYERS;\n\n protected async waitUntilModuleReady(): Promise<void> {\n await waitUntilMapIsReady(this.tomtomMap);\n if (!this.moduleReady) {\n await new Promise<void>((resolve) => {\n const interval = setInterval(() => {\n if (this.tomtomMap.mapReady && this.moduleReady) {\n clearInterval(interval);\n resolve();\n }\n }, 200);\n });\n }\n }\n\n /**\n * Applies a configuration to this module.\n *\n * This method updates the module's behavior and appearance based on the provided configuration.\n * The configuration is stored internally and will be automatically reapplied if the map style changes.\n *\n * @param config - The configuration object to apply to the module. Pass `undefined` to reset\n * the configuration to default values.\n *\n * @remarks\n * When a configuration is applied, the module updates its visual representation and behavior\n * accordingly. The configuration persists across map style changes, ensuring consistent\n * module behavior even when the map's base style is modified.\n *\n * @example\n * ```typescript\n * // Apply a new configuration\n * myModule.applyConfig({ visible: true, opacity: 0.8 });\n *\n * // Reset to default configuration\n * myModule.applyConfig(undefined);\n * ```\n *\n * @see {@link resetConfig} for a convenience method to reset configuration\n * @see {@link getConfig} to retrieve the current configuration\n */\n applyConfig(config: CFG | undefined) {\n this.config = this._applyConfig(config);\n }\n\n /**\n * Internal implementation to apply config for the specific module.\n * @param config The config to apply. this.config contains the previous configuration (if any).\n * Once the method returns config, it will be assigned to this.config.\n * @protected\n * @ignore\n */\n protected abstract _applyConfig(config: CFG | undefined): CFG | undefined;\n\n /**\n * Resets the configuration of this module to its default values.\n *\n * This is a convenience method that clears any previously applied configuration\n * and restores the module to its initial state. This is equivalent to calling\n * `applyConfig(undefined)`.\n *\n * @remarks\n * After calling this method, the module will behave as if no configuration was ever applied.\n * Any custom settings, styling, or behavior modifications will be removed and replaced\n * with default values.\n *\n * @example\n * ```typescript\n * // Apply some configuration\n * myModule.applyConfig({ visible: true, opacity: 0.5 });\n *\n * // Later, reset to defaults\n * myModule.resetConfig();\n * ```\n *\n * @see {@link applyConfig} to apply a new configuration\n * @see {@link getConfig} to retrieve the current configuration before resetting\n */\n resetConfig(): void {\n this.applyConfig(undefined);\n }\n\n private async restoreDataAndConfig() {\n // defensively declaring the module as not ready to prevent race conditions:\n this.moduleReady = false;\n if (this.sourceType === 'geojson') {\n // (We use setTimeout to compensate for a MapLibre glitch where symbol layers can't get added right after\n // a styledata event. With this setTimeout, we wait just a tiny bit more which mitigates the issue)\n setTimeout(() => this.restoreDataAndConfigImpl(), 400);\n } else {\n this.restoreDataAndConfigImpl();\n }\n }\n\n /**\n * implementation needed to restore the module state (data and config applied to the module).\n * to be used to restore module state after map style change\n * @protected\n * @ignore\n */\n protected restoreDataAndConfigImpl(): void {\n this.initSourcesWithLayers(this.config, true);\n this._applyConfig(this.config);\n }\n\n /**\n * Retrieves a copy of the current module configuration.\n *\n * This method returns a shallow copy of the configuration object that is currently\n * applied to the module. If no configuration has been applied, it returns `undefined`.\n *\n * @returns A shallow copy of the current configuration object, or `undefined` if no\n * configuration is currently applied. The returned object is a copy to prevent\n * unintended modifications to the internal state.\n *\n * @remarks\n * The returned configuration object is a shallow copy, which means that while the\n * top-level properties are copied, any nested objects or arrays are still referenced\n * from the original configuration. This is sufficient for most use cases but should\n * be kept in mind when dealing with complex configurations.\n *\n * @example\n * ```typescript\n * // Apply a configuration\n * myModule.applyConfig({ visible: true, opacity: 0.8 });\n *\n * // Later, retrieve the current configuration\n * const currentConfig = myModule.getConfig();\n * console.log(currentConfig); // { visible: true, opacity: 0.8 }\n *\n * // When no config is applied\n * myModule.resetConfig();\n * console.log(myModule.getConfig()); // undefined\n * ```\n *\n * @see {@link applyConfig} to modify the configuration\n * @see {@link resetConfig} to clear the configuration\n */\n getConfig() {\n return this.config && { ...this.config };\n }\n\n /**\n * Gets the source and layer identifiers for all sources managed by this module.\n *\n * This property provides access to the MapLibre source and layer IDs that were created\n * and are managed by this module. These IDs can be used to interact directly with\n * MapLibre's API or to identify which layers belong to this module.\n *\n * @returns A record mapping each source name to its corresponding source ID and layer IDs.\n * Each entry contains the MapLibre source identifier and an array of layer identifiers\n * associated with that source.\n *\n * @remarks\n * The returned IDs are useful when you need to:\n * - Directly manipulate layers using MapLibre's native API\n * - Identify which layers on the map belong to this module\n * - Set layer ordering or positioning relative to other layers\n * - Access source or layer properties through MapLibre methods\n *\n * @example\n * ```typescript\n * const ids = myModule.sourceAndLayerIDs;\n * console.log(ids);\n * // {\n * // mySource: {\n * // sourceID: 'my-source-id',\n * // layerIDs: ['layer-1', 'layer-2']\n * // }\n * // }\n *\n * // Use with MapLibre API\n * const map = myModule.mapLibreMap;\n * ids.mySource.layerIDs.forEach(layerId => {\n * map.setLayoutProperty(layerId, 'visibility', 'visible');\n * });\n * ```\n */\n get sourceAndLayerIDs(): Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs> {\n return this._sourceAndLayerIDs;\n }\n}\n","import type { MapGeoJSONFeature } from 'maplibre-gl';\nimport type { EventsProxy } from './EventsProxy';\nimport type { EventHandlerConfig, EventType, SourceWithLayers, UserEventHandler } from './types';\n\n/**\n * Event handling interface for map features.\n *\n * Provides a simple API for attaching and removing event handlers for user interactions\n * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,\n * Places, etc.) exposes an `events` property that returns an EventsModule instance.\n *\n * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)\n *\n * @remarks\n * **Supported Event Types:**\n * - `click`: User clicks/taps on a feature\n * - `contextmenu`: User right-clicks on a feature (or long-press on mobile)\n * - `hover`: Mouse enters a feature\n * - `long-hover`: Mouse hovers over feature for configured duration (300-800ms)\n *\n * **Event Handler Signature:**\n * ```typescript\n * (feature: T, lngLat: LngLat, features: T[]) => void\n * ```\n *\n * **Parameters:**\n * - `feature`: The primary feature under the cursor\n * - `lngLat`: Geographic coordinates of the event\n * - `features`: All features at this location (when multiple overlap)\n *\n * **Key Features:**\n * - Automatic cursor management (pointer on hover)\n * - Smart event handling for overlapping features\n * - Configurable hover delays\n * - Memory-safe cleanup when removing handlers\n *\n * @example\n * ```typescript\n * // POI click handler\n * const pois = map.pois();\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('Clicked POI:', feature.properties.name);\n * console.log('Location:', lngLat);\n * showInfoWindow(feature.properties);\n * });\n *\n * // Route waypoint hover\n * const routing = map.routing();\n * routing.events.waypoints.on('hover', (waypoint) => {\n * showTooltip(`Waypoint ${waypoint.properties.index}`);\n * });\n *\n * // Long-hover for detailed info\n * pois.events.on('long-hover', (feature) => {\n * loadAndShowDetailedInfo(feature.properties.id);\n * });\n *\n * // Context menu (right-click)\n * routing.events.mainLines.on('contextmenu', (route, lngLat) => {\n * showContextMenu(lngLat, [\n * { label: 'Add waypoint here', action: () => addWaypoint(lngLat) },\n * { label: 'View route details', action: () => showDetails(route) }\n * ]);\n * });\n *\n * // Remove all click handlers\n * pois.events.off('click');\n * ```\n *\n * @example\n * ```typescript\n * // Complete interaction example\n * const places = map.places();\n *\n * // Show name on hover\n * places.events.on('hover', (place) => {\n * tooltip.show(place.properties.name);\n * });\n *\n * // Show details on click\n * places.events.on('click', (place, lngLat) => {\n * sidebar.show({\n * title: place.properties.name,\n * address: place.properties.address.freeformAddress,\n * coordinates: lngLat\n * });\n * });\n *\n * // Cleanup on component unmount\n * onUnmount(() => {\n * places.events.off('hover');\n * places.events.off('click');\n * });\n * ```\n *\n * @group User Interaction Events\n */\nexport class EventsModule<T = MapGeoJSONFeature> {\n constructor(\n private readonly eventProxy: EventsProxy,\n private readonly sourceWithLayers: SourceWithLayers,\n private readonly config: EventHandlerConfig | undefined,\n ) {}\n\n /**\n * Register an event handler for user interactions with map features.\n *\n * Attaches a callback function that will be invoked when users interact with\n * features in this module (e.g., clicking on a POI, hovering over a route).\n *\n * @param type The type of event to listen for (click, contextmenu, hover, long-hover)\n * @param handler Callback function invoked when the event occurs\n *\n * @remarks\n * **Handler Parameters:**\n * - `feature`: The primary feature that triggered the event\n * - `lngLat`: Geographic coordinates [longitude, latitude] of the event\n * - `features`: Array of all features at the event location (for overlapping features)\n *\n * **Behavior:**\n * - Only one handler per event type (calling `on()` again replaces the previous handler)\n * - Handlers are preserved across map style changes\n * - Cursor automatically changes to pointer on hover\n * - Events respect module visibility (hidden features don't trigger events)\n *\n * **Performance:**\n * - Hover events use spatial indexing for fast lookup\n * - Long-hover has configurable delay to prevent accidental triggers\n * - Event handlers should be lightweight to maintain smooth interaction\n *\n * @example\n * ```typescript\n * // Basic click handler\n * module.events.on('click', (feature, lngLat, features) => {\n * console.log('Clicked feature:', feature.properties);\n * console.log('Location:', lngLat);\n * console.log('All features here:', features.length);\n * });\n *\n * // Hover with tooltip\n * module.events.on('hover', (feature) => {\n * const name = feature.properties.name || 'Unnamed';\n * tooltip.show(name);\n * });\n *\n * // Long-hover for detailed preview\n * module.events.on('long-hover', (feature) => {\n * // Only triggered after hovering for 300-800ms\n * loadPreview(feature.properties.id);\n * });\n *\n * // Right-click context menu\n * module.events.on('contextmenu', (feature, lngLat) => {\n * event.preventDefault(); // Prevent browser context menu\n * showCustomMenu(lngLat, feature);\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Route-specific handlers\n * const routing = map.routing();\n *\n * // Handle route line clicks\n * routing.events.mainLines.on('click', (route) => {\n * highlightRoute(route.properties.routeID);\n * showRouteSummary(route.properties.summary);\n * });\n *\n * // Handle waypoint interactions\n * routing.events.waypoints.on('hover', (waypoint) => {\n * const index = waypoint.properties.index;\n * showTooltip(`Stop ${index + 1}`);\n * });\n * ```\n */\n on(type: EventType, handler: UserEventHandler<T>) {\n this.eventProxy.addEventHandler(this.sourceWithLayers, handler, type, this.config);\n }\n\n /**\n * Remove all event handlers for a specific event type.\n *\n * Unregisters the callback function for the specified event type, stopping\n * further event notifications. This is important for cleanup to prevent\n * memory leaks and unwanted behavior.\n *\n * @param type The type of event to stop listening for\n *\n * @remarks\n * **Cleanup Behavior:**\n * - Removes only the specified event type (other types remain active)\n * - Resets cursor behavior for this module\n * - Safe to call multiple times (no error if no handler exists)\n * - Does not affect other modules' event handlers\n *\n * **When to Use:**\n * - Component unmounting/cleanup\n * - Switching between interaction modes\n * - Temporarily disabling interactions\n * - Replacing an existing handler (call `off()` then `on()`)\n *\n * **Best Practices:**\n * - Always clean up event handlers when component unmounts\n * - Remove handlers before removing features from the map\n * - Use framework lifecycle hooks for automatic cleanup\n *\n * @example\n * ```typescript\n * // Remove click handlers\n * module.events.off('click');\n *\n * // Remove all handlers\n * module.events.off('click');\n * module.events.off('hover');\n * module.events.off('long-hover');\n * module.events.off('contextmenu');\n * ```\n *\n * @example\n * ```typescript\n * // React component cleanup\n * useEffect(() => {\n * const pois = map.pois();\n *\n * pois.events.on('click', handlePoiClick);\n * pois.events.on('hover', handlePoiHover);\n *\n * return () => {\n * // Cleanup on unmount\n * pois.events.off('click');\n * pois.events.off('hover');\n * };\n * }, [map]);\n * ```\n *\n * @example\n * ```typescript\n * // Replace handler\n * module.events.off('click'); // Remove old handler\n * module.events.on('click', newHandler); // Add new handler\n *\n * // Disable interactions temporarily\n * const savedHandler = currentHandler;\n * module.events.off('click'); // Disable\n * // ... later ...\n * module.events.on('click', savedHandler); // Re-enable\n * ```\n */\n off(type: EventType) {\n this.eventProxy.remove(this.sourceWithLayers, type);\n }\n}\n","import { isEmpty, remove } from 'lodash-es';\nimport type { LayerSpecification, MapGeoJSONFeature } from 'maplibre-gl';\nimport type { EventHandlerConfig, EventType, SourcesWithLayers, SourceWithLayers, UserEventHandler } from './types';\n\n// TODO: add support for multiple handlers per source, layers, and event type?\n// ... (this means multiple handlers for the same module, or repeated \"on\" calls for the same module)\ntype SourceEventTypeHandler = {\n sourceWithLayers: SourceWithLayers;\n layerIDs: string[];\n fn: UserEventHandler<any>;\n config?: EventHandlerConfig;\n};\n\ntype SourceEventHandlers = Partial<Record<EventType, SourceEventTypeHandler[]>>;\n\n// Source ID to event handlers for that source:\n// Example:\n// const handlers = {\n// vectorTiles: {\n// click: [\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [\"Buildings\", \"Roads - Major\"],\n// fn: UserEventsHandler...\n// },\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [\"Water\", \"Landuse - Parks],\n// fn: UserEventsHandler...\n// }\n// ],\n// hover: [\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [...],\n// fn: UserEventsHandler...\n// }\n// ]\n// },\ntype EventHandlers = Record<string, SourceEventHandlers>;\n\nconst matchesLayers = (layers: LayerSpecification[], layerIDs: string[]): boolean =>\n layerIDs.every((layerId, index) => layerId === layers[index].id);\n\n/**\n * @ignore\n */\nexport abstract class AbstractEventProxy {\n protected interactiveLayerIDs: string[] = [];\n protected handlers: EventHandlers = {};\n\n /**\n * Adds the given layers as interactive, so we'll listen to them for hover and click.\n * @param sourceWithLayers The sources and layers to listen to.\n */\n private ensureInteractiveLayerIDsAdded(sourceWithLayers: SourceWithLayers) {\n sourceWithLayers._layerSpecs.forEach((layerSpec) => {\n if (!this.interactiveLayerIDs.includes(layerSpec.id)) {\n this.interactiveLayerIDs.push(layerSpec.id);\n }\n });\n }\n\n /**\n * Register an event listener to the list.\n * @param sourceWithLayers The sources and layers to added.\n * @param handlerFn Function that will handle the event.\n * @param type Type of event to listen to.\n * @param config Optional configuration for the event handler.\n */\n addEventHandler<T = MapGeoJSONFeature>(\n sourceWithLayers: SourceWithLayers,\n handlerFn: UserEventHandler<T>,\n type: EventType,\n config: EventHandlerConfig | undefined,\n ) {\n this.ensureInteractiveLayerIDsAdded(sourceWithLayers);\n const sourceId = sourceWithLayers.source.id;\n\n if (!this.handlers[sourceId]) {\n this.handlers[sourceId] = { [type]: [] };\n }\n this.handlers[sourceId][type] ??= [];\n\n this.handlers[sourceId][type]?.push({\n sourceWithLayers,\n layerIDs: sourceWithLayers._layerSpecs.map((layer) => layer.id),\n fn: handlerFn,\n config,\n });\n }\n\n /**\n * Removes the given sources and layers from the interactive list. When not present, nothing happens.\n * @param type The event type to be removed.\n * @param sourceWithLayers The sources and layers to remove, matched by source and layer IDs.\n */\n remove(sourceWithLayers: SourceWithLayers, type: EventType) {\n const sourceEventTypeHandlers = this.handlers[sourceWithLayers.source.id]?.[type];\n if (sourceEventTypeHandlers) {\n // @ts-ignore\n remove(sourceEventTypeHandlers, (handler) => matchesLayers(sourceWithLayers._layerSpecs, handler.layerIDs));\n // cleaning up empty arrays and objects if necessary:\n if (!sourceEventTypeHandlers.length) {\n delete this.handlers[sourceWithLayers.source.id]?.[type];\n if (isEmpty(this.handlers[sourceWithLayers.source.id])) {\n delete this.handlers[sourceWithLayers.source.id];\n }\n }\n }\n for (const layer of sourceWithLayers._layerSpecs) {\n // @ts-ignore\n remove(this.interactiveLayerIDs, (id) => layer.id === id);\n }\n }\n\n /**\n * Removes all interactive sources and layers.\n */\n removeAll() {\n this.interactiveLayerIDs = [];\n this.handlers = {};\n }\n\n /**\n * Returns whether this source is registered for events (has handlers attached).\n * @param sourceId The source id (should be linked to a SourceWithLayers instance).\n */\n hasSourceID(sourceId: string): boolean {\n return !!this.handlers[sourceId];\n }\n\n /**\n * Updates the given sourcesWithLayers, if they have any handlers.\n * * (This is typically called to refresh any registered, stale sourceWithLayers references after a map style has changed).\n * @param sourcesWithLayers The new sources with layers to replace existing ones.\n */\n updateIfRegistered(sourcesWithLayers: SourcesWithLayers): void {\n for (const sourceWithLayers of Object.values(sourcesWithLayers)) {\n const sourceHandlers = this.handlers[sourceWithLayers.source.id];\n if (sourceHandlers) {\n for (const sourceEventTypeHandlers of Object.values(sourceHandlers)) {\n for (const handler of sourceEventTypeHandlers) {\n if (sourceWithLayers.equalSourceAndLayerIDs(handler.sourceWithLayers)) {\n // We keep the reference fresh:\n handler.sourceWithLayers = sourceWithLayers;\n }\n }\n }\n }\n }\n }\n\n protected findHandlers = (\n types: EventType[],\n sourceId: string | undefined,\n layerId: string | undefined,\n ): SourceEventTypeHandler[] =>\n (sourceId &&\n layerId &&\n types.flatMap((type) => {\n const sourceEventTypeHandlers = this.handlers[sourceId]?.[type];\n return sourceEventTypeHandlers?.length === 1\n ? // if there's only handler for that source and type, we just return it, no need to match layers:\n sourceEventTypeHandlers\n : this.handlers[sourceId]?.[type]?.filter((handler) => handler.layerIDs.includes(layerId)) || [];\n })) ||\n [];\n}\n","import type { Feature } from 'geojson';\nimport { isNil, omit } from 'lodash-es';\nimport type { MapGeoJSONFeature, Point2D } from 'maplibre-gl';\nimport { areBothDefinedAndEqual } from './mapUtils';\nimport { GeoJSONSourceWithLayers } from './SourceWithLayers';\nimport type { EventType, SourceWithLayers } from './types';\n\ntype IndexedFeature<F extends Feature = Feature> = { feature: F; index: number };\n\nconst findFeatureById = (features: Feature[], id: string | number | undefined): IndexedFeature | undefined => {\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n if (feature.id === id) {\n return { feature, index: i };\n }\n }\n return undefined;\n};\n\nconst isHighPriority = (eventType: EventType): boolean => eventType === 'click' || eventType === 'contextmenu';\n\n/**\n * Puts or removes the given event state to the right feature in featuresToUpdate based on the\n * @param eventState The new event state to apply or to use as reference.\n * @param featureId The ID of the feature to update within featuresToUpdate.\n * @param featuresToUpdate The features list which will be updated.\n * @param mode If updateInProps, replaces the existing eventState. If removeFromProps, removes the existing eventState.\n * @return The index of the updated feature in the mutated featuresToUpdate array.\n * @ignore\n */\nexport const putEventState = (\n eventState: EventType,\n featureId: string | number | undefined,\n featuresToUpdate: Feature[], // \"featuresToUpdate\" will be mutated\n mode: 'updateInProps' | 'removeFromProps' = 'updateInProps',\n): number | undefined => {\n const { feature, index } = findFeatureById(featuresToUpdate, featureId) || {};\n if (feature && (!isHighPriority(feature.properties?.eventState) || isHighPriority(eventState))) {\n const updatedFeature = {\n ...feature,\n properties:\n mode === 'updateInProps'\n ? { ...feature?.properties, eventState }\n : omit(feature?.properties, 'eventState'),\n };\n featuresToUpdate.splice(index as number, 1, updatedFeature);\n return index;\n }\n return undefined;\n};\n\nconst removeEventStateAndShow = (\n newEventType: EventType,\n rawFeature: MapGeoJSONFeature,\n sourceWithLayers: GeoJSONSourceWithLayers,\n): void => {\n const prevFeaturesToUpdate = [...sourceWithLayers.shownFeatures.features];\n const updatedIndex = putEventState(newEventType, rawFeature.id, prevFeaturesToUpdate, 'removeFromProps');\n if (!isNil(updatedIndex)) {\n sourceWithLayers.show({ ...sourceWithLayers.shownFeatures, features: prevFeaturesToUpdate });\n }\n};\n\n/**\n * Updates the event state props of the given features.\n * @param eventState The type of event that is being done or undone.\n * @param eventFeature The current MapLibre feature affected by the event, if any.\n * If undefined, it means the event is being undone from prevRawFeature without going to any other one.\n * @param prevEventFeature The previous MapLibre feature affected by the event type, if any (e.g. previous one clicked or hovered).\n * @param sourceWithLayers The source with layers of eventFeature, if any.\n * @param prevSourceWithLayers The source with layers of prevEventFeature, if any.\n * @ignore\n */\nexport const updateEventState = (\n eventState: EventType,\n eventFeature: MapGeoJSONFeature | undefined,\n prevEventFeature: MapGeoJSONFeature | undefined,\n sourceWithLayers: SourceWithLayers | undefined,\n prevSourceWithLayers: SourceWithLayers | undefined,\n): Partial<IndexedFeature> => {\n if (eventFeature && sourceWithLayers instanceof GeoJSONSourceWithLayers) {\n const featuresToUpdate = [...sourceWithLayers.shownFeatures.features];\n const updatedIndex = putEventState(eventState, eventFeature.id, featuresToUpdate) as number;\n\n if (prevEventFeature && !areBothDefinedAndEqual(prevEventFeature, eventFeature)) {\n // (we have both current and prev features for this event type)\n if (prevSourceWithLayers === sourceWithLayers) {\n // we undo the event state from prev feature next to the new one (they will be shown below):\n putEventState(eventState, prevEventFeature.id, featuresToUpdate, 'removeFromProps');\n } else if (prevSourceWithLayers instanceof GeoJSONSourceWithLayers) {\n // the prev feature is in other source/layers, so we update and show them:\n removeEventStateAndShow(eventState, prevEventFeature, prevSourceWithLayers);\n }\n }\n\n sourceWithLayers.show({ ...sourceWithLayers.shownFeatures, features: featuresToUpdate });\n\n return { feature: featuresToUpdate[updatedIndex], index: updatedIndex };\n }\n if (prevEventFeature && prevSourceWithLayers instanceof GeoJSONSourceWithLayers) {\n removeEventStateAndShow(eventState, prevEventFeature, prevSourceWithLayers);\n }\n return { feature: eventFeature };\n};\n\n/**\n * Detects whether there's been a hovering change with the given event and state params.\n * @param hoveringPoint The current hovering pixel coordinates.\n * @param hoveringFeature The current feature being hovered, if any.\n * @param prevHoveredPoint The pixel coordinates from the previous hovering event, if any.\n * @param prevHoveredFeature The previous feature being hovered, if any (could be the same as hoveringFeature).\n * @ignore\n */\nexport const detectHoverState = (\n hoveringPoint: Point2D,\n hoveringFeature: MapGeoJSONFeature | undefined,\n prevHoveredPoint: Point2D | undefined,\n prevHoveredFeature: MapGeoJSONFeature | undefined,\n): {\n /**\n * Whether a hover state change happened, such as no-hover -> hover or vice-versa.\n */\n hoverChanged?: boolean;\n /**\n * Whether the mouse is moving along the hovered feature (not stopped on it).\n */\n mouseInMotionOverHoveredFeature?: boolean;\n} => {\n if (hoveringFeature) {\n if (!prevHoveredFeature) {\n return { hoverChanged: true };\n }\n if (\n (hoveringFeature.id && hoveringFeature.id !== prevHoveredFeature.id) ||\n (hoveringFeature.properties.id && hoveringFeature.properties.id !== prevHoveredFeature.properties.id) ||\n hoveringFeature.source !== prevHoveredFeature.source ||\n // comparing by layer ID is needed when two id-less features from the same source but different layers are compared\n // this can happen when e.g. hovering over different layer groups for the base map\n hoveringFeature.layer.id !== prevHoveredFeature.layer.id\n ) {\n // hovering from one feature to another one (from the same or different layer/source):\n return { hoverChanged: true };\n }\n // (else we're hovering along the same feature)\n if (\n prevHoveredPoint &&\n (hoveringPoint.x - prevHoveredPoint.x != 0 || hoveringPoint.y - prevHoveredPoint.y != 0)\n ) {\n return { mouseInMotionOverHoveredFeature: true };\n }\n } else if (prevHoveredFeature) {\n return { hoverChanged: true };\n }\n return {};\n};\n","import type { LngLat, Map, MapGeoJSONFeature, MapMouseEvent, Point2D, PointLike } from 'maplibre-gl';\nimport type { MapEventsConfig } from '../init';\nimport { AbstractEventProxy } from './AbstractEventProxy';\nimport { detectHoverState, updateEventState } from './eventUtils';\nimport { deserializeFeatures } from './mapUtils';\nimport type { ClickEventType, EventHandlerConfig, SourceWithLayers } from './types';\n\n// Default values for events\nconst eventsProxyDefaultConfig: Required<MapEventsConfig> = {\n precisionMode: 'box',\n paddingBoxPx: 5,\n cursorOnHover: 'pointer',\n cursorOnMouseDown: 'grabbing',\n cursorOnMap: 'default',\n /**\n * Delayed hover control:\n * * The first hover we do after the map moves is longer\n */\n longHoverDelayAfterMapMoveMS: 800,\n /* Followup hovers with the same non-moving map are quicker (\"hovering around mode\") */\n longHoverDelayOnStillMapMS: 300,\n};\n\n/**\n * This is the place where we handle the user events on the map (mousemove/hover and click mostly).\n * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.\n * @ignore\n */\nexport class EventsProxy extends AbstractEventProxy {\n private readonly map: Map;\n private readonly mapCanvas: HTMLCanvasElement;\n private enabled = true;\n private hoveringLngLat?: LngLat;\n private hoveringPoint?: Point2D;\n private hoveringFeature?: MapGeoJSONFeature;\n private hoveringFeatures?: MapGeoJSONFeature[];\n private hoveringSourceWithLayers?: SourceWithLayers;\n private longHoverTimeoutHandlerID?: number;\n // Control flag to indicate that the coming hover is the first one since the map is \"quiet\" again:\n private firstDelayedHoverSinceMapMove = true;\n private lastClickedFeature?: MapGeoJSONFeature;\n private lastClickedSourceWithLayers?: SourceWithLayers;\n private lastCursorStyle: string;\n // Configuration\n private readonly config: Required<MapEventsConfig>;\n\n constructor(map: Map, config: MapEventsConfig = {}) {\n super();\n this.map = map;\n this.mapCanvas = map.getCanvas();\n this.config = { ...eventsProxyDefaultConfig, ...config };\n this.mapCanvas.style.cursor = this.config.cursorOnMap;\n this.lastCursorStyle = this.config.cursorOnMap;\n this.listenToEvents();\n }\n\n private listenToEvents() {\n this.map.on('mousemove', (ev) => this.onMouseMove(ev));\n this.map.on('movestart', () => this.onMouseStart());\n this.map.on('mouseout', () => this.onMouseOut());\n this.map.on('mouseover', (ev) => this.onMouseMove(ev));\n this.map.on('mousedown', () => this.onMouseDown());\n this.map.on('mouseup', () => this.onMouseUp());\n this.map.on('click', (ev) => this.onMapClick('click', ev));\n this.map.on('contextmenu', (ev) => this.onMapClick('contextmenu', ev));\n }\n\n // Enable/Disable Events\n public enable(enabled: boolean) {\n this.enabled = enabled;\n if (!enabled) {\n this.clearLongHoverTimeout();\n }\n }\n\n private toPaddedBounds(point: Point2D): [[number, number], [number, number]] {\n const padding = this.config.paddingBoxPx;\n return [\n // sw:\n [point.x - padding, point.y + padding],\n // ne:\n [point.x + padding, point.y - padding],\n ];\n }\n\n private isEnabled() {\n return this.enabled && !this.map.isMoving();\n }\n\n private getRenderedFeatures(point: Point2D): MapGeoJSONFeature[] {\n if (!this.interactiveLayerIDs.length) {\n return [];\n }\n const options = { layers: this.interactiveLayerIDs, validate: false };\n const precision = this.config.precisionMode;\n // first optional attempt right in the given coordinates:\n const renderedFeatures =\n precision === 'point-then-box' || precision === 'point'\n ? this.map.queryRenderedFeatures(point as PointLike, options)\n : [];\n return renderedFeatures.length || precision === 'point'\n ? renderedFeatures\n : // second attempt using 'box' = padded bounds (trying to hit something slightly further from the pointer location)\n this.map.queryRenderedFeatures(this.toPaddedBounds(point), options);\n }\n\n private clearLongHoverTimeout() {\n window.clearTimeout(this.longHoverTimeoutHandlerID);\n }\n\n private restartLongHoverTimeout() {\n this.clearLongHoverTimeout();\n this.longHoverTimeoutHandlerID = window.setTimeout(\n () => this.handleLongHoverTimeout(),\n this.firstDelayedHoverSinceMapMove\n ? this.config.longHoverDelayAfterMapMoveMS\n : this.config.longHoverDelayOnStillMapMS,\n );\n }\n\n private handleLongHoverTimeout() {\n // We avoid firing long hovers when the feature is in clicked state:\n this.firstDelayedHoverSinceMapMove = false;\n\n if (this.hoveringSourceWithLayers) {\n const eventState = updateEventState(\n 'long-hover',\n this.hoveringFeature,\n undefined,\n this.hoveringSourceWithLayers,\n undefined,\n );\n\n this.findHandlers(['long-hover'], this.hoveringFeature?.source, this.hoveringFeature?.layer.id).forEach(\n (handler) =>\n handler.fn(\n eventState.feature,\n this.hoveringLngLat as LngLat,\n this.hoveringFeatures as MapGeoJSONFeature[],\n this.hoveringSourceWithLayers as SourceWithLayers,\n ),\n );\n }\n }\n\n private onMouseStart() {\n this.firstDelayedHoverSinceMapMove = true;\n this.clearLongHoverTimeout();\n }\n\n private onMouseOut() {\n // Preventing accidental de-hover event if we actually leave the map canvas.\n // Since this could potentially be about jumping into a map popup, so we leave that up to the caller.\n this.clearLongHoverTimeout();\n }\n\n private onMouseDown() {\n this.lastCursorStyle = this.mapCanvas.style.cursor;\n this.mapCanvas.style.cursor = this.config.cursorOnMouseDown;\n }\n\n private onMouseUp() {\n this.mapCanvas.style.cursor = this.lastCursorStyle;\n }\n\n private onMouseMove(ev: MapMouseEvent) {\n if (!this.isEnabled()) {\n // We ensure no unwanted hover handling while disabled or the map moves\n return;\n }\n\n this.hoveringFeatures = this.getRenderedFeatures(ev.point);\n deserializeFeatures(this.hoveringFeatures);\n const [hoveredTopFeature] = this.hoveringFeatures;\n\n // Check if the layer has any handlers registered.\n // Since hover is the \"lowest\" event type, having a handler for any event type justifies supporting hover state.\n // However, we'll only fire the hover events if there are handlers for hover specifically.\n if (hoveredTopFeature && !this.hasSourceID(hoveredTopFeature.source)) {\n return;\n }\n\n // hoverChangeDetected: whether a change happened, such as no-hover -> hover or vice versa:\n // mouseInMotionOverHoveredFeature: whether the mouse is moving along the hovered feature (not stopped on it):\n const { hoverChanged, mouseInMotionOverHoveredFeature } = detectHoverState(\n ev.point,\n hoveredTopFeature,\n this.hoveringPoint,\n this.hoveringFeature,\n );\n\n if (hoverChanged || mouseInMotionOverHoveredFeature) {\n this.hoveringLngLat = ev.lngLat;\n this.hoveringPoint = ev.point;\n const prevHoveredFeature = this.hoveringFeature;\n this.hoveringFeature = hoveredTopFeature;\n const prevHoveredSourceWithLayers = this.hoveringSourceWithLayers;\n\n // Hovering basic event states are still processed if any other handlers are registered for that source/layers.\n // We do so because basic hovering states indicate a feature is interactive.\n // (e.g. if there's a click handler, we'll still apply basic hover states, even if we don't fire hover events)\n const firstHandler = this.findHandlers(\n ['hover', 'long-hover', 'click', 'contextmenu'],\n hoveredTopFeature?.source,\n hoveredTopFeature?.layer.id,\n )?.[0];\n\n // NOTE: handlers overlapping in source and layer IDs won't be supported properly:\n this.hoveringSourceWithLayers = firstHandler?.sourceWithLayers;\n\n if (hoverChanged) {\n this.updateHoverCursor(firstHandler?.config);\n\n const eventState = updateEventState(\n 'hover',\n this.hoveringFeature,\n prevHoveredFeature,\n this.hoveringSourceWithLayers,\n prevHoveredSourceWithLayers,\n );\n\n const hoverHandlers = this.findHandlers(\n ['hover'],\n hoveredTopFeature?.source,\n hoveredTopFeature?.layer.id,\n );\n\n for (const handler of hoverHandlers) {\n handler.fn(eventState.feature, ev.lngLat, this.hoveringFeatures, this.hoveringSourceWithLayers);\n }\n }\n\n this.restartLongHoverTimeout();\n }\n }\n\n private updateHoverCursor(config: EventHandlerConfig | undefined) {\n if (this.hoveringFeature) {\n this.mapCanvas.style.cursor = config?.cursorOnHover ?? this.config.cursorOnHover;\n } else {\n this.mapCanvas.style.cursor = this.config.cursorOnMap;\n }\n }\n\n private onMapClick(clickType: ClickEventType, ev: MapMouseEvent) {\n if (!this.isEnabled()) {\n // We avoid any accidental click handling while disabled or the map moves\n return;\n }\n\n const clickedFeatures = this.getRenderedFeatures(ev.point);\n // Deserialize Features from maplibre queryRenderedFeatures response\n deserializeFeatures(clickedFeatures);\n\n const prevClickedFeature = this.lastClickedFeature;\n this.lastClickedFeature = clickedFeatures[0];\n const prevClickedSourceWithLayers = this.lastClickedSourceWithLayers;\n const clickHandlers = this.findHandlers(\n [clickType],\n this.lastClickedFeature?.source,\n this.lastClickedFeature?.layer.id,\n );\n\n // NOTE: handlers overlapping in source and layer IDs won't be supported properly:\n this.lastClickedSourceWithLayers = clickHandlers?.[0]?.sourceWithLayers;\n\n const eventState = updateEventState(\n clickType,\n this.lastClickedFeature,\n prevClickedFeature,\n this.lastClickedSourceWithLayers,\n prevClickedSourceWithLayers,\n );\n\n for (const handler of clickHandlers) {\n handler.fn(eventState.feature, ev.lngLat, clickedFeatures, this.lastClickedSourceWithLayers);\n }\n }\n}\n","/**\n * Key layer IDs from the vector map style for positioning custom layers.\n *\n * @remarks\n * This constant provides reference layer IDs from TomTom's vector map styles that are used\n * as anchors when positioning custom layers in the map's layer stack. By referencing these\n * layer IDs, SDK modules and custom implementations can control where their layers appear\n * in the rendering order (visual stacking).\n *\n * **Understanding Layer Order:**\n *\n * \"Lowest\" refers to position in the layer stack, not physical elevation. Layers are rendered\n * from bottom to top - layers lower in the stack are drawn first and appear underneath layers\n * higher in the stack. When you add a layer \"before\" a reference layer, it's inserted lower\n * in the stack and will be drawn underneath that reference layer.\n *\n * **How SDK Modules Use These IDs:**\n *\n * **RoutingModule** - Positions route visualizations below labels for readability:\n * ```typescript\n * // Routes appear below labels but above the base map\n * const routingModule = await RoutingModule.get(map);\n * // Uses mapStyleLayerIDs.lowestLabel by default\n * ```\n *\n * **GeometriesModule** - Configurable layer positioning for polygon areas:\n * ```typescript\n * // Default: below labels\n * const geometriesModule = await GeometriesModule.get(map);\n *\n * // Custom: below buildings to show at ground level\n * const geometriesModule = await GeometriesModule.get(map, {\n * beforeLayerConfig: 'lowestBuilding'\n * });\n *\n * // On top of everything\n * const geometriesModule = await GeometriesModule.get(map, {\n * beforeLayerConfig: 'top'\n * });\n * ```\n *\n * **Custom Layer Implementation:**\n * ```typescript\n * // Add a highlight layer below labels\n * map.addLayer({\n * id: 'search-results',\n * type: 'fill',\n * source: 'results-source',\n * paint: { 'fill-color': '#ffcc00', 'fill-opacity': 0.4 }\n * }, mapStyleLayerIDs.lowestLabel);\n * ```\n *\n * **Style Persistence:**\n *\n * These layer IDs remain consistent across TomTom map style changes (e.g., switching from\n * 'standardLight' to 'standardDark'). The SDK automatically repositions module layers using\n * the corresponding reference layers in the new style, maintaining the intended visual hierarchy.\n *\n * **Important Notes:**\n * - `lowestBuilding` is not available in the Satellite style\n * - If a reference layer doesn't exist, custom layers will be added on top of the style\n * - Both RoutingModule and GeometriesModule default to `lowestLabel` for optimal visibility\n *\n * @see {@link GeometryBeforeLayerConfig} for GeometriesModule layer positioning options\n * @see {@link RouteLayersConfig} for RoutingModule layer configuration\n *\n * @group Map Style\n */\nexport const mapStyleLayerIDs = {\n /**\n * Country name label layer.\n *\n * @remarks\n * Lower in the stack than most labels. Use to position elements below country\n * labels but above other map features.\n */\n country: 'Places - Country name',\n /**\n * The lowest layer for place labels.\n *\n * @remarks\n * Lower in the stack than city labels. Use to position content below all place\n * name labels while keeping it visible above geographic features.\n */\n lowestPlaceLabel: 'Places - Village / Hamlet',\n /**\n * Points of Interest layer.\n *\n * @remarks\n * Use to position custom content in the layer stack relative to POI icons and labels.\n */\n poi: 'POI',\n /**\n * The lowest labels layer in the stack.\n *\n * @remarks\n * **Most commonly used reference layer.** Positioning layers before this ensures\n * content appears below all text labels, maintaining map readability while keeping\n * visualizations prominent.\n *\n * **Default for SDK modules:**\n * - RoutingModule uses this for route lines and waypoints\n * - GeometriesModule uses this as the default for polygon fills and borders\n *\n * This provides optimal balance between visibility and not obscuring map labels.\n */\n lowestLabel: 'Borders - Treaty label',\n /**\n * The lowest road line layer in the stack.\n *\n * @remarks\n * Represents tunnel railway outlines. Use to position content below the road network,\n * useful for showing base layers or features that should appear beneath transportation\n * infrastructure.\n */\n lowestRoadLine: 'Tunnel - Railway outline',\n /**\n * The lowest building layer in the stack.\n *\n * @remarks\n * Use to position content below 3D building extrusions while keeping it above\n * flat map features like roads and terrain.\n *\n * **Note:** Not available in the Satellite style.\n */\n lowestBuilding: 'Buildings - Underground',\n} as const;\n","/**\n * Source identifier for POI (Point of Interest) vector tiles.\n *\n * @remarks\n * Used to reference the POI layer in the map style, which contains\n * business locations, landmarks, and other points of interest.\n *\n * @group POIs\n */\nexport const POI_SOURCE_ID = 'vectorTiles';\n\n/**\n * Source identifier for hillshade terrain visualization.\n *\n * @remarks\n * References the raster source that provides terrain shading to visualize\n * elevation and topography on the map.\n *\n * @group Hillshade\n */\nexport const HILLSHADE_SOURCE_ID = 'hillshade';\n\n/**\n * Source identifier for base map vector tiles.\n *\n * @remarks\n * References the primary vector tile source containing roads, buildings,\n * land use, water bodies, and other fundamental map features.\n *\n * @group Base Map\n */\nexport const BASE_MAP_SOURCE_ID = 'vectorTiles';\n\n/**\n * Source identifier for traffic incidents vector tiles.\n *\n * @remarks\n * References the vector tile source containing real-time traffic incident data\n * such as accidents, road closures, and construction.\n *\n * @group Traffic Incidents\n */\nexport const TRAFFIC_INCIDENTS_SOURCE_ID = 'vectorTilesIncidents';\n\n/**\n * Source identifier for traffic flow vector tiles.\n *\n * @remarks\n * References the vector tile source containing real-time traffic flow data\n * showing current traffic speeds and congestion levels.\n *\n * @group Traffic Flow\n */\nexport const TRAFFIC_FLOW_SOURCE_ID = 'vectorTilesFlow';\n","/**\n * Layer IDs for POIs on the map.\n * @ignore\n */\nexport const poiLayerIDs = ['POI', 'POI - Micro'];\n","import type { POICategory } from '@tomtom-org/maps-sdk/core';\n\n/**\n * POI category mappings that have a direct equivalent in Map Display POI categories.\n * @ignore\n */\nexport const mapDisplayPoiCategoryMappings: Partial<Record<POICategory, string>> = {\n ACCESS_GATEWAY: 'access_gateway',\n ADVENTURE_SPORTS_FACILITY: 'adventure_sports_facility',\n ADVENTURE_SPORTS_VENUE: 'adventure_sports_venue',\n AGRICULTURE: 'agriculture_business',\n AIRPORT: 'airport',\n AMUSEMENT_PARK: 'amusement_park',\n AQUATIC_ZOO: 'zoo_or_aquarium',\n ASHRAM: 'religious_site',\n ATM: 'atm',\n AUTOMOTIVE_DEALER: 'automotive_dealer',\n BANK: 'bank',\n BEACH: 'beach',\n BUS_STOP: 'bus_station',\n BUSINESS_PARK: 'business_park',\n CAFE_PUB: 'cafe',\n CAMPING_GROUND: 'camping_ground',\n CAR_WASH: 'car_wash',\n CASH_DISPENSER: 'atm',\n CASINO: 'casino',\n CHURCH: 'religious_site',\n CINEMA: 'cinema',\n CLOTHING_SHOP: 'clothing_shop',\n CLUB_ASSOCIATION: 'club_and_association',\n COLLEGE_UNIVERSITY: 'college_or_university',\n COMMERCIAL_BUILDING: 'commercial_building',\n COMMUNITY_CENTER: 'community_center',\n COMPANY: 'company_or_office',\n CONCERT_HALL: 'nightlife',\n COURTHOUSE: 'courthouse',\n CULTURAL_CENTER: 'cultural_center',\n DENTIST: 'dentist',\n DEPARTMENT_STORE: 'department_store',\n DOCTOR: 'doctor',\n ELECTRIC_VEHICLE_STATION: 'charging_location',\n EMBASSY: 'institution_office',\n EMERGENCY_MEDICAL_SERVICE: 'emergency_medical_service',\n EMERGENCY_ROOM: 'emergency_room',\n ENTERTAINMENT: 'entertainment',\n EXCHANGE: 'stock_exchange',\n EXHIBITION_CONVENTION_CENTER: 'cultural_center',\n FERRY_TERMINAL: 'ferry_terminal',\n FIRE_STATION_BRIGADE: 'fire_station',\n FRONTIER_CROSSING: 'frontier_crossing',\n FUEL_FACILITIES: 'fuel_station',\n GAS_STATION: 'fuel_station',\n GEOGRAPHIC_FEATURE: 'geographic_feature',\n GOLD_EXCHANGE: 'gold_exchange',\n GOLF_COURSE: 'golf_course',\n GOVERNMENT_OFFICE: 'institution_office',\n GURUDWARA: 'religious_site',\n HEALTH_CARE_SERVICE: 'healthcare_service',\n HELIPAD_HELICOPTER_LANDING: 'heliport_or_helipad',\n HILL: 'elevation_point',\n HOLIDAY_RENTAL: 'holiday_home',\n HOSPITAL: 'hospital',\n HOSPITAL_POLYCLINIC: 'hospital',\n HOTEL_MOTEL: 'hotel_or_motel',\n ICE_SKATING_RINK: 'ice_skating_rink',\n IMPORTANT_TOURIST_ATTRACTION: 'tourist_attraction',\n INDUSTRIAL_BUILDING: 'industrial_building',\n LEISURE_CENTER: 'leisure_center',\n LIBRARY: 'library',\n MANUFACTURING_FACILITY: 'manufacturing_facility',\n MARINA: 'marina',\n MARKET: 'marketplace',\n MEDIA_FACILITY: 'media_facility',\n MILITARY_INSTALLATION: 'military_facility',\n MOSQUE: 'religious_site',\n MOTORING_ORGANIZATION_OFFICE: 'motoring_organization_office',\n MOUNTAIN_PASS: 'mountain_pass',\n MOUNTAIN_PEAK: 'elevation_point',\n MOVIE_THEATER: 'cinema',\n MUSEUM: 'museum',\n NATIVE_RESERVATION: 'native_reservation',\n NIGHTLIFE: 'nightlife',\n NON_GOVERNMENTAL_ORGANIZATION: 'non_governmental_organization',\n OPEN_PARKING_AREA: 'parking_facility',\n OPERA_HOUSE: 'theater',\n PAGODA: 'religious_site',\n PARK_RECREATION_AREA: 'park_and_recreation_area',\n PARKING_GARAGE: 'parking_facility',\n PETROL_STATION: 'fuel_station',\n PHARMACY: 'pharmacy',\n PLACE_OF_WORSHIP: 'place_of_worship',\n POLICE_STATION: 'police_station',\n PORT_WAREHOUSE_FACILITY: 'port_or_warehouse_facility',\n POST_OFFICE: 'post_office',\n PRIMARY_RESOURCE_UTILITY: 'primary_resource_or_utility',\n PRISON_CORRECTIONAL_FACILITY: 'prison',\n PUBLIC_AMENITY: 'public_amenity',\n PUBLIC_TRANSPORT_STOP: 'public_transport_stop',\n RAILWAY_STATION: 'railway_station',\n RENT_A_CAR_FACILITY: 'car_rental',\n RENT_A_CAR_PARKING: 'rent_a_car_parking',\n REPAIR_FACILITY: 'repair_facility',\n RESEARCH_FACILITY: 'research_facility',\n RESIDENTIAL_ACCOMMODATION: 'urban_ground',\n REST_AREA: 'rest_area',\n RESTAURANT: 'restaurant',\n RESTAURANT_AREA: 'restaurant_area',\n SCENIC_PANORAMIC_VIEW: 'viewpoint',\n SCHOOL: 'school',\n SHOP: 'shop_or_store',\n SHOPPING_CENTER: 'shop_or_store',\n SPORTS_CENTER: 'sport_facility',\n STADIUM: 'stadium',\n SUPERMARKETS_HYPERMARKETS: 'supermarket',\n SWIMMING_POOL: 'swimming_pool',\n SYNAGOG: 'religious_site',\n TAXI_STAND: 'taxi_stand',\n TEMPLE: 'religious_site',\n TENNIS_COURT: 'tennis_court',\n THEATER: 'theater',\n TOLL_GATE: 'toll_gate',\n TOURIST_INFORMATION_OFFICE: 'tourist_information_office',\n TRAFFIC_CONTROL_DEPARTMENT: 'traffic_control_department',\n TRAFFIC_SERVICE_CENTER: 'traffic_service_center',\n TRAIL_SYSTEM: 'trail_system',\n TRAILS: 'trails',\n TRANSPORT_AUTHORITY_VEHICLE_REGISTRATION: 'transport_authority_or_vehicle_registration',\n TRUCK_STOP: 'truck_stop',\n VACATION_RENTAL: 'vacation_rental',\n VETERINARIAN: 'veterinarian',\n WATER_SPORT: 'water_sport',\n WEIGH_STATION: 'weigh_station',\n WELFARE_ORGANIZATION: 'welfare_organization',\n WINERY: 'manufacturing_facility',\n ZOOS_ARBORETA_BOTANICAL_GARDEN: 'zoo_or_aquarium',\n} as const;\n\n/**\n * Complete POI category mappings including all POI categories.\n * Extends the original mappings with additional categories mapped to semantically appropriate values.\n * @ignore\n */\nconst completeMapDisplayPoiCategoryMappings: Record<POICategory, string> = {\n ...(mapDisplayPoiCategoryMappings as Record<POICategory, string>),\n // Additional POI categories not in the original mapping\n SECURED_ENTRANCE: 'access_gateway',\n AGRICULTURAL_BUSINESS: 'agriculture_business',\n FARM: 'agriculture_business',\n HORTICULTURE: 'agriculture_business',\n PRIMARY_PRODUCER: 'agriculture_business',\n AIRFIELD: 'airport',\n AIRLINE_ACCESS: 'airport',\n MILITARY_AIRPORT: 'airport',\n PRIVATE_AIRPORT: 'airport',\n PUBLIC_AIRPORT: 'airport',\n ATV_DEALER: 'automotive_dealer',\n BOAT_DEALER: 'automotive_dealer',\n BUS_DEALER: 'automotive_dealer',\n CAR_DEALER: 'automotive_dealer',\n MOTORCYCLE_DEALER: 'automotive_dealer',\n RECREATIONAL_VEHICLE_DEALER: 'automotive_dealer',\n TRUCK_DEALER: 'automotive_dealer',\n VAN_DEALER: 'automotive_dealer',\n DIVERSIFIED_FINANCIALS: 'bank',\n SAVINGS_INSTITUTION: 'bank',\n BEACH_CLUB: 'beach',\n BAR: 'cafe',\n CAFE: 'cafe',\n COCKTAIL_BAR: 'cafe',\n COFFEE_SHOP: 'cafe',\n INTERNET_CAFE: 'cafe',\n PUB: 'cafe',\n TEA_HOUSE: 'cafe',\n WINE_BAR: 'cafe',\n CARAVAN_SITE: 'camping_ground',\n RECREATIONAL_CAMPING_GROUND: 'camping_ground',\n REST_CAMP: 'camping_ground',\n TRUCK_WASH: 'car_wash',\n DRIVE_IN_MOVIES: 'cinema',\n CHILDRENS_CLOTHES: 'clothing_shop',\n MENS_CLOTHING: 'clothing_shop',\n SPECIALTY_CLOTHING_SHOP: 'clothing_shop',\n WOMENS_CLOTHING: 'clothing_shop',\n PRIVATE_CLUB: 'club_and_association',\n JUNIOR_COLLEGE_COMMUNITY_COLLEGE: 'college_or_university',\n BUILDING: 'commercial_building',\n ADVERTISING_COMPANY: 'company_or_office',\n AGRICULTURAL_TECHNOLOGY: 'company_or_office',\n AIRLINE_COMPANY: 'company_or_office',\n AUTOMOBILE_COMPANY: 'company_or_office',\n BUSINESS_SERVICES: 'company_or_office',\n BUS_CHARTER_COMPANY: 'company_or_office',\n CABLE_TELEPHONE_COMPANY: 'company_or_office',\n CLEANING_SERVICES: 'company_or_office',\n COMPUTER_DATA_SERVICES: 'company_or_office',\n CONSTRUCTION_COMPANY: 'company_or_office',\n DELIVERY_SERVICE: 'company_or_office',\n ELECTRONICS_COMPANY: 'company_or_office',\n EQUIPMENT_RENTAL: 'company_or_office',\n FUNERAL_SERVICE_MORTUARIES: 'company_or_office',\n IMPORT_EXPORT_AND_DISTRIBUTION: 'company_or_office',\n INSURANCE_COMPANY: 'company_or_office',\n INVESTMENT_ADVISOR: 'company_or_office',\n LEGAL_SERVICES: 'company_or_office',\n MINING_COMPANY: 'company_or_office',\n MOVING_STORAGE_COMPANY: 'company_or_office',\n OIL_NATURAL_GAS: 'company_or_office',\n PHARMACEUTICAL_COMPANY: 'company_or_office',\n PUBLIC_HEALTH_TECHNOLOGY_COMPANY: 'company_or_office',\n PUBLISHING_TECHNOLOGIES: 'company_or_office',\n REAL_ESTATE_AGENT: 'company_or_office',\n REAL_ESTATE_COMPANY: 'company_or_office',\n SERVICE_COMPANY: 'company_or_office',\n SOFTWARE_COMPANY: 'company_or_office',\n TAX_SERVICES: 'company_or_office',\n TELECOMMUNICATIONS: 'company_or_office',\n TRANSPORT_COMPANY: 'company_or_office',\n TRAVEL_AGENT: 'company_or_office',\n WEDDING_SERVICES: 'company_or_office',\n GENERAL_PRACTITIONER: 'doctor',\n SPECIALIST: 'doctor',\n RIDGE: 'elevation_point',\n AMBULANCE_UNIT: 'emergency_medical_service',\n ROAD_RESCUE: 'emergency_medical_service',\n AMUSEMENT_ARCADE: 'entertainment',\n AMUSEMENT_PLACE: 'entertainment',\n BETTING_STATION: 'entertainment',\n FAIRGROUND: 'entertainment',\n MUSIC_CENTER: 'entertainment',\n CHECKPOINT: 'frontier_crossing',\n BAY: 'geographic_feature',\n BRIDGE: 'geographic_feature',\n BRIDGE_TUNNEL_OPERATIONS: 'geographic_feature',\n CAPE: 'geographic_feature',\n COVE: 'geographic_feature',\n DAM: 'geographic_feature',\n DUNE: 'geographic_feature',\n ISLAND: 'geographic_feature',\n LAGOON: 'geographic_feature',\n LAKESHORE: 'geographic_feature',\n LOCALE: 'geographic_feature',\n MARSH: 'geographic_feature',\n OASIS: 'geographic_feature',\n PAN: 'geographic_feature',\n PARKWAY: 'geographic_feature',\n PLAIN_FLAT: 'geographic_feature',\n PLATEAU: 'geographic_feature',\n RAPIDS: 'geographic_feature',\n REEF: 'geographic_feature',\n RESERVOIR: 'geographic_feature',\n RIVER_CROSSING: 'geographic_feature',\n RIVER_SCENIC_AREA: 'geographic_feature',\n ROCKS: 'geographic_feature',\n SEASHORE: 'geographic_feature',\n TUNNEL: 'geographic_feature',\n VALLEY: 'geographic_feature',\n WATER_HOLE: 'geographic_feature',\n WELL: 'geographic_feature',\n BUNGALOW_RENTAL: 'holiday_home',\n CABINS_LODGES: 'holiday_home',\n CHALET_RENTAL: 'holiday_home',\n COTTAGE_RENTAL: 'holiday_home',\n VILLA_RENTAL: 'holiday_home',\n BLOOD_BANK: 'hospital',\n HOSPITAL_FOR_WOMEN_AND_CHILDREN: 'hospital',\n HOSPITAL_OF_CHINESE_MEDICINE: 'hospital',\n SPECIAL_HOSPITAL: 'hospital',\n B_B_GUEST_HOUSE: 'hotel_or_motel',\n HOSTEL: 'hotel_or_motel',\n HOTEL: 'hotel_or_motel',\n MOTEL: 'hotel_or_motel',\n RESORT: 'hotel_or_motel',\n QUARRY: 'industrial_building',\n AUTOMOBILE_MANUFACTURING: 'manufacturing_facility',\n CHEMICAL_COMPANY: 'manufacturing_facility',\n MANUFACTURING_COMPANY: 'manufacturing_facility',\n MECHANICAL_ENGINEERING: 'manufacturing_facility',\n MICROBREWERY: 'manufacturing_facility',\n OEM: 'manufacturing_facility',\n BOAT_LAUNCHING_RAMP: 'marina',\n HARBOR: 'marina',\n YACHT_BASIN: 'marina',\n FARMERS_MARKET: 'marketplace',\n FOOD_MARKET: 'marketplace',\n INFORMAL_MARKET: 'marketplace',\n PUBLIC_MARKET: 'marketplace',\n PLANETARIUM: 'museum',\n CABARET_THEATER: 'nightlife',\n COMEDY_CLUB: 'nightlife',\n DISCO_CLUB: 'nightlife',\n JAZZ_CLUB: 'nightlife',\n KARAOKE_CLUB: 'nightlife',\n FISHING_HUNTING_AREA: 'park_and_recreation_area',\n FOREST_AREA: 'park_and_recreation_area',\n HISTORICAL_PARK: 'park_and_recreation_area',\n NATURAL_RECREATION_ATTRACTION: 'park_and_recreation_area',\n PARK: 'park_and_recreation_area',\n PICNIC_AREA: 'park_and_recreation_area',\n PRESERVE: 'park_and_recreation_area',\n RECREATION_AREA: 'park_and_recreation_area',\n WILDERNESS_AREA: 'park_and_recreation_area',\n OPEN_CAR_PARKING_AREA: 'parking_facility',\n DRUG_STORE: 'pharmacy',\n MARIJUANA_DISPENSARY: 'pharmacy',\n MEDICINAL_MARIJUANA_DISPENSARY: 'pharmacy',\n RECREATIONAL_MARIJUANA_DISPENSARY: 'pharmacy',\n COURIER_DROP_BOX: 'post_office',\n LOCAL_POST_OFFICE: 'post_office',\n PUBLIC_CALL_BOX: 'public_amenity',\n PUBLIC_TOILET: 'public_amenity',\n BUS_LINES: 'public_transport_stop',\n COACH_STOP: 'public_transport_stop',\n PASSENGER_TRANSPORT_TICKET_OFFICE: 'public_transport_stop',\n PEDESTRIAN_SUBWAY: 'public_transport_stop',\n STREETCAR_STOP: 'public_transport_stop',\n SUBWAY_STATION: 'public_transport_stop',\n INTERNATIONAL_RAILROAD_STATION: 'railway_station',\n NATIONAL_RAILROAD_STATION: 'railway_station',\n RAILROAD_SIDING: 'railway_station',\n STATION_ACCESS: 'railway_station',\n URBAN_STATION: 'railway_station',\n BODYSHOP: 'repair_facility',\n CAR_GLASS_REPLACEMENT_SHOP: 'repair_facility',\n CAR_REPAIR_AND_SERVICE: 'repair_facility',\n HOME_APPLIANCE_REPAIR: 'repair_facility',\n MOTORCYCLE_REPAIR: 'repair_facility',\n OTHER_REPAIR_SHOPS: 'repair_facility',\n REPAIR_SHOP: 'repair_facility',\n TIRE_SERVICE: 'repair_facility',\n TRUCK_REPAIR_AND_SERVICE: 'repair_facility',\n AFGHAN_RESTAURANT: 'restaurant',\n AFRICAN_RESTAURANT: 'restaurant',\n ALGERIAN_RESTAURANT: 'restaurant',\n AMERICAN_RESTAURANT: 'restaurant',\n ARABIAN_RESTAURANT: 'restaurant',\n ARGENTINIAN_RESTAURANT: 'restaurant',\n ARMENIAN_RESTAURANT: 'restaurant',\n ASIAN_RESTAURANT: 'restaurant',\n AUSTRALIAN_RESTAURANT: 'restaurant',\n AUSTRIAN_RESTAURANT: 'restaurant',\n BANQUET_ROOMS: 'restaurant',\n BARBECUE_RESTAURANT: 'restaurant',\n BASQUE_RESTAURANT: 'restaurant',\n BELGIAN_RESTAURANT: 'restaurant',\n BISTRO: 'restaurant',\n BOLIVIAN_RESTAURANT: 'restaurant',\n BOSNIAN_RESTAURANT: 'restaurant',\n BRAZILIAN_RESTAURANT: 'restaurant',\n BRITISH_RESTAURANT: 'restaurant',\n BUFFET_RESTAURANT: 'restaurant',\n BULGARIAN_RESTAURANT: 'restaurant',\n BURMESE_RESTAURANT: 'restaurant',\n CAFETERIA: 'restaurant',\n CALIFORNIAN_RESTAURANT: 'restaurant',\n CAMBODIAN_RESTAURANT: 'restaurant',\n CANADIAN_RESTAURANT: 'restaurant',\n CARIBBEAN_RESTAURANT: 'restaurant',\n CATERING_SERVICES: 'restaurant',\n CHICKEN_RESTAURANT: 'restaurant',\n CHILEAN_RESTAURANT: 'restaurant',\n CHINESE_RESTAURANT: 'restaurant',\n COLOMBIAN_RESTAURANT: 'restaurant',\n CORSICAN_RESTAURANT: 'restaurant',\n CREOLE_RESTAURANT: 'restaurant',\n CREPERIE: 'restaurant',\n CUBAN_RESTAURANT: 'restaurant',\n CYPRIOT_RESTAURANT: 'restaurant',\n CZECH_RESTAURANT: 'restaurant',\n DANISH_RESTAURANT: 'restaurant',\n DINNER_THEATER: 'restaurant',\n DOMINICAN_RESTAURANT: 'restaurant',\n DONGBEI_RESTAURANT: 'restaurant',\n DOUGHNUT_RESTAURANT: 'restaurant',\n DUTCH_RESTAURANT: 'restaurant',\n EGYPTIAN_RESTAURANT: 'restaurant',\n ENGLISH_RESTAURANT: 'restaurant',\n EROTIC_RESTAURANT: 'restaurant',\n ETHIOPIAN_RESTAURANT: 'restaurant',\n EXOTIC_RESTAURANT: 'restaurant',\n FAST_FOOD: 'restaurant',\n FINNISH_RESTAURANT: 'restaurant',\n FONDUE_RESTAURANT: 'restaurant',\n FRENCH_RESTAURANT: 'restaurant',\n FUSION_RESTAURANT: 'restaurant',\n GERMAN_RESTAURANT: 'restaurant',\n GREEK_RESTAURANT: 'restaurant',\n GRILL_RESTAURANT: 'restaurant',\n GUANGDONG_RESTAURANT: 'restaurant',\n HAMBURGER_RESTAURANT: 'restaurant',\n HAWAIIAN_RESTAURANT: 'restaurant',\n HOT_POT_RESTAURANT: 'restaurant',\n HUNAN_RESTAURANT: 'restaurant',\n HUNGARIAN_RESTAURANT: 'restaurant',\n ICE_CREAM_PARLOR: 'restaurant',\n INDIAN_RESTAURANT: 'restaurant',\n INDONESIAN_RESTAURANT: 'restaurant',\n INTERNATIONAL_RESTAURANT: 'restaurant',\n IRANIAN_RESTAURANT: 'restaurant',\n IRISH_RESTAURANT: 'restaurant',\n ISRAELI_RESTAURANT: 'restaurant',\n ITALIAN_RESTAURANT: 'restaurant',\n JAMAICAN_RESTAURANT: 'restaurant',\n JAPANESE_RESTAURANT: 'restaurant',\n JEWISH_RESTAURANT: 'restaurant',\n KOREAN_RESTAURANT: 'restaurant',\n KOSHER_RESTAURANT: 'restaurant',\n LATIN_AMERICAN_RESTAURANT: 'restaurant',\n LEBANESE_RESTAURANT: 'restaurant',\n LUXEMBOURGIAN_RESTAURANT: 'restaurant',\n MACROBIOTIC_RESTAURANT: 'restaurant',\n MAGHRIB_RESTAURANT: 'restaurant',\n MALTESE_RESTAURANT: 'restaurant',\n MAURITIAN_RESTAURANT: 'restaurant',\n MEDITERRANEAN_RESTAURANT: 'restaurant',\n MEXICAN_RESTAURANT: 'restaurant',\n MIDDLE_EASTERN_RESTAURANT: 'restaurant',\n MONGOLIAN_RESTAURANT: 'restaurant',\n MOROCCAN_RESTAURANT: 'restaurant',\n MUSSELS_RESTAURANT: 'restaurant',\n NEPALESE_RESTAURANT: 'restaurant',\n NORWEGIAN_RESTAURANT: 'restaurant',\n ORGANIC_FOOD_RESTAURANT: 'restaurant',\n ORIENTAL_RESTAURANT: 'restaurant',\n PAKISTANI_RESTAURANT: 'restaurant',\n PERUVIAN_RESTAURANT: 'restaurant',\n PHILIPPINE_RESTAURANT: 'restaurant',\n PIZZERIA: 'restaurant',\n POLISH_RESTAURANT: 'restaurant',\n POLYNESIAN_RESTAURANT: 'restaurant',\n PORTUGUESE_RESTAURANT: 'restaurant',\n PROVENCAL_RESTAURANT: 'restaurant',\n PUB_FOOD: 'restaurant',\n ROADSIDE_RESTAURANT: 'restaurant',\n ROMANIAN_RESTAURANT: 'restaurant',\n RUSSIAN_RESTAURANT: 'restaurant',\n SALAD_BAR: 'restaurant',\n SANDWICH_RESTAURANT: 'restaurant',\n SAVOY_RESTAURANT: 'restaurant',\n SCANDINAVIAN_RESTAURANT: 'restaurant',\n SCOTTISH_RESTAURANT: 'restaurant',\n SEAFOOD: 'restaurant',\n SHANDONG_RESTAURANT: 'restaurant',\n SHANGHAI_RESTAURANT: 'restaurant',\n SICHUAN_RESTAURANT: 'restaurant',\n SICILIAN_RESTAURANT: 'restaurant',\n SLAVIC_RESTAURANT: 'restaurant',\n SLOVAK_RESTAURANT: 'restaurant',\n SNACKS_RESTAURANT: 'restaurant',\n SOUL_FOOD: 'restaurant',\n SOUP_RESTAURANT: 'restaurant',\n SPANISH_RESTAURANT: 'restaurant',\n STEAK_HOUSE: 'restaurant',\n SUDANESE_RESTAURANT: 'restaurant',\n SURINAMESE_RESTAURANT: 'restaurant',\n SUSHI_RESTAURANT: 'restaurant',\n SWEDISH_RESTAURANT: 'restaurant',\n SWISS_RESTAURANT: 'restaurant',\n SYRIAN_RESTAURANT: 'restaurant',\n TAIWANESE_RESTAURANT: 'restaurant',\n TAKEOUT_FOOD: 'restaurant',\n TAPAS_RESTAURANT: 'restaurant',\n TEPPANYAKI_RESTAURANT: 'restaurant',\n THAI_RESTAURANT: 'restaurant',\n TIBETAN_RESTAURANT: 'restaurant',\n TUNISIAN_RESTAURANT: 'restaurant',\n TURKISH_RESTAURANT: 'restaurant',\n URUGUAYAN_RESTAURANT: 'restaurant',\n VEGETARIAN_RESTAURANT: 'restaurant',\n VENEZUELAN_RESTAURANT: 'restaurant',\n VIETNAMESE_RESTAURANT: 'restaurant',\n WELSH_RESTAURANT: 'restaurant',\n WESTERN_RESTAURANT: 'restaurant',\n YOGURT_JUICE_BAR: 'restaurant',\n ART_SCHOOL: 'school',\n CHILD_CARE_FACILITY: 'school',\n CULINARY_SCHOOL: 'school',\n DANCE_STUDIO_SCHOOL: 'school',\n DRIVING_SCHOOL: 'school',\n HIGH_SCHOOL: 'school',\n LANGUAGE_SCHOOL: 'school',\n MIDDLE_SCHOOL: 'school',\n PRE_SCHOOL: 'school',\n PRIMARY_SCHOOL: 'school',\n SENIOR_HIGH_SCHOOL: 'school',\n SPECIAL_SCHOOL: 'school',\n SPORT_SCHOOL: 'school',\n TECHNICAL_SCHOOL: 'school',\n VOCATIONAL_SCHOOL: 'school',\n AGRICULTURAL_SUPPLIES: 'shop_or_store',\n ANTIQUE_ART_SHOP: 'shop_or_store',\n BAGS_LEATHERWEAR: 'shop_or_store',\n BAKERY: 'shop_or_store',\n BEAUTY_SALON: 'shop_or_store',\n BEAUTY_SUPPLIES: 'shop_or_store',\n BOATING_EQUIPMENT_ACCESSORIES: 'shop_or_store',\n BOOK_SHOP: 'shop_or_store',\n BUTCHER: 'shop_or_store',\n CAMERAS_PHOTOGRAPHY: 'shop_or_store',\n CARPET_FLOOR_COVERINGS: 'shop_or_store',\n CAR_ACCESSORIES: 'shop_or_store',\n CHRISTMAS_HOLIDAY_SHOP: 'shop_or_store',\n COMPUTER_COMPUTER_SUPPLIES: 'shop_or_store',\n CONSTRUCTION_MATERIAL_EQUIPMENT: 'shop_or_store',\n CONSUMER_ELECTRONICS: 'shop_or_store',\n CONVENIENCE_STORE: 'shop_or_store',\n CURTAINS_TEXTILES: 'shop_or_store',\n C_DS_DVD_VIDEOS: 'shop_or_store',\n DELICATESSEN: 'shop_or_store',\n DO_IT_YOURSELF_CENTERS: 'shop_or_store',\n DRIVE_THROUGH_BOTTLE_SHOP: 'shop_or_store',\n DRY_CLEANER: 'shop_or_store',\n ELECTRICAL_APPLIANCES_SHOP: 'shop_or_store',\n FACTORY_OUTLET: 'shop_or_store',\n FISHMONGER: 'shop_or_store',\n FLORISTS: 'shop_or_store',\n FOOTWEAR_SHOE_REPAIRS: 'shop_or_store',\n FURNITURE_HOME_FURNISHINGS: 'shop_or_store',\n GARDEN_CENTERS_SERVICES: 'shop_or_store',\n GIFTS_CARDS_NOVELTIES_SOUVENIRS: 'shop_or_store',\n GLASSWARE_CERAMIC_SHOP: 'shop_or_store',\n GLASS_WINDOWS_STORE: 'shop_or_store',\n GREENGROCER: 'shop_or_store',\n GROCERY_STORE: 'shop_or_store',\n HAIRDRESSER: 'shop_or_store',\n HARDWARE_STORE: 'shop_or_store',\n HOBBY_SHOP: 'shop_or_store',\n HOUSE_GARDEN_FURNITURE_FITTINGS: 'shop_or_store',\n JEWELRY_CLOCKS_WATCHES: 'shop_or_store',\n KITCHENS_BATHROOMS: 'shop_or_store',\n LAUNDRY: 'shop_or_store',\n LIGHTING_SHOPS: 'shop_or_store',\n LOCAL_SPECIALITIES_SHOP: 'shop_or_store',\n LOTTERY_SHOP: 'shop_or_store',\n MARINE_ELECTRONIC_EQUIPMENT: 'shop_or_store',\n MEDICAL_SUPPLIES_EQUIPMENT: 'shop_or_store',\n MOBILE_PHONE_SHOP: 'shop_or_store',\n MUSIC_INSTRUMENTS_STORE: 'shop_or_store',\n NAIL_SALON: 'shop_or_store',\n NEWSAGENTS_TOBACCONISTS: 'shop_or_store',\n OFFICE_EQUIPMENT: 'shop_or_store',\n OPTICIAN: 'shop_or_store',\n OTHER_FOOD_SHOPS: 'shop_or_store',\n PAINTING_DECORATING: 'shop_or_store',\n PAWN_SHOP: 'shop_or_store',\n PERSONAL_CARE_FACILITY: 'shop_or_store',\n PERSONAL_SERVICE: 'shop_or_store',\n PET_SUPPLIES: 'shop_or_store',\n PHOTOCOPY_SHOP: 'shop_or_store',\n PHOTO_LAB_DEVELOPMENT: 'shop_or_store',\n RECYCLING_SHOP: 'shop_or_store',\n RETAIL_OUTLET: 'shop_or_store',\n SAUNA_SOLARIUM_MASSAGE: 'shop_or_store',\n SECURITY_PRODUCTS: 'shop_or_store',\n SHOPPING_SERVICE: 'shop_or_store',\n SPECIALTY_FOODS: 'shop_or_store',\n SPORTS_EQUIPMENT_CLOTHING: 'shop_or_store',\n STAMP_SHOP: 'shop_or_store',\n TAILOR_SHOP: 'shop_or_store',\n TOYS_GAMES_SHOP: 'shop_or_store',\n VARIETY_STORE: 'shop_or_store',\n VIDEO_RENTAL_SHOP: 'shop_or_store',\n WHOLESALE_CLUB: 'shop_or_store',\n WINE_SPIRITS: 'shop_or_store',\n ATHLETICS_TRACK: 'sport_facility',\n BASEBALL_PARK: 'sport_facility',\n BASKETBALL_ARENA: 'sport_facility',\n BOWLING_CENTER: 'sport_facility',\n CRICKET_GROUND: 'sport_facility',\n FITNESS_CLUB_CENTER: 'sport_facility',\n FLYING_CLUB: 'sport_facility',\n HOCKEY_CLUB: 'sport_facility',\n HORSE_RACING_TRACK: 'sport_facility',\n HORSE_RIDING_CENTER: 'sport_facility',\n ICE_HOCKEY_ARENA: 'sport_facility',\n OTHER_WINTER_SPORT: 'sport_facility',\n RACE_TRACK: 'sport_facility',\n RUGBY_GROUND: 'sport_facility',\n SKI_RESORT: 'sport_facility',\n SNOOKER_POOL_BILLIARD: 'sport_facility',\n THEMATIC_SPORT_CENTER: 'sport_facility',\n FOOTBALL_STADIUM: 'stadium',\n MOTOR_RACING_STADIUM: 'stadium',\n MULTI_PURPOSE_STADIUM: 'stadium',\n NETBALL_STADIUM: 'stadium',\n SOCCER_STADIUM: 'stadium',\n STOCK_EXCHANGE: 'stock_exchange',\n TAXI_LIMOUSINE_SHUTTLE_SERVICE: 'taxi_stand',\n AMPHITHEATER: 'theater',\n ARCH: 'tourist_attraction',\n BATTLEFIELD: 'tourist_attraction',\n CAVE: 'tourist_attraction',\n CEMETERY: 'tourist_attraction',\n HISTORIC_SITE: 'tourist_attraction',\n MAUSOLEUM_GRAVE: 'tourist_attraction',\n MEMORIAL: 'tourist_attraction',\n MINERAL_HOT_SPRINGS: 'tourist_attraction',\n MONUMENT: 'tourist_attraction',\n NATURAL_TOURIST_ATTRACTION: 'tourist_attraction',\n OBSERVATORY: 'tourist_attraction',\n STATUE: 'tourist_attraction',\n TOURIST_ATTRACTION: 'tourist_attraction',\n TOWER: 'tourist_attraction',\n ROAD_TRAFFIC_CONTROL_CENTER: 'traffic_control_department',\n ADVENTURE_VEHICLE_TRAIL: 'trails',\n HIKING_TRAIL: 'trails',\n HORSE_RIDING_TRAIL: 'trails',\n MOUNTAIN_BIKE_TRAIL: 'trails',\n ROCK_CLIMBING_TRAIL: 'trails',\n APARTMENT_RENTAL: 'urban_ground',\n CONDOMINIUM_COMPLEX: 'urban_ground',\n FLATS_APARTMENT_COMPLEX: 'urban_ground',\n RESIDENTIAL_ESTATE: 'urban_ground',\n RETIREMENT_COMMUNITY: 'urban_ground',\n TOWNHOUSE_COMPLEX: 'urban_ground',\n ANIMAL_SERVICES: 'veterinarian',\n ANIMAL_SHELTER: 'veterinarian',\n WEIGH_SCALES: 'weigh_station',\n WILDLIFE_PARK: 'zoo_or_aquarium',\n ZOO: 'zoo_or_aquarium',\n} as const;\n\n/**\n * Map style POI category type.\n *\n * @remarks\n * Represents all available POI (Point of Interest) categories used in the map style.\n * These categories correspond to Search API classification codes and are used for\n * filtering, styling, and displaying POI icons on the map.\n *\n * Each category maps to a specific icon sprite and can be used with custom icon configurations.\n *\n * @example\n * ```ts\n * const category: MapStylePOICategory = 'RESTAURANT';\n * ```\n *\n * @see {@link POICategoryGroup} - For grouped collections of related categories\n *\n * @group POIs\n */\nexport type MapStylePOICategory = keyof typeof mapDisplayPoiCategoryMappings;\n\n/**\n * @ignore\n */\nexport const toBaseMapPOICategory = (category: POICategory): string => completeMapDisplayPoiCategoryMappings[category];\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * Bold font face used in the TomTom map style.\n *\n * @remarks\n * This is the primary bold font used for prominent labels and headings in the map.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_BOLD_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_BOLD_FONT],\n * 'text-field': ['get', 'name']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_BOLD_FONT = 'Noto-Bold';\n\n/**\n * Regular font face used in the TomTom map style.\n *\n * @remarks\n * This is the standard font used for most text labels on the map.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_REGULAR_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_REGULAR_FONT],\n * 'text-field': ['get', 'description']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_REGULAR_FONT = 'Noto-Regular';\n\n/**\n * Medium weight font face used in the TomTom map style.\n *\n * @remarks\n * This font provides a middle ground between regular and bold weights.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_MEDIUM_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_MEDIUM_FONT],\n * 'text-field': ['get', 'title']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_MEDIUM_FONT = 'Noto-Medium';\n\n/**\n * Italic font face used in the TomTom map style.\n *\n * @remarks\n * This is the italic variant used for emphasized or secondary text labels.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_ITALIC_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_ITALIC_FONT],\n * 'text-field': ['get', 'subtitle']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_ITALIC_FONT = 'NotoSans-MediumItalic';\n\n/**\n * Default text size expression used in the TomTom map style.\n *\n * @remarks\n * This MapLibre expression defines zoom-dependent text sizing that scales from 12px at zoom 10\n * to 14px at zoom 16. Use this for consistent text sizing across zoom levels.\n *\n * @example\n * ```typescript\n * import { DEFAULT_TEXT_SIZE } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-size': DEFAULT_TEXT_SIZE,\n * 'text-field': ['get', 'name']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const DEFAULT_TEXT_SIZE: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 10, 14, 18, 16];\n\n/**\n * Array of all available font faces in the TomTom map style.\n *\n * @remarks\n * Contains all font variants available in the map style. Useful for font selection\n * or validation when creating custom layers.\n *\n * @example\n * ```typescript\n * import { mapFonts } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Check if a font is available\n * if (mapFonts.includes('Noto-Bold')) {\n * // Use the font\n * }\n *\n * // Use as fallback list\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [...mapFonts]\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const mapFonts = [MAP_REGULAR_FONT, MAP_ITALIC_FONT, MAP_BOLD_FONT, MAP_MEDIUM_FONT] as const;\n\n/**\n * Type representing valid font faces available in the TomTom map style.\n *\n * @remarks\n * Use this type to ensure type-safe font selection when working with text layers.\n * Restricts values to only the fonts available in the map style.\n *\n * @example\n * ```typescript\n * import type { MapFont } from '@tomtom-international/maps-sdk-js/map';\n *\n * function createTextLayer(font: MapFont) {\n * return {\n * type: 'symbol',\n * layout: {\n * 'text-font': [font],\n * 'text-field': ['get', 'name']\n * }\n * };\n * }\n *\n * // Type-safe: only accepts valid map fonts\n * const layer = createTextLayer('Noto-Bold');\n * ```\n *\n * @group Map Style\n */\nexport type MapFont = (typeof mapFonts)[number];\n\n/**\n * @ignore\n */\nexport const PIN_ICON_SIZE: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 8, 0.6, 22, 0.8];\n\n/**\n * @ignore\n */\nexport const SELECTED_PIN_ICON_SIZE: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 8, 0.8, 22, 1];\n","import { SymbolLayerSpecification } from 'maplibre-gl';\nimport { LayerSpecTemplate } from '../types';\nimport { DEFAULT_TEXT_SIZE, MAP_BOLD_FONT, PIN_ICON_SIZE } from './commonLayerProps';\n\n/**\n * @ignore\n */\nexport const TITLE = 'title';\n\n/**\n * @ignore\n */\nexport const ICON_ID = 'iconID';\n\n/**\n * @ignore\n */\nexport const DEFAULT_PLACE_ICON_ID = 'default_place';\n\n/**\n * @ignore\n */\nexport const pinIconBaseLayout: SymbolLayerSpecification['layout'] = {\n 'icon-image': ['get', ICON_ID],\n 'icon-anchor': 'bottom',\n 'icon-size': PIN_ICON_SIZE,\n 'icon-allow-overlap': true,\n 'icon-padding': 0,\n};\n\n/**\n * @ignore\n */\nexport const pinIconBasePaint: SymbolLayerSpecification['paint'] = {\n 'icon-translate': [0, 5],\n 'icon-translate-anchor': 'viewport',\n};\n\n/**\n * @ignore\n */\nexport const pinTextBaseLayout: SymbolLayerSpecification['layout'] = {\n 'text-optional': true,\n 'text-font': [MAP_BOLD_FONT],\n 'text-field': ['get', TITLE],\n 'text-justify': 'auto',\n 'text-variable-anchor': ['top', 'left', 'right'],\n // NOTE: make sure to text against pins and waypoints, in a way that there's enough distance from the pin so the text doesn't disappear\n 'text-variable-anchor-offset': ['top', [0, 0.7], 'left', [1.4, -1.4], 'right', [-1.4, -1.4]],\n 'text-size': DEFAULT_TEXT_SIZE,\n 'text-padding': 5,\n};\n\n/**\n * @ignore\n */\nexport const pinTextBasePaint: SymbolLayerSpecification['paint'] = {\n 'text-color': '#333333',\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': ['interpolate', ['linear'], ['zoom'], 6, 1, 10, 1.5],\n 'text-translate-anchor': 'viewport',\n};\n\n/**\n * Pin places, base layer with mostly the icon portion.\n * @ignore\n */\nexport const pinLayerBaseSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n layout: { ...pinIconBaseLayout, ...pinTextBaseLayout },\n paint: { ...pinIconBasePaint, ...pinTextBasePaint },\n};\n","/**\n * Returns a text with a number suffixed after a hyphen.\n * @ignore\n */\nexport const suffixNumber = (text: string, numberToSuffix: number): string => `${text}-${numberToSuffix}`;\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * @ignore\n */\nexport const isClickEventState: ExpressionSpecification = [\n 'in',\n ['get', 'eventState'],\n ['literal', ['click', 'contextmenu']],\n];\n","import type {\n DataDrivenPropertyValueSpecification,\n ExpressionSpecification,\n Map,\n SymbolLayerSpecification,\n} from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { SELECTED_PIN_ICON_SIZE } from '../../shared/layers/commonLayerProps';\nimport { isClickEventState } from '../../shared/layers/eventState';\nimport { ICON_ID, pinLayerBaseSpec, TITLE } from '../../shared/layers/symbolLayers';\nimport type { PlaceLayerName, PlaceLayersConfig, PlacesModuleConfig } from '../types/placesModuleConfig';\n\n/**\n * @ignore\n */\nexport const hasEventState: ExpressionSpecification = ['has', 'eventState'];\n\n/**\n * @ignore\n */\nexport const SELECTED_COLOR = '#3f9cd9';\n\n/**\n * @ignore\n */\nexport const pinLayerSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...pinLayerBaseSpec,\n filter: ['!', hasEventState],\n};\n\n/**\n * We use an extra layer for highlighted text since it's not easy to enforce z-ordering with icons and text\n * while text has different collision rules.\n * @ignore\n */\nexport const selectedPinLayerSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...pinLayerBaseSpec,\n filter: hasEventState,\n layout: {\n ...pinLayerBaseSpec.layout,\n 'icon-size': SELECTED_PIN_ICON_SIZE,\n 'text-allow-overlap': true,\n },\n paint: {\n ...pinLayerBaseSpec.paint,\n 'text-color': SELECTED_COLOR,\n },\n};\n\nconst withConfig = (\n layerSpec: LayerSpecTemplate<SymbolLayerSpecification>,\n config: PlacesModuleConfig | undefined,\n layerName: PlaceLayerName,\n): LayerSpecTemplate<SymbolLayerSpecification> => {\n const textConfig = config?.text;\n const customLayer = config?.layers?.[layerName];\n return {\n ...layerSpec,\n layout: {\n ...layerSpec.layout,\n ...(textConfig?.size && { 'text-size': textConfig.size }),\n ...(textConfig?.font && { 'text-font': textConfig.font }),\n ...(textConfig?.offset && { 'text-offset': textConfig.offset }),\n ...(textConfig?.title &&\n typeof textConfig?.title !== 'function' && {\n 'text-field': textConfig?.title,\n }),\n ...customLayer?.layout,\n },\n paint: {\n ...layerSpec.paint,\n ...(textConfig?.color && { 'text-color': textConfig.color }),\n ...(textConfig?.haloColor && { 'text-halo-color': textConfig.haloColor }),\n ...(textConfig?.haloWidth && { 'text-halo-width': textConfig.haloWidth }),\n ...customLayer?.paint,\n },\n ...customLayer,\n };\n};\n\n/**\n * @ignore\n */\nexport const getTextSizeSpec = (\n textSize?: DataDrivenPropertyValueSpecification<number>,\n): DataDrivenPropertyValueSpecification<number> => {\n return JSON.parse(JSON.stringify(textSize)?.replace(/name/g, TITLE));\n};\n\nconst buildPoiLikeLayerSpec = (map: Map): LayerSpecTemplate<SymbolLayerSpecification> => {\n const poiLayer = (map.getStyle().layers.filter((layer) => layer.id === 'POI')[0] as SymbolLayerSpecification) || {};\n const textSize = poiLayer.layout?.['text-size'];\n return {\n filter: ['!', isClickEventState],\n type: 'symbol',\n paint: poiLayer.paint,\n layout: {\n ...poiLayer.layout,\n 'text-field': ['get', TITLE],\n 'icon-image': ['get', ICON_ID],\n ...(textSize && { 'text-size': getTextSizeSpec(textSize) }),\n },\n };\n};\n\n/**\n * @ignore\n */\nexport const buildPlacesLayerSpecs = (config: PlacesModuleConfig | undefined, map: Map): PlaceLayersConfig => {\n // Build the layer spec templates based on the theme:\n let layerSpecTemplates;\n if (config?.theme === 'base-map') {\n const poiLikeLayerSpec = buildPoiLikeLayerSpec(map);\n layerSpecTemplates = {\n main: poiLikeLayerSpec,\n selected: {\n ...poiLikeLayerSpec,\n filter: hasEventState,\n layout: {\n ...poiLikeLayerSpec.layout,\n 'text-allow-overlap': true,\n },\n paint: {\n ...poiLikeLayerSpec.paint,\n 'text-color': SELECTED_COLOR,\n },\n },\n };\n } else {\n // pin / circle\n layerSpecTemplates = {\n main: pinLayerSpec,\n selected: selectedPinLayerSpec,\n };\n }\n\n return {\n main: withConfig(layerSpecTemplates.main, config, 'main'),\n selected: withConfig(layerSpecTemplates.selected, config, 'selected'),\n ...config?.layers?.additional,\n };\n};\n","import { SVGIconStyleOptions } from '../../shared';\nimport { isDOMImageSupported, svgToImg } from '../../shared/imageUtils';\nimport { pinSvg } from '../../shared/resources';\n\n/**\n * Default pin for selected images without a specific category on it.\n * @ignore\n */\nexport const defaultPin = (options?: SVGIconStyleOptions): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return svgToImg(pinSvg(options));\n};\n","// Supported sub-categories for map display pins\n// See: https://github.com/tomtom-internal/mdt-backend-mapbox-gl-js-styles/blob/orbis-preview/src/orbis/sprites/poi_light/config.json\n// For the rest we'll use the main categories (which are the first 4 digits of a category)\nconst supportedPinSubcategories: Set<number> = new Set([\n 7339002, 8099002, 7369004, 7321003, 7376006, 9362003, 9362004, 9160004, 9376007, 7315015, 9376006, 9376002, 7315078,\n 7315149, 9376005, 7372003, 9352045, 9352032, 9361048, 9902003, 9378005, 7383004, 9910004, 7320002, 9362016, 7320003,\n 9362025, 9942002, 9942003, 7380005, 9663003, 9361021, 9379009, 9379004, 7315147, 9376003, 9160002, 9160003, 9352008,\n 9361006, 7389004, 9910006,\n]);\n\n/**\n * @ignore\n */\nexport const toPinImageID = (categoryID: number | undefined): string | undefined => {\n if (!categoryID) {\n return undefined;\n }\n\n // Check if the category ID is in our supported subcategories:\n if (supportedPinSubcategories.has(categoryID)) {\n return categoryID.toString();\n }\n\n // If not, fall back to the main category (first 4 digits of the category ID):\n return categoryID.toString().substring(0, 4);\n};\n","import { generateId, Place, Places, POICategory, poiCategoriesToID } from '@tomtom-org/maps-sdk/core';\nimport { toBaseMapPOICategory } from '../../pois/poiCategoryMapping';\nimport { DEFAULT_PLACE_ICON_ID } from '../../shared/layers/symbolLayers';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport type { DisplayPlaceProps } from '../types/placeDisplayProps';\nimport type { PlacesModuleConfig, PlacesTheme } from '../types/placesModuleConfig';\nimport { toPinImageID } from './toPinImageID';\n\n/**\n * Builds the title of the place to display it on the map.\n * @param place The place to display.\n * @ignore\n */\nexport const buildPlaceTitle = (place: Place): string =>\n place.properties.poi?.name ?? place.properties.address.freeformAddress;\n\n/**\n * Resolves the image ID to use for the given POI category and icon theme.\n */\nconst toImageID = (poiCategory: POICategory, iconTheme: PlacesTheme, defaultPlaceIconID: string): string => {\n if (iconTheme === 'pin') {\n const imageID = toPinImageID(poiCategoriesToID[poiCategory]);\n return imageID ?? defaultPlaceIconID;\n } else {\n const imageID = toBaseMapPOICategory(poiCategory);\n return imageID ? `poi-${imageID}` : defaultPlaceIconID;\n }\n};\n\n/**\n * Gets the map style sprite image ID to display on the map for the give place.\n * @ignore\n */\nexport const getIconIDForPlace = (place: Place, instanceIndex: number, config: PlacesModuleConfig = {}): string => {\n const iconTheme = config.theme ?? 'pin';\n const defaultPlaceIconID = suffixNumber(DEFAULT_PLACE_ICON_ID, instanceIndex);\n\n const imageMapping = config.icon?.mapping;\n // First, try custom mapping if provided:\n if (imageMapping) {\n if (imageMapping.to === 'imageID') {\n // Direct image ID mapping\n return imageMapping.fn(place);\n } else {\n // POI category mapping - resolve category to icon ID\n return toImageID(imageMapping.fn(place), iconTheme, defaultPlaceIconID);\n }\n }\n\n // Next, try to match any custom icon:\n const poiCategory = place.properties.poi?.classifications?.[0]?.code as POICategory;\n const matchingCustomIcon = config.icon?.categoryIcons?.find((customIcon) => customIcon.id === poiCategory);\n if (matchingCustomIcon) {\n return suffixNumber(matchingCustomIcon.id, instanceIndex);\n }\n // Else: if no custom icon matched, we map to the map style icons:\n return toImageID(poiCategory, iconTheme, defaultPlaceIconID);\n};\n\n/**\n * Maps a Place category to the poi layer one, so the latter's style can apply it.\n * @ignore\n */\nexport const getPOILayerCategoryForPlace = (place: Place): string | undefined => {\n const category = place.properties.poi?.classifications?.[0]?.code;\n // if it's one of the different categories between search and poi layer, use poi layer category\n return category && toBaseMapPOICategory(category);\n};\n\n/**\n * Transforms the input of a \"show\" call to FeatureCollection \"Places\".\n * @ignore\n */\nexport const toPlaces = (places: Place | Place[] | Places): Places => {\n if (Array.isArray(places)) {\n return { type: 'FeatureCollection', features: places };\n }\n return places.type === 'Feature' ? { type: 'FeatureCollection', features: [places] } : places;\n};\n\n/**\n * prepare places features to be displayed on map by adding needed properties for title, icon and style\n * @ignore\n */\nexport const preparePlacesForDisplay = (\n placesInput: Place | Place[] | Places,\n instanceIndex: number,\n config: PlacesModuleConfig = {},\n): Places<DisplayPlaceProps> => {\n const places = toPlaces(placesInput);\n return {\n ...places,\n features: places.features.map((place) => {\n const title =\n typeof config?.text?.title === 'function' ? config?.text?.title(place) : buildPlaceTitle(place);\n\n const extraFeatureProps = config.extraFeatureProps\n ? Object.fromEntries(\n Object.entries(config.extraFeatureProps).map(([prop, value]) => [\n prop,\n typeof value === 'function' ? value(place) : value,\n ]),\n )\n : {};\n\n const id = place.id ?? generateId();\n\n return {\n ...place,\n id,\n geometry: { ...place.geometry, bbox: place.bbox },\n properties: {\n ...place.properties,\n id, // we need id in properties due to promoteId feature\n title,\n iconID: getIconIDForPlace(place, instanceIndex, config),\n ...(config?.theme === 'base-map' && { category: getPOILayerCategoryForPlace(place) }),\n ...extraFeatureProps,\n },\n };\n }),\n };\n};\n","import type { Place, Places } from '@tomtom-org/maps-sdk/core';\nimport type {\n CleanEventStateOptions,\n CleanEventStatesOptions,\n PutEventStateOptions,\n SymbolLayerSpecWithoutSource,\n} from '../shared';\nimport { AbstractMapModule, EventsModule, GeoJSONSourceWithLayers } from '../shared';\nimport { DEFAULT_PLACE_ICON_ID } from '../shared/layers/symbolLayers';\nimport { suffixNumber } from '../shared/layers/utils';\nimport { addOrUpdateImage, changeLayersProps, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { buildPlacesLayerSpecs } from './layers/placesLayers';\nimport { defaultPin } from './resources';\nimport type { DisplayPlaceProps } from './types/placeDisplayProps';\nimport {\n PlaceIconConfig,\n PlaceLayerName,\n PlacesModuleConfig,\n PlacesTheme,\n PlaceTextConfig,\n} from './types/placesModuleConfig';\nimport { preparePlacesForDisplay } from './utils/preparePlacesForDisplay';\n\ntype PlacesSourcesAndLayers = {\n /**\n * Places source id with corresponding layers ids.\n */\n places: GeoJSONSourceWithLayers<Places<DisplayPlaceProps>>;\n};\n\n/**\n * Map module for displaying and managing place markers.\n *\n * The PlacesModule provides functionality to display location markers (pins) on the map\n * for points of interest, search results, or custom locations. It supports various marker\n * styles, custom icons, text labels, and interactive events.\n *\n * @remarks\n * **Features:**\n * - Multiple marker styles (pin, circle, POI-like)\n * - Custom icons per POI category\n * - Text labels with styling options\n * - Data-driven styling via MapLibre expressions\n * - Interactive events (click, hover, etc.)\n * - Support for custom feature properties\n *\n * **Marker Styles:**\n * - `pin`: Traditional teardrop-shaped map pins\n * - `circle`: Simple circular markers\n * - `base-map`: Mimics built-in POI layer styling\n *\n * **Common Use Cases:**\n * - Search result visualization\n * - Custom location markers\n * - Store locators\n * - Delivery/pickup points\n * - Saved locations display\n *\n * @example\n * ```typescript\n * // Create places module with pin markers\n * const placesModule = await PlacesModule.get(map, {\n * icon: {\n * categoryIcons: []\n * },\n * text: {\n * field: (place) => place.properties.poi?.name || 'Unknown'\n * },\n * theme: 'pin'\n * });\n *\n * // Display places from search\n * await placesModule.show(searchResults);\n *\n * // Handle clicks\n * placesModule.events.on('click', (feature) => {\n * console.log('Clicked:', feature.properties);\n * });\n *\n * placesModule.events.on('hover', (feature) => {\n * showTooltip(feature.properties.poi?.name);\n * });\n * ```\n *\n * @see [Places Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/places)\n *\n * @group Places\n */\nexport class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, PlacesModuleConfig> {\n private static lastInstanceIndex = -1;\n private layerSpecs!: Record<PlaceLayerName, SymbolLayerSpecWithoutSource>;\n private sourceID!: string;\n private layerIDPrefix!: string;\n /**\n * The index of this instance, to generate unique source and layer IDs.\n * * Starts with 0 and each instance increments it by one.\n * @private\n */\n private instanceIndex!: number;\n private defaultPlaceIconID!: string;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n */\n static async get(tomtomMap: TomTomMap, config?: PlacesModuleConfig): Promise<PlacesModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new PlacesModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: PlacesModuleConfig) {\n super('geojson', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: PlacesModuleConfig, restore?: boolean): PlacesSourcesAndLayers {\n // Only increment the instance index for new instances, not for restore operations\n if (!restore) {\n PlacesModule.lastInstanceIndex++;\n this.instanceIndex = PlacesModule.lastInstanceIndex;\n this.sourceID = `places-${this.instanceIndex}`;\n this.layerIDPrefix = this.sourceID;\n this.defaultPlaceIconID = suffixNumber(DEFAULT_PLACE_ICON_ID, this.instanceIndex);\n }\n\n // Update each layer id with the instance-specific prefix\n this.layerSpecs = this.buildLayerSpecs(config);\n\n return {\n places: new GeoJSONSourceWithLayers(this.mapLibreMap, this.sourceID, [\n this.layerSpecs.main,\n this.layerSpecs.selected,\n ]),\n };\n }\n\n private buildLayerSpecs(config?: PlacesModuleConfig) {\n const layerSpecTemplates = buildPlacesLayerSpecs(config, this.mapLibreMap);\n\n // Update each layer id with the instance-specific prefix\n return Object.fromEntries(\n Object.entries(layerSpecTemplates).map(([key, spec]) => [\n key,\n { ...spec, id: `${this.layerIDPrefix}-${key}` },\n ]),\n ) as Record<PlaceLayerName, SymbolLayerSpecWithoutSource>;\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: PlacesModuleConfig | undefined) {\n this.updateLayersAndData(config);\n return config;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previousShownFeatures = this.sourcesWithLayers.places.shownFeatures;\n this.initSourcesWithLayers(this.config, true);\n this.config && this._applyConfig(this.config);\n this.show(previousShownFeatures);\n }\n\n /**\n * Updates the visual theme for displayed places.\n *\n * @param theme - The theme style to apply to place markers.\n *\n * @remarks\n * **Available Themes:**\n * - `pin`: Traditional teardrop-shaped map pins\n * - `circle`: Simple circular markers\n * - `base-map`: Mimics the map's built-in POI layer style with category icons\n *\n * Changes apply immediately to all currently shown places. Other configuration\n * properties (icon config, text config) remain unchanged.\n *\n * @example\n * ```typescript\n * // Switch to pin markers\n * placesModule.applyTheme('pin');\n *\n * // Use simple circles\n * placesModule.applyTheme('circle');\n *\n * // Match map's POI style (ideal to blend in)\n * placesModule.applyTheme('base-map');\n * ```\n */\n applyTheme(theme: PlacesTheme): void {\n this.applyConfigPart({ theme });\n }\n\n /**\n * Updates the icon configuration for displayed places.\n *\n * @param iconConfig - New icon configuration settings.\n *\n * @remarks\n * - Changes apply immediately to currently shown places\n * - Custom icons are loaded if not already in style\n * - Other configuration properties remain unchanged\n *\n * @example\n * ```typescript\n * placesModule.applyIconConfig({\n * categoryIcons: [\n * { category: 'RESTAURANT', id: 'restaurant-icon', image: '/icons/food.png' }\n * ]\n * });\n * ```\n */\n applyIconConfig(iconConfig: PlaceIconConfig): void {\n this.applyConfigPart({ icon: iconConfig });\n }\n\n /**\n * Updates the text/label configuration for displayed places.\n *\n * @param textConfig - New text configuration settings.\n *\n * @remarks\n * Supports both functions and MapLibre expressions for dynamic text.\n *\n * @example\n * ```typescript\n * // Use function\n * placesModule.applyTextConfig({\n * field: (place) => place.properties.poi?.name || 'Unknown'\n * });\n *\n * // Use MapLibre expression\n * placesModule.applyTextConfig({\n * field: ['get', 'title'],\n * size: 14,\n * color: '#333'\n * });\n * ```\n */\n applyTextConfig(textConfig: PlaceTextConfig): void {\n this.applyConfigPart({ text: textConfig });\n }\n\n private applyConfigPart(partialConfig: Partial<PlacesModuleConfig>): void {\n const config = { ...this.config, ...partialConfig };\n this.updateLayersAndData(config);\n this.config = config;\n }\n\n /**\n * Applies additional feature properties to displayed places.\n *\n * @param extraFeatureProps - Object mapping property names to values or functions.\n *\n * @remarks\n * Useful for adding computed properties or metadata for styling/filtering.\n *\n * @example\n * ```typescript\n * placesModule.applyExtraFeatureProps({\n * category: (place) => place.properties.poi?.categories?.[0],\n * rating: (place) => place.properties.poi?.rating || 0,\n * isOpen: true\n * });\n * ```\n */\n applyExtraFeatureProps(extraFeatureProps: { [key: string]: any }): void {\n const config = { ...this.config, extraFeatureProps };\n this.updateData(config);\n this.config = config;\n }\n\n private updateLayersAndData(config: PlacesModuleConfig | undefined): void {\n this.setupImages(config);\n const newLayerSpecs = this.buildLayerSpecs(config);\n // Convert layerSpecs objects to arrays for changeLayersProps\n const newLayerSpecsArray = [newLayerSpecs.main, newLayerSpecs.selected];\n const oldLayerSpecsArray = [this.layerSpecs.main, this.layerSpecs.selected];\n changeLayersProps(newLayerSpecsArray, oldLayerSpecsArray, this.mapLibreMap);\n this.layerSpecs = newLayerSpecs;\n this.updateData(config);\n }\n\n private setupImages(config: PlacesModuleConfig | undefined): void {\n // Ensure default pin is added:\n if (config?.icon) {\n // If we have custom icons, ensure they're added to the map style:\n for (const customIcon of config.icon.categoryIcons ?? []) {\n addOrUpdateImage(\n 'if-not-in-sprite',\n suffixNumber(customIcon.id, this.instanceIndex),\n customIcon.image as string | HTMLImageElement,\n this.mapLibreMap,\n {\n pixelRatio: customIcon.pixelRatio ?? 2,\n },\n );\n }\n\n if (config.icon.default) {\n if (config.icon.default.image) {\n addOrUpdateImage(\n 'if-not-in-sprite',\n this.defaultPlaceIconID,\n config.icon.default.image.image as string | HTMLImageElement,\n this.mapLibreMap,\n {\n pixelRatio: config.icon.default.image.pixelRatio ?? 2,\n },\n );\n }\n if (config.icon.default.style) {\n addOrUpdateImage(\n 'if-not-in-sprite',\n this.defaultPlaceIconID,\n defaultPin(config.icon.default.style),\n this.mapLibreMap,\n { pixelRatio: 2 },\n );\n }\n }\n } else {\n // Ensure default pin is added:\n addOrUpdateImage('if-not-in-sprite', this.defaultPlaceIconID, defaultPin(), this.mapLibreMap, {\n pixelRatio: 2,\n });\n }\n }\n\n private updateData(config: PlacesModuleConfig | undefined): void {\n this.sourcesWithLayers.places.source.runtimeSource?.setData(\n preparePlacesForDisplay(this.sourcesWithLayers.places.shownFeatures, this.instanceIndex, config),\n );\n }\n\n /**\n * Displays the given places on the map.\n *\n * @param places - Place data to display. Can be a single Place, array of Places,\n * or a Places FeatureCollection.\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown places\n * - Applies current module styling configuration\n * - Automatically generates labels if text config is set\n * - Waits for module to be ready before displaying\n *\n * **Data Sources:**\n * - TomTom Search API results\n * - Custom place objects matching the Place interface\n * - GeoJSON Point features\n *\n * @example\n * Display search results:\n * ```typescript\n * import { search } from '@tomtom-international/maps-sdk-js/services';\n *\n * const results = await search({ query: 'coffee' });\n * await placesModule.show(results);\n * ```\n *\n * @example\n * Display single place:\n * ```typescript\n * await placesModule.show({\n * type: 'Feature',\n * geometry: { type: 'Point', coordinates: [4.9041, 52.3676] },\n * properties: {\n * address: { freeformAddress: 'Amsterdam' },\n * poi: { name: 'Amsterdam Central' }\n * }\n * });\n * ```\n *\n * @example\n * Display multiple places:\n * ```typescript\n * await placesModule.show([place1, place2, place3]);\n * ```\n */\n async show(places: Place | Place[] | Places) {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.places.show(preparePlacesForDisplay(places, this.instanceIndex, this.config));\n }\n\n /**\n * Removes all places from the map.\n *\n * @remarks\n * - Clears all displayed places\n * - Does not reset styling configuration\n * - Module remains initialized and ready for new data\n *\n * @example\n * ```typescript\n * await placesModule.clear();\n * ```\n */\n async clear() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.places.clear();\n }\n\n /**\n * Programmatically sets an event state on a specific place.\n *\n * @param options - Configuration for the event state to apply.\n *\n * @remarks\n * Use this to make places appear clicked or hovered programmatically.\n *\n * @example\n * ```typescript\n * // Make first place appear clicked\n * placesModule.putEventState({\n * index: 0,\n * state: 'click',\n * mode: 'put'\n * });\n * ```\n */\n putEventState(options: PutEventStateOptions) {\n this.sourcesWithLayers.places.putEventState(options);\n }\n\n /**\n * Removes an event state from a specific place.\n *\n * @param options - Configuration for which event state to remove.\n *\n * @example\n * ```typescript\n * placesModule.cleanEventState({ index: 0 });\n * ```\n */\n cleanEventState(options: CleanEventStateOptions): void {\n this.sourcesWithLayers.places.cleanEventState(options);\n }\n\n /**\n * Removes event states from multiple places.\n *\n * @param options - Optional filter for which states to remove.\n *\n * @example\n * ```typescript\n * // Remove all event states\n * placesModule.cleanEventStates();\n *\n * // Remove only hover states\n * placesModule.cleanEventStates({ states: ['hover'] });\n * ```\n */\n cleanEventStates(options?: CleanEventStatesOptions) {\n this.sourcesWithLayers.places.cleanEventStates(options);\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule<Place<DisplayPlaceProps>>(\n this.eventsProxy,\n this.sourcesWithLayers.places,\n this.config?.events,\n );\n }\n}\n","import type { ExpressionFilterSpecification, FilterSpecification, LegacyFilterSpecification } from 'maplibre-gl';\nimport type { FilterShowMode, FilterSyntaxVersion, MultiSyntaxFilter, ValuesFilter } from './types';\n\n/**\n * @ignore\n */\nconst isExpressionFilter = (filter: FilterSpecification): filter is ExpressionFilterSpecification => {\n if (filter === true || filter === false) {\n return true;\n }\n\n if (!Array.isArray(filter) || filter.length === 0) {\n return false;\n }\n switch (filter[0]) {\n case 'has':\n return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';\n\n case 'in':\n return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2]));\n\n case '!in':\n case '!has':\n case 'none':\n return false;\n\n case '==':\n case '!=':\n case '>':\n case '>=':\n case '<':\n case '<=':\n return filter.length !== 3 || Array.isArray(filter[1]) || Array.isArray(filter[2]);\n\n case 'any':\n case 'all':\n for (const f of filter.slice(1)) {\n if (!isExpressionFilter(f as FilterSpecification) && typeof f !== 'boolean') {\n return false;\n }\n }\n return true;\n\n default:\n return true;\n }\n};\n\n/**\n * @ignore\n */\nexport const getSyntaxVersion = (expression: FilterSpecification): FilterSyntaxVersion =>\n isExpressionFilter(expression) ? 'expression' : 'legacy';\n\n/**\n * @ignore\n */\nexport const getMergedAnyFilter = (filters: MultiSyntaxFilter[]): MultiSyntaxFilter | null => {\n if (!filters?.length) {\n return null;\n }\n if (filters.length === 1) {\n return filters[0];\n }\n return {\n expression: ['any', ...filters.map((filter) => filter?.expression)],\n legacy: ['any', ...filters.map((filter) => filter?.legacy)],\n };\n};\n\n/**\n * @ignore\n */\nexport const getMergedAllFilter = (\n filterToAdd: MultiSyntaxFilter,\n originalFilter: FilterSpecification | undefined,\n): FilterSpecification => {\n if (originalFilter) {\n return ['all', filterToAdd[getSyntaxVersion(originalFilter)], originalFilter] as FilterSpecification;\n }\n return filterToAdd.expression;\n};\n\n/**\n * @ignore\n */\nexport const buildMappedValuesFilter = <T>(\n propName: string,\n showMode: FilterShowMode,\n values: T[],\n): MultiSyntaxFilter => {\n if (values.length === 1) {\n const comparator = showMode === 'only' ? '==' : '!=';\n return {\n expression: [comparator, ['get', propName], values[0]] as ExpressionFilterSpecification,\n legacy: [comparator, propName, values[0]] as LegacyFilterSpecification,\n };\n }\n const filterArrayNew = ['in', ['get', propName], ['literal', values]];\n if (showMode === 'only') {\n return {\n expression: filterArrayNew as ExpressionFilterSpecification,\n legacy: ['in', propName, ...values] as LegacyFilterSpecification,\n };\n }\n return {\n expression: ['!', filterArrayNew as ExpressionFilterSpecification],\n legacy: ['!in', propName, ...values] as LegacyFilterSpecification,\n };\n};\n\n/**\n * @ignore\n */\nexport const buildValuesFilter = <T>(\n propName: string,\n filter: ValuesFilter<T>,\n valuesMapping?: (value: T) => unknown,\n): MultiSyntaxFilter =>\n buildMappedValuesFilter(propName, filter.show, valuesMapping ? filter.values.map(valuesMapping) : filter.values);\n","import type { MapStylePOICategory } from '../places';\n\n/**\n * Predefined groups of related POI categories for convenient filtering.\n *\n * @remarks\n * This object maps group names to arrays of {@link MapStylePOICategory} values.\n * Each group contains POI categories that share a common theme or purpose,\n * making it easier to filter multiple related POI types with a single identifier.\n *\n * **Available Groups:**\n * - `FOOD_DRINKS_GROUP` - Dining and beverage establishments (restaurants, cafes, pubs, etc.)\n * - `SHOPPING_GROUP` - Retail stores and shopping centers (shops, markets, supermarkets, etc.)\n * - `TRANSPORTATION_GROUP` - Transportation hubs and stops (airports, stations, terminals, etc.)\n * - `HEALTH_GROUP` - Healthcare facilities and services (hospitals, clinics, pharmacies, etc.)\n * - `PARKING_GROUP` - Parking facilities (garages and open parking areas)\n * - `HOLIDAY_TOURISM_GROUP` - Tourist attractions and recreational sites (museums, parks, beaches, etc.)\n * - `EV_CHARGING_STATIONS_GROUP` - Electric vehicle charging locations\n * - `GAS_STATIONS_GROUP` - Fuel stations for traditional vehicles\n * - `ACCOMMODATION_GROUP` - Lodging facilities (hotels, motels, camping grounds, etc.)\n * - `ENTERTAINMENT_GROUP` - Entertainment venues (cinemas, theaters, nightlife, casinos, etc.)\n * - `SPORTS_LEISURE_GROUP` - Sports and leisure facilities (stadiums, gyms, pools, golf courses, etc.)\n * - `EDUCATION_GROUP` - Educational institutions (schools, universities, libraries, etc.)\n * - `GOVERNMENT_GROUP` - Government and public safety facilities (offices, courts, embassies, police, fire stations)\n *\n * @example\n * Filter to show only food-related POIs:\n * ```ts\n * import { poiCategoryGroups } from '@tomtom-international/maps-sdk-js/map';\n *\n * const foodCategories = poiCategoryGroups.FOOD_DRINKS_GROUP;\n * console.log(foodCategories);\n * // ['RESTAURANT', 'FAST_FOOD', 'CAFE_PUB', 'PUB', 'WINERY', ...]\n * ```\n *\n * @example\n * Use with POI module filtering:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'show',\n * values: ['FOOD_DRINKS_GROUP', 'ENTERTAINMENT_GROUP']\n * }\n * });\n * ```\n *\n * @see {@link POICategoryGroup} - Type representing all available group names\n * @see {@link MapStylePOICategory} - Individual POI category identifiers\n *\n * @group POIs\n */\nexport const poiCategoryGroups: Record<string, MapStylePOICategory[]> = {\n FOOD_DRINKS_GROUP: [\n 'RESTAURANT',\n 'FAST_FOOD',\n 'CAFE_PUB',\n 'PUB',\n 'WINERY',\n 'PUB_FOOD',\n 'SOUL_FOOD',\n 'DELICATESSEN',\n ],\n SHOPPING_GROUP: [\n 'SHOP',\n 'SHOPPING_CENTER',\n 'CLOTHING_SHOP',\n 'MARKET',\n 'FOOD_MARKET',\n 'SUPERMARKETS_HYPERMARKETS',\n 'DEPARTMENT_STORE',\n 'CONVENIENCE_STORE',\n 'GROCERY_STORE',\n 'HARDWARE_STORE',\n 'ELECTRICAL_APPLIANCES_SHOP',\n ],\n TRANSPORTATION_GROUP: [\n 'AIRPORT',\n 'FERRY_TERMINAL',\n 'HELIPAD_HELICOPTER_LANDING',\n 'PUBLIC_TRANSPORT_STOP',\n 'RAILWAY_STATION',\n 'BUS_STOP',\n 'TAXI_STAND',\n ],\n HEALTH_GROUP: [\n 'DOCTOR',\n 'EMERGENCY_MEDICAL_SERVICE',\n 'EMERGENCY_ROOM',\n 'HEALTH_CARE_SERVICE',\n 'HOSPITAL',\n 'HOSPITAL_POLYCLINIC',\n 'PHARMACY',\n 'DENTIST',\n 'WELFARE_ORGANIZATION',\n ],\n PARKING_GROUP: ['PARKING_GARAGE', 'OPEN_PARKING_AREA'],\n HOLIDAY_TOURISM_GROUP: [\n 'AMUSEMENT_PARK',\n 'BEACH',\n 'HOLIDAY_RENTAL',\n 'GEOGRAPHIC_FEATURE',\n 'IMPORTANT_TOURIST_ATTRACTION',\n 'LEISURE_CENTER',\n 'MOUNTAIN_PASS',\n 'MOUNTAIN_PEAK',\n 'MUSEUM',\n 'SCENIC_PANORAMIC_VIEW',\n 'TOURIST_INFORMATION_OFFICE',\n ],\n EV_CHARGING_STATIONS_GROUP: ['ELECTRIC_VEHICLE_STATION'],\n GAS_STATIONS_GROUP: ['GAS_STATION', 'PETROL_STATION'],\n ACCOMMODATION_GROUP: ['CAMPING_GROUND', 'HOTEL_MOTEL', 'HOLIDAY_RENTAL'],\n ENTERTAINMENT_GROUP: [\n 'CINEMA',\n 'THEATER',\n 'MOVIE_THEATER',\n 'NIGHTLIFE',\n 'CONCERT_HALL',\n 'ENTERTAINMENT',\n 'CLUB_ASSOCIATION',\n 'CASINO',\n ],\n SPORTS_LEISURE_GROUP: [\n 'SPORTS_CENTER',\n 'WATER_SPORT',\n 'SWIMMING_POOL',\n 'GOLF_COURSE',\n 'STADIUM',\n 'BEACH',\n 'ICE_SKATING_RINK',\n 'LEISURE_CENTER',\n 'MOUNTAIN_PASS',\n 'MOUNTAIN_PEAK',\n ],\n EDUCATION_GROUP: ['SCHOOL', 'COLLEGE_UNIVERSITY', 'LIBRARY', 'CULTURAL_CENTER'],\n GOVERNMENT_GROUP: ['GOVERNMENT_OFFICE', 'COURTHOUSE', 'EMBASSY', 'FIRE_STATION_BRIGADE', 'POLICE_STATION'],\n};\n\n/**\n * POI category group type.\n *\n * @remarks\n * Represents predefined groups of related POI categories for convenient filtering.\n * Each group contains multiple {@link MapStylePOICategory} values that share a common theme.\n *\n * Using category groups simplifies filtering by allowing you to show or hide\n * multiple related POI types with a single filter value.\n *\n * **Available groups:**\n * - `FOOD_DRINKS_GROUP` - Restaurants, cafes, fast food, wineries, etc.\n * - `SHOPPING_GROUP` - Stores, malls, markets, supermarkets, etc.\n * - `TRANSPORTATION_GROUP` - Airports, train stations, bus stops, ferry terminals, etc.\n * - `HEALTH_GROUP` - Hospitals, clinics, pharmacies, doctors, dentists, etc.\n * - `PARKING_GROUP` - Parking garages and open parking areas\n * - `HOLIDAY_TOURISM_GROUP` - Tourist attractions, museums, beaches, scenic views, etc.\n * - `EV_CHARGING_STATIONS_GROUP` - Electric vehicle charging stations\n * - `GAS_STATIONS_GROUP` - Gas and petrol stations\n * - `ACCOMMODATION_GROUP` - Hotels, motels, camping grounds, etc.\n * - `ENTERTAINMENT_GROUP` - Cinemas, theaters, nightlife, casinos, etc.\n * - `SPORTS_LEISURE_GROUP` - Stadiums, sports centers, swimming pools, golf courses, etc.\n * - `EDUCATION_GROUP` - Schools, universities, libraries, cultural centers\n * - `GOVERNMENT_GROUP` - Government offices, courthouses, embassies, police, fire stations\n *\n * @example\n * Filter to show only food-related POIs:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'show',\n * values: ['FOOD_DRINKS_GROUP']\n * }\n * });\n * ```\n *\n * @example\n * Hide parking and gas stations:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'hide',\n * values: ['PARKING_GROUP', 'GAS_STATIONS_GROUP']\n * }\n * });\n * ```\n *\n * @example\n * Combine multiple groups for tourism use case:\n * ```ts\n * const tourismFilter = {\n * mode: 'show',\n * values: [\n * 'HOLIDAY_TOURISM_GROUP',\n * 'ACCOMMODATION_GROUP',\n * 'FOOD_DRINKS_GROUP',\n * 'ENTERTAINMENT_GROUP'\n * ]\n * };\n * ```\n *\n * @see {@link poiCategoryGroups} - The object containing all group definitions\n * @see {@link MapStylePOICategory} - For individual POI categories\n *\n * @group POIs\n */\nexport type POICategoryGroup = keyof typeof poiCategoryGroups;\n","import { POICategory } from '@tomtom-org/maps-sdk/core';\nimport { isNil } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport { toBaseMapPOICategory } from '../places';\nimport type { ValuesFilter } from '../shared';\nimport { AbstractMapModule, EventsModule, POI_SOURCE_ID, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { buildMappedValuesFilter, getMergedAllFilter } from '../shared/mapLibreFilterUtils';\nimport { waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { poiLayerIDs } from './layers/poisLayers';\nimport { poiCategoryGroups } from './poiCategoryGroups';\nimport type { FilterablePOICategory, POIsModuleConfig, POIsModuleFeature } from './types/poisModuleConfig';\n\n/**\n * Gets the specified filtered categories icon IDs to be used in map filtering.\n * @param categories list of filtered categories.\n * @ignore\n */\nexport const getStyleCategories = (categories: FilterablePOICategory[]): string[] => {\n const categoryIds: string[] = [];\n categories.forEach((category: FilterablePOICategory) => {\n if (category in poiCategoryGroups) {\n categoryIds.push(...poiCategoryGroups[category].map(toBaseMapPOICategory));\n } else {\n categoryIds.push(toBaseMapPOICategory(category as POICategory));\n }\n });\n return [...new Set(categoryIds)];\n};\n\n/**\n * IDs of sources and layers for places of interest module.\n */\ntype PoIsSourcesAndLayers = {\n /**\n * Places of interest with corresponding layer ids.\n * TODO: technically source ID is vectorTiles if POIs stay included in base map for Orbis\n */\n poi: StyleSourceWithLayers;\n};\n\n/**\n * POIs Module for controlling Points of Interest displayed in the map style.\n *\n * This module manages the built-in POI layer from the vector map, allowing you to\n * show/hide POIs and filter them by category. POIs are already part of the map style\n * and include businesses, landmarks, and other points of interest.\n *\n * @remarks\n * **Features:**\n * - Toggle POI visibility on/off\n * - Filter by POI categories or category groups\n * - Event handling for POI interactions\n * - Based on vector tile data in the map style\n *\n * **POI Categories:**\n * - Individual categories (e.g., RESTAURANT, HOTEL_MOTEL, PARKING_GARAGE)\n * - Category groups (e.g., FOOD_DRINKS_GROUP, SHOPPING_GROUP, TRANSPORTATION_GROUP)\n *\n * **Difference from PlacesModule:**\n * - POIsModule: Controls existing POIs in the map style\n * - PlacesModule: Displays custom place data from Search API or other sources\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { POIsModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module\n * const poisModule = await POIsModule.get(map);\n *\n * // Toggle visibility\n * poisModule.setVisible(false);\n * poisModule.setVisible(true);\n * ```\n *\n * @example\n * Filter specific categories:\n * ```typescript\n * // Show only restaurants and hotels\n * poisModule.filterCategories({\n * show: 'only',\n * values: ['RESTAURANT', 'HOTEL_MOTEL']\n * });\n *\n * // Hide parking garages\n * poisModule.filterCategories({\n * show: 'all_except',\n * values: ['PARKING_GARAGE', 'OPEN_PARKING_AREA']\n * });\n * ```\n *\n * @example\n * Filter using category groups:\n * ```typescript\n * // Show only food and shopping POIs\n * poisModule.filterCategories({\n * show: 'only',\n * values: ['FOOD_DRINKS_GROUP', 'SHOPPING_GROUP']\n * });\n *\n * // Hide transportation POIs\n * pois.filterCategories({\n * show: 'all_except',\n * values: ['TRANSPORTATION_GROUP']\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('Clicked POI:', feature.properties.name);\n * console.log('Category:', feature.properties.category);\n * });\n * ```\n *\n * @see [POIs Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/pois)\n *\n * @group POIs\n */\nexport class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers, POIsModuleConfig> {\n private categoriesFilter?: ValuesFilter<FilterablePOICategory> | null;\n private originalFilter?: FilterSpecification;\n\n /**\n * Retrieves a POIsModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional initial configuration for visibility and filters.\n *\n * @returns A promise that resolves to the initialized POIsModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `filters.categories`: Category filter to apply on initialization\n *\n * @throws Error if the POI source is not found in the map style\n *\n * @example\n * Default initialization:\n * ```typescript\n * const poisModule = await POIsModule.get(map);\n * ```\n *\n * @example\n * With initial filter:\n * ```typescript\n * const poisModule = await POIsModule.get(map, {\n * visible: true,\n * filters: {\n * categories: {\n * show: 'only',\n * values: ['RESTAURANT', 'CAFE_PUB']\n * }\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: POIsModuleConfig): Promise<POIsModule> {\n await waitUntilMapIsReady(map);\n return new POIsModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: POIsModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const poiRuntimeSource = this.mapLibreMap.getSource(POI_SOURCE_ID);\n if (!poiRuntimeSource) {\n throw notInTheStyle(`init ${POIsModule.name} with source ID ${POI_SOURCE_ID}`);\n }\n const poi = new StyleSourceWithLayers(this.mapLibreMap, poiRuntimeSource, (layer) =>\n poiLayerIDs.includes(layer.id),\n );\n // TODO: check if the layers are present in the style, and if not, throw exception?\n const mainLayer = poi.sourceAndLayerIDs.layerIDs[0];\n if (this.mapLibreMap.getLayer(mainLayer)) {\n this.originalFilter = this.mapLibreMap.getFilter(mainLayer) as FilterSpecification;\n }\n return { poi };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: POIsModuleConfig | undefined) {\n if (config && !isNil(config.visible)) {\n this.setVisible(config.visible);\n } else if (!this._initializing && !this.isVisible()) {\n // applying default:\n this.setVisible(true);\n }\n\n this.filterCategories(config?.filters?.categories);\n return config;\n }\n\n /**\n * Checks if POI layers are currently visible.\n *\n * @returns `true` if at least one POI layer is visible, `false` if all are hidden.\n *\n * @example\n * ```typescript\n * if (pois.isVisible()) {\n * console.log('POIs are displayed');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.poi.isAnyLayerVisible();\n }\n\n /**\n * Sets the visibility of POI layers.\n *\n * @param visible - `true` to show POIs, `false` to hide them.\n *\n * @remarks\n * Changes are applied immediately if the map is ready.\n *\n * @example\n * ```typescript\n * pois.setVisible(false); // Hide all POIs\n * pois.setVisible(true); // Show all POIs\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = {\n ...this.config,\n visible,\n };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.poi.setLayersVisible(visible);\n }\n }\n\n /**\n * Filters POIs by category or category group.\n *\n * @param categoriesFilter - Filter configuration specifying which categories to show/hide.\n * Pass `undefined` to reset to default (show all).\n *\n * @remarks\n * **Filter Modes:**\n * - `only`: Show only the specified categories, hide all others\n * - `all_except`: Show all categories except the specified ones\n *\n * **Category Types:**\n * - Individual categories (e.g., 'RESTAURANT', 'HOTEL_MOTEL')\n * - Category groups (e.g., 'FOOD_DRINKS_GROUP', 'SHOPPING_GROUP')\n *\n * **Available Category Groups:**\n * - FOOD_DRINKS_GROUP\n * - SHOPPING_GROUP\n * - TRANSPORTATION_GROUP\n * - HEALTH_GROUP\n * - PARKING_GROUP\n * - HOLIDAY_TOURISM_GROUP\n * - EV_CHARGING_STATIONS_GROUP\n * - GAS_STATIONS_GROUP\n * - ACCOMMODATION_GROUP\n * - ENTERTAINMENT_GROUP\n * - SPORTS_LEISURE_GROUP\n * - EDUCATION_GROUP\n * - GOVERNMENT_GROUP\n *\n * @example\n * Show only restaurants:\n * ```typescript\n * pois.filterCategories({\n * show: 'only',\n * values: ['RESTAURANT']\n * });\n * ```\n *\n * @example\n * Hide parking:\n * ```typescript\n * pois.filterCategories({\n * show: 'all_except',\n * values: ['PARKING_GROUP']\n * });\n * ```\n *\n * @example\n * Reset filter (show all):\n * ```typescript\n * pois.filterCategories(undefined);\n * ```\n */\n filterCategories(categoriesFilter?: ValuesFilter<FilterablePOICategory> | undefined): void {\n if (categoriesFilter) {\n if (this.tomtomMap.mapReady) {\n const poiFilter = buildMappedValuesFilter(\n 'category',\n categoriesFilter.show,\n getStyleCategories(categoriesFilter.values),\n );\n\n this.mapLibreMap.setFilter('POI', getMergedAllFilter(poiFilter, this.originalFilter));\n }\n this.config = {\n ...this.config,\n filters: {\n categories: categoriesFilter,\n },\n };\n } else if (this.categoriesFilter) {\n // reset categories config to default\n this.config = {\n ...this.config,\n filters: {\n categories: {\n show: 'all_except',\n values: [],\n },\n },\n };\n if (this.tomtomMap.mapReady) {\n // Applies default:\n this.mapLibreMap.setFilter('POI', this.originalFilter);\n }\n }\n\n this.categoriesFilter = categoriesFilter;\n }\n\n /**\n * Gets the events interface for handling user interactions with POIs.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a POI\n * - `contextmenu`: User right-clicks on a POI\n * - `hover`: Mouse enters a POI\n * - `long-hover`: Mouse hovers over POI for extended time\n *\n * **Event Feature Properties:**\n * - `id`: Unique POI identifier\n * - `name`: POI name in native language\n * - `category`: POI category\n * - `iconID`: Icon sprite ID\n * - `group`: Category group\n * - `priority`: Importance level (lower = more important)\n *\n * @example\n * ```typescript\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('POI:', feature.properties.name);\n * console.log('Category:', feature.properties.category);\n * console.log('ID:', feature.properties.id);\n * });\n *\n * pois.events.on('hover', (feature) => {\n * showTooltip(feature.properties.name);\n * });\n * ```\n */\n get events() {\n return new EventsModule<POIsModuleFeature>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.poi,\n this.config?.events,\n );\n }\n}\n","import type { LayerSpecification } from 'maplibre-gl';\nimport { poiLayerIDs } from '../pois';\nimport type { LayerSpecFilter } from '../shared';\nimport type { BaseMapLayerGroupName, BaseMapLayerGroups } from './types/baseMapModuleConfig';\n\ntype LayerGroupMapping = {\n layerIDMatches: string[];\n layerTypes: LayerSpecification['type'][];\n};\n\nconst layerGroupMappings: Record<BaseMapLayerGroupName, LayerGroupMapping> = {\n land: {\n layerIDMatches: ['lulc'],\n layerTypes: ['fill'],\n },\n borders: {\n layerIDMatches: ['borders'],\n layerTypes: ['line'],\n },\n water: {\n layerIDMatches: ['water'],\n layerTypes: ['fill', 'line'],\n },\n buildings2D: {\n layerIDMatches: ['building'],\n layerTypes: ['fill', 'line'],\n },\n buildings3D: {\n layerIDMatches: ['building'],\n layerTypes: ['fill-extrusion'],\n },\n houseNumbers: {\n layerIDMatches: ['house number'],\n layerTypes: ['symbol'],\n },\n roadLines: {\n layerIDMatches: ['road', 'tunnel', 'bridge', 'surface'],\n layerTypes: ['fill', 'line'],\n },\n roadLabels: {\n layerIDMatches: ['road', 'tunnel', 'bridge', 'surface'],\n layerTypes: ['symbol'],\n },\n roadShields: {\n layerIDMatches: ['shield'],\n layerTypes: ['symbol'],\n },\n placeLabels: {\n layerIDMatches: ['places'],\n layerTypes: ['symbol'],\n },\n smallerTownLabels: {\n layerIDMatches: ['town', 'village', 'neighbourhood'],\n layerTypes: ['symbol'],\n },\n cityLabels: {\n layerIDMatches: ['city', 'capital'],\n layerTypes: ['symbol'],\n },\n capitalLabels: {\n layerIDMatches: ['capital'],\n layerTypes: ['symbol'],\n },\n stateLabels: {\n layerIDMatches: ['state'],\n layerTypes: ['symbol'],\n },\n countryLabels: {\n layerIDMatches: ['places - country'],\n layerTypes: ['symbol'],\n },\n};\n\nconst isMatching = (group: BaseMapLayerGroupName, layer: LayerSpecification) => {\n const mapping = layerGroupMappings[group];\n return (\n mapping.layerIDMatches.some((part) => layer.id.toLowerCase().includes(part)) &&\n mapping.layerTypes.includes(layer.type)\n );\n};\n\n/**\n * @ignore\n */\nexport const buildLayerGroupFilter = (layerGroups: BaseMapLayerGroups): LayerSpecFilter => {\n const mode = layerGroups.mode;\n const groups = layerGroups.names;\n if (mode === 'include') {\n return (layer) => groups.some((group) => isMatching(group, layer));\n }\n if (mode === 'exclude') {\n return (layer) => !groups.some((group) => isMatching(group, layer));\n }\n // No filtering if we don't recognize the mode:\n console.error('Unrecognized layer group mode:', mode);\n return () => true;\n};\n\n/**\n * @ignore\n */\nexport const filterLayerByGroups = (layer: LayerSpecification, layerGroups?: BaseMapLayerGroups): boolean => {\n const mode = layerGroups?.mode;\n const groups = layerGroups?.names;\n if (mode && groups?.length) {\n if (mode === 'include') {\n return groups.some((group) => isMatching(group, layer));\n }\n if (mode === 'exclude') {\n return !groups.some((group) => isMatching(group, layer));\n }\n }\n return true;\n};\n\n/**\n * @ignore\n */\nexport const buildBaseMapLayerGroupFilter =\n (layerGroupsFilter?: BaseMapLayerGroups): LayerSpecFilter =>\n (layer: LayerSpecification): boolean =>\n (!layerGroupsFilter || filterLayerByGroups(layer, layerGroupsFilter)) && !poiLayerIDs.includes(layer.id);\n","import { isNil } from 'lodash-es';\n\nimport { AbstractMapModule, BASE_MAP_SOURCE_ID, EventsModule, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { waitUntilMapIsReady } from '../shared/mapUtils';\nimport { TomTomMap } from '../TomTomMap';\nimport { buildBaseMapLayerGroupFilter, buildLayerGroupFilter } from './layerGroups';\nimport type { BaseMapLayerGroups, BaseMapModuleConfig, BaseMapModuleInitConfig } from './types/baseMapModuleConfig';\n\ntype BaseSourceAndLayers = {\n vectorTiles: StyleSourceWithLayers;\n};\n\n/**\n * Base Map Module for controlling standard map layers and their visibility.\n *\n * This module manages the fundamental map layers including background, water, land, roads,\n * buildings, labels, and other vector tile layers from the base map style.\n *\n * @remarks\n * **Managed Layers:**\n * - Background and terrain\n * - Water bodies and coastlines\n * - Country and administrative borders\n * - Buildings (2D and 3D)\n * - Road lines, labels, and shields\n * - Place labels at various zoom levels\n * - House numbers\n *\n * **Does NOT Include:**\n * - Traffic flow/incidents (use {@link TrafficFlowModule} or {@link TrafficIncidentsModule})\n * - Points of Interest/POIs (use {@link POIsModule})\n * - Hillshade/terrain shading (use {@link HillshadeModule})\n *\n * **Use Cases:**\n * - Toggle base map visibility on/off\n * - Show only specific layer groups (e.g., roads only)\n * - Create custom map appearances by hiding certain elements\n * - Build overlay maps with selective base layers\n *\n * @example\n * Basic usage:\n * ```typescript\n * // Get module with default configuration\n * const baseMap = await BaseMapModule.get(map);\n *\n * // Toggle visibility\n * baseMap.setVisible(false); // Hide all base layers\n * baseMap.setVisible(true); // Show all base layers\n *\n * // Check current state\n * if (baseMap.isVisible()) {\n * console.log('Base map is visible');\n * }\n * ```\n *\n * @example\n * Working with layer groups:\n * ```typescript\n * // Show only roads and borders\n * const baseMap = await BaseMapModule.get(map, {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'borders']\n * }\n * });\n *\n * // Hide buildings and labels\n * baseMap.setVisible(false, {\n * layerGroups: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D', 'placeLabels']\n * }\n * });\n *\n * // Show only water and land\n * baseMap.setVisible(true, {\n * layerGroups: {\n * mode: 'include',\n * names: ['water', 'land']\n * }\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map);\n *\n * // Listen for clicks on base map features\n * baseMap.events.on('click', (feature, lngLat) => {\n * console.log('Clicked base map feature:', feature);\n * });\n *\n * // Remove event listeners\n * baseMap.events.off('click');\n * ```\n *\n * @see [Base Map Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/base-map)\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n *\n * @group Base Map\n */\nexport class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseMapModuleConfig> {\n /**\n * Asynchronously retrieves a BaseMapModule instance for the given map.\n *\n * This is the recommended way to create a BaseMapModule. It ensures the map\n * is fully loaded before initializing the module.\n *\n * @param tomtomMap - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for module initialization.\n *\n * @returns A promise that resolves to the initialized BaseMapModule.\n *\n * @remarks\n * **Initialization:**\n * - Waits for map to be ready before creating module\n * - Validates that required sources exist in the map style\n * - Applies initial configuration if provided\n *\n * **Configuration Options:**\n * - `visible`: Initial visibility state\n * - `layerGroupsFilter`: Which layer groups to include/exclude\n * - `layerGroupsVisibility`: Fine-grained visibility per group\n *\n * @throws Error if the base map source is not found in the style\n *\n * @example\n * Default initialization:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map);\n * ```\n *\n * @example\n * With configuration:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map, {\n * visible: true,\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings3D', 'houseNumbers']\n * }\n * });\n * ```\n *\n * @example\n * Show only specific groups:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map, {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land', 'borders']\n * },\n * visible: true\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: BaseMapModuleInitConfig): Promise<BaseMapModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new BaseMapModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: BaseMapModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config: BaseMapModuleInitConfig | undefined) {\n const source = this.mapLibreMap.getSource(BASE_MAP_SOURCE_ID);\n if (!source) {\n throw notInTheStyle(`init ${BaseMapModule.name} with source ID ${BASE_MAP_SOURCE_ID}`);\n }\n\n return {\n vectorTiles: new StyleSourceWithLayers(\n this.mapLibreMap,\n source,\n buildBaseMapLayerGroupFilter(config?.layerGroupsFilter),\n ),\n };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: BaseMapModuleConfig | undefined) {\n if (config && !isNil(config.visible)) {\n this.setVisible(config.visible);\n } else if (!this._initializing && !this.isVisible()) {\n // applying default:\n this.setVisible(true);\n }\n\n if (config?.layerGroupsVisibility) {\n this.setVisible(config.layerGroupsVisibility.visible, { layerGroups: config.layerGroupsVisibility });\n }\n\n // We merge the given config with the previous one to ensure init config parameters are kept:\n // (the init config can have more parameters than the runtime one)\n return this.config || config ? { ...this.config, ...config } : undefined;\n }\n\n /**\n * Checks if any base map layers are currently visible.\n *\n * @returns `true` if at least one base map layer is visible, `false` if all are hidden.\n *\n * @remarks\n * This checks the actual visibility state of layers in the map, not just the\n * module's configuration setting.\n *\n * @example\n * ```typescript\n * if (baseMap.isVisible()) {\n * console.log('Base map is rendered');\n * } else {\n * console.log('Base map is hidden');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.vectorTiles.isAnyLayerVisible();\n }\n\n /**\n * Sets the visibility of base map layers.\n *\n * @param visible - `true` to show layers, `false` to hide them.\n * @param options - Optional settings for fine-grained control.\n * @param options.layerGroups - Target specific layer groups instead of all layers.\n *\n * @remarks\n * **Behavior:**\n * - Without `options.layerGroups`: Affects all base map layers\n * - With `options.layerGroups`: Affects only specified layer groups\n * - Changes are applied immediately if map is ready\n *\n * **Layer Groups:**\n * Available groups: `land`, `water`, `borders`, `buildings2D`, `buildings3D`,\n * `houseNumbers`, `roadLines`, `roadLabels`, `roadShields`, `placeLabels`,\n * `smallerTownLabels`, `cityLabels`, `capitalLabels`, `stateLabels`, `countryLabels`\n *\n * @example\n * Show/hide all layers:\n * ```typescript\n * baseMap.setVisible(false); // Hide everything\n * baseMap.setVisible(true); // Show everything\n * ```\n *\n * @example\n * Control specific groups:\n * ```typescript\n * // Hide only buildings\n * baseMap.setVisible(false, {\n * layerGroups: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D']\n * }\n * });\n *\n * // Show everything except labels\n * baseMap.setVisible(true, {\n * layerGroups: {\n * mode: 'exclude',\n * names: ['placeLabels', 'cityLabels', 'countryLabels']\n * }\n * });\n * ```\n *\n * @example\n * Toggle visibility:\n * ```typescript\n * const isVisible = baseMap.isVisible();\n * baseMap.setVisible(!isVisible); // Toggle\n * ```\n */\n setVisible(visible: boolean, options?: { layerGroups?: BaseMapLayerGroups }): void {\n if (!options?.layerGroups) {\n // We remove the layer groups visibility from the config if it was there:\n delete this.config?.layerGroupsVisibility;\n this.config = { ...this.config, visible };\n } else {\n this.config = { ...this.config, layerGroupsVisibility: { ...options.layerGroups, visible } };\n }\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.vectorTiles.setLayersVisible(\n visible,\n options?.layerGroups && buildLayerGroupFilter(options.layerGroups),\n );\n }\n }\n\n /**\n * Gets the events interface for this module to handle user interactions.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a base map feature\n * - `contextmenu`: User right-clicks on a feature\n * - `hover`: Mouse enters a feature\n * - `long-hover`: Mouse hovers over a feature for extended time\n *\n * **Event Handler Signature:**\n * ```typescript\n * (feature: MapGeoJSONFeature, lngLat: LngLat, allFeatures: MapGeoJSONFeature[]) => void\n * ```\n *\n * @example\n * Register click handler:\n * ```typescript\n * baseMap.events.on('click', (feature, lngLat) => {\n * console.log('Clicked on:', feature.properties);\n * console.log('At coordinates:', lngLat);\n * });\n * ```\n *\n * @example\n * Multiple event types:\n * ```typescript\n * // Show tooltip on hover\n * baseMap.events.on('hover', (feature) => {\n * showTooltip(feature.properties.name);\n * });\n *\n * // Handle clicks\n * baseMap.events.on('click', (feature) => {\n * selectFeature(feature.id);\n * });\n *\n * // Clean up\n * baseMap.events.off('hover');\n * baseMap.events.off('click');\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.vectorTiles, this.config?.events);\n }\n}\n","import type { MapModuleCommonConfig } from '../../shared';\n\n/**\n * Available base map layer group identifiers.\n *\n * @remarks\n * Use these names with {@link BaseMapModule} to control layer visibility.\n *\n * @see {@link BaseMapLayerGroupName}\n * @see {@link BaseMapModuleInitConfig.layerGroupsFilter}\n *\n * @group Base Map\n */\nexport const baseMapLayerGroupNames = [\n 'land',\n 'water',\n 'borders',\n 'buildings2D',\n 'buildings3D',\n 'houseNumbers',\n 'roadLines',\n 'roadLabels',\n 'roadShields',\n 'placeLabels',\n 'smallerTownLabels',\n 'cityLabels',\n 'capitalLabels',\n 'stateLabels',\n 'countryLabels',\n] as const;\n\n/**\n * Name of a base map layer group.\n *\n * Identifies specific categories of base map layers that can be controlled together.\n *\n * @remarks\n * **Available Layer Groups:**\n * - `land` - Land areas and terrain\n * - `water` - Water bodies (oceans, lakes, rivers)\n * - `borders` - Country and administrative boundaries\n * - `buildings2D` - 2D building footprints\n * - `buildings3D` - 3D building models\n * - `houseNumbers` - House number labels\n * - `roadLines` - Road line geometries\n * - `roadLabels` - Street name labels\n * - `roadShields` - Highway shields (e.g., I-95, A1)\n * - `placeLabels` - General place labels\n * - `smallerTownLabels` - Small town/village labels\n * - `cityLabels` - City labels\n * - `capitalLabels` - Capital city labels\n * - `stateLabels` - State/province labels\n * - `countryLabels` - Country name labels\n *\n * @example\n * ```typescript\n * const group: BaseMapLayerGroupName = 'roadLines';\n * const labels: BaseMapLayerGroupName[] = ['cityLabels', 'countryLabels'];\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroupName = (typeof baseMapLayerGroupNames)[number];\n\n/**\n * Layer group visibility configuration with explicit visible state.\n *\n * Extends {@link BaseMapLayerGroups} to include a visibility flag, allowing\n * you to show or hide specific groups of base map layers.\n *\n * @example\n * ```typescript\n * // Hide all buildings\n * const config: BaseMapLayerGroupsVisibility = {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * };\n *\n * // Show only roads\n * const roadsOnly: BaseMapLayerGroupsVisibility = {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels'],\n * visible: true\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroupsVisibility = BaseMapLayerGroups & { visible: boolean };\n\n/**\n * Layer group filter for selective base map display.\n *\n * Defines which layer groups to include or exclude from the base map module.\n * Can be expressed as explicit inclusions (show only these) or exclusions\n * (show all except these).\n *\n * @remarks\n * **Filter Modes:**\n * - `include`: Only the specified groups are shown, all others are hidden\n * - `exclude`: All groups are shown except the specified ones\n *\n * **Common Use Cases:**\n * - Show only roads and labels (minimal map)\n * - Hide buildings for cleaner appearance\n * - Show only water and land (base terrain)\n * - Remove labels for overlay maps\n *\n * @example\n * ```typescript\n * // Show only roads and borders\n * const roadsOnly: BaseMapLayerGroups = {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'borders']\n * };\n *\n * // Show everything except buildings\n * const noBuildings: BaseMapLayerGroups = {\n * mode: 'exclude',\n * names: ['buildings2D', 'buildings3D']\n * };\n *\n * // Show only terrain (no labels, no roads)\n * const terrainOnly: BaseMapLayerGroups = {\n * mode: 'include',\n * names: ['land', 'water']\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroups = {\n /**\n * Filter mode determining whether groups are included or excluded.\n *\n * @remarks\n * - `include`: Only the specified groups are considered, all others are ignored\n * - `exclude`: All base map groups except the specified ones are considered\n *\n * @example\n * ```typescript\n * mode: 'include' // Whitelist approach\n * mode: 'exclude' // Blacklist approach\n * ```\n */\n mode: 'include' | 'exclude';\n\n /**\n * Names of the layer groups to include or exclude.\n *\n * @remarks\n * The meaning depends on the `mode`:\n * - In `include` mode: Only these groups will be shown\n * - In `exclude` mode: These groups will be hidden, all others shown\n *\n * @example\n * ```typescript\n * // Show only these\n * names: ['roadLines', 'roadLabels', 'water']\n *\n * // Hide these\n * names: ['buildings2D', 'buildings3D', 'houseNumbers']\n * ```\n */\n names: BaseMapLayerGroupName[];\n};\n\n/**\n * Configuration for the BaseMapModule (initialization or runtime).\n *\n * Controls visibility and behavior of base map layer groups. Can be used both\n * during module initialization and for runtime updates.\n *\n * @remarks\n * This configuration allows fine-grained control over which base map elements\n * are displayed, enabling you to create custom map appearances for different\n * use cases.\n *\n * @example\n * ```typescript\n * // Hide specific layer groups\n * const config: BaseMapModuleConfig = {\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * }\n * };\n *\n * // Show only certain groups\n * const minimalConfig: BaseMapModuleConfig = {\n * visible: true,\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['roadLines', 'water', 'land'],\n * visible: true\n * }\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapModuleConfig = MapModuleCommonConfig & {\n /**\n * Controls the visibility of all layers associated with this module.\n *\n * @default true\n */\n visible?: boolean;\n\n /**\n * Optional visibility configuration for specific layer groups.\n *\n * @remarks\n * **Important:** The layer groups specified here must be included in the\n * module (not excluded by `layerGroupsFilter` during initialization).\n *\n * Use this to control visibility of layer groups at runtime without\n * reinitializing the module.\n *\n * @example\n * ```typescript\n * // Hide all building layers\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * }\n *\n * // Show only labels\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['placeLabels', 'cityLabels', 'countryLabels'],\n * visible: true\n * }\n * ```\n */\n layerGroupsVisibility?: BaseMapLayerGroupsVisibility;\n};\n\n/**\n * Initialization configuration for the BaseMapModule.\n *\n * Extends {@link BaseMapModuleConfig} with additional options available only\n * during module initialization.\n *\n * @remarks\n * **Initialization vs Runtime:**\n * - `layerGroupsFilter`: Only available at init - determines which groups to load\n * - `layerGroupsVisibility`: Available at init and runtime - controls visibility\n *\n * **Use Cases:**\n * - Create minimal maps with only essential layers\n * - Build custom map styles by excluding certain features\n * - Optimize performance by not loading unnecessary layers\n *\n * @example\n * ```typescript\n * // Initialize with only roads and water\n * const initConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'water', 'land']\n * },\n * visible: true\n * };\n *\n * // Exclude buildings from initialization\n * const noBuildingsConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings2D', 'buildings3D', 'houseNumbers']\n * }\n * };\n *\n * // Minimal map for data overlay\n * const overlayBaseConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land', 'borders']\n * },\n * visible: true\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapModuleInitConfig = BaseMapModuleConfig & {\n /**\n * Layer groups to include/exclude during module initialization.\n *\n * @remarks\n * **One-time configuration:** This can only be set during initialization.\n * Once the module is created, you cannot change which groups are loaded,\n * only their visibility via `layerGroupsVisibility`.\n *\n * @example\n * ```typescript\n * // Load only essential layers\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['land', 'water', 'roadLines', 'borders']\n * }\n *\n * // Load everything except 3D buildings\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings3D']\n * }\n *\n * // Minimal overlay map\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land']\n * }\n * ```\n */\n layerGroupsFilter?: BaseMapLayerGroups;\n};\n","import type { Anything, CommonPlaceProps } from '@tomtom-org/maps-sdk/core';\nimport type { SupportsEvents } from '../../shared';\n\n/**\n * Extra properties to display color and title for a geometry on the map.\n *\n * Provides customization options for rendering polygon geometries, including\n * visual styling and labeling.\n *\n * @remarks\n * **Use Cases:**\n * - Search result boundaries (e.g., city limits, postal codes)\n * - Reachable range polygons\n * - Delivery zones\n * - Custom area highlights\n *\n * These properties override default styling and allow per-feature customization.\n *\n * @example\n * ```typescript\n * const geometryProps: ExtraGeometryDisplayProps = {\n * title: 'Amsterdam City Center',\n * color: '#FF5733',\n * eventState: 'click'\n * };\n *\n * // With custom properties\n * const customProps: ExtraGeometryDisplayProps = {\n * title: 'Delivery Zone A',\n * color: '#00FF00',\n * zoneId: 'zone-a',\n * capacity: 100\n * };\n * ```\n *\n * @group Geometries\n */\nexport type ExtraGeometryDisplayProps = {\n /**\n * Display title for the geometry.\n *\n * @remarks\n * Optional text label displayed at the center of the polygon.\n * If not provided, no label will be shown.\n *\n * **Common Uses:**\n * - Area names (e.g., \"Downtown\", \"Zone A\")\n * - Statistics (e.g., \"30 min reachable\")\n * - Custom labels\n *\n * @example\n * ```typescript\n * title: 'Amsterdam City Center'\n * title: 'Zone A'\n * title: '30 min driving range'\n * title: undefined // No label\n * ```\n */\n title?: string;\n\n /**\n * Fill color for the geometry.\n *\n * @remarks\n * Overrides the default fill color from the module configuration.\n * Accepts any valid CSS color value.\n *\n * **Color Formats:**\n * - Hex: '#FF5733'\n * - RGB: 'rgb(255, 87, 51)'\n * - RGBA: 'rgba(255, 87, 51, 0.5)'\n * - Named: 'red', 'blue', 'green'\n *\n * @example\n * ```typescript\n * color: '#FF5733'\n * color: 'rgb(0, 128, 255)'\n * color: 'rgba(255, 0, 0, 0.5)'\n * color: 'red'\n * ```\n */\n color?: string;\n} & SupportsEvents &\n Anything;\n\n/**\n * Geometry base and display properties.\n *\n * Combines complete place information with geometry-specific display properties\n * for rendering polygon features on the map.\n *\n * @remarks\n * Used by the GeometriesModule for rendering:\n * - Search API geometry results\n * - Reachable range polygons\n * - Custom polygon overlays\n * - Administrative boundaries\n *\n * Includes both geographic/metadata and visual styling properties.\n *\n * @example\n * ```typescript\n * const geometry: DisplayGeometryProps = {\n * type: 'Polygon',\n * id: 'geom-123',\n * title: 'Amsterdam',\n * color: '#0080FF',\n * address: {\n * municipalitySubdivision: 'Amsterdam',\n * countryCode: 'NL'\n * }\n * };\n * ```\n *\n * @group Geometries\n */\nexport type DisplayGeometryProps = CommonPlaceProps & ExtraGeometryDisplayProps;\n\n/**\n * @ignore\n */\nexport const GEOMETRY_TITLE_PROP = 'title';\n\n/**\n * @ignore\n */\nexport const GEOMETRY_COLOR_PROP = 'color';\n","import type { FillLayerSpecification, LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { GEOMETRY_COLOR_PROP } from '../types/geometryDisplayProps';\n\nexport const colorPalettes = {\n warm: [\n '#793F0D',\n '#AC703D',\n '#C38E63',\n '#E49969',\n '#E5AE86',\n '#EEC5A9',\n '#6E7649',\n '#9D9754',\n '#C7C397',\n '#B4A851',\n '#DFD27C',\n '#E7E3B5',\n '#846D74',\n '#B7A6AD',\n '#D3C9CE',\n ],\n browns: [\n '#edc4b3',\n '#e6b8a2',\n '#deab90',\n '#d69f7e',\n '#cd9777',\n '#c38e70',\n '#b07d62',\n '#9d6b53',\n '#8a5a44',\n '#774936',\n ],\n cold: ['#344464', '#548ca4', '#549cac', '#2c445c', '#a4ccd4', '#acbccc', '#b4c4d4', '#acd4cc', '#5c8ca4'],\n fadedBlues: [\n '#152033',\n '#1d2d44',\n '#2e455d',\n '#3e5c76',\n '#4c6884',\n '#597491',\n '#67809e',\n '#6e86a5',\n '#7b91ad',\n '#879bb4',\n ],\n blues: ['#03045e', '#023e8a', '#0077b6', '#0096c7', '#00b4d8', '#48cae4', '#90e0ef', '#ade8f4', '#caf0f8'],\n greens: ['#004b23', '#006400', '#007200', '#008000', '#38b000', '#70e000', '#9ef01a', '#ccff33'],\n fadedGreenToBlue: [\n '#d9ed92',\n '#b5e48c',\n '#99d98c',\n '#76c893',\n '#52b69a',\n '#34a0a4',\n '#168aad',\n '#1a759f',\n '#1e6091',\n '#184e77',\n ],\n blueToRed: [\n '#033270',\n '#1368aa',\n '#4091c9',\n '#9dcee2',\n '#fedfd4',\n '#f29479',\n '#f26a4f',\n '#ef3c2d',\n '#cb1b16',\n '#65010c',\n ],\n greenToYellow: [\n '#007f5f',\n '#2b9348',\n '#55a630',\n '#80b918',\n '#aacc00',\n '#bfd200',\n '#d4d700',\n '#dddf00',\n '#eeef20',\n '#ffff3f',\n ],\n pastel: [\n '#fec5bb',\n '#fcd5ce',\n '#fae1dd',\n '#f8edeb',\n '#e8e8e4',\n '#d8e2dc',\n '#ece4db',\n '#ffe5d9',\n '#ffd7ba',\n '#fec89a',\n ],\n retro: [\n '#f94144',\n '#f3722c',\n '#f8961e',\n '#f9844a',\n '#f9c74f',\n '#90be6d',\n '#43aa8b',\n '#4d908e',\n '#577590',\n '#277da1',\n ],\n contrastRetro: [\n '#001219',\n '#005f73',\n '#0a9396',\n '#94d2bd',\n '#e9d8a6',\n '#ee9b00',\n '#ca6702',\n '#bb3e03',\n '#ae2012',\n '#9b2226',\n ],\n fadedRainbow: ['#ffadad', '#ffd6a5', '#fdffb6', '#caffbf', '#9bf6ff', '#a0c4ff', '#bdb2ff', '#ffc6ff', '#fffffc'],\n pastelRainbow: [\n '#54478c',\n '#2c699a',\n '#048ba8',\n '#0db39e',\n '#16db93',\n '#83e377',\n '#b9e769',\n '#efea5a',\n '#f1c453',\n '#f29e4c',\n ],\n};\n\nexport type ColorPaletteOptions = keyof typeof colorPalettes;\n\nconst defaultColor = '#0A3653';\n\n/**\n * @ignore\n */\nexport const geometryFillSpec: LayerSpecTemplate<FillLayerSpecification> = {\n type: 'fill',\n paint: {\n 'fill-color': ['coalesce', ['get', GEOMETRY_COLOR_PROP], defaultColor],\n 'fill-opacity': 0.15,\n 'fill-antialias': false,\n },\n};\n\n/**\n * @ignore\n */\nexport const geometryOutlineSpec: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n paint: {\n 'line-color': defaultColor,\n 'line-opacity': 0.45,\n 'line-width': 2,\n },\n};\n","import { bboxCenter, bboxFromCoordsArray, generateId, PolygonFeatures } from '@tomtom-org/maps-sdk/core';\nimport type { Feature, FeatureCollection, GeoJsonProperties, MultiPolygon, Point, Polygon, Position } from 'geojson';\nimport { isNil } from 'lodash-es';\nimport type { DataDrivenPropertyValueSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { SymbolLayerSpecWithoutSource } from '../shared';\nimport { MAP_BOLD_FONT } from '../shared/layers/commonLayerProps';\nimport type { ColorPaletteOptions } from './layers/geometryLayers';\nimport { colorPalettes, geometryFillSpec, geometryOutlineSpec } from './layers/geometryLayers';\nimport type { GeometriesModuleConfig } from './types/geometriesModuleConfig';\nimport type { DisplayGeometryProps, ExtraGeometryDisplayProps } from './types/geometryDisplayProps';\nimport { GEOMETRY_TITLE_PROP } from './types/geometryDisplayProps';\n\n/**\n * Builds Geometry layer specifications for fill and outline layers.\n * @ignore\n */\nexport const buildGeometryLayerSpecs = (\n fillLayerId: string,\n outlineLayerId: string,\n config?: GeometriesModuleConfig,\n): [SymbolLayerSpecWithoutSource, SymbolLayerSpecWithoutSource] => {\n const colorConfig = config?.colorConfig;\n const lineConfig = config?.lineConfig;\n\n const fillLayerSpec = {\n ...geometryFillSpec,\n id: fillLayerId,\n paint: {\n ...geometryFillSpec.paint,\n ...(!isNil(colorConfig?.fillOpacity) && { 'fill-opacity': colorConfig?.fillOpacity }),\n ...(colorConfig?.fillColor && { 'fill-color': ['get', 'color'] }),\n },\n } as unknown as SymbolLayerSpecWithoutSource;\n\n const outlineLayerSpec = {\n ...geometryOutlineSpec,\n id: outlineLayerId,\n paint: {\n ...geometryOutlineSpec.paint,\n ...(!isNil(lineConfig?.lineColor) && { 'line-color': lineConfig?.lineColor }),\n ...(!isNil(lineConfig?.lineWidth) && { 'line-width': lineConfig?.lineWidth }),\n ...(!isNil(lineConfig?.lineOpacity) && { 'line-opacity': lineConfig?.lineOpacity }),\n },\n } as unknown as SymbolLayerSpecWithoutSource;\n\n return [fillLayerSpec, outlineLayerSpec];\n};\n\n/**\n * Build geometry Title. The type can be a string or a Maplibre expression.\n * @param feature - Geometry\n * @param config - Geometry module configuration\n * @returns\n */\nconst buildTitle = (\n feature: Feature<Polygon | MultiPolygon, DisplayGeometryProps | GeoJsonProperties>,\n config: GeometriesModuleConfig,\n): DataDrivenPropertyValueSpecification<string> | string | undefined => {\n if (config.textConfig?.textField) {\n return config.textConfig.textField;\n }\n\n return feature.properties?.address?.freeformAddress;\n};\n\n/**\n * Builds a geometry color string or MapLibre expression.\n * @param config - Geometry module configuration\n * @param index - Number to use as index to pick color from palette option\n */\nconst buildColor = (\n config: GeometriesModuleConfig,\n index: number,\n): DataDrivenPropertyValueSpecification<string> | string | undefined => {\n const color = config?.colorConfig?.fillColor;\n\n if (typeof color === 'string' && colorPalettes[color as ColorPaletteOptions]) {\n const palette = colorPalettes[color as ColorPaletteOptions];\n return palette[index % palette.length];\n }\n\n return color;\n};\n\n/**\n * Build geometry layer specification for title\n * @param layerID\n * @param config\n * @returns\n * @ignore\n */\nexport const buildGeometryTitleLayerSpec = (\n layerId: string,\n config?: GeometriesModuleConfig,\n): Omit<SymbolLayerSpecification, 'source'> => {\n const textConfig = config?.textConfig;\n\n return {\n type: 'symbol',\n id: layerId,\n layout: {\n 'text-field': ['get', GEOMETRY_TITLE_PROP],\n ...(textConfig?.textField && { 'text-field': textConfig.textField }),\n 'text-padding': 5,\n 'text-size': 12,\n 'text-font': [MAP_BOLD_FONT],\n 'symbol-placement': 'point',\n },\n paint: {\n 'text-color': '#333333',\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': ['interpolate', ['linear'], ['zoom'], 6, 1, 10, 1.5],\n 'text-translate-anchor': 'viewport',\n },\n };\n};\n\n/**\n * Prepare geometry for display.\n * If colorConfig is set, it will apply the property \"color\" to \"properties\" in each feature.\n * @param geometry\n * @param config\n * @returns\n * @ignore\n */\nexport const prepareGeometryForDisplay = (\n geometry: PolygonFeatures<GeoJsonProperties | DisplayGeometryProps>,\n config: GeometriesModuleConfig = {},\n): PolygonFeatures<ExtraGeometryDisplayProps> => ({\n ...geometry,\n features: geometry.features.map((feature, index) => {\n const title = feature.properties?.title ?? buildTitle(feature, config);\n const color = feature.properties?.color ?? buildColor(config, index);\n return {\n ...feature,\n properties: {\n ...feature.properties,\n ...(title && { title }),\n ...(color && { color }),\n id: feature.properties?.id ?? generateId(),\n },\n };\n }),\n});\n\n/**\n * Find the biggest array length inside an array.\n * Used to find the biggest array in a Multi-Polygon feature.\n * @param coordinates\n * @returns\n */\nconst getLongestArray = (coordinates: Position[][][]) =>\n coordinates.flat().reduce((result, coord) => (coord.length > result.length ? coord : result), []);\n\n/**\n * Create a Feature<Point> with coordinates where title will be placed.\n * If feature properties contains a coordinates value, it will use it.\n * In case there is not coordinates value, it will get the biggest Polygon inside a feature and calculate\n * the bounding box for those coordinates and finally calculate the bounding box center to place the title.\n * @param geometries\n * @returns\n * @ignore\n */\nexport const prepareTitleForDisplay = (geometries: PolygonFeatures): FeatureCollection<Point> => {\n const features = geometries.features.map((feature) => {\n let coordinates: Position[] | Position | null;\n\n if (feature.properties?.placeCoordinates) {\n coordinates = feature.properties?.placeCoordinates;\n } else if (feature.geometry.type === 'MultiPolygon') {\n const biggestPolygon = getLongestArray(feature.geometry.coordinates);\n const bbox = bboxFromCoordsArray(biggestPolygon);\n coordinates = (bbox && bboxCenter(bbox)) || null;\n } else {\n coordinates = feature.geometry.coordinates.flat();\n }\n\n const id = feature.id ?? feature.properties?.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: { type: 'Point', coordinates },\n properties: {\n ...feature.properties,\n id, // we need id in properties due to promoteId feature\n },\n } as Feature<Point>;\n });\n\n return { type: 'FeatureCollection', bbox: geometries.bbox, features };\n};\n","import type { PolygonFeatures } from '@tomtom-org/maps-sdk/core';\nimport type { FeatureCollection, Point } from 'geojson';\nimport type { SymbolLayerSpecification } from 'maplibre-gl';\nimport type { SymbolLayerSpecWithoutSource, ToBeAddedLayerSpec } from '../shared';\nimport { AbstractMapModule, EventsModule, GeoJSONSourceWithLayers, mapStyleLayerIDs } from '../shared';\nimport { changeLayerProps, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport {\n buildGeometryLayerSpecs,\n buildGeometryTitleLayerSpec,\n prepareGeometryForDisplay,\n prepareTitleForDisplay,\n} from './prepareGeometryForDisplay';\nimport type {\n GeometriesModuleConfig,\n GeometryBeforeLayerConfig,\n GeometryTextConfig,\n} from './types/geometriesModuleConfig';\n\n/**\n * IDs of sources and layers from a geometry module.\n */\ntype GeometrySourcesWithLayers = {\n geometry: GeoJSONSourceWithLayers<PolygonFeatures>;\n geometryLabel: GeoJSONSourceWithLayers<FeatureCollection<Point>>;\n};\n\n/**\n * Geometries Module for displaying polygon areas with custom styling on the map.\n *\n * This module enables visualization of geographic areas (polygons) with customizable\n * colors, borders, and labels. Ideal for displaying search results, administrative\n * boundaries, service areas, or any polygon-based geographic data.\n *\n * @remarks\n * **Features:**\n * - Display single or multiple polygon geometries\n * - Customizable fill colors and opacity\n * - Configurable borders (color, width, opacity)\n * - Optional text labels for geometries\n * - Support for data-driven styling via MapLibre expressions\n * - Layer ordering control\n * - Event handling for user interactions\n *\n * **Data Format:**\n * - Accepts GeoJSON Polygon and MultiPolygon features\n * - Supports FeatureCollection for multiple geometries\n * - Compatible with TomTom Search API geometry results\n *\n * **Styling:**\n * - Use predefined color palettes or custom colors\n * - Apply MapLibre expressions for dynamic styling\n * - Per-feature styling via feature properties\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { GeometriesModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Initialize module\n * const geometriesModule = await GeometriesModule.get(map);\n *\n * // Display a polygon\n * await geometriesModule.show({\n * type: 'Feature',\n * geometry: {\n * type: 'Polygon',\n * coordinates: [[[4.88, 52.37], [4.89, 52.37], [4.89, 52.38], [4.88, 52.38], [4.88, 52.37]]]\n * },\n * properties: {\n * title: 'Area of Interest'\n * }\n * });\n * ```\n *\n * @example\n * Custom styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * fillColor: '#FF5733',\n * fillOpacity: 0.3\n * },\n * lineConfig: {\n * lineColor: '#C70039',\n * lineWidth: 3\n * },\n * textConfig: {\n * textField: ['get', 'name']\n * }\n * });\n *\n * await geometriesModule.show(polygonFeatures);\n * ```\n *\n * @example\n * Multiple geometries with different colors:\n * ```typescript\n * await geometriesModule.show({\n * type: 'FeatureCollection',\n * features: [\n * {\n * type: 'Feature',\n * geometry: { type: 'Polygon', coordinates: [...] },\n * properties: { color: '#FF0000', title: 'Red Zone' }\n * },\n * {\n * type: 'Feature',\n * geometry: { type: 'Polygon', coordinates: [...] },\n * properties: { color: '#00FF00', title: 'Green Zone' }\n * }\n * ]\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * geometriesModule.events.on('click', (feature, lngLat) => {\n * console.log('Clicked geometry:', feature.properties.title);\n * console.log('At coordinates:', lngLat);\n * });\n *\n * geometriesModule.events.on('hover', (feature) => {\n * showTooltip(feature.properties.title);\n * });\n * ```\n *\n * @see [Geometries Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/geometries)\n *\n * @group Geometries\n */\nexport class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLayers, GeometriesModuleConfig> {\n private static lastInstanceIndex = -1;\n\n private titleLayerSpecs!: SymbolLayerSpecWithoutSource;\n private geometryFillLayerSpecs!: SymbolLayerSpecWithoutSource;\n private geometryOutlineLayerSpecs!: SymbolLayerSpecWithoutSource;\n\n private sourceID!: string;\n private fillLayerID!: string;\n private outlineLayerID!: string;\n\n private titleSourceID!: string;\n private titleLayerID!: string;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n *\n * @remarks\n * **Configuration Options:**\n * - `colorConfig`: Fill color and opacity settings\n * - `lineConfig`: Border/outline styling\n * - `textConfig`: Label display configuration\n * - `beforeLayerConfig`: Layer ordering (place above/below other layers)\n *\n * **Multiple Instances:**\n * You can create multiple GeometriesModule instances on the same map,\n * each managing different sets of geometries with different styles.\n *\n * @example\n * Default initialization:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map);\n * ```\n *\n * @example\n * With custom styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * fillColor: 'blue',\n * fillOpacity: 0.25\n * },\n * lineConfig: {\n * lineColor: 'darkblue',\n * lineWidth: 2,\n * lineOpacity: 0.8\n * },\n * textConfig: {\n * textField: ['get', 'title']\n * },\n * beforeLayerConfig: 'top'\n * });\n * ```\n *\n * @example\n * Data-driven styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * // Color based on feature properties\n * fillColor: [\n * 'match',\n * ['get', 'type'],\n * 'residential', '#FFEB3B',\n * 'commercial', '#2196F3',\n * 'industrial', '#9E9E9E',\n * '#E0E0E0' // default\n * ],\n * fillOpacity: 0.4\n * }\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: GeometriesModuleConfig): Promise<GeometriesModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new GeometriesModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: GeometriesModuleConfig) {\n super('geojson', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: GeometriesModuleConfig, restore?: boolean): GeometrySourcesWithLayers {\n if (!restore) {\n GeometriesModule.lastInstanceIndex++;\n this.sourceID = `geometry-${GeometriesModule.lastInstanceIndex}`;\n this.titleSourceID = `geometryTitle-${GeometriesModule.lastInstanceIndex}`;\n const layerIdPrefix = `geometry-${GeometriesModule.lastInstanceIndex}`;\n this.fillLayerID = `${layerIdPrefix}_Fill`;\n this.outlineLayerID = `${layerIdPrefix}_Outline`;\n this.titleLayerID = `${layerIdPrefix}_Title`;\n }\n\n const [geometryFillSpec, geometryOutlineSpec] = buildGeometryLayerSpecs(\n this.fillLayerID,\n this.outlineLayerID,\n config,\n );\n const titleLayerSpec = buildGeometryTitleLayerSpec(this.titleLayerID, config);\n this.titleLayerSpecs = titleLayerSpec;\n this.geometryFillLayerSpecs = geometryFillSpec;\n this.geometryOutlineLayerSpecs = geometryOutlineSpec;\n\n return {\n geometry: new GeoJSONSourceWithLayers(this.mapLibreMap, this.sourceID, [\n { ...geometryFillSpec },\n { ...geometryOutlineSpec },\n ]),\n geometryLabel: new GeoJSONSourceWithLayers(this.mapLibreMap, this.titleSourceID, [\n titleLayerSpec as ToBeAddedLayerSpec<SymbolLayerSpecification>,\n ]),\n };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: GeometriesModuleConfig | undefined) {\n if (config?.textConfig || config?.colorConfig || config?.lineConfig) {\n this.updateLayerAndData(config);\n }\n if (config?.beforeLayerConfig) {\n this.moveBeforeLayer(config.beforeLayerConfig);\n }\n return config;\n }\n\n private moveBeforeLayerID(beforeLayerId?: string) {\n for (const layer of this.sourcesWithLayers.geometry.sourceAndLayerIDs.layerIDs) {\n this.mapLibreMap.moveLayer(layer, beforeLayerId);\n }\n }\n\n /**\n * Positions the geometry layers relative to other map layers.\n *\n * @param layerConfig - Layer positioning configuration.\n * Can be `'top'` to place above all layers, or a specific layer ID.\n *\n * @remarks\n * **Use Cases:**\n * - Place geometries above base map but below labels\n * - Ensure geometries appear above/below specific features\n * - Control visual hierarchy of multiple data layers\n *\n * **Available Layer IDs:**\n * Use predefined layer IDs from `mapStyleLayerIDs` or custom layer IDs.\n *\n * @example\n * ```typescript\n * import { mapStyleLayerIDs } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Place below labels\n * geometries.moveBeforeLayer(mapStyleLayerIDs.lowestLabel);\n *\n * // Place on top\n * geometries.moveBeforeLayer('top');\n * ```\n */\n moveBeforeLayer(layerConfig: GeometryBeforeLayerConfig) {\n this.config = { ...this.config, beforeLayerConfig: layerConfig };\n this.moveBeforeLayerID(layerConfig === 'top' ? this.titleLayerID : mapStyleLayerIDs[layerConfig]);\n }\n\n /**\n * Updates the text/label configuration for displayed geometries.\n *\n * @param textConfig - New text configuration settings.\n *\n * @remarks\n * **Configuration:**\n * - `textField`: MapLibre expression for label text content\n * - Supports dynamic text based on feature properties\n * - Changes apply to currently shown and future geometries\n *\n * @example\n * ```typescript\n * // Show feature property as label\n * geometries.applyTextConfig({\n * textField: ['get', 'name']\n * });\n *\n * // Conditional labels\n * geometries.applyTextConfig({\n * textField: [\n * 'case',\n * ['has', 'label'],\n * ['get', 'label'],\n * ['get', 'title']\n * ]\n * });\n * ```\n */\n applyTextConfig(textConfig: GeometryTextConfig) {\n const config = { ...this.config, textConfig };\n this.updateLayerAndData(config);\n // TODO: is this consistent with _applyConfig?\n this.sourcesWithLayers.geometryLabel.show(\n prepareTitleForDisplay(this.sourcesWithLayers.geometry.shownFeatures),\n );\n this.config = config;\n }\n\n private updateLayerAndData(config: GeometriesModuleConfig) {\n const [geometryFillSpec, geometryOutlineSpec] = buildGeometryLayerSpecs(\n this.fillLayerID,\n this.outlineLayerID,\n config,\n );\n const newTitleLayerSpecs = buildGeometryTitleLayerSpec(this.titleLayerID, config);\n\n changeLayerProps(geometryFillSpec, this.geometryFillLayerSpecs, this.mapLibreMap);\n changeLayerProps(geometryOutlineSpec, this.geometryOutlineLayerSpecs, this.mapLibreMap);\n changeLayerProps(newTitleLayerSpecs, this.titleLayerSpecs, this.mapLibreMap);\n\n this.geometryFillLayerSpecs = geometryFillSpec;\n this.geometryOutlineLayerSpecs = geometryOutlineSpec;\n this.titleLayerSpecs = newTitleLayerSpecs;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previousShownFeatures = this.sourcesWithLayers.geometry.shownFeatures;\n this.initSourcesWithLayers(this.config, true);\n this.config && this._applyConfig(this.config);\n this.show(previousShownFeatures);\n }\n\n /**\n * Displays the given polygon geometries on the map.\n *\n * @param geometries - Polygon features to display. Can be a single Feature,\n * array of Features, or a FeatureCollection.\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown geometries\n * - Applies current module styling configuration\n * - Waits for module to be ready before displaying\n * - Automatically handles both Polygon and MultiPolygon types\n *\n * **Feature Properties:**\n * - `title`: Used for labels if text config is set\n * - `color`: Override fill color per feature\n * - Custom properties accessible in styling expressions\n *\n * @example\n * Single polygon:\n * ```typescript\n * await geometries.show({\n * type: 'Feature',\n * geometry: {\n * type: 'Polygon',\n * coordinates: [[[4.88, 52.37], [4.89, 52.37], [4.89, 52.38], [4.88, 52.37]]]\n * },\n * properties: {\n * title: 'Amsterdam Center',\n * color: '#FF5733'\n * }\n * });\n * ```\n *\n * @example\n * Multiple polygons:\n * ```typescript\n * await geometries.show({\n * type: 'FeatureCollection',\n * features: [\n * { type: 'Feature', geometry: {...}, properties: {...} },\n * { type: 'Feature', geometry: {...}, properties: {...} }\n * ]\n * });\n * ```\n *\n * @example\n * From search API response:\n * ```typescript\n * import { search } from '@tomtom-international/maps-sdk-js/services';\n *\n * const result = await search.geometrySearch({\n * query: 'Amsterdam',\n * geometryList: [{ type: 'CIRCLE', position: [52.37, 4.89], radius: 5000 }]\n * });\n *\n * if (result.results[0].dataSources?.geometry) {\n * await geometries.show(result.results[0].dataSources.geometry);\n * }\n * ```\n */\n async show(geometries: PolygonFeatures) {\n await this.waitUntilModuleReady();\n const geometry = this.sourcesWithLayers.geometry;\n geometry.show(prepareGeometryForDisplay(geometries, this.config));\n this.sourcesWithLayers.geometryLabel.show(prepareTitleForDisplay(geometry.shownFeatures));\n }\n\n /**\n * Removes all geometries from the map.\n *\n * @remarks\n * - Clears both geometry layers and labels\n * - Does not reset styling configuration\n * - Module remains initialized and ready for new data\n *\n * @example\n * ```typescript\n * // Clear displayed geometries\n * await geometries.clear();\n *\n * // Show new geometries\n * await geometries.show(newGeometries);\n * ```\n */\n async clear() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.geometry.clear();\n }\n\n /**\n * Gets the events interface for handling user interactions with geometries.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a geometry\n * - `contextmenu`: User right-clicks on a geometry\n * - `hover`: Mouse enters a geometry\n * - `long-hover`: Mouse hovers over geometry for extended time\n *\n * **Event Features:**\n * - Receive the original feature data passed to `show()`\n * - Access feature properties and geometry\n * - Get click/hover coordinates\n *\n * @example\n * Basic event handling:\n * ```typescript\n * geometries.events.on('click', (feature, lngLat) => {\n * console.log('Clicked:', feature.properties);\n * console.log('Location:', lngLat);\n * });\n * ```\n *\n * @example\n * Multiple handlers:\n * ```typescript\n * // Highlight on hover\n * geometries.events.on('hover', (feature) => {\n * highlightGeometry(feature.id);\n * });\n *\n * // Show details on click\n * geometries.events.on('click', (feature) => {\n * showDetailPanel(feature.properties);\n * });\n *\n * // Context menu\n * geometries.events.on('contextmenu', (feature, lngLat) => {\n * showContextMenu(lngLat, feature);\n * });\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.geometry, this.config?.events);\n }\n}\n","import { AbstractMapModule, EventsModule, HILLSHADE_SOURCE_ID, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport type { HillshadeModuleConfig } from '.';\n\n/**\n * IDs of sources and layers for hillshade module.\n */\ntype HillshadeSourcesWithLayers = {\n hillshade: StyleSourceWithLayers;\n};\n\n/**\n * Map module for displaying terrain shading (hillshade).\n *\n * The HillshadeModule adds realistic terrain depth perception to the map by rendering\n * shadow and highlight effects based on elevation data. This enhances the 3D appearance\n * of mountainous and hilly terrain.\n *\n * @remarks\n * **Features:**\n * - Realistic terrain shading\n * - Uses vector tile elevation data\n * - Lightweight performance impact\n * - Seamlessly integrates with other map layers\n * - Toggle visibility on/off\n *\n * **Common Use Cases:**\n * - Outdoor recreation maps (hiking, skiing)\n * - Geographic/topographic applications\n * - Environmental visualization\n * - Landscape planning tools\n *\n * @example\n * ```typescript\n * // Create the module with hillshade visible\n * const hillshade = await HillshadeModule.getInstance(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * hillshade.setVisible(false);\n *\n * // Listen to events\n * hillshade.events.on('click', (feature, lngLat) => {\n * console.log('Clicked hillshade at:', lngLat);\n * });\n * ```\n *\n * @see [Hillshade Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/hillshade)\n *\n * @group Hillshade\n */\nexport class HillshadeModule extends AbstractMapModule<HillshadeSourcesWithLayers, HillshadeModuleConfig> {\n /**\n * Retrieves a HillshadeModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization and visibility.\n *\n * @returns A promise that resolves to the initialized HillshadeModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `ensureAddedToStyle`: Auto-add hillshade to style if missing\n *\n * **Style Requirement:**\n * - Hillshade must be included in the map style or added via `ensureAddedToStyle`\n * - Some styles may not support hillshade (e.g., satellite)\n *\n * @throws Error if hillshade source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map);\n * ```\n *\n * @example\n * Auto-add to style if missing:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map, {\n * visible: true\n * });\n * ```\n *\n * @example\n * Start hidden:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map, {\n * visible: false\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: HillshadeModuleConfig): Promise<HillshadeModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, HILLSHADE_SOURCE_ID, 'hillshade');\n return new HillshadeModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: HillshadeModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const hillshadeSource = this.mapLibreMap.getSource(HILLSHADE_SOURCE_ID);\n if (!hillshadeSource) {\n throw notInTheStyle(`init ${HillshadeModule.name} with source ID ${HILLSHADE_SOURCE_ID}`);\n }\n return { hillshade: new StyleSourceWithLayers(this.mapLibreMap, hillshadeSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: HillshadeModuleConfig | undefined) {\n this.setVisible(config?.visible ?? false);\n return config;\n }\n\n /**\n * Sets the visibility of the hillshade layer.\n *\n * @param visible - `true` to show hillshade, `false` to hide it.\n *\n * @remarks\n * Changes are applied immediately if the map is ready.\n *\n * @example\n * ```typescript\n * hillshade.setVisible(true); // Show terrain shading\n * hillshade.setVisible(false); // Hide terrain shading\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = {\n ...this.config,\n visible,\n };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.hillshade.setLayersVisible(visible);\n }\n }\n\n /**\n * Checks if the hillshade layer is currently visible.\n *\n * @returns `true` if visible, `false` if hidden.\n *\n * @example\n * ```typescript\n * if (hillshade.isVisible()) {\n * console.log('Terrain shading is active');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.hillshade.isAnyLayerVisible();\n }\n\n /**\n * Gets the events interface for handling user interactions with hillshade.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on the hillshade layer\n * - `contextmenu`: User right-clicks\n * - `hover`: Mouse enters hillshade area\n * - `long-hover`: Extended hover\n *\n * @example\n * ```typescript\n * hillshade.events.on('click', (feature, lngLat) => {\n * console.log('Clicked terrain at:', lngLat);\n * });\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.hillshade, this.config?.events);\n }\n}\n","import type { GlobalConfig } from '@tomtom-org/maps-sdk/core';\nimport type { MapOptions, StyleSpecification } from 'maplibre-gl';\nimport type { MapEventsConfig } from './mapEventsConfig';\n\n/**\n * Array of all available standard style identifiers.\n *\n * This constant provides the complete list of TomTom-hosted standard map styles\n * that can be used when initializing a map. It serves as the source of truth for\n * valid style IDs and is used to derive the {@link StandardStyleID} type.\n *\n * @remarks\n * Use this array when you need to:\n * - Iterate over all available styles (e.g., building a style picker UI)\n * - Validate if a style ID is a standard style\n * - Display available options to users\n *\n * The array is defined as `const` with `as const` assertion to ensure type safety\n * and prevent modifications at runtime.\n *\n * @example\n * ```typescript\n * import { standardStyleIDs } from '@tomtom-org/maps-sdk/map';\n *\n * // Build a dropdown menu with all standard styles\n * const styleSelector = document.getElementById('style-selector');\n * standardStyleIDs.forEach((styleId) => {\n * const option = new Option(styleId);\n * styleSelector.add(option);\n * });\n *\n * // Check if a style ID is valid\n * const isValidStyle = (id: string): boolean => {\n * return standardStyleIDs.includes(id as any);\n * };\n * ```\n *\n * @see {@link StandardStyleID} - The type derived from this array\n *\n * @group Map Style\n */\nexport const standardStyleIDs = [\n 'standardLight',\n 'standardDark',\n // TODO: driving styles not supported in Orbis for now\n 'drivingLight',\n 'drivingDark',\n 'monoLight',\n 'monoDark',\n 'satellite',\n] as const;\n\n/**\n * Identifier for a TomTom-hosted standard map style.\n *\n * Standard styles are officially maintained by TomTom and provide consistent,\n * professionally designed map appearances.\n *\n * @remarks\n * Available styles:\n * - `standardLight`: Default light theme with full detail\n * - `standardDark`: Dark theme for low-light environments\n * - `drivingLight`: Optimized for in-car navigation (light)\n * - `drivingDark`: Optimized for in-car navigation (dark)\n * - `monoLight`: Minimalist monochrome light theme\n * - `monoDark`: Minimalist monochrome dark theme\n * - `satellite`: Satellite imagery basemap\n *\n * @example\n * ```typescript\n * const styleId: StandardStyleID = 'standardLight';\n * ```\n *\n * @group Map Style\n */\nexport type StandardStyleID = (typeof standardStyleIDs)[number];\n\n/**\n * Configuration for a TomTom standard map style.\n *\n * Provides options to customize which modules are included and which style version to use.\n *\n * @example\n * ```typescript\n * // Standard style with all default modules\n * const style: StandardStyle = {\n * id: 'standardLight'\n * };\n *\n * // Exclude traffic modules\n * const styleNoTraffic: StandardStyle = {\n * id: 'standardLight',\n * include: ['hillshade'] // Only include hillshade, exclude traffic\n * };\n *\n * // Use specific style version\n * const versionedStyle: StandardStyle = {\n * id: 'standardDark',\n * version: '1.0.0'\n * };\n * ```\n *\n * @group Map Style\n */\nexport type StandardStyle = {\n /**\n * Standard style identifier.\n *\n * Determines the visual appearance of the map.\n */\n id?: StandardStyleID;\n /**\n * Modules to include when loading the style.\n * * Use this to selectively enable only needed modules for better performance.\n *\n * If not specified, all available modules are included by default.\n * If an empty array is provided, no optional modules will be included.\n *\n * @default All available modules\n *\n * @remarks\n * Available modules:\n * - `trafficIncidents`: Real-time traffic incidents (accidents, closures)\n * - `trafficFlow`: Real-time traffic flow visualization\n * - `hillshade`: Terrain elevation shading\n *\n * @example\n * ```typescript\n * // Include only traffic modules\n * include: ['trafficIncidents', 'trafficFlow']\n *\n * // Include only hillshade\n * include: ['hillshade']\n *\n * // Include no optional modules\n * include: []\n * ```\n */\n include?: StyleModule[];\n /**\n * Style version to load.\n *\n * Allows pinning to a specific style version for consistency.\n * If not specified, uses the latest SDK-supported version.\n *\n * @default Latest SDK-supported version\n *\n * @example\n * ```typescript\n * version: '1.0.0'\n * ```\n */\n version?: string;\n};\n\n/**\n * Configuration for a custom map style.\n *\n * Allows using your own map style either via URL or direct JSON specification.\n *\n * @remarks\n * Use custom styles for:\n * - Branded map appearances\n * - Specialized use cases (indoor maps, thematic maps)\n * - Integration with custom tile servers\n *\n * @example\n * ```typescript\n * // Load from URL\n * const urlStyle: CustomStyle = {\n * url: 'https://example.com/my-custom-style.json'\n * };\n *\n * // Direct JSON specification\n * const jsonStyle: CustomStyle = {\n * json: {\n * version: 8,\n * sources: { ... },\n * layers: [ ... ]\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport type CustomStyle = {\n /**\n * URL to a MapLibre/Mapbox style JSON.\n *\n * The URL should not include the API key - it will be automatically added.\n * Mutually exclusive with the `json` property.\n *\n * @example\n * ```typescript\n * url: 'https://api.tomtom.com/style/1/style/my-custom-style'\n * ```\n */\n url?: string;\n /**\n * Direct style specification as JSON.\n *\n * Provide the complete MapLibre Style Specification object.\n * Mutually exclusive with the `url` property.\n *\n * @see [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/)\n *\n * @example\n * ```typescript\n * json: {\n * version: 8,\n * sources: {\n * 'my-source': { type: 'vector', url: '...' }\n * },\n * layers: [\n * { id: 'background', type: 'background', paint: { 'background-color': '#f0f0f0' } }\n * ]\n * }\n * ```\n */\n json?: StyleSpecification;\n};\n\n/**\n * Array of all available style modules.\n *\n * @group Map Style\n */\nexport const styleModules = ['trafficIncidents', 'trafficFlow', 'hillshade'] as const;\n\n/**\n * Optional map modules that can be included with a style.\n *\n * @remarks\n * - `trafficIncidents`: Shows real-time traffic incidents on the map\n * - `trafficFlow`: Shows real-time traffic flow with color-coded speeds\n * - `hillshade`: Adds terrain elevation shading for topographic context\n *\n * @group Map Style\n */\nexport type StyleModule = (typeof styleModules)[number];\n\n/**\n * Map style specification for initialization.\n *\n * Defines which map style to load and how it should be configured.\n * Supports standard TomTom styles or custom styles.\n *\n * @remarks\n * Three input formats:\n * 1. **Simple ID**: Just pass a standard style ID string\n * 2. **Standard style object**: Use a TomTom style with custom configuration\n * 3. **Custom style object**: Load your own style from URL or JSON\n *\n * @example\n * ```typescript\n * // 1. Simple standard style\n * style: 'standardLight'\n *\n * // 2. Standard style with configuration\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * }\n *\n * // 3. Custom style from URL\n * style: {\n * type: 'custom',\n * url: 'https://example.com/style.json'\n * }\n *\n * // 4. Custom style from JSON\n * style: {\n * type: 'custom',\n * json: { version: 8, sources: {...}, layers: [...] }\n * }\n * ```\n *\n * @group Map Style\n */\nexport type StyleInput = StandardStyleID | (StandardStyle & { type: 'standard' }) | (CustomStyle & { type: 'custom' });\n\n/**\n * MapLibre-specific options for advanced map configuration.\n *\n * Extends MapLibre GL JS MapOptions, excluding style and attribution control\n * which are handled by the TomTom SDK.\n *\n * @remarks\n * Includes options for:\n * - Initial viewport (center, zoom, bearing, pitch)\n * - Interaction controls (zoom, rotation, drag)\n * - Rendering options (antialiasing, terrain)\n * - Localization and accessibility\n *\n * @see [MapLibre MapOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/)\n *\n * @group Map\n */\nexport type MapLibreOptions = Omit<MapOptions, 'style' | 'attributionControl'>;\n\n/**\n * Parameters for initializing a TomTom map instance.\n *\n * Combines global SDK configuration with map-specific settings like style, events, and MapLibre options.\n * All GlobalConfig properties (key, baseURL, etc.) are optional and will be merged from global configuration.\n * Only mapLibre.container is strictly required.\n *\n * @example\n * ```typescript\n * const mapParams: TomTomMapParams = {\n * key: 'your-api-key',\n * style: 'standardLight',\n * events: {\n * onClick: (event) => console.log('Map clicked', event)\n * },\n * mapLibre: {\n * container: 'map-container',\n * center: [4.9041, 52.3676],\n * zoom: 12\n * }\n * };\n * ```\n *\n * @group Map\n */\nexport type TomTomMapParams = Partial<GlobalConfig> & {\n /**\n * Map style to load.\n *\n * If not specified, defaults to 'standardLight'.\n *\n * @default 'standardLight'\n *\n * @example\n * ```typescript\n * // Use dark theme\n * style: 'standardDark'\n *\n * // Custom configuration\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow']\n * }\n * ```\n */\n style?: StyleInput;\n\n /**\n * Event handler configuration for map interactions.\n *\n * Define callbacks for various map events like clicks, hovers, and movements.\n *\n * @example\n * ```typescript\n * events: {\n * onClick: (event) => {\n * console.log('Clicked at', event.lngLat);\n * },\n * onMoveEnd: () => {\n * console.log('Map moved to', map.getCenter());\n * }\n * }\n * ```\n */\n events?: MapEventsConfig;\n\n /**\n * MapLibre-specific options for map configuration.\n *\n * Includes options for viewport settings, interaction controls, rendering options, and more.\n *\n * @example\n * ```typescript\n * mapLibre: {\n * container: 'map',\n * center: [4.9041, 52.3676],\n * zoom: 12,\n * pitch: 45,\n * bearing: -17.6,\n * antialias: true,\n * maxZoom: 18,\n * minZoom: 8\n * }\n * ```\n */\n mapLibre: MapLibreOptions;\n};\n\n/**\n * Complete TomTom map parameters after merging with global configuration.\n * This type represents the fully resolved configuration used internally by the SDK.\n *\n * @ignore\n */\nexport type InternalTomTomMapParams = GlobalConfig & TomTomMapParams;\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * Main route line foreground color.\n * @ignore\n */\nexport const ROUTE_LINE_FOREGROUND_COLOR = '#36A8F0';\n\n/**\n * Main route outline color.\n */\nexport const ROUTE_LINE_OUTLINE_COLOR = '#105287';\n\n/**\n * Deselected route line foreground color.\n * @ignore\n */\nexport const DESELECTED_FOREGROUND_COLOR = '#ABAFB3';\n\n/**\n * Deselected route line outline color.\n * @ignore\n */\nexport const DESELECTED_OUTLINE_COLOR = '#3C4956';\n\n/**\n * @ignore\n */\nexport const DESELECTED_SECONDARY_COLOR = '#727C85';\n\n/**\n * Main route line width based on zoom level.\n * @ignore\n */\nexport const ROUTE_LINE_FOREGROUND_WIDTH: ExpressionSpecification = [\n 'interpolate',\n ['linear'],\n ['zoom'],\n 1,\n 3,\n 5,\n 4,\n 10,\n 7,\n 18,\n 10,\n];\n\n/**\n * Used for showing/hiding layer depending on layer being part of selected route or not.\n *\n * @remarks\n * Add this to layers that depend on whether they are part of the selected route or not.\n *\n * @example:\n * filter: SELECTED_ROUTE_FILTER\n\n * @group Routing\n */\nexport const SELECTED_ROUTE_FILTER: ExpressionSpecification = ['==', ['get', 'routeState'], 'selected'];\n\n/**\n * Used for showing/hiding layer depending on layer being part of deselected route or not.\n *\n * @remarks\n * Add this to layers that depend on whether they are part of the deselected route or not.\n *\n * @example:\n * filter: DESELECTED_ROUTE_FILTER\n\n * @group Routing\n */\nexport const DESELECTED_ROUTE_FILTER: ExpressionSpecification = ['==', ['get', 'routeState'], 'deselected'];\n\n/**\n * @ignore\n */\nexport const MAJOR_DELAY_COLOR = '#AD0000';\n/**\n * @ignore\n */\nexport const MODERATE_DELAY_COLOR = '#FB2D09';\n/**\n * @ignore\n */\nexport const MINOR_DELAY_LABEL_COLOR = '#f58240';\n/**\n * @ignore\n */\nexport const UNKNOWN_DELAY_COLOR = '#000000';\n","import type {\n DataDrivenPropertyValueSpecification,\n FormattedSpecification,\n SymbolLayerSpecification,\n} from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { pinLayerBaseSpec } from '../../shared/layers/symbolLayers';\nimport { ChargingStopsConfig, ChargingStopTextConfig } from '../types/routeModuleConfig';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\nconst chargingStopTextField = (\n config: ChargingStopTextConfig | undefined,\n): DataDrivenPropertyValueSpecification<FormattedSpecification> => {\n if (config?.visible === false) {\n return '';\n }\n\n return (\n config?.title ?? [\n 'format',\n ['get', 'title'],\n '\\n',\n ['get', 'chargingPower'],\n ' • ',\n ['get', 'chargingDuration'],\n ]\n );\n};\n\n/**\n * @ignore\n * @see toDisplayChargingStops\n */\nexport const chargingStopSymbol = (\n config: ChargingStopsConfig | undefined,\n): LayerSpecTemplate<SymbolLayerSpecification> => {\n return {\n ...pinLayerBaseSpec,\n filter: SELECTED_ROUTE_FILTER,\n minzoom: 4,\n layout: {\n ...pinLayerBaseSpec.layout,\n 'text-field': chargingStopTextField(config?.text),\n },\n paint: {\n ...pinLayerBaseSpec.paint,\n },\n };\n};\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\nconst commonProps = {\n filter: SELECTED_ROUTE_FILTER,\n minzoom: 16,\n};\n\nconst commonLineProps: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonProps,\n type: 'line',\n layout: { 'line-cap': 'round' },\n};\n\n/**\n * @ignore\n */\nexport const instructionOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonLineProps,\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 16, 14, 22, 20],\n 'line-color': 'grey',\n },\n};\n\n/**\n * @ignore\n */\nexport const instructionLine: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonLineProps,\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 16, 12, 22, 17],\n 'line-color': 'white',\n },\n};\n\n/**\n * @ignore\n */\nexport const INSTRUCTION_ARROW_IMAGE_ID = 'instruction-arrow';\n\n/**\n * @ignore\n */\nexport const instructionArrow: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...commonProps,\n type: 'symbol',\n layout: {\n 'icon-allow-overlap': true,\n 'icon-image': INSTRUCTION_ARROW_IMAGE_ID, // Will be updated with instance suffix in config\n 'icon-rotation-alignment': 'map',\n 'icon-rotate': ['get', 'lastPointBearingDegrees'],\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 16, 1, 22, 2],\n },\n};\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { ROUTE_LINE_FOREGROUND_WIDTH, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeFerriesLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n 'line-color': '#6dc4ed',\n },\n};\n\n/**\n * @ignore\n */\nexport const routeFerriesSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 6,\n // zoom where the map POI naturally appears:\n maxzoom: 16.5,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-image': 'poi-ferry_terminal',\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.8, 16.5, 1],\n // helps smooth the transition from along-route to map-poi, which also has a label in it:\n 'icon-ignore-placement': true,\n },\n};\n","import type { ExpressionSpecification, LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport {\n DESELECTED_FOREGROUND_COLOR,\n DESELECTED_OUTLINE_COLOR,\n DESELECTED_ROUTE_FILTER,\n ROUTE_LINE_FOREGROUND_COLOR,\n ROUTE_LINE_FOREGROUND_WIDTH,\n ROUTE_LINE_OUTLINE_COLOR,\n SELECTED_ROUTE_FILTER,\n} from './shared';\n\n/**\n * @ignore\n */\nexport const routeLineBaseTemplate: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n 'line-sort-key': ['get', 'index'],\n },\n};\n\nconst outlineLineWidth: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 1, 5, 5, 6, 10, 10, 18, 14];\n\n/**\n * @ignore\n */\nexport const routeDeselectedOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: DESELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': DESELECTED_OUTLINE_COLOR,\n 'line-width': outlineLineWidth,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeDeselectedLine: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: DESELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': DESELECTED_FOREGROUND_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: SELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': ROUTE_LINE_OUTLINE_COLOR,\n 'line-width': outlineLineWidth,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeMainLine = (props?: { color?: string }): LayerSpecTemplate<LineLayerSpecification> => ({\n ...routeLineBaseTemplate,\n filter: SELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': props?.color ?? ROUTE_LINE_FOREGROUND_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n});\n\n/**\n * @ignore\n */\nexport const routeLineArrows: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n layout: {\n 'symbol-placement': 'line',\n 'icon-image': 'roads-arrow-white',\n // The current arrow icon seems to point backwards otherwise. Check with caution!\n 'icon-rotate': 180,\n },\n};\n\n/**\n * @ignore\n */\nexport const SELECTED_SUMMARY_POPUP_IMAGE_ID = 'selected-route-summary-popup';\n/**\n * @ignore\n */\nexport const DESELECTED_SUMMARY_POPUP_IMAGE_ID = 'deselected-route-summary-popup';\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeTollRoadsOutline: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 1, 9, 5, 11, 10, 15, 18, 20],\n 'line-color': '#BEBFFA',\n },\n};\n\n/**\n * @ignore\n */\nexport const routeTollRoadsSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 4,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-image': 'poi-toll_plaza',\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 4, 0.8, 16.5, 1],\n },\n};\n","import type { ExpressionSpecification, LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT } from '../../shared/layers/commonLayerProps';\nimport {\n MAJOR_DELAY_COLOR,\n MINOR_DELAY_LABEL_COLOR,\n MODERATE_DELAY_COLOR,\n SELECTED_ROUTE_FILTER,\n UNKNOWN_DELAY_COLOR,\n} from './shared';\n\nconst EXTRA_FOREGROUND_LINE_WIDTH: ExpressionSpecification = [\n 'interpolate',\n ['linear'],\n ['zoom'],\n 1,\n 2,\n 5,\n 3,\n 10,\n 4,\n 18,\n 6,\n];\n\n/**\n * @ignore\n */\nexport const routeIncidentsBGLine: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n layout: { 'line-cap': 'round' },\n paint: {\n 'line-width': EXTRA_FOREGROUND_LINE_WIDTH,\n 'line-color': [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'minor',\n '#FFC105',\n 'moderate',\n MODERATE_DELAY_COLOR,\n 'major',\n MAJOR_DELAY_COLOR,\n // other\n '#C7D2D8',\n ],\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsDashedLine: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n filter: ['in', ['get', 'magnitudeOfDelay'], ['literal', ['unknown', 'indefinite']]],\n layout: { 'line-join': 'round' },\n paint: {\n 'line-width': EXTRA_FOREGROUND_LINE_WIDTH,\n 'line-color': [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'unknown',\n 'rgba(190, 39, 27, 1)',\n // other (undefined):\n 'rgba(137, 150, 168, 1)',\n ],\n 'line-dasharray': [1.5, 1],\n },\n};\n\n/**\n * @ignore\n */\nexport const magnitudeOfDelayTextColor: ExpressionSpecification = [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'minor',\n MINOR_DELAY_LABEL_COLOR,\n 'moderate',\n MODERATE_DELAY_COLOR,\n 'major',\n MAJOR_DELAY_COLOR,\n 'indefinite',\n '#666666',\n // other\n UNKNOWN_DELAY_COLOR,\n];\n\nconst routeIncidentsSymbolBase: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 6,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-ignore-placement': true,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsJamSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...routeIncidentsSymbolBase,\n filter: ['all', ['has', 'jamIconID'], routeIncidentsSymbolBase.filter as ExpressionSpecification],\n layout: {\n ...routeIncidentsSymbolBase.layout,\n 'icon-image': ['get', 'jamIconID'],\n 'icon-anchor': 'bottom-left',\n 'text-anchor': 'bottom-left',\n // Jam symbols have delay labels in them:\n 'text-field': ['get', 'title'],\n 'text-font': [MAP_BOLD_FONT],\n 'text-offset': [3.9, -1.4],\n 'text-size': 13,\n },\n paint: {\n ...routeIncidentsSymbolBase.paint,\n 'text-color': magnitudeOfDelayTextColor,\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': 1,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsCauseSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...routeIncidentsSymbolBase,\n filter: ['all', ['has', 'causeIconID'], routeIncidentsSymbolBase.filter as ExpressionSpecification],\n layout: {\n ...routeIncidentsSymbolBase.layout,\n 'icon-image': ['get', 'causeIconID'],\n 'icon-anchor': 'bottom-right',\n // Cause symbols have no label in them.\n },\n paint: { ...routeIncidentsSymbolBase.paint },\n};\n","import type { LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { ROUTE_LINE_FOREGROUND_WIDTH, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeTunnelsLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n 'line-color': '#000000',\n 'line-opacity': 0.3,\n },\n};\n","import type { LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport {\n ROUTE_LINE_FOREGROUND_COLOR,\n ROUTE_LINE_FOREGROUND_WIDTH,\n ROUTE_LINE_OUTLINE_COLOR,\n SELECTED_ROUTE_FILTER,\n} from './shared';\n\n/**\n * @ignore\n */\nexport const routeVehicleRestrictedBackgroundLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-color': ROUTE_LINE_OUTLINE_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeVehicleRestrictedDottedLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-color': ROUTE_LINE_FOREGROUND_COLOR,\n 'line-width': ['interpolate', ['linear'], ['zoom'], 1, 2, 5, 3, 10, 5, 18, 7],\n 'line-dasharray': [0, 1.5],\n },\n};\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT, MAP_MEDIUM_FONT } from '../../shared/layers/commonLayerProps';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport { DESELECTED_SUMMARY_POPUP_IMAGE_ID, SELECTED_SUMMARY_POPUP_IMAGE_ID } from './routeMainLineLayers';\nimport { magnitudeOfDelayTextColor } from './routeTrafficSectionLayers';\nimport { DESELECTED_SECONDARY_COLOR, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const TRAFFIC_CLEAR_IMAGE_ID = 'traffic-clear';\n/**\n * @ignore\n */\nexport const TRAFFIC_MAJOR_IMAGE_ID = 'traffic-major';\n/**\n * @ignore\n */\nexport const TRAFFIC_MODERATE_IMAGE_ID = 'traffic-moderate';\n/**\n * @ignore\n */\nexport const TRAFFIC_MINOR_IMAGE_ID = 'traffic-minor';\n\nconst hasFormattedTraffic: ExpressionSpecification = ['has', 'formattedTraffic'];\n\n/**\n * Builds the summary bubble symbol layer specification with instance-specific image IDs.\n * @param instanceIndex - Optional instance index for supporting multiple RoutingModule instances\n * @ignore\n */\nexport const buildSummaryBubbleSymbolPoint = (instanceIndex?: number): LayerSpecTemplate<SymbolLayerSpecification> => {\n const selectedImageID =\n instanceIndex !== undefined\n ? suffixNumber(SELECTED_SUMMARY_POPUP_IMAGE_ID, instanceIndex)\n : SELECTED_SUMMARY_POPUP_IMAGE_ID;\n const deselectedImageID =\n instanceIndex !== undefined\n ? suffixNumber(DESELECTED_SUMMARY_POPUP_IMAGE_ID, instanceIndex)\n : DESELECTED_SUMMARY_POPUP_IMAGE_ID;\n const trafficClearID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_CLEAR_IMAGE_ID, instanceIndex) : TRAFFIC_CLEAR_IMAGE_ID;\n const trafficMajorID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_MAJOR_IMAGE_ID, instanceIndex) : TRAFFIC_MAJOR_IMAGE_ID;\n const trafficModerateID =\n instanceIndex !== undefined\n ? suffixNumber(TRAFFIC_MODERATE_IMAGE_ID, instanceIndex)\n : TRAFFIC_MODERATE_IMAGE_ID;\n const trafficMinorID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_MINOR_IMAGE_ID, instanceIndex) : TRAFFIC_MINOR_IMAGE_ID;\n\n return {\n type: 'symbol',\n layout: {\n 'icon-image': ['case', SELECTED_ROUTE_FILTER, selectedImageID, deselectedImageID],\n 'symbol-placement': 'point',\n 'icon-rotation-alignment': 'viewport',\n 'text-rotation-alignment': 'viewport',\n 'symbol-sort-key': ['case', SELECTED_ROUTE_FILTER, 0, 1],\n 'icon-text-fit': 'both',\n 'icon-text-fit-padding': [10, 5, 5, 10],\n 'text-font': [MAP_MEDIUM_FONT],\n 'text-size': 13,\n 'icon-padding': 0,\n 'text-justify': 'left',\n 'text-line-height': 1.5,\n 'text-field': [\n 'format',\n ['get', 'formattedDuration'],\n {\n 'text-font': ['literal', [MAP_BOLD_FONT]],\n 'text-color': ['case', SELECTED_ROUTE_FILTER, 'black', DESELECTED_SECONDARY_COLOR],\n },\n ['concat', '\\t\\t', ['get', 'formattedDistance']],\n { 'text-color': DESELECTED_SECONDARY_COLOR },\n ['case', hasFormattedTraffic, '\\n', ''],\n {},\n [\n 'image',\n [\n 'case',\n hasFormattedTraffic,\n [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'major',\n trafficMajorID,\n 'moderate',\n trafficModerateID,\n 'minor',\n trafficMinorID,\n trafficClearID,\n ],\n '',\n ],\n ],\n {},\n ['case', hasFormattedTraffic, ['concat', ' ', ['get', 'formattedTraffic']], ''],\n {\n 'text-font': ['literal', [MAP_BOLD_FONT]],\n 'text-color': magnitudeOfDelayTextColor,\n },\n ],\n },\n paint: {\n 'icon-translate': [0, -35],\n 'text-translate': [0, -35],\n },\n };\n};\n\n/**\n * Default summary bubble symbol layer (without instance suffix)\n * @ignore\n */\nexport const summaryBubbleSymbolPoint: LayerSpecTemplate<SymbolLayerSpecification> = buildSummaryBubbleSymbolPoint();\n","import type { PlaceDisplayProps } from '../../places';\n\n/**\n * @group Routing\n */\nexport const START_INDEX = 'start';\n/**\n * @group Routing\n */\nexport const MIDDLE_INDEX = 'middle';\n/**\n * @group Routing\n */\nexport const FINISH_INDEX = 'finish';\n/**\n * @group Routing\n */\nexport type WaypointIndexType = typeof START_INDEX | typeof MIDDLE_INDEX | typeof FINISH_INDEX;\n\n/**\n * Display properties for a waypoint marker on the map.\n *\n * Extends location display properties with waypoint-specific information\n * including position in the route and stop numbering.\n *\n * @remarks\n * Waypoints are displayed differently based on their position:\n * - **Start**: Origin marker (often \"A\" or green pin)\n * - **Middle**: Numbered stop markers (1, 2, 3, etc.)\n * - **Finish**: Destination marker (often \"B\" or red pin)\n *\n * @example\n * ```typescript\n * // Start waypoint\n * const start: WaypointDisplayProps = {\n * id: 'waypoint-0',\n * iconID: 'waypoint-start',\n * index: 0,\n * indexType: 'start',\n * title: 'Amsterdam Central Station'\n * };\n *\n * // Intermediate stop\n * const stop: WaypointDisplayProps = {\n * id: 'waypoint-1',\n * iconID: 'waypoint-stop',\n * index: 1,\n * indexType: 'middle',\n * stopDisplayIndex: 1,\n * title: 'Schiphol Airport'\n * };\n *\n * // Destination\n * const finish: WaypointDisplayProps = {\n * id: 'waypoint-2',\n * iconID: 'waypoint-finish',\n * index: 2,\n * indexType: 'finish',\n * title: 'Rotterdam Central Station'\n * };\n * ```\n *\n * @group Routing\n */\nexport type WaypointDisplayProps = PlaceDisplayProps & {\n /**\n * The index of the waypoint in relation to the other waypoints.\n *\n * @remarks\n * Zero-based index of this waypoint in the complete waypoints array,\n * including start, all stops, and finish.\n *\n * @example\n * ```typescript\n * index: 0 // First waypoint (start)\n * index: 1 // Second waypoint (first stop or finish)\n * index: 2 // Third waypoint\n * ```\n */\n index: number;\n\n /**\n * The type associated to the index, describing how the waypoint sits in the list of waypoints.\n *\n * @remarks\n * Determines the waypoint's role and visual representation:\n * - `start`: Origin point\n * - `middle`: Intermediate stop\n * - `finish`: Final destination\n *\n * This affects icon selection and labeling behavior.\n */\n indexType: WaypointIndexType;\n\n /**\n * The stop index to be displayed.\n *\n * @remarks\n * Stops are the non-soft waypoints added between origin and destination,\n * numbered starting from 1. Only present for middle waypoints.\n *\n * **Display Behavior:**\n * - Start waypoint: undefined\n * - First stop: 1\n * - Second stop: 2\n * - Finish waypoint: undefined\n *\n * Used for displaying stop numbers (e.g., \"Stop 1\", \"Stop 2\") in the UI.\n *\n * @example\n * ```typescript\n * stopDisplayIndex: 1 // First intermediate stop\n * stopDisplayIndex: 2 // Second intermediate stop\n * stopDisplayIndex: undefined // Start or finish waypoint\n * ```\n */\n stopDisplayIndex?: number;\n};\n\n/**\n * @ignore\n */\nexport const INDEX_TYPE = 'indexType';\n\n/**\n * @ignore\n */\nexport const STOP_DISPLAY_INDEX = 'stopDisplayIndex';\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT } from '../../shared/layers/commonLayerProps';\nimport {\n ICON_ID,\n pinIconBaseLayout,\n pinIconBasePaint,\n pinTextBaseLayout,\n pinTextBasePaint,\n} from '../../shared/layers/symbolLayers';\nimport { INDEX_TYPE, MIDDLE_INDEX, STOP_DISPLAY_INDEX } from '../types/waypointDisplayProps';\n\n/**\n * Waypoint start image ID.\n * @group Routing\n */\nexport const WAYPOINT_START_IMAGE_ID = 'waypointStart';\n/**\n * Waypoint stop image ID.\n *\n * @remarks\n * Used for intermediate waypoints in a route.\n *\n * @group Routing.\n */\nexport const WAYPOINT_STOP_IMAGE_ID = 'waypointStop';\n/**\n * Soft waypoint image ID.\n *\n * @remarks\n * This is currently unsupported in Orbis maps.\n *\n * @group Routing\n */\nexport const WAYPOINT_SOFT_IMAGE_ID = 'waypointSoft';\n/**\n * Waypoint finish image ID.\n *\n * @group Routing\n */\nexport const WAYPOINT_FINISH_IMAGE_ID = 'waypointFinish';\n\nconst isSoftWaypoint: ExpressionSpecification = [\n 'all',\n ['==', ['get', INDEX_TYPE], MIDDLE_INDEX],\n ['!', ['has', STOP_DISPLAY_INDEX]],\n];\n\nconst pinIndexLabelPaint: SymbolLayerSpecification['paint'] = {\n 'text-color': '#ffffff',\n};\n\nconst pinIndexLabelLayout: SymbolLayerSpecification['layout'] = {\n // optional centered text to indicate stop numbers (1, 2 ...):\n 'text-field': ['get', STOP_DISPLAY_INDEX],\n 'text-font': [MAP_BOLD_FONT],\n 'text-size': ['interpolate', ['linear'], ['zoom'], 13, 14, 18, 16],\n 'text-offset': [0, -1.6],\n // pin vs circle:\n 'icon-anchor': [\n 'case',\n isSoftWaypoint,\n 'center',\n // else\n 'bottom',\n ],\n 'text-allow-overlap': true,\n};\n\n// TODO: reusable display of pins with indexes, not just waypoints\n/**\n * @ignore\n */\nexport const waypointSymbols: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n paint: {\n ...pinIconBasePaint,\n ...pinIndexLabelPaint,\n },\n layout: {\n ...pinIconBaseLayout,\n ...pinIndexLabelLayout,\n 'symbol-sort-key': [\n 'case',\n ['==', ['get', ICON_ID], WAYPOINT_SOFT_IMAGE_ID],\n 0,\n ['abs', ['-', ['get', 'index'], 1000]],\n ],\n },\n};\n\n/**\n * @ignore\n */\nexport const waypointLabels: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n paint: {\n ...pinTextBasePaint,\n 'text-color': 'black',\n 'text-halo-width': 1.5,\n 'text-halo-color': '#ffffff',\n },\n layout: {\n ...pinTextBaseLayout,\n 'text-anchor': 'top',\n 'text-offset': [0, 0.4],\n },\n};\n","import { mapStyleLayerIDs } from '../../shared';\nimport type { RouteLayersConfig, RoutingModuleConfig } from '../types/routeModuleConfig';\nimport { chargingStopSymbol } from './chargingStopLayers';\nimport { instructionArrow, instructionLine, instructionOutline } from './guidanceLayers';\nimport { routeFerriesLine, routeFerriesSymbol } from './routeFerrySectionLayers';\nimport {\n routeDeselectedLine,\n routeDeselectedOutline,\n routeLineArrows,\n routeMainLine,\n routeOutline,\n} from './routeMainLineLayers';\nimport { routeTollRoadsOutline, routeTollRoadsSymbol } from './routeTollRoadLayers';\nimport {\n routeIncidentsBGLine,\n routeIncidentsCauseSymbol,\n routeIncidentsDashedLine,\n routeIncidentsJamSymbol,\n} from './routeTrafficSectionLayers';\nimport { routeTunnelsLine } from './routeTunnelSectionLayers';\nimport { routeVehicleRestrictedBackgroundLine, routeVehicleRestrictedDottedLine } from './routeVehicleRestrictedLayers';\nimport { buildSummaryBubbleSymbolPoint, summaryBubbleSymbolPoint } from './summaryBubbleLayers';\nimport { waypointLabels, waypointSymbols } from './waypointLayers';\n\n/**\n * Helper function to add layer ID prefix to beforeID references, but only for internal routing layer IDs\n * @ignore\n */\nconst prefixBeforeID = (beforeID: string | undefined, layerIDPrefix: string | undefined): string | undefined => {\n if (!beforeID || !layerIDPrefix) {\n return beforeID;\n }\n // Don't prefix map style layer IDs (they start with capital letters or contain specific prefixes)\n if (beforeID.startsWith('route') || beforeID.startsWith('waypoint')) {\n return `${layerIDPrefix}-${beforeID}`;\n }\n return beforeID;\n};\n\n/**\n * Helper function to process additional layers and prefix their beforeID fields\n * @ignore\n */\nconst prefixBeforeIDs = (\n additional: Record<string, any> | undefined,\n layerIDPrefix: string | undefined,\n): Record<string, any> | undefined => {\n if (!additional || !layerIDPrefix) {\n return additional;\n }\n\n return Object.fromEntries(\n Object.entries(additional).map(([key, layer]) => [\n key,\n layer?.beforeID ? { ...layer, beforeID: prefixBeforeID(layer.beforeID, layerIDPrefix) } : layer,\n ]),\n );\n};\n\n/**\n * Helper function to add instance suffix to image IDs for supporting multiple RoutingModule instances\n * @ignore\n */\nconst suffixImageID = (imageID: string | undefined, instanceIndex: number | undefined): string | undefined => {\n if (!imageID || instanceIndex === undefined) {\n return imageID;\n }\n return `${imageID}-${instanceIndex}`;\n};\n\n/**\n * Generates the routing layers configuration for route visualization on the map.\n * @param config - Optional routing module configuration to customize layer properties.\n * @param layerIDPrefix - Optional prefix to add to layer IDs for supporting multiple instances.\n * @param instanceIndex - Optional instance index for image ID suffixes.\n * @ignore\n */\nexport const buildRoutingLayers = (\n config: RoutingModuleConfig = {},\n layerIDPrefix?: string,\n instanceIndex?: number,\n): Required<RouteLayersConfig> => {\n const configLayers = config.layers;\n const configSectionLayers = configLayers?.sections;\n const mainColor = config.theme?.mainColor;\n\n return {\n mainLines: {\n routeLineArrows: {\n ...routeLineArrows,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configLayers?.mainLines?.routeLineArrows,\n },\n routeLine: {\n ...routeMainLine({ color: mainColor }),\n beforeID: prefixBeforeID('routeIncidentBackgroundLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeLine,\n },\n routeOutline: {\n ...routeOutline,\n beforeID: prefixBeforeID('routeLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeOutline,\n },\n routeDeselectedLine: {\n ...routeDeselectedLine,\n beforeID: prefixBeforeID('routeOutline', layerIDPrefix),\n ...configLayers?.mainLines?.routeDeselectedLine,\n },\n routeDeselectedOutline: {\n ...routeDeselectedOutline,\n beforeID: prefixBeforeID('routeDeselectedLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeDeselectedOutline,\n },\n ...prefixBeforeIDs(configLayers?.mainLines?.additional, layerIDPrefix),\n },\n waypoints: {\n routeWaypointSymbol: {\n ...waypointSymbols,\n beforeID: prefixBeforeID('routeSummaryBubbleSymbol', layerIDPrefix),\n ...configLayers?.waypoints?.routeWaypointSymbol,\n },\n routeWaypointLabel: {\n ...waypointLabels,\n beforeID: prefixBeforeID('routeWaypointSymbol', layerIDPrefix),\n ...configLayers?.waypoints?.routeWaypointLabel,\n },\n ...prefixBeforeIDs(configLayers?.waypoints?.additional, layerIDPrefix),\n },\n chargingStops: {\n routeChargingStopSymbol: {\n ...chargingStopSymbol(config.chargingStops),\n beforeID: prefixBeforeID('routeWaypointSymbol', layerIDPrefix),\n ...configLayers?.chargingStops?.routeChargingStopSymbol,\n },\n ...prefixBeforeIDs(configLayers?.chargingStops?.additional, layerIDPrefix),\n },\n sections: {\n incident: {\n routeIncidentJamSymbol: {\n ...routeIncidentsJamSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentJamSymbol,\n },\n routeIncidentCauseSymbol: {\n ...routeIncidentsCauseSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentCauseSymbol,\n },\n routeIncidentBackgroundLine: {\n ...routeIncidentsBGLine,\n beforeID: prefixBeforeID('routeIncidentDashedLine', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentBackgroundLine,\n },\n routeIncidentDashedLine: {\n ...routeIncidentsDashedLine,\n beforeID: prefixBeforeID('routeTunnelLine', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentDashedLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.incident?.additional, layerIDPrefix),\n },\n ferry: {\n routeFerryLine: {\n ...routeFerriesLine,\n beforeID: prefixBeforeID('routeLineArrows', layerIDPrefix),\n ...configSectionLayers?.ferry?.routeFerryLine,\n },\n routeFerrySymbol: {\n ...routeFerriesSymbol,\n beforeID: prefixBeforeID('routeIncidentJamSymbol', layerIDPrefix),\n ...configSectionLayers?.ferry?.routeFerrySymbol,\n },\n ...prefixBeforeIDs(configSectionLayers?.ferry?.additional, layerIDPrefix),\n },\n tollRoad: {\n routeTollRoadOutline: {\n ...routeTollRoadsOutline,\n beforeID: prefixBeforeID('routeDeselectedOutline', layerIDPrefix),\n ...configSectionLayers?.tollRoad?.routeTollRoadOutline,\n },\n routeTollRoadSymbol: {\n ...routeTollRoadsSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.tollRoad?.routeTollRoadSymbol,\n },\n ...prefixBeforeIDs(configSectionLayers?.tollRoad?.additional, layerIDPrefix),\n },\n tunnel: {\n routeTunnelLine: {\n ...routeTunnelsLine,\n beforeID: prefixBeforeID('routeLineArrows', layerIDPrefix),\n ...configSectionLayers?.tunnel?.routeTunnelLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.tunnel?.additional, layerIDPrefix),\n },\n vehicleRestricted: {\n routeVehicleRestrictedBackgroundLine: {\n ...routeVehicleRestrictedBackgroundLine,\n beforeID: prefixBeforeID('routeVehicleRestrictedForegroundLine', layerIDPrefix),\n ...configSectionLayers?.vehicleRestricted?.routeVehicleRestrictedBackgroundLine,\n },\n routeVehicleRestrictedForegroundLine: {\n ...routeVehicleRestrictedDottedLine,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configSectionLayers?.vehicleRestricted?.routeVehicleRestrictedForegroundLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.vehicleRestricted?.additional, layerIDPrefix),\n },\n },\n instructionLines: {\n routeInstructionLine: {\n ...instructionLine,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configLayers?.instructionLines?.routeInstructionLine,\n },\n routeInstructionOutline: {\n ...instructionOutline,\n beforeID: prefixBeforeID('routeInstructionLine', layerIDPrefix),\n ...configLayers?.instructionLines?.routeInstructionOutline,\n },\n ...prefixBeforeIDs(configLayers?.instructionLines?.additional, layerIDPrefix),\n },\n instructionArrows: {\n routeInstructionArrowSymbol: {\n ...instructionArrow,\n beforeID: prefixBeforeID('routeInstructionLine', layerIDPrefix),\n ...(instanceIndex !== undefined && {\n layout: {\n ...instructionArrow.layout,\n 'icon-image': suffixImageID(instructionArrow.layout?.['icon-image'] as string, instanceIndex),\n },\n }),\n ...configLayers?.instructionArrows?.routeInstructionArrowSymbol,\n },\n ...prefixBeforeIDs(configLayers?.instructionArrows?.additional, layerIDPrefix),\n },\n summaryBubbles: {\n routeSummaryBubbleSymbol: {\n ...(instanceIndex !== undefined\n ? buildSummaryBubbleSymbolPoint(instanceIndex)\n : summaryBubbleSymbolPoint),\n ...configLayers?.summaryBubbles?.routeSummaryBubbleSymbol,\n },\n ...prefixBeforeIDs(configLayers?.summaryBubbles?.additional, layerIDPrefix),\n },\n };\n};\n\n/**\n * Default routing layers configuration. Calls routingLayers with no parameters.\n *\n * @remarks\n * This configuration defines the complete visual styling for all route-related map layers,\n * including main route lines, waypoints, special road sections (ferries, tunnels, toll roads, etc.),\n * turn-by-turn guidance instructions, and route summary information.\n *\n * **Usage:**\n * - Automatically applied when initializing {@link RoutingModule} without custom layer configuration\n * - Can be used as a reference or starting point for creating custom layer configurations\n * - Individual properties can be selectively overridden while keeping defaults for others\n *\n * @see {@link buildRoutingLayers} for details.\n *\n * @see {@link RouteLayersConfig} for the configuration type definition\n * @see {@link RoutingModule.get} for initialization options\n * @see {@link RoutingModule.applyConfig} for runtime configuration updates\n *\n * @group Routing\n */\nexport const defaultRoutingLayers: Required<RouteLayersConfig> = buildRoutingLayers();\n","import type { StyleImageMetadata } from 'maplibre-gl';\nimport { SVGIconStyleOptions } from '../../shared';\nimport { isDOMImageSupported, svgToImg } from '../../shared/imageUtils';\nimport { parseSvg, pinSvg } from '../../shared/resources';\nimport circleSvgRaw from './circle.svg?raw';\nimport finishSvgRaw from './finish.svg?raw';\nimport instructionArrowSvgRaw from './instruction-line-arrow.svg?raw';\nimport startSvgRaw from './start.svg?raw';\nimport summaryMapBubbleSvgRaw from './summary-map-bubble.svg?raw';\nimport trafficSvgRaw from './traffic.svg?raw';\n\nlet instructionArrowIconImg: HTMLImageElement;\n\n// defensive check for SSR\nif (isDOMImageSupported()) {\n instructionArrowIconImg = svgToImg(parseSvg(instructionArrowSvgRaw));\n}\n\n/**\n * @ignore\n */\nexport { instructionArrowIconImg };\n\n/**\n * @ignore\n */\nexport const summaryMapBubbleImg = (color: string): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg: SVGElement = parseSvg(summaryMapBubbleSvgRaw);\n svg.querySelector('#bubble')?.setAttribute('fill', color);\n svg.querySelector('#pin')?.setAttribute('fill', color);\n return svgToImg(svg);\n};\n\n/**\n * Options to effectively stretch the summary bubble image to fit its text.\n * * They are tightly coupled with the SVG original dimensions.\n * @ignore\n */\nexport const summaryBubbleImageOptions: Partial<StyleImageMetadata> = {\n pixelRatio: 2,\n stretchX: [\n [20, 45],\n [100, 130],\n ],\n stretchY: [[20, 35]],\n content: [10, 10, 130, 45],\n};\n\n/**\n * @ignore\n * @param color\n */\nexport const trafficImg = (color: string): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg: SVGElement = parseSvg(trafficSvgRaw);\n const main = svg.querySelector('#main') as Element;\n main.setAttribute('transform', 'scale(2)');\n main.setAttribute('fill', color);\n return svgToImg(svg);\n};\n\n/**\n * @ignore\n */\nexport const waypointIcon = (\n foregroundSvg: SVGElement | undefined,\n svgOptions: SVGIconStyleOptions | undefined,\n): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg = pinSvg(svgOptions);\n if (foregroundSvg) {\n svg.appendChild(foregroundSvg);\n }\n return svgToImg(svg);\n};\n\n/**\n * @ignore\n */\nexport const waypointStartIcon = (svgOptions: SVGIconStyleOptions | undefined): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return waypointIcon(parseSvg(startSvgRaw), svgOptions);\n};\n\n/**\n * @ignore\n */\nexport const waypointFinishIcon = (svgOptions: SVGIconStyleOptions | undefined): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return waypointIcon(parseSvg(finishSvgRaw), svgOptions);\n};\n\n/**\n * @ignore\n */\nexport const softWaypointIcon = (): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return svgToImg(parseSvg(circleSvgRaw));\n};\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"50\\\" height=\\\"50\\\">\\n <path d=\\\"M1.562 40.569L25 1.562l23.438 39.007L25 27.566 1.562 40.569z\\\" fill=\\\"#fff\\\"/>\\n <path d=\\\"M25.369.107c.782.429.506.167.917.682l23.438 39.007c.79 1.316-.671 2.829-2.014 2.085L25 29.281l-22.71 12.6c-1.343.744-2.804-.769-2.014-2.085L23.714.789c.461-.694.9-.682 1.656-.682zM25 1.562L1.562 40.569 25 27.566l23.438 13.003L25 1.562z\\\"\\n fill=\\\"gray\\\"/>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"160\\\" height=\\\"65\\\">\\n <g filter=\\\"url(#A)\\\">\\n <rect id=\\\"pin\\\" x=\\\"81.899\\\" y=\\\"47\\\" width=\\\"10\\\" height=\\\"10\\\" rx=\\\"2\\\" transform=\\\"rotate(45 81.899 47)\\\"/>\\n <rect id=\\\"bubble\\\" x=\\\"10\\\" y=\\\"10\\\" width=\\\"140\\\" height=\\\"45\\\" rx=\\\"12\\\"/>\\n </g>\\n <defs>\\n <filter id=\\\"A\\\">\\n <feDropShadow dx=\\\"0\\\" dy=\\\"2\\\" stdDeviation=\\\"4\\\" flood-opacity=\\\".3\\\"/>\\n </filter>\\n </defs>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"32\\\" height=\\\"32\\\">\\n <g id=\\\"main\\\">\\n <path fill-rule=\\\"evenodd\\\"\\n d=\\\"M11.389 4H9.025a.86.86 0 0 0-.517.173l-.001-.001a.5.5 0 0 1-.464.059l-.028-.011a.5.5 0 0 1-.129-.83A1.86 1.86 0 0 1 9.025 3h2.364a2 2 0 0 1 1.789 1.106l1.02 2.04c.471.176.802.63.802 1.156v.803c0 .543 0 .815-.071 1.038a1.5 1.5 0 0 1-.914.953c-.219.08-.491.092-1.034.114l-1.481.062v-.166-.803a2.23 2.23 0 0 0-1.055-1.897l-.74-1.479 2.326.033h.955l-.703-1.406A1 1 0 0 0 11.389 4zM12 8.4a1 1 0 1 1 2 0 .5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\\\"/>\\n <path d=\\\"M11.833 11.115c0-.109.089-.198.198-.198h1.979c.109 0 .198.089.198.198 0 .328-.266.594-.594.594h-1.187c-.328 0-.594-.266-.594-.594z\\\"/>\\n <path fill-rule=\\\"evenodd\\\"\\n d=\\\"M1.802 8.146C1.331 8.321 1 8.776 1 9.302v.803c0 .543 0 .815.071 1.038a1.5 1.5 0 0 0 .914.953c.219.08.491.092 1.034.114l2.731.114 2.731-.114c.543-.023.814-.034 1.034-.114a1.5 1.5 0 0 0 .914-.953c.071-.223.071-.494.071-1.038v-.803c0-.526-.331-.98-.802-1.156l-1.02-2.04A2 2 0 0 0 6.889 5H4.611a2 2 0 0 0-1.789 1.106l-1.02 2.04zM6.889 6H4.611a1 1 0 0 0-.894.553l-.703 1.406h.955 3.563.955l-.703-1.406A1 1 0 0 0 6.889 6zM2 10.4a1 1 0 1 1 2 0 .5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm6.5-1a1 1 0 0 0-1 1 .5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5 1 1 0 0 0-1-1z\\\"/>\\n <path d=\\\"M1.792 13.115c0-.109.089-.198.198-.198h1.979c.109 0 .198.089.198.198 0 .328-.266.594-.594.594H2.385c-.328 0-.594-.266-.594-.594zm5.739-.198c-.109 0-.198.089-.198.198 0 .328.266.594.594.594h1.188c.328 0 .594-.266.594-.594 0-.109-.089-.198-.198-.198h-1.98z\\\"/>\\n </g>\\n</svg>\\n\"","import { TomTomConfig } from '@tomtom-org/maps-sdk/core';\nimport type { ToBeAddedLayerSpecTemplate, ToBeAddedLayerSpecWithoutSource } from '../../shared';\nimport { buildRoutingLayers } from '../layers/routingLayers';\nimport type { RouteLayersConfig, RoutingModuleConfig } from '../types/routeModuleConfig';\nimport type { RoutingLayersSpecs } from '../types/routingSourcesAndLayers';\n\n/**\n * @ignore\n */\nconst mapLayerSpecs = (\n layerSpecs: Record<string, Partial<ToBeAddedLayerSpecTemplate>> = {},\n layerIDPrefix?: string,\n): ToBeAddedLayerSpecWithoutSource[] =>\n // The key of the entry is the layer ID:\n Object.entries(layerSpecs).map(\n ([id, spec]) =>\n ({\n ...spec,\n id: layerIDPrefix ? `${layerIDPrefix}-${id}` : id,\n }) as ToBeAddedLayerSpecWithoutSource,\n );\n\n/**\n * @ignore\n */\nexport const createLayersSpecs = (\n layerConfigs: RouteLayersConfig = {},\n layerIDPrefix?: string,\n): RoutingLayersSpecs => ({\n mainLines: mapLayerSpecs(layerConfigs.mainLines, layerIDPrefix),\n waypoints: mapLayerSpecs(layerConfigs.waypoints, layerIDPrefix),\n chargingStops: mapLayerSpecs(layerConfigs?.chargingStops, layerIDPrefix),\n ferries: mapLayerSpecs(layerConfigs.sections?.ferry, layerIDPrefix),\n incidents: mapLayerSpecs(layerConfigs.sections?.incident, layerIDPrefix),\n tollRoads: mapLayerSpecs(layerConfigs.sections?.tollRoad, layerIDPrefix),\n tunnels: mapLayerSpecs(layerConfigs.sections?.tunnel, layerIDPrefix),\n vehicleRestricted: mapLayerSpecs(layerConfigs.sections?.vehicleRestricted, layerIDPrefix),\n instructionLines: mapLayerSpecs(layerConfigs.instructionLines, layerIDPrefix),\n instructionArrows: mapLayerSpecs(layerConfigs.instructionArrows, layerIDPrefix),\n summaryBubbles: mapLayerSpecs(layerConfigs.summaryBubbles, layerIDPrefix),\n});\n\n/**\n * @ignore\n */\nexport const routeModuleConfigWithDefaults = (\n config: RoutingModuleConfig | undefined,\n layerIDPrefix: string,\n instanceIndex: number,\n): RoutingModuleConfig => {\n const globalDisplayUnits = TomTomConfig.instance.get().displayUnits;\n const displayUnits = config?.displayUnits;\n return {\n // First apply the provided configuration not to lose any properties:\n ...config,\n ...(displayUnits ? {} : { displayUnits: globalDisplayUnits }),\n layers: buildRoutingLayers(config, layerIDPrefix, instanceIndex),\n };\n};\n","import {\n ChargingStop,\n ChargingStopProps,\n formatDuration,\n generateId,\n type Place,\n type Routes,\n} from '@tomtom-org/maps-sdk/core';\nimport { FeatureCollection, Point } from 'geojson';\nimport { PlaceDisplayProps } from '../../places';\nimport type { DisplayRouteProps, RouteStateProps } from '../types/displayRoutes';\nimport { RoutingModuleConfig } from '../types/routeModuleConfig';\n\nconst getIconID = (chargingStop: ChargingStop, config: RoutingModuleConfig | undefined): string => {\n const iconConfig = config?.chargingStops?.icon;\n if (iconConfig?.mapping) {\n const mapping = iconConfig.mapping;\n switch (mapping.basedOn) {\n case 'chargingSpeed':\n if (chargingStop.properties.chargingConnectionInfo?.chargingSpeed) {\n return mapping.value[chargingStop.properties.chargingConnectionInfo?.chargingSpeed];\n }\n break;\n case 'custom':\n return mapping.fn(chargingStop);\n }\n }\n\n // default: (genesis-like) categorySet ID for \"EV Charging Station\" based on search\n return '7309';\n};\n\nconst formatTitle = (chargingStop: ChargingStop): string => {\n const properties = chargingStop.properties;\n return properties.chargingParkName ?? (properties.chargingParkOperatorName as string);\n};\n\ntype DisplayChargingStopProps = PlaceDisplayProps &\n ChargingStopProps &\n RouteStateProps & {\n chargingDuration: string;\n chargingPower: string;\n };\n\ntype DisplayChargingStops = FeatureCollection<Point, DisplayChargingStopProps>;\n\n/**\n * Generates display-ready charging stations for the given planning context ones.\n * @param routes The routes return for ldEV.\n * @param config The charging stops display configuration.\n * @see chargingStopLayers\n * @ignore\n */\nexport const toDisplayChargingStops = (\n routes: Routes<DisplayRouteProps>,\n config: RoutingModuleConfig | undefined,\n): DisplayChargingStops => {\n const displayChargingStops: Place<DisplayChargingStopProps>[] = [];\n\n if (config?.chargingStops?.visible !== false) {\n for (const route of routes.features) {\n for (const leg of route.properties.sections.leg) {\n const chargingStop = leg.summary.chargingInformationAtEndOfLeg;\n\n if (chargingStop) {\n const properties = chargingStop.properties;\n displayChargingStops.push({\n ...chargingStop,\n properties: {\n ...chargingStop.properties,\n id: chargingStop.properties.chargingParkId ?? generateId(),\n iconID: getIconID(chargingStop, config),\n title: formatTitle(chargingStop),\n chargingPower: `${properties.chargingConnectionInfo?.chargingPowerInkW} kW`,\n chargingDuration: formatDuration(\n properties.chargingTimeInSeconds,\n config?.displayUnits?.time,\n ) as string,\n routeState: route.properties.routeState,\n },\n });\n }\n }\n }\n }\n return { type: 'FeatureCollection', features: displayChargingStops };\n};\n","import { formatDuration, type TrafficSectionProps } from '@tomtom-org/maps-sdk/core';\nimport type { DisplayTrafficSectionProps } from '../types/routeSections';\n\nconst hasJam = (sectionProps: TrafficSectionProps): boolean => sectionProps.categories.includes('jam');\n\nconst buildTitle = (sectionProps: TrafficSectionProps): string | undefined => {\n if (hasJam(sectionProps)) {\n return formatDuration(sectionProps.delayInSeconds);\n }\n return undefined;\n};\n\nconst toTrafficJamIconSuffix = (title: string | undefined): 'collapsed' | 'small' | 'medium' | 'large' => {\n if (!title?.length) {\n return 'collapsed';\n }\n if (title.length < 6) {\n // 1 digit minutes\n return 'small';\n }\n if (title.length < 8) {\n // 2 digit minutes\n return 'medium';\n }\n // hours + minutes\n return 'large';\n};\n\nconst toJamIconID = (sectionProps: TrafficSectionProps, title: string | undefined): string | null => {\n if (!hasJam(sectionProps)) {\n return null;\n }\n const magnitude = sectionProps.magnitudeOfDelay ?? 'unknown';\n return `traffic-jam-${magnitude}-${toTrafficJamIconSuffix(title)}`;\n};\n\nconst toCauseIconID = (sectionProps: TrafficSectionProps): string | null => {\n const firstNonJamCategory = sectionProps.categories.find((category) => category !== 'jam');\n switch (firstNonJamCategory) {\n case 'accident':\n return 'traffic-incidents-accident';\n case 'roadworks':\n return 'traffic-incidents-roadworks';\n case 'road-closed':\n return 'traffic-incidents-road_closed';\n case 'danger':\n case 'animals-on-road':\n return 'traffic-incidents-danger';\n case 'broken-down-vehicle':\n return 'traffic-incidents-broken_down_vehicle';\n case 'lane-closed':\n case 'narrow-lanes':\n return 'traffic-incidents-lane_closed';\n case 'wind':\n return 'traffic-incidents-wind';\n case 'fog':\n return 'traffic-incidents-fog';\n case 'rain':\n return 'traffic-incidents-rain';\n case 'frost':\n return 'traffic-incidents-frost';\n case 'flooding':\n return 'traffic-incidents-flooding';\n default:\n return null;\n }\n};\n\n/**\n * @ignore\n */\nexport const toDisplayTrafficSectionProps = (\n sectionProps: TrafficSectionProps,\n): Omit<DisplayTrafficSectionProps, 'routeState' | 'routeIndex'> => {\n const title = buildTitle(sectionProps);\n const jamIconID = toJamIconID(sectionProps, title);\n const causeIconID = toCauseIconID(sectionProps);\n return {\n ...sectionProps,\n ...(jamIconID && { jamIconID }),\n ...(causeIconID && { causeIconID }),\n ...(title && { title }),\n };\n};\n","import type { CommonPlaceProps, Waypoint, WaypointLike, Waypoints } from '@tomtom-org/maps-sdk/core';\nimport { generateId, getPosition } from '@tomtom-org/maps-sdk/core';\nimport type { Point, Position } from 'geojson';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport {\n WAYPOINT_FINISH_IMAGE_ID,\n WAYPOINT_SOFT_IMAGE_ID,\n WAYPOINT_START_IMAGE_ID,\n WAYPOINT_STOP_IMAGE_ID,\n} from '../layers/waypointLayers';\nimport type { PlanningWaypoint } from '../types/planningWaypoint';\nimport type { WaypointsConfig } from '../types/routeModuleConfig';\nimport type { WaypointDisplayProps, WaypointIndexType } from '../types/waypointDisplayProps';\nimport { FINISH_INDEX, MIDDLE_INDEX, START_INDEX } from '../types/waypointDisplayProps';\n\nconst indexTypeFor = (index: number, arrayLength: number): WaypointIndexType =>\n index === 0 ? START_INDEX : index < arrayLength - 1 ? MIDDLE_INDEX : FINISH_INDEX;\n\n/**\n * Builds the title of the given waypoint.\n * @param waypoint The waypoint for which to build the title.\n */\nexport const buildWaypointTitle = (waypoint: Waypoint): string | undefined => {\n const placeProperties = waypoint?.properties as CommonPlaceProps;\n return placeProperties?.poi?.name ?? placeProperties?.address?.freeformAddress ?? undefined;\n};\n\nexport const getImageIDForWaypoint = (\n waypoint: Waypoint,\n indexType: WaypointIndexType,\n instanceIndex?: number,\n): string => {\n if (waypoint.properties.radiusMeters) {\n return instanceIndex !== undefined\n ? suffixNumber(WAYPOINT_SOFT_IMAGE_ID, instanceIndex)\n : WAYPOINT_SOFT_IMAGE_ID;\n }\n let baseImageID: string;\n switch (indexType) {\n case 'start':\n baseImageID = WAYPOINT_START_IMAGE_ID;\n break;\n case 'finish':\n baseImageID = WAYPOINT_FINISH_IMAGE_ID;\n break;\n default:\n baseImageID = WAYPOINT_STOP_IMAGE_ID;\n break;\n }\n return instanceIndex !== undefined ? suffixNumber(baseImageID, instanceIndex) : baseImageID;\n};\n\nconst toWaypointFromPosition = (position: Position): Waypoint => ({\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: position,\n },\n properties: {},\n});\n\nconst toWaypointFromPoint = (point: Point): Waypoint => ({\n type: 'Feature',\n geometry: point,\n properties: {},\n ...(point.bbox && { bbox: point.bbox }),\n});\n\nconst asWaypoint = (waypointInput: WaypointLike): Waypoint => {\n if (Array.isArray(waypointInput)) {\n return toWaypointFromPosition(waypointInput);\n }\n if (waypointInput.type === 'Point') {\n return toWaypointFromPoint(waypointInput);\n }\n return waypointInput as Waypoint;\n};\n\n/**\n * Determines whether the given waypoint is a regular start/stop/destination with guidance attached,\n * as opposed to a circle (soft) waypoint.\n * @param waypoint The waypoint to verify.\n */\nexport const isHardWaypoint = (waypoint: Waypoint): boolean => !waypoint.properties.radiusMeters;\n\n/**\n * Generates display-ready waypoints for the given planning context ones.\n * @param waypoints The planning context waypoints.\n * @param options\n * @param instanceIndex Optional instance index for supporting multiple RoutingModule instances\n */\nexport const toDisplayWaypoints = (\n waypoints: PlanningWaypoint[],\n options: WaypointsConfig | undefined,\n instanceIndex?: number,\n): Waypoints<WaypointDisplayProps> => {\n // Since waypoints are of mixed types (hard and soft), we need to calculate the hard-only indexes\n // in case we have stops with numbered icons:\n let hardWaypointIndex = -1;\n return {\n type: 'FeatureCollection',\n features: waypoints\n .map((waypointInput, index) => {\n if (!waypointInput) {\n // (we consider placeholder waypoints to be \"hard\", since they typically occupy a position in a planner panel)\n hardWaypointIndex++;\n // (will be filtered out below - we don't pre-filter it to keep the original input index)\n return null as unknown as Waypoint<WaypointDisplayProps>;\n }\n const waypoint: Waypoint = asWaypoint(waypointInput);\n const indexType = indexTypeFor(index, waypoints.length);\n const hardWaypoint = isHardWaypoint(waypoint);\n if (hardWaypoint) {\n hardWaypointIndex++;\n }\n const title = buildWaypointTitle(waypoint);\n const id = (waypoint.id as string) ?? generateId();\n return {\n ...waypoint,\n ...(options?.entryPoints === 'main-when-available' && {\n geometry: {\n type: 'Point',\n // We replace the waypoint coordinates with their main entry point ones:\n coordinates: getPosition(waypoint, { useEntryPoint: 'main-when-available' }),\n } as Point,\n }),\n id,\n properties: {\n ...waypoint.properties,\n id,\n index,\n indexType,\n ...(title && { title }),\n iconID: getImageIDForWaypoint(waypoint, indexType, instanceIndex),\n ...(hardWaypoint && indexType === MIDDLE_INDEX && { stopDisplayIndex: hardWaypointIndex }),\n },\n };\n })\n .filter((feature) => feature),\n };\n};\n","// index.ts\nvar earthRadius = 63710088e-1;\nvar factors = {\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n degrees: 360 / (2 * Math.PI),\n feet: earthRadius * 3.28084,\n inches: earthRadius * 39.37,\n kilometers: earthRadius / 1e3,\n kilometres: earthRadius / 1e3,\n meters: earthRadius,\n metres: earthRadius,\n miles: earthRadius / 1609.344,\n millimeters: earthRadius * 1e3,\n millimetres: earthRadius * 1e3,\n nauticalmiles: earthRadius / 1852,\n radians: 1,\n yards: earthRadius * 1.0936\n};\nvar areaFactors = {\n acres: 247105e-9,\n centimeters: 1e4,\n centimetres: 1e4,\n feet: 10.763910417,\n hectares: 1e-4,\n inches: 1550.003100006,\n kilometers: 1e-6,\n kilometres: 1e-6,\n meters: 1,\n metres: 1,\n miles: 386e-9,\n nauticalmiles: 29155334959812285e-23,\n millimeters: 1e6,\n millimetres: 1e6,\n yards: 1.195990046\n};\nfunction feature(geom, properties, options = {}) {\n const feat = { type: \"Feature\" };\n if (options.id === 0 || options.id) {\n feat.id = options.id;\n }\n if (options.bbox) {\n feat.bbox = options.bbox;\n }\n feat.properties = properties || {};\n feat.geometry = geom;\n return feat;\n}\nfunction geometry(type, coordinates, _options = {}) {\n switch (type) {\n case \"Point\":\n return point(coordinates).geometry;\n case \"LineString\":\n return lineString(coordinates).geometry;\n case \"Polygon\":\n return polygon(coordinates).geometry;\n case \"MultiPoint\":\n return multiPoint(coordinates).geometry;\n case \"MultiLineString\":\n return multiLineString(coordinates).geometry;\n case \"MultiPolygon\":\n return multiPolygon(coordinates).geometry;\n default:\n throw new Error(type + \" is invalid\");\n }\n}\nfunction point(coordinates, properties, options = {}) {\n if (!coordinates) {\n throw new Error(\"coordinates is required\");\n }\n if (!Array.isArray(coordinates)) {\n throw new Error(\"coordinates must be an Array\");\n }\n if (coordinates.length < 2) {\n throw new Error(\"coordinates must be at least 2 numbers long\");\n }\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {\n throw new Error(\"coordinates must contain numbers\");\n }\n const geom = {\n type: \"Point\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction points(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return point(coords, properties);\n }),\n options\n );\n}\nfunction polygon(coordinates, properties, options = {}) {\n for (const ring of coordinates) {\n if (ring.length < 4) {\n throw new Error(\n \"Each LinearRing of a Polygon must have 4 or more Positions.\"\n );\n }\n if (ring[ring.length - 1].length !== ring[0].length) {\n throw new Error(\"First and last Position are not equivalent.\");\n }\n for (let j = 0; j < ring[ring.length - 1].length; j++) {\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error(\"First and last Position are not equivalent.\");\n }\n }\n }\n const geom = {\n type: \"Polygon\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction polygons(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return polygon(coords, properties);\n }),\n options\n );\n}\nfunction lineString(coordinates, properties, options = {}) {\n if (coordinates.length < 2) {\n throw new Error(\"coordinates must be an array of two or more positions\");\n }\n const geom = {\n type: \"LineString\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction lineStrings(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return lineString(coords, properties);\n }),\n options\n );\n}\nfunction featureCollection(features, options = {}) {\n const fc = { type: \"FeatureCollection\" };\n if (options.id) {\n fc.id = options.id;\n }\n if (options.bbox) {\n fc.bbox = options.bbox;\n }\n fc.features = features;\n return fc;\n}\nfunction multiLineString(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiLineString\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction multiPoint(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiPoint\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction multiPolygon(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiPolygon\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction geometryCollection(geometries, properties, options = {}) {\n const geom = {\n type: \"GeometryCollection\",\n geometries\n };\n return feature(geom, properties, options);\n}\nfunction round(num, precision = 0) {\n if (precision && !(precision >= 0)) {\n throw new Error(\"precision must be a positive number\");\n }\n const multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\nfunction radiansToLength(radians, units = \"kilometers\") {\n const factor = factors[units];\n if (!factor) {\n throw new Error(units + \" units is invalid\");\n }\n return radians * factor;\n}\nfunction lengthToRadians(distance, units = \"kilometers\") {\n const factor = factors[units];\n if (!factor) {\n throw new Error(units + \" units is invalid\");\n }\n return distance / factor;\n}\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\nfunction bearingToAzimuth(bearing) {\n let angle = bearing % 360;\n if (angle < 0) {\n angle += 360;\n }\n return angle;\n}\nfunction azimuthToBearing(angle) {\n angle = angle % 360;\n if (angle > 180) {\n return angle - 360;\n } else if (angle < -180) {\n return angle + 360;\n }\n return angle;\n}\nfunction radiansToDegrees(radians) {\n const normalisedRadians = radians % (2 * Math.PI);\n return normalisedRadians * 180 / Math.PI;\n}\nfunction degreesToRadians(degrees) {\n const normalisedDegrees = degrees % 360;\n return normalisedDegrees * Math.PI / 180;\n}\nfunction convertLength(length, originalUnit = \"kilometers\", finalUnit = \"kilometers\") {\n if (!(length >= 0)) {\n throw new Error(\"length must be a positive number\");\n }\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);\n}\nfunction convertArea(area, originalUnit = \"meters\", finalUnit = \"kilometers\") {\n if (!(area >= 0)) {\n throw new Error(\"area must be a positive number\");\n }\n const startFactor = areaFactors[originalUnit];\n if (!startFactor) {\n throw new Error(\"invalid original units\");\n }\n const finalFactor = areaFactors[finalUnit];\n if (!finalFactor) {\n throw new Error(\"invalid final units\");\n }\n return area / startFactor * finalFactor;\n}\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\nfunction isObject(input) {\n return input !== null && typeof input === \"object\" && !Array.isArray(input);\n}\nfunction validateBBox(bbox) {\n if (!bbox) {\n throw new Error(\"bbox is required\");\n }\n if (!Array.isArray(bbox)) {\n throw new Error(\"bbox must be an Array\");\n }\n if (bbox.length !== 4 && bbox.length !== 6) {\n throw new Error(\"bbox must be an Array of 4 or 6 numbers\");\n }\n bbox.forEach((num) => {\n if (!isNumber(num)) {\n throw new Error(\"bbox must only contain numbers\");\n }\n });\n}\nfunction validateId(id) {\n if (!id) {\n throw new Error(\"id is required\");\n }\n if ([\"string\", \"number\"].indexOf(typeof id) === -1) {\n throw new Error(\"id must be a number or a string\");\n }\n}\nexport {\n areaFactors,\n azimuthToBearing,\n bearingToAzimuth,\n convertArea,\n convertLength,\n degreesToRadians,\n earthRadius,\n factors,\n feature,\n featureCollection,\n geometry,\n geometryCollection,\n isNumber,\n isObject,\n lengthToDegrees,\n lengthToRadians,\n lineString,\n lineStrings,\n multiLineString,\n multiPoint,\n multiPolygon,\n point,\n points,\n polygon,\n polygons,\n radiansToDegrees,\n radiansToLength,\n round,\n validateBBox,\n validateId\n};\n//# sourceMappingURL=index.js.map","// index.ts\nimport { isNumber } from \"@turf/helpers\";\nfunction getCoord(coord) {\n if (!coord) {\n throw new Error(\"coord is required\");\n }\n if (!Array.isArray(coord)) {\n if (coord.type === \"Feature\" && coord.geometry !== null && coord.geometry.type === \"Point\") {\n return [...coord.geometry.coordinates];\n }\n if (coord.type === \"Point\") {\n return [...coord.coordinates];\n }\n }\n if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {\n return [...coord];\n }\n throw new Error(\"coord must be GeoJSON Point or an Array of numbers\");\n}\nfunction getCoords(coords) {\n if (Array.isArray(coords)) {\n return coords;\n }\n if (coords.type === \"Feature\") {\n if (coords.geometry !== null) {\n return coords.geometry.coordinates;\n }\n } else {\n if (coords.coordinates) {\n return coords.coordinates;\n }\n }\n throw new Error(\n \"coords must be GeoJSON Feature, Geometry Object or an Array\"\n );\n}\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {\n return true;\n }\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error(\"coordinates must only contain numbers\");\n}\nfunction geojsonType(value, type, name) {\n if (!type || !name) {\n throw new Error(\"type and name required\");\n }\n if (!value || value.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + value.type\n );\n }\n}\nfunction featureOf(feature, type, name) {\n if (!feature) {\n throw new Error(\"No feature passed\");\n }\n if (!name) {\n throw new Error(\".featureOf() requires a name\");\n }\n if (!feature || feature.type !== \"Feature\" || !feature.geometry) {\n throw new Error(\n \"Invalid input to \" + name + \", Feature with geometry required\"\n );\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + feature.geometry.type\n );\n }\n}\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) {\n throw new Error(\"No featureCollection passed\");\n }\n if (!name) {\n throw new Error(\".collectionOf() requires a name\");\n }\n if (!featureCollection || featureCollection.type !== \"FeatureCollection\") {\n throw new Error(\n \"Invalid input to \" + name + \", FeatureCollection required\"\n );\n }\n for (const feature of featureCollection.features) {\n if (!feature || feature.type !== \"Feature\" || !feature.geometry) {\n throw new Error(\n \"Invalid input to \" + name + \", Feature with geometry required\"\n );\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + feature.geometry.type\n );\n }\n }\n}\nfunction getGeom(geojson) {\n if (geojson.type === \"Feature\") {\n return geojson.geometry;\n }\n return geojson;\n}\nfunction getType(geojson, _name) {\n if (geojson.type === \"FeatureCollection\") {\n return \"FeatureCollection\";\n }\n if (geojson.type === \"GeometryCollection\") {\n return \"GeometryCollection\";\n }\n if (geojson.type === \"Feature\" && geojson.geometry !== null) {\n return geojson.geometry.type;\n }\n return geojson.type;\n}\nexport {\n collectionOf,\n containsNumber,\n featureOf,\n geojsonType,\n getCoord,\n getCoords,\n getGeom,\n getType\n};\n//# sourceMappingURL=index.js.map","// index.ts\nimport { degreesToRadians, radiansToDegrees } from \"@turf/helpers\";\nimport { getCoord } from \"@turf/invariant\";\nfunction bearing(start, end, options = {}) {\n if (options.final === true) {\n return calculateFinalBearing(start, end);\n }\n const coordinates1 = getCoord(start);\n const coordinates2 = getCoord(end);\n const lon1 = degreesToRadians(coordinates1[0]);\n const lon2 = degreesToRadians(coordinates2[0]);\n const lat1 = degreesToRadians(coordinates1[1]);\n const lat2 = degreesToRadians(coordinates2[1]);\n const a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n const b = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n return radiansToDegrees(Math.atan2(a, b));\n}\nfunction calculateFinalBearing(start, end) {\n let bear = bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\nvar index_default = bearing;\nexport {\n bearing,\n index_default as default\n};\n//# sourceMappingURL=index.js.map","import { generateId, Routes } from '@tomtom-org/maps-sdk/core';\nimport calcBearing from '@turf/bearing';\nimport type { DisplayRouteProps } from '../types/displayRoutes';\nimport type {\n DisplayInstruction,\n DisplayInstructionArrow,\n DisplayInstructionArrows,\n DisplayInstructions,\n} from '../types/guidance';\n\n/**\n * @ignore\n */\nexport const toDisplayInstructions = (routes: Routes<DisplayRouteProps>): DisplayInstructions => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap(\n (route, routeIndex) =>\n route.properties.guidance?.instructions\n ?.filter((instruction) => instruction.routePath?.length)\n .map(\n (instruction): DisplayInstruction => ({\n type: 'Feature',\n geometry: {\n type: 'LineString',\n coordinates: instruction.routePath.map((pathPoint) => pathPoint.point),\n },\n properties: {\n ...instruction,\n id: generateId(),\n routeIndex,\n routeState: route.properties.routeState,\n },\n }),\n ) || [],\n ),\n});\n\n/**\n * @ignore\n */\nexport const toDisplayInstructionArrows = (routes: Routes<DisplayRouteProps>): DisplayInstructionArrows => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap(\n (route, routeIndex) =>\n route.properties.guidance?.instructions\n ?.filter((instruction) => instruction.routePath?.length && instruction.routePath.length > 1)\n .map((instruction): DisplayInstructionArrow => {\n const instructionLastSegment = [\n instruction.routePath[instruction.routePath.length - 2]?.point,\n instruction.routePath[instruction.routePath.length - 1]?.point,\n ];\n\n return {\n type: 'Feature',\n geometry: { type: 'Point', coordinates: instructionLastSegment[1] },\n properties: {\n ...instruction,\n id: generateId(),\n routeIndex,\n routeState: route.properties.routeState,\n lastPointBearingDegrees: calcBearing(instructionLastSegment[0], instructionLastSegment[1]),\n },\n };\n }) || [],\n ),\n});\n","import { generateId, Route, Routes, SectionProps, SectionType } from '@tomtom-org/maps-sdk/core';\nimport type { DisplayRouteProps } from '../types/displayRoutes';\nimport type { DisplaySectionProps, RouteSection, RouteSections } from '../types/routeSections';\n\nconst buildRouteSectionsFromRoute = <\n S extends SectionProps = SectionProps,\n D extends DisplaySectionProps = DisplaySectionProps,\n>(\n route: Route<DisplayRouteProps>,\n sectionType: SectionType,\n displaySectionPropsBuilder?: (\n sectionProps: S,\n routeProps?: DisplayRouteProps,\n ) => Omit<D, 'routeState' | 'routeIndex'>,\n): RouteSection<D>[] =>\n (route.properties.sections[sectionType] as S[])?.map((sectionProps) => {\n const id = sectionProps.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: {\n type: 'LineString',\n coordinates: route.geometry.coordinates.slice(\n sectionProps.startPointIndex,\n sectionProps.endPointIndex + 1,\n ),\n },\n properties: {\n ...(displaySectionPropsBuilder\n ? displaySectionPropsBuilder(sectionProps, route.properties)\n : sectionProps),\n routeState: route.properties.routeState,\n routeIndex: route.properties.index,\n id, // we need id in properties due to promoteId feature\n } as D,\n };\n }) || [];\n\n/**\n * Builds display-ready LineString features to render the sections of a given type, from the given route.\n * @param routes The routes from which to extract the section props.\n * @param sectionType The type of the sections to extract.\n * @param displaySectionPropsBuilder An optional function which will convert each section props into an extended display-ready version.\n * @ignore\n */\nexport const toDisplayRouteSections = <\n S extends SectionProps = SectionProps,\n D extends DisplaySectionProps = DisplaySectionProps,\n>(\n routes: Routes<DisplayRouteProps>,\n sectionType: SectionType,\n displaySectionPropsBuilder?: (\n sectionProps: S,\n routeProps?: DisplayRouteProps,\n ) => Omit<D, 'routeState' | 'routeIndex'>,\n): RouteSections<D> => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap((route) =>\n buildRouteSectionsFromRoute<S, D>(route, sectionType, displaySectionPropsBuilder),\n ),\n});\n","import type { Routes } from '@tomtom-org/maps-sdk/core';\nimport type { FeatureCollection, Geometry } from 'geojson';\nimport type { GeoJSONSourceWithLayers } from '../../shared';\nimport type { DisplayRouteProps, DisplayRouteRelatedProps } from '../types/displayRoutes';\n\n/**\n * Rebuilds route-related display features such as sections or instructions, with the updated route selection based on the given routes.\n * @ignore\n */\nexport const rebuildFeaturesWithRouteSelection = <T extends FeatureCollection<Geometry, DisplayRouteRelatedProps>>(\n routes: Routes<DisplayRouteProps>,\n featureCollection: T,\n): T => ({\n ...featureCollection,\n features: featureCollection.features.map((features) => ({\n ...features,\n properties: {\n ...features.properties,\n routeState: routes.features[features.properties.routeIndex || 0].properties.routeState,\n },\n })),\n});\n\n/**\n * @ignore\n */\nexport const showFeaturesWithRouteSelection = <T extends FeatureCollection<Geometry, DisplayRouteRelatedProps>>(\n routesWithSelection: Routes<DisplayRouteProps>,\n sourceWithLayers: GeoJSONSourceWithLayers<T>,\n): void =>\n sourceWithLayers.show(rebuildFeaturesWithRouteSelection(routesWithSelection, sourceWithLayers.shownFeatures));\n","import {\n DelayMagnitude,\n DisplayUnits,\n formatDistance,\n formatDuration,\n generateId,\n Route,\n Routes,\n TrafficSectionProps,\n} from '@tomtom-org/maps-sdk/core';\nimport type { DisplayRouteProps, DisplayRouteSummaries } from '../types/displayRoutes';\n\n/**\n * Builds map display-ready routes, applying default style props.\n * @ignore\n */\nexport const toDisplayRoutes = (routes: Route | Routes, selectedIndex = 0): Routes<DisplayRouteProps> => {\n const routesCollection: Routes = 'features' in routes ? routes : { type: 'FeatureCollection', features: [routes] };\n return {\n ...routesCollection,\n features: routesCollection.features.map((route, index) => {\n const id = route.id ?? generateId();\n return {\n ...route,\n id,\n properties: {\n ...route.properties,\n id, // we need id in properties due to promoteId feature\n routeState: index === selectedIndex ? 'selected' : 'deselected',\n },\n };\n }),\n };\n};\n\nconst hasMagnitude = (sections: TrafficSectionProps[], magnitude: DelayMagnitude): boolean =>\n sections.some((section) => section.magnitudeOfDelay === magnitude);\n\nconst summaryDelayMagnitude = (route: Route): DelayMagnitude | undefined => {\n const trafficSections = route.properties.sections.traffic;\n if (!trafficSections?.length) {\n return undefined;\n }\n if (hasMagnitude(trafficSections, 'major')) {\n return 'major';\n }\n if (hasMagnitude(trafficSections, 'moderate')) {\n return 'moderate';\n }\n if (hasMagnitude(trafficSections, 'minor')) {\n return 'minor';\n }\n return undefined;\n};\n/**\n * Builds map display-ready route summaries based on display routes.\n * @ignore\n */\nexport const toDisplayRouteSummaries = (\n routes: Routes<DisplayRouteProps>,\n displayUnits?: DisplayUnits,\n): DisplayRouteSummaries => ({\n type: 'FeatureCollection',\n features: routes.features.map((route) => {\n const summary = route.properties.summary;\n const routeCoordinates = route.geometry.coordinates;\n const formattedTraffic = formatDuration(summary.trafficDelayInSeconds, displayUnits?.time);\n const magnitudeOfDelay = summaryDelayMagnitude(route);\n const id = route.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: {\n type: 'Point',\n coordinates: routeCoordinates[Math.round(routeCoordinates.length / 2)],\n },\n properties: {\n id, // we need id in properties due to promoteId feature\n routeIndex: route.properties.index,\n routeState: route.properties.routeState,\n formattedDistance: formatDistance(summary.lengthInMeters, displayUnits?.distance),\n ...(magnitudeOfDelay && { magnitudeOfDelay }),\n ...(formattedTraffic && { formattedTraffic }),\n formattedDuration: formatDuration(summary.travelTimeInSeconds, displayUnits?.time),\n },\n };\n }),\n});\n","import type { Route, Routes, Waypoint, Waypoints } from '@tomtom-org/maps-sdk/core';\nimport { isEqual } from 'lodash-es';\nimport type { StyleImageMetadata } from 'maplibre-gl';\nimport {\n AbstractMapModule,\n EventsModule,\n GeoJSONSourceWithLayers,\n mapStyleLayerIDs,\n SVGIconStyleOptions,\n} from '../shared';\nimport { suffixNumber } from '../shared/layers/utils';\nimport { addLayers, addOrUpdateImage, updateLayersAndSource, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { INSTRUCTION_ARROW_IMAGE_ID } from './layers/guidanceLayers';\nimport { DESELECTED_SUMMARY_POPUP_IMAGE_ID, SELECTED_SUMMARY_POPUP_IMAGE_ID } from './layers/routeMainLineLayers';\nimport { MAJOR_DELAY_COLOR, MINOR_DELAY_LABEL_COLOR, MODERATE_DELAY_COLOR, UNKNOWN_DELAY_COLOR } from './layers/shared';\nimport {\n TRAFFIC_CLEAR_IMAGE_ID,\n TRAFFIC_MAJOR_IMAGE_ID,\n TRAFFIC_MINOR_IMAGE_ID,\n TRAFFIC_MODERATE_IMAGE_ID,\n} from './layers/summaryBubbleLayers';\nimport {\n WAYPOINT_FINISH_IMAGE_ID,\n WAYPOINT_SOFT_IMAGE_ID,\n WAYPOINT_START_IMAGE_ID,\n WAYPOINT_STOP_IMAGE_ID,\n} from './layers/waypointLayers';\nimport {\n instructionArrowIconImg,\n softWaypointIcon,\n summaryBubbleImageOptions,\n summaryMapBubbleImg,\n trafficImg,\n waypointFinishIcon,\n waypointIcon,\n waypointStartIcon,\n} from './resources';\nimport type { DisplayRouteProps, DisplayRouteSummary } from './types/displayRoutes';\nimport type { DisplayInstruction } from './types/guidance';\nimport type { PlanningWaypoint } from './types/planningWaypoint';\nimport type { RoutingModuleConfig } from './types/routeModuleConfig';\nimport type { DisplayTrafficSectionProps, RouteSection, RouteSections } from './types/routeSections';\nimport type { RoutingLayersSpecs, RoutingSourcesWithLayers } from './types/routingSourcesAndLayers';\nimport type { ShowRoutesOptions } from './types/showOptions';\nimport type { WaypointDisplayProps } from './types/waypointDisplayProps';\nimport { createLayersSpecs, routeModuleConfigWithDefaults } from './util/config';\nimport { toDisplayChargingStops } from './util/displayChargingStops';\nimport { toDisplayTrafficSectionProps } from './util/displayTrafficSectionProps';\nimport { toDisplayWaypoints } from './util/displayWaypoints';\nimport { toDisplayInstructionArrows, toDisplayInstructions } from './util/guidance';\nimport { toDisplayRouteSections } from './util/routeSections';\nimport { showFeaturesWithRouteSelection } from './util/routeSelection';\nimport { toDisplayRouteSummaries, toDisplayRoutes } from './util/routes';\n\n/**\n * Map module for displaying and managing route visualizations.\n *\n * The RoutingModule provides comprehensive functionality for displaying routes on the map,\n * including route lines, alternative routes, turn-by-turn guidance, and interactive waypoints.\n * It integrates seamlessly with the TomTom Routing API.\n *\n * @remarks\n * **Features:**\n * - Display route lines with customizable styling\n * - Show alternative routes with different styling\n * - Interactive waypoint markers (drag, add, remove)\n * - Turn-by-turn guidance instructions\n * - Route section highlighting\n * - Distance and duration information\n * - Support for multiple routes simultaneously\n *\n * **Common Use Cases:**\n * - Turn-by-turn navigation displays\n * - Route planning and comparison\n * - Multi-stop route optimization\n * - Interactive route editing\n * - Fleet management route visualization\n *\n * @example\n * ```typescript\n * // Create the module\n * const routingModule = await RoutingModule.getInstance(map, {\n * displayUnits: {\n * distance: { type: 'metric' }\n * }\n * });\n *\n * // Calculate and display a route\n * const result = await calculateRoute({\n * key: 'your-api-key',\n * locations: [\n * [4.9041, 52.3676], // Amsterdam\n * [4.4777, 51.9244] // Rotterdam\n * ],\n * routeOptions: {\n * travelMode: 'car',\n * routeType: 'fastest'\n * }\n * });\n *\n * await routingModule.showRoutes(result);\n * ```\n *\n * @see [Routing Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/routing)\n *\n * @group Routing\n */\nexport class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers, RoutingModuleConfig> {\n private static lastInstanceIndex = -1;\n private layersSpecs!: RoutingLayersSpecs;\n private layerIDPrefix!: string;\n /**\n * The index of this instance, to generate unique source and layer IDs.\n * * Starts with 0 and each instance increments it by one.\n * @private\n */\n private instanceIndex!: number;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n *\n * @remarks\n * **Configuration Options:**\n * - `displayUnits`: Distance units (metric/imperial)\n * - `waypointsSource`: Waypoint entry point options\n * - `layers`: Complete layer styling configuration\n *\n * **Default Styling:**\n * If no custom layers are provided, uses {@link defaultRoutingLayers}.\n *\n * @example\n * Default initialization:\n * ```typescript\n * const routingModule = await RoutingModule.get(map);\n * ```\n *\n * @example\n * With custom configuration:\n * ```typescript\n * const routingModule = await RoutingModule.get(map, {\n * displayUnits: 'imperial',\n * waypointsSource: {\n * entryPoints: 'main-when-available'\n * }\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: RoutingModuleConfig): Promise<RoutingModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new RoutingModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: RoutingModuleConfig) {\n super('geojson', map, config);\n }\n\n private createSourcesWithLayers(layersSpecs: RoutingLayersSpecs): RoutingSourcesWithLayers {\n const sourcePrefix = suffixNumber('routes', this.instanceIndex);\n return {\n mainLines: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-mainLines`,\n layersSpecs.mainLines,\n false,\n ),\n waypoints: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-waypoints`,\n layersSpecs.waypoints,\n false,\n ),\n incidents: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-incidents`,\n layersSpecs.incidents,\n false,\n ),\n ferries: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-ferries`,\n layersSpecs.ferries,\n false,\n ),\n chargingStops: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-chargingStops`,\n layersSpecs.chargingStops,\n false,\n ),\n tollRoads: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-tollRoads`,\n layersSpecs.tollRoads,\n false,\n ),\n tunnels: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-tunnels`,\n layersSpecs.tunnels,\n false,\n ),\n vehicleRestricted: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-vehicleRestricted`,\n layersSpecs.vehicleRestricted,\n false,\n ),\n instructionLines: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-instructionLines`,\n layersSpecs.instructionLines,\n false,\n ),\n instructionArrows: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-instructionArrows`,\n layersSpecs.instructionArrows,\n false,\n ),\n summaryBubbles: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-summaryBubbles`,\n layersSpecs.summaryBubbles,\n false,\n ),\n };\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: RoutingModuleConfig, restore?: boolean): RoutingSourcesWithLayers {\n // Only increment the instance index for new instances, not for restore operations\n if (!restore) {\n RoutingModule.lastInstanceIndex++;\n this.instanceIndex = RoutingModule.lastInstanceIndex;\n this.layerIDPrefix = suffixNumber('routes', this.instanceIndex);\n }\n\n this.layersSpecs = createLayersSpecs(\n routeModuleConfigWithDefaults(config, this.layerIDPrefix, this.instanceIndex).layers,\n this.layerIDPrefix,\n );\n const routingSourcesWithLayers: RoutingSourcesWithLayers = this.createSourcesWithLayers(this.layersSpecs);\n addLayers(\n Object.values(routingSourcesWithLayers).flatMap((source) => source._layerSpecs),\n this.mapLibreMap,\n );\n\n const svgIconOptions: SVGIconStyleOptions = {\n // first comes the main theme fill color, if any:\n fillColor: config?.theme?.mainColor,\n // then come any icon style configs for the waypoint icons, if any:\n ...config?.waypoints?.icon?.style,\n };\n const options: Partial<StyleImageMetadata> = { pixelRatio: 2 };\n\n // Generate instance-specific image IDs to support multiple RoutingModule instances\n const waypointStartImageId = suffixNumber(WAYPOINT_START_IMAGE_ID, this.instanceIndex);\n const waypointStopImageId = suffixNumber(WAYPOINT_STOP_IMAGE_ID, this.instanceIndex);\n const waypointSoftImageId = suffixNumber(WAYPOINT_SOFT_IMAGE_ID, this.instanceIndex);\n const waypointFinishImageId = suffixNumber(WAYPOINT_FINISH_IMAGE_ID, this.instanceIndex);\n const instructionArrowImageId = suffixNumber(INSTRUCTION_ARROW_IMAGE_ID, this.instanceIndex);\n const selectedSummaryPopupImageId = suffixNumber(SELECTED_SUMMARY_POPUP_IMAGE_ID, this.instanceIndex);\n const deselectedSummaryPopupImageId = suffixNumber(DESELECTED_SUMMARY_POPUP_IMAGE_ID, this.instanceIndex);\n const trafficClearImageId = suffixNumber(TRAFFIC_CLEAR_IMAGE_ID, this.instanceIndex);\n const trafficMajorImageId = suffixNumber(TRAFFIC_MAJOR_IMAGE_ID, this.instanceIndex);\n const trafficModerateImageId = suffixNumber(TRAFFIC_MODERATE_IMAGE_ID, this.instanceIndex);\n const trafficMinorImageId = suffixNumber(TRAFFIC_MINOR_IMAGE_ID, this.instanceIndex);\n\n // loading of extra assets if not present in the map style:\n this.addImageIfNotExisting(waypointStartImageId, waypointStartIcon(svgIconOptions), options);\n this.addImageIfNotExisting(waypointStopImageId, waypointIcon(undefined, svgIconOptions), options);\n this.addImageIfNotExisting(waypointSoftImageId, softWaypointIcon(), options);\n this.addImageIfNotExisting(waypointFinishImageId, waypointFinishIcon(svgIconOptions), options);\n this.addImageIfNotExisting(instructionArrowImageId, instructionArrowIconImg, options);\n this.addImageIfNotExisting(\n selectedSummaryPopupImageId,\n summaryMapBubbleImg('white'),\n summaryBubbleImageOptions,\n );\n this.addImageIfNotExisting(\n deselectedSummaryPopupImageId,\n summaryMapBubbleImg('#EEEEEE'),\n summaryBubbleImageOptions,\n );\n this.addImageIfNotExisting(trafficClearImageId, trafficImg(UNKNOWN_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficMajorImageId, trafficImg(MAJOR_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficModerateImageId, trafficImg(MODERATE_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficMinorImageId, trafficImg(MINOR_DELAY_LABEL_COLOR), options);\n\n // If we have custom icons, ensure they're added to the map style:\n for (const customChargingStopIcon of config?.chargingStops?.icon?.customIcons ?? []) {\n this.addImageIfNotExisting(customChargingStopIcon.id, customChargingStopIcon.image as string, {\n pixelRatio: customChargingStopIcon.pixelRatio ?? 2,\n });\n }\n\n return routingSourcesWithLayers;\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config?: RoutingModuleConfig) {\n const mergedConfig = routeModuleConfigWithDefaults(config, this.layerIDPrefix, this.instanceIndex);\n\n // If there was already some config set, we must update the changes:\n if (this.config) {\n // replace existing configuration with new one\n const newLayersSpecs = createLayersSpecs(mergedConfig.layers, this.layerIDPrefix);\n\n // here we assume that keys for layer specs and sources are the same, please keep it that way to simplify the logic\n Object.keys(newLayersSpecs).forEach((layersSpecID) => {\n const id = layersSpecID as keyof RoutingSourcesWithLayers;\n updateLayersAndSource(\n newLayersSpecs[id],\n this.layersSpecs[id],\n this.sourcesWithLayers[id],\n this.mapLibreMap,\n );\n });\n // we need to add layers correctly\n const listOfSources = Object.values(this.sourcesWithLayers) as GeoJSONSourceWithLayers[];\n addLayers(\n listOfSources.flatMap((source) => source._layerSpecs),\n this.mapLibreMap,\n );\n // set the correct visibility if there are new layers\n listOfSources.forEach((source) => source.setLayersVisible(!!source.shownFeatures.features.length));\n this.layersSpecs = newLayersSpecs;\n }\n\n // Summary bubbles have dedicated sources and contain distance-units dependent text ...\n // ... so we need to re-show them if that config part changed:\n if (\n !isEqual(this.config?.displayUnits, mergedConfig.displayUnits) &&\n this.sourcesWithLayers.summaryBubbles.shownFeatures.features.length\n ) {\n this.sourcesWithLayers.summaryBubbles.show(\n toDisplayRouteSummaries(this.sourcesWithLayers.mainLines.shownFeatures, mergedConfig.displayUnits),\n );\n }\n\n return mergedConfig;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previouslyShown = Object.entries(this.sourcesWithLayers)\n .map((entry) => ({\n [entry[0]]: entry[1].shownFeatures,\n }))\n .reduce((acc, item) => ({ ...acc, ...item }), {}) as Record<keyof RoutingSourcesWithLayers, any>;\n\n this.initSourcesWithLayers(this.config, true);\n this._applyConfig(this.config);\n\n for (const key of Object.keys(previouslyShown) as (keyof RoutingSourcesWithLayers)[]) {\n this.sourcesWithLayers[key].show(previouslyShown[key]);\n }\n }\n\n private addImageIfNotExisting(\n imageId: string,\n image: string | HTMLImageElement,\n options: Partial<StyleImageMetadata> | undefined,\n ) {\n addOrUpdateImage('if-not-in-sprite', imageId, image, this.mapLibreMap, options);\n }\n\n /**\n * Displays the given routes on the map.\n *\n * @param routes - Route data from Routing API or custom routes.\n * @param options - Optional configuration for route selection and display.\n * @param options.selectedIndex - Index of the route to display as selected (default: 0).\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown routes\n * - Shows all route-related features: lines, sections, summaries, guidance\n * - First route is selected by default (appears more prominent)\n * - Waypoints are NOT shown automatically (use {@link showWaypoints})\n *\n * **Route Features:**\n * - Main route lines (selected and deselected styles)\n * - Traffic sections with delays\n * - Ferry, tunnel, and toll sections\n * - EV charging stations (for EV routes)\n * - Turn-by-turn instruction lines and arrows\n * - Summary bubbles with distance/time/traffic info\n *\n * @example\n * Show single route:\n * ```typescript\n * await routing.showRoutes(response.routes);\n * ```\n *\n * @example\n * Show multiple routes with specific selection:\n * ```typescript\n * await routing.showRoutes(response.routes, { selectedIndex: 1 });\n * ```\n *\n * @example\n * Complete routing workflow:\n * ```typescript\n * import { routing as routingAPI } from '@tomtom-international/maps-sdk-js/services';\n *\n * // Calculate route\n * const response = await routingAPI.calculateRoute({\n * locations: [[4.9, 52.4], [4.5, 51.9]],\n * traffic: true,\n * travelMode: 'car'\n * });\n *\n * // Display on map\n * const routing = await RoutingModule.get(map);\n * await routing.showRoutes(response.routes);\n * await routing.showWaypoints(response.routes[0].legs[0].points);\n * ```\n */\n async showRoutes(routes: Route | Routes, options?: ShowRoutesOptions) {\n const displayRoutes = toDisplayRoutes(routes, options?.selectedIndex);\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.mainLines.show(displayRoutes);\n this.sourcesWithLayers.vehicleRestricted.show(toDisplayRouteSections(displayRoutes, 'vehicleRestricted'));\n this.sourcesWithLayers.incidents.show(\n toDisplayRouteSections(displayRoutes, 'traffic', toDisplayTrafficSectionProps),\n );\n this.sourcesWithLayers.chargingStops.show(toDisplayChargingStops(displayRoutes, this.config));\n this.sourcesWithLayers.ferries.show(toDisplayRouteSections(displayRoutes, 'ferry'));\n this.sourcesWithLayers.tunnels.show(toDisplayRouteSections(displayRoutes, 'tunnel'));\n this.sourcesWithLayers.tollRoads.show(toDisplayRouteSections(displayRoutes, 'toll'));\n this.sourcesWithLayers.instructionLines.show(toDisplayInstructions(displayRoutes));\n this.sourcesWithLayers.instructionArrows.show(toDisplayInstructionArrows(displayRoutes));\n this.sourcesWithLayers.summaryBubbles.show(toDisplayRouteSummaries(displayRoutes, this.config?.displayUnits));\n }\n\n /**\n * Clears any previously shown routes from the map.\n *\n * @remarks\n * - Clears all route-related layers (lines, sections, guidance, summaries)\n * - Does NOT clear waypoints (use {@link clearWaypoints})\n * - Module remains initialized and ready for new routes\n *\n * @example\n * ```typescript\n * await routing.clearRoutes();\n * ```\n */\n async clearRoutes() {\n await this.waitUntilModuleReady();\n for (const key of Object.keys(this.sourcesWithLayers) as (keyof RoutingSourcesWithLayers)[]) {\n if (key !== 'waypoints') {\n this.sourcesWithLayers[key as keyof RoutingSourcesWithLayers].clear();\n }\n }\n }\n\n /**\n * Changes which route appears as selected.\n *\n * @param index - Zero-based index of the route to select.\n *\n * @remarks\n * **Visual Changes:**\n * - Selected route appears more prominent (thicker, brighter)\n * - Previously selected route becomes deselected style\n * - Updates all route-related features (sections, guidance)\n *\n * **Requirements:**\n * - Route must already be displayed via {@link showRoutes}\n * - Index must be within range of displayed routes\n *\n * @example\n * ```typescript\n * // Show multiple routes\n * await routingModule.showRoutes(routes);\n *\n * // User clicks alternative route\n * await routingModule.selectRoute(1);\n *\n * // Switch back to first route\n * await routingModule.selectRoute(0);\n * ```\n */\n async selectRoute(index: number) {\n const updatedRoutes = toDisplayRoutes(this.sourcesWithLayers.mainLines.shownFeatures, index);\n\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.mainLines.show(updatedRoutes);\n // TODO: simply update route style instead of regenerating EV stations again\n this.sourcesWithLayers.chargingStops.show(toDisplayChargingStops(updatedRoutes, this.config));\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.vehicleRestricted);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.incidents);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.ferries);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.tollRoads);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.tunnels);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.instructionLines);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.instructionArrows);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.summaryBubbles);\n }\n\n /**\n * Shows the given waypoints on the map.\n * @param waypoints The waypoint-like inputs to show.\n */\n async showWaypoints(waypoints: PlanningWaypoint[] | Waypoints) {\n const displayWaypoints = Array.isArray(waypoints)\n ? toDisplayWaypoints(waypoints, this.config?.waypoints, this.instanceIndex)\n : // FeatureCollection expected:\n toDisplayWaypoints(waypoints.features as PlanningWaypoint[], this.config?.waypoints, this.instanceIndex);\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.waypoints.show(displayWaypoints);\n }\n\n /**\n * Clears any previously shown waypoints from the map.\n * * If nothing was shown before, nothing happens.\n */\n async clearWaypoints() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.waypoints.clear();\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return {\n mainLines: new EventsModule<Route<DisplayRouteProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.mainLines,\n this.config?.events,\n ),\n waypoints: new EventsModule<Waypoint<WaypointDisplayProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.waypoints,\n this.config?.events,\n ),\n chargingStops: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.chargingStops,\n this.config?.events,\n ),\n summaryBubbles: new EventsModule<DisplayRouteSummary>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.summaryBubbles,\n this.config?.events,\n ),\n incidents: new EventsModule<RouteSections<DisplayTrafficSectionProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.incidents,\n this.config?.events,\n ),\n vehicleRestricted: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.vehicleRestricted,\n this.config?.events,\n ),\n ferries: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.ferries,\n this.config?.events,\n ),\n tollRoads: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.tollRoads,\n this.config?.events,\n ),\n tunnels: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.tunnels,\n this.config?.events,\n ),\n instructionLines: new EventsModule<DisplayInstruction>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.instructionLines,\n this.config?.events,\n ),\n };\n }\n\n /**\n * Returns the map style layer under which route lines are rendered.\n * * Useful if you want to render extra layers just above the route ones but not on top of everything else.\n * * It might differ depending on the loaded style/version.\n */\n getLayerToRenderLinesUnder(): string {\n return mapStyleLayerIDs.lowestLabel;\n }\n}\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path d=\\\"M63.734 86.383c-1.404.026-2.78-.393-3.93-1.197s-2.01-1.949-2.46-3.271l-3.15-9.339c-1.093-3.403-3.748-6.089-7.154-7.238L37.5 62.21c-2.742-.902-4.567-3.477-4.5-6.345-.058-2.874 1.761-5.457 4.5-6.388l36-11.886c2.461-.88 5.213-.27 7.062 1.567s2.466 4.571 1.578 7.015L70.17 81.918c-.938 2.719-3.54 4.526-6.436 4.469h0z\\\"\\n fill=\\\"#f4f5f6\\\"/>\\n</svg>\\n\"","export default \"<svg width=\\\"32\\\" height=\\\"32\\\" viewBox=\\\"0 0 32 32\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\">\\n <circle id=\\\"circle\\\" cx=\\\"16\\\" cy=\\\"16\\\" r=\\\"12\\\" fill=\\\"white\\\" stroke=\\\"#105287\\\" stroke-width=\\\"4\\\"/>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path d=\\\"M33 83.404a2.99 2.99 0 0 1-3-2.978V44.681a2.99 2.99 0 1 1 6 0v35.745a2.99 2.99 0 0 1-3 2.978zm48-38.723H39v17.872h42V44.681zm3.878 37.851a3.02 3.02 0 0 0 4.244 0c.561-.559.878-1.317.878-2.106V44.681a2.99 2.99 0 1 0-6 0v35.745c0 .789.317 1.547.878 2.106z\\\"\\n fill=\\\"#f4f5f6\\\"/>\\n</svg>\\n\"","import type { StyleSpecification } from 'maplibre-gl';\nimport type { InternalTomTomMapParams, StandardStyle, StandardStyleID, StyleInput, StyleModule } from './types/mapInit';\nimport { styleModules } from './types/mapInit';\n\nconst DEFAULT_STANDARD_STYLE_ID: StandardStyleID = 'standardLight';\nconst URL_PREFIX = '${baseURL}/maps/orbis/assets/styles/${version}/style.json?&apiVersion=1&key=${apiKey}';\n\nconst standardStyleModulesValues: Record<StandardStyleID, Record<StyleModule, string>> = {\n standardLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_light',\n },\n standardDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_dark',\n },\n drivingLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_light',\n },\n drivingDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_dark',\n },\n monoLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_mono-light',\n },\n monoDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_mono-dark',\n },\n satellite: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_satellite',\n },\n};\n\nconst baseMapStyleUrlTemplate = (suffix: string): string => `${URL_PREFIX}&map=${suffix}`;\n\nconst baseMapStyleUrlTemplates: Record<StandardStyleID, string> = {\n standardLight: baseMapStyleUrlTemplate('basic_street-light'),\n standardDark: baseMapStyleUrlTemplate('basic_street-dark'),\n drivingLight: baseMapStyleUrlTemplate('basic_street-light-driving'),\n drivingDark: baseMapStyleUrlTemplate('basic_street-dark-driving'),\n monoLight: baseMapStyleUrlTemplate('basic_mono-light'),\n monoDark: baseMapStyleUrlTemplate('basic_mono-dark'),\n satellite: baseMapStyleUrlTemplate('basic_street-satellite'),\n};\n\nconst buildStandardStyleUrl = (standardStyle: StandardStyle, baseUrl: string, apiKey: string): string => {\n const standardStyleID = standardStyle.id ?? DEFAULT_STANDARD_STYLE_ID;\n\n const styleURL = new URL(\n baseMapStyleUrlTemplates[standardStyleID]\n .replace('${baseURL}', baseUrl)\n .replace('${version}', standardStyle.version ?? '0.6.0-0')\n .replace('${apiKey}', apiKey),\n );\n\n for (const module of standardStyle.include ?? styleModules) {\n styleURL.searchParams.append(module, standardStyleModulesValues[standardStyleID][module]);\n }\n\n return styleURL.toString();\n};\n\nconst withApiKey = (givenUrl: string, apiKey: string): string => {\n const url = new URL(givenUrl);\n if (!url.searchParams.has('key')) {\n url.searchParams.set('key', apiKey);\n } else {\n console.warn(\n 'The style URL is coming with an API key parameter which takes priority. ' +\n 'If you want to use the SDK configured API key, remove the key param from the style URL',\n );\n }\n return url.toString();\n};\n\n/**\n * @ignore\n * @param mapParams The SDK parameters to convert to input renderer style.\n * @return The map style to load into the renderer.\n */\nexport const buildStyleInput = (mapParams: InternalTomTomMapParams): StyleSpecification | string => {\n const style = mapParams.style;\n const baseUrl = mapParams.commonBaseURL;\n const apiKey = mapParams.apiKey;\n\n if (typeof style === 'string') {\n return buildStandardStyleUrl({ id: style }, baseUrl, apiKey);\n } else if (style?.type === 'standard') {\n return buildStandardStyleUrl(style, baseUrl, apiKey);\n } else if (style?.type === 'custom' && style?.url) {\n return withApiKey(style.url, apiKey);\n } else if (style?.type === 'custom' && style?.json) {\n return style.json;\n }\n\n // no style defined, use default\n return buildStandardStyleUrl({ id: DEFAULT_STANDARD_STYLE_ID }, baseUrl, apiKey);\n};\n\n/**\n * Includes the previous standard style parts into the given standard style if the new one didn't define any.\n * * Both new and previous styles must be of \"standard\" type.\n * @ignore\n */\nexport const withPreviousStyleParts = (style: StyleInput, previousStyle?: StyleInput): StyleInput => {\n if (\n previousStyle &&\n typeof previousStyle === 'object' &&\n previousStyle.type === 'standard' &&\n previousStyle.include\n ) {\n if (typeof style === 'string' || (style.type === 'standard' && !style.include)) {\n return {\n type: 'standard',\n id: typeof style === 'string' ? style : style.id,\n include: (previousStyle as StandardStyle).include,\n };\n }\n }\n return style;\n};\n","import { type BBox, type Language, mergeFromGlobal } from '@tomtom-org/maps-sdk/core';\nimport { isEqual } from 'lodash-es';\nimport { getRTLTextPluginStatus, Map, setRTLTextPlugin } from 'maplibre-gl';\nimport { version as maplibreVersion } from 'maplibre-gl/package.json';\nimport type { InternalTomTomMapParams, MapLibreOptions, StyleInput, TomTomMapParams } from './init';\nimport { buildMapOptions } from './init/buildMapOptions';\nimport { buildStyleInput, withPreviousStyleParts } from './init/styleInputBuilder';\nimport {\n EventsProxy,\n filterLayersBySources,\n HILLSHADE_SOURCE_ID,\n LightDark,\n TRAFFIC_FLOW_SOURCE_ID,\n TRAFFIC_INCIDENTS_SOURCE_ID,\n} from './shared';\nimport { isLayerLocalizable } from './shared/localization';\nimport { addPinCategoriesSpriteToStyle, getStyleLightDarkTheme } from './shared/mapUtils';\n\n/**\n * Handler interface for responding to map style changes.\n *\n * @remarks\n * This interface defines callbacks that are invoked when the map style changes via {@link TomTomMap.setStyle}.\n * Use this to perform cleanup or reinitialization of custom map features when styles are switched.\n *\n * **Lifecycle:**\n * 1. `onStyleAboutToChange` - Called before the new style is applied\n * 2. Style change occurs\n * 3. `onStyleChanged` - Called after the new style has been fully loaded\n *\n * **Common Use Cases:**\n * - Saving and restoring custom layers or sources\n * - Reinitializing map modules after style changes\n * - Updating UI components based on the new style\n * - Cleaning up resources tied to the previous style\n *\n * @example\n * ```typescript\n * const styleHandler: StyleChangeHandler = {\n * onStyleAboutToChange: () => {\n * console.log('Style changing - saving state...');\n * // Save custom layer data\n * },\n * onStyleChanged: () => {\n * console.log('Style changed - restoring state...');\n * // Restore custom layers\n * }\n * };\n *\n * map.addStyleChangeHandler(styleHandler);\n * ```\n *\n * @see {@link TomTomMap.addStyleChangeHandler}\n * @see {@link TomTomMap.setStyle}\n *\n * @group Map Style\n */\nexport type StyleChangeHandler = {\n /**\n * Callback invoked immediately before a style change begins.\n *\n * @remarks\n * Use this to perform cleanup or save state before the current style is removed.\n * This method can be synchronous or asynchronous.\n *\n * @returns void or a Promise that resolves when preparation is complete\n */\n onStyleAboutToChange: () => void | Promise<void>;\n /**\n * Callback invoked after a new style has been fully loaded.\n *\n * @remarks\n * Use this to restore state, reinitialize layers, or perform other setup\n * that depends on the new style being ready. This method can be synchronous or asynchronous.\n *\n * @returns void or a Promise that resolves when reinitialization is complete\n */\n onStyleChanged: () => void | Promise<void>;\n};\n\n/**\n * Main TomTom Map class for displaying interactive maps in web applications.\n *\n * This is the entry point for rendering TomTom maps. It wraps MapLibre GL JS and provides\n * a simplified, enhanced API for common mapping tasks.\n *\n * @remarks\n * **Key Features:**\n * - Built on MapLibre GL JS for high-performance rendering\n * - Seamless style switching without map reload\n * - Integrated event handling system\n * - Multi-language support with dynamic switching\n * - Compatible with TomTom map modules (traffic, POIs, routing, etc.)\n *\n * **Architecture:**\n * - Exposes the underlying MapLibre Map instance via {@link mapLibreMap}\n * - Manages map lifecycle and style transitions\n * - Coordinates with map modules for data visualization\n *\n * @example\n * Basic map initialization:\n * ```typescript\n * import { TomTomMap } from '@tomtom-international/maps-sdk-js/map';\n *\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: 'standardLight',\n * mapLibre: {\n * container: 'map',\n * center: [4.9041, 52.3676],\n * zoom: 10\n * }\n * });\n * ```\n *\n * @example\n * With modules and configuration:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: {\n * type: 'standard',\n * id: 'standardDark',\n * include: ['trafficFlow', 'trafficIncidents']\n * },\n * language: 'en-US',\n * events: {\n * precisionMode: 'point-then-box',\n * cursorOnHover: 'pointer'\n * },\n * mapLibre: {\n * container: 'map',\n * center: [-74.006, 40.7128],\n * zoom: 12\n * }\n * });\n *\n * // Access MapLibre functionality directly\n * map.mapLibreMap.on('load', () => {\n * console.log('Map loaded');\n * });\n * ```\n *\n * @group Map\n */\nexport class TomTomMap {\n /**\n * Indicates whether the map style has been fully loaded and is ready for interaction.\n *\n * @remarks\n * - `true` when the style is loaded and modules can be safely initialized\n * - `false` during map construction or style changes\n * - Check this before performing style-dependent operations\n *\n * @example\n * ```typescript\n * if (map.mapReady) {\n * // Safe to initialize modules\n * const trafficFlowModule = await TrafficFlowModule.get(map);\n * }\n * ```\n */\n mapReady = false;\n\n /**\n * The underlying MapLibre GL JS Map instance.\n *\n * @remarks\n * **When to Use:**\n * - Access advanced MapLibre functionality not exposed by TomTomMap\n * - Add custom layers, sources, or controls\n * - Listen to MapLibre-specific events\n * - Integrate third-party MapLibre plugins\n *\n * **Important:**\n * - Available immediately after TomTomMap construction\n * - Direct modifications may affect SDK module behavior\n * - Coordinate with SDK modules to avoid conflicts\n *\n * @example\n * Add custom layer:\n * ```typescript\n * map.mapLibreMap.addLayer({\n * id: 'custom-layer',\n * type: 'circle',\n * source: 'my-data',\n * paint: {\n * 'circle-radius': 6,\n * 'circle-color': '#ff0000'\n * }\n * });\n * ```\n *\n * @example\n * Listen to events:\n * ```typescript\n * map.mapLibreMap.on('moveend', () => {\n * console.log('Camera position:', map.mapLibreMap.getCenter());\n * });\n * ```\n *\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Documentation}\n */\n readonly mapLibreMap: Map;\n /**\n * @ignore\n */\n readonly _eventsProxy: EventsProxy;\n /**\n * @ignore\n */\n _params: InternalTomTomMapParams;\n\n styleLightDarkTheme: LightDark;\n\n private readonly styleChangeHandlers: StyleChangeHandler[] = [];\n\n /**\n * Constructs a new TomTom Map instance and attaches it to a DOM element.\n *\n * @param mapParams - Combined TomTom and MapLibre parameters for map initialization.\n * Includes API key, style, events, and MapLibre options like container, center, zoom, etc.\n * See {@link TomTomMapParams} for all available parameters.\n *\n * @remarks\n * **Initialization Process:**\n * 1. Merges `mapParams` with global configuration\n * 2. Creates underlying MapLibre map instance\n * 3. Loads specified style asynchronously\n * 4. Sets `mapReady` to `true` when complete\n *\n * **Configuration Priority:**\n * - Parameters passed here override global configuration\n * - Allows per-map customization while sharing common settings\n *\n * @example\n * Minimal initialization:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * mapLibre: {\n * container: 'map',\n * center: [0, 0],\n * zoom: 2\n * }\n * });\n * ```\n *\n * @example\n * Full configuration:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * },\n * language: 'en-US',\n * events: {\n * precisionMode: 'point-then-box',\n * paddingBoxPx: 10\n * },\n * mapLibre: {\n * container: 'map',\n * center: [-122.4194, 37.7749],\n * zoom: 13,\n * pitch: 45,\n * bearing: -17.6,\n * antialias: true,\n * maxZoom: 18,\n * minZoom: 8\n * }\n * });\n * ```\n *\n * @throws Will log errors if RTL text plugin fails to load (non-blocking)\n *\n * @see {@link MapLibreOptions}\n * @see {@link TomTomMapParams}\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Parameters}\n * @see [Map Quickstart Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/quickstart)\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n * @see [User Interaction Events Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/user-events)\n */\n constructor(mapParams: TomTomMapParams) {\n this._params = mergeFromGlobal(mapParams);\n this.styleLightDarkTheme = getStyleLightDarkTheme(this._params.style);\n this.ensureMapLibreCSSLoaded();\n\n this.mapLibreMap = new Map(buildMapOptions(this._params));\n this.mapLibreMap.once('styledata', () => {\n this.handleStyleData(false);\n });\n this._eventsProxy = new EventsProxy(this.mapLibreMap, this._params?.events);\n\n this.loadRTLTextPlugin();\n }\n\n private loadRTLTextPlugin(): void {\n // deferred (just in case), lazy loading of the RTL plugin:\n setTimeout(() => {\n if (!['deferred', 'loaded'].includes(getRTLTextPluginStatus())) {\n setRTLTextPlugin(\n 'https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.3.0/dist/mapbox-gl-rtl-text.js',\n true,\n ).catch((error) => console.error('Something went wrong when setting RTL plugin', error));\n }\n });\n }\n\n /**\n * Dynamically loads the MapLibre CSS stylesheet from CDN.\n */\n private ensureMapLibreCSSLoaded(): void {\n if (typeof document === 'undefined') {\n return;\n }\n // Check if the CSS is already loaded to avoid duplicates:\n const existingLink = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"], style')).some((element) =>\n element.textContent?.includes('.maplibregl-map'),\n );\n if (existingLink) {\n return;\n }\n\n // Create and inject a link tag to load CSS from unpkg CDN\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = `https://unpkg.com/maplibre-gl@${maplibreVersion}/dist/maplibre-gl.css`;\n document.head.appendChild(link);\n }\n\n /**\n * Changes the map style dynamically without reloading the entire map.\n *\n * @param style - The new style to apply. Can be a string ID or a detailed style configuration.\n * @param options - Configuration options for the style change behavior.\n * @param options.keepState - Whether to preserve SDK-rendered items and configurations when changing styles.\n * When `true` (default), maintains traffic layers, routes, markers, and other SDK features.\n * When `false`, performs a clean style switch without preserving previous state.\n *\n * @remarks\n * **Behavior:**\n * - Temporarily sets {@link mapReady} to `false` during the transition\n * - Triggers all registered {@link StyleChangeHandler} callbacks\n * - Resets {@link mapReady} to `true` when the new style is fully loaded\n *\n * **State Preservation (keepState: true):**\n * - Merges style parts from the previous style with the new one\n * - Maintains SDK module layers (traffic, routes, POIs, etc.)\n * - Preserves language settings\n *\n * **Clean Switch (keepState: false):**\n * - Applies the new style without merging previous configuration\n * - Removes all SDK module layers\n * - Useful for complete style resets\n *\n * @example\n * Simple style change:\n * ```typescript\n * // Switch to dark mode\n * map.setStyle('standardDark');\n * ```\n *\n * @example\n * Style change with detailed configuration:\n * ```typescript\n * map.setStyle({\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * });\n * ```\n *\n * @example\n * Clean style switch without state preservation:\n * ```typescript\n * // Complete reset - removes all SDK layers and modules\n * map.setStyle('standardDark', { keepState: false });\n * ```\n *\n * @example\n * With style change handlers:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * console.log('Preparing for style change...');\n * },\n * onStyleChanged: () => {\n * console.log('New style applied!');\n * }\n * });\n *\n * map.setStyle('standardDark');\n * ```\n *\n * @see {@link TomTomMapParams.style} - For setting style during initialization\n * @see {@link StyleChangeHandler} - For handling style change events\n * @see {@link getStyle} - For retrieving the current style\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n */\n setStyle = (style: StyleInput, options: { keepState?: boolean } = { keepState: true }): void => {\n this.mapReady = false;\n for (const handler of this.styleChangeHandlers) {\n try {\n handler.onStyleAboutToChange();\n } catch (e) {\n console.error(e);\n }\n }\n const effectiveStyle = options.keepState ? withPreviousStyleParts(style, this._params.style) : style;\n this._params = { ...this._params, style: effectiveStyle };\n this.styleLightDarkTheme = getStyleLightDarkTheme(effectiveStyle);\n this.mapLibreMap.once('styledata', () => {\n // We only handle the style data change if the applied style is still the same as the one we set,\n // to prevent race conditions when handling stale styles applied quickly in succession.\n // (If the current style parameters are different, there's likely a new style being set, which will trigger the handler soon after)\n if (!this.mapReady && isEqual(effectiveStyle, this._params.style)) {\n this.handleStyleData(options.keepState || true);\n }\n });\n this.mapLibreMap.setStyle(buildStyleInput(this._params), { validate: false });\n };\n\n /**\n * Retrieves the current style configuration of the map.\n *\n * @returns The current {@link StyleInput} configuration, or `undefined` if no style is set.\n *\n * @remarks\n * Returns the style configuration as it was set, not the fully resolved MapLibre style object.\n * Use this to inspect or store the current style configuration for later restoration.\n *\n * **Return Value:**\n * - String ID (e.g., `'standardLight'`) for simple style configurations\n * - Style object with `type`, `id`, and optional `include` properties for detailed configurations\n * - `undefined` if no style has been explicitly set\n *\n * @example\n * ```typescript\n * const currentStyle = map.getStyle();\n * console.log('Current style:', currentStyle);\n *\n * // Save style for later\n * const savedStyle = map.getStyle();\n *\n * // Later, restore it\n * if (savedStyle) {\n * map.setStyle(savedStyle);\n * }\n * ```\n *\n * @example\n * Conditional logic based on current style:\n * ```typescript\n * const style = map.getStyle();\n * if (typeof style === 'string' && style.includes('Dark')) {\n * console.log('Dark mode is active');\n * }\n * ```\n *\n * @see {@link setStyle} - For changing the map style\n * @see {@link StyleInput} - For available style configuration options\n */\n getStyle = (): StyleInput | undefined => {\n return this._params.style;\n };\n\n private _setLanguage(language: Language) {\n this._params = { ...this._params, language };\n const mapLanguage = language?.includes('-') ? language.split('-')[0] : language;\n this.mapLibreMap.getStyle().layers.forEach((layer) => {\n if (layer.type === 'symbol' && isLayerLocalizable(layer)) {\n const textFieldValue = mapLanguage\n ? ['coalesce', ['get', `name_${mapLanguage}`], ['get', 'name']]\n : ['get', 'name'];\n this.mapLibreMap.setLayoutProperty(layer.id, 'text-field', textFieldValue, { validate: false });\n }\n });\n }\n\n /**\n * Changes the language of the map.\n * * You can use this method to change the language at runtime.\n * * To set the language upon initialization, you can better do it via {@link core!TomTomConfig global config}\n * or {@link TomTomMapParams}.\n * @param language The language to be used in map translations.\n *\n * @remarks\n * **Behavior:**\n * - Updates all localizable map labels to the specified language\n * - Falls back to the default label name if the requested language is unavailable\n * - Can be called before or after the map is fully loaded\n * - If called before map is ready, will apply once the style loads\n *\n * **Language Format:**\n * - Simple language codes: `'en'`, `'fr'`, `'de'`, `'ja'`, `'zh'`\n * - Locale-specific codes: `'en-US'`, `'en-GB'`, `'zh-CN'`, `'pt-BR'`\n * - When using locale codes (with `-`), only the language portion is used for labels\n *\n * **Persistence:**\n * - Language setting persists across style changes (when `keepState: true`)\n * - Set during initialization via {@link TomTomMapParams.language} for immediate application\n *\n * @example\n * Change language at runtime:\n * ```typescript\n * // Switch to French\n * map.setLanguage('fr');\n * ```\n *\n * @example\n * Use locale-specific codes:\n * ```typescript\n * // Use Simplified Chinese\n * map.setLanguage('zh-CN');\n *\n * // Use Brazilian Portuguese\n * map.setLanguage('pt-BR');\n * ```\n *\n * @example\n * Language switcher UI:\n * ```typescript\n * const languageSelector = document.getElementById('lang-select');\n * languageSelector.addEventListener('change', (e) => {\n * map.setLanguage(e.target.value);\n * });\n * ```\n *\n * @see {@link TomTomMapParams.language} - For setting language during initialization\n * @see {@link https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes | ISO 639-1 Language Codes}\n */\n setLanguage(language: Language) {\n if (this.mapReady) {\n this._setLanguage(language);\n } else {\n this.mapLibreMap.once('styledata', () => this.setLanguage(language));\n }\n }\n\n /**\n * Retrieves the current visible map area as a GeoJSON bounding box.\n *\n * @returns A {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox} array\n * in the format `[west, south, east, north]` representing the map's current viewport bounds.\n *\n * @remarks\n * **Return Format:**\n * - Array of four numbers: `[minLongitude, minLatitude, maxLongitude, maxLatitude]`\n * - Coordinates are in WGS84 decimal degrees\n * - West/East values range from -180 to 180\n * - South/North values range from -90 to 90\n *\n * @example\n * Get current bounds:\n * ```typescript\n * const bbox = map.getBBox();\n * console.log('Bounds:', bbox);\n * // Output: [-122.5, 37.7, -122.3, 37.8]\n * // [west, south, east, north]\n * ```\n *\n * @example\n * Use bounds for spatial query:\n * ```typescript\n * const bbox = map.getBBox();\n * const results = await searchAPI.searchInBoundingBox({\n * bbox: bbox,\n * query: 'restaurants'\n * });\n * ```\n *\n * @example\n * Save and restore map view:\n * ```typescript\n * // Save current view\n * const savedBounds = map.getBBox();\n * const savedZoom = map.mapLibreMap.getZoom();\n *\n * // Later, restore the view\n * const [west, south, east, north] = savedBounds;\n * map.mapLibreMap.fitBounds([[west, south], [east, north]]);\n * ```\n *\n * @see {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox Specification}\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/geography/#lnglatbounds | MapLibre LngLatBounds}\n */\n getBBox(): BBox {\n return this.mapLibreMap.getBounds().toArray().flat() as BBox;\n }\n\n private handleStyleData(keepState: boolean) {\n // We ensure to make traffic and hillshade hidden by default (even if right after the modules bring it back to visible state)\n // This way we ensure such layers are invisible even of their related SDK modules are not used.\n for (const layer of filterLayersBySources(this.mapLibreMap, [\n TRAFFIC_INCIDENTS_SOURCE_ID,\n TRAFFIC_FLOW_SOURCE_ID,\n HILLSHADE_SOURCE_ID,\n ])) {\n this.mapLibreMap.setLayoutProperty(layer.id, 'visibility', 'none', { validate: false });\n }\n\n // For most use cases we'll need to have pins available (places, routing...) so we add them by default:\n // (subsequent loads for the same sprite should be cached)\n addPinCategoriesSpriteToStyle(this._params, this.mapLibreMap);\n // We restore the language if it was set before:\n this._params.language && this._setLanguage(this._params.language);\n\n this.mapReady = true;\n if (keepState) {\n for (const handler of this.styleChangeHandlers) {\n try {\n handler.onStyleChanged();\n } catch (e) {\n console.error(e);\n }\n }\n }\n }\n\n /**\n * Registers a handler to be notified when the map style changes.\n *\n * @param handler - A {@link StyleChangeHandler} object with callbacks for style change events.\n *\n * @remarks\n * **When to Use:**\n * - You have custom layers or sources that need to be recreated after style changes\n * - Your application needs to respond to style switches (e.g., light/dark mode transitions)\n * - You need to save and restore state during style changes\n * - Map modules need to reinitialize when styles change\n *\n * **Handler Lifecycle:**\n * 1. `onStyleAboutToChange()` - Called before the style change begins\n * 2. Style change occurs\n * 3. `onStyleChanged()` - Called after the new style has been fully loaded\n *\n * **Multiple Handlers:**\n * - Multiple handlers can be registered and will all be called in registration order\n * - Each handler's errors are caught independently and logged to the console\n * - One failing handler won't prevent others from executing\n *\n * **Important Notes:**\n * - Handlers are only triggered by {@link setStyle} calls, not initial map construction\n * - Only called when `keepState: true` in {@link setStyle} options\n * - Handlers persist for the lifetime of the TomTomMap instance\n *\n * @example\n * Basic usage:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * console.log('Style is changing...');\n * },\n * onStyleChanged: () => {\n * console.log('Style changed successfully!');\n * }\n * });\n *\n * // Later trigger the handlers\n * map.setStyle('standardDark');\n * ```\n *\n * @example\n * Preserve custom layers across style changes:\n * ```typescript\n * let customLayerData = null;\n *\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * // Save custom layer data before style changes\n * if (map.mapLibreMap.getLayer('my-custom-layer')) {\n * customLayerData = map.mapLibreMap.getSource('my-data')._data;\n * map.mapLibreMap.removeLayer('my-custom-layer');\n * map.mapLibreMap.removeSource('my-data');\n * }\n * },\n * onStyleChanged: () => {\n * // Restore custom layer after new style is loaded\n * if (customLayerData) {\n * map.mapLibreMap.addSource('my-data', {\n * type: 'geojson',\n * data: customLayerData\n * });\n * map.mapLibreMap.addLayer({\n * id: 'my-custom-layer',\n * type: 'circle',\n * source: 'my-data',\n * paint: { 'circle-radius': 6, 'circle-color': '#007cbf' }\n * });\n * }\n * }\n * });\n * ```\n *\n * @example\n * Async handler for external API calls:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: async () => {\n * await saveStateToAPI(map.getStyle());\n * },\n * onStyleChanged: async () => {\n * await loadStateFromAPI();\n * }\n * });\n * ```\n *\n * @example\n * Update UI based on style:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * document.body.classList.add('style-changing');\n * },\n * onStyleChanged: () => {\n * document.body.classList.remove('style-changing');\n * const style = map.getStyle();\n * if (typeof style === 'string' && style.includes('Dark')) {\n * document.body.classList.add('dark-mode');\n * } else {\n * document.body.classList.remove('dark-mode');\n * }\n * }\n * });\n * ```\n *\n * @see {@link StyleChangeHandler} - Handler interface definition\n * @see {@link setStyle} - Method that triggers the handlers\n */\n addStyleChangeHandler(handler: StyleChangeHandler): void {\n this.styleChangeHandlers.push(handler);\n }\n}\n","import type { MapOptions } from 'maplibre-gl';\nimport { injectTomTomHeaders } from '../shared/mapUtils';\nimport { buildStyleInput } from './styleInputBuilder';\nimport type { InternalTomTomMapParams } from './types/mapInit';\n\n/**\n * @ignore\n * @param tomtomMapParams\n */\nexport const buildMapOptions = (tomtomMapParams: InternalTomTomMapParams): MapOptions => {\n return {\n // defaults (can be overwritten by given options)\n validateStyle: false,\n maxTileCacheZoomLevels: 22,\n cancelPendingTileRequestsWhileZooming: false,\n // given options:\n ...tomtomMapParams.mapLibre,\n // SDK overrides (won't have any effect via given options):\n style: buildStyleInput(tomtomMapParams),\n attributionControl: { compact: false },\n transformRequest: injectTomTomHeaders(tomtomMapParams),\n };\n};\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\n\n/**\n * @ignore\n */\nexport const isLayerLocalizable = (layer: SymbolLayerSpecification): boolean => {\n const textField = (layer.layout?.['text-field'] ?? '') as string | ExpressionSpecification;\n return textField\n ? // tries to detect layers which have a \"text-field\" that can be localized\n // ex. \"text-field\": \"{name}\" or \"text-field\": [\"get\", \"name\"]\n textField === '{name}' ||\n (textField.length === 2 && textField[1] === 'name') ||\n // tries to detect layers which have \"text-field\" that was localized already\n // ex. \"text-field\": [\"coalesce\", [\"get\", \"name_en\"], [\"get\", \"name\"]]\n (textField.length === 3 &&\n Array.isArray(textField[1]) &&\n typeof textField[1][1] === 'string' &&\n textField[1][1].includes('name_') &&\n Array.isArray(textField[2]) &&\n textField[2].includes('name'))\n : false;\n};\n","import type { DelayMagnitude } from '@tomtom-org/maps-sdk/core';\nimport type { FilterShowMode, MapModuleCommonConfig, ValuesFilter } from '../../shared';\n\n/**\n * Available traffic incident category identifiers.\n *\n * @remarks\n * These categories classify different types of traffic incidents that can be displayed on the map.\n *\n * @group Traffic Incidents\n */\nexport const incidentCategories = [\n 'unknown',\n 'accident',\n 'fog',\n 'dangerous_conditions',\n 'rain',\n 'ice',\n 'jam',\n 'lane_closed',\n 'road_closed',\n 'road_works',\n 'wind',\n 'flooding',\n 'broken_down_vehicle',\n] as const;\n\n/**\n * Traffic incident category type.\n *\n * @remarks\n * Represents the type of traffic incident affecting road conditions.\n * Used for filtering and categorizing incidents displayed on the map.\n *\n * Available categories:\n * - `unknown` - Unclassified incident\n * - `accident` - Vehicle collision or crash\n * - `fog` - Low visibility due to fog\n * - `dangerous_conditions` - Hazardous road conditions\n * - `rain` - Heavy rain affecting traffic\n * - `ice` - Icy road conditions\n * - `jam` - Traffic congestion or standstill\n * - `lane_closed` - One or more lanes unavailable\n * - `road_closed` - Complete road closure\n * - `road_works` - Construction or maintenance\n * - `wind` - Strong winds affecting traffic\n * - `flooding` - Water on roadway\n * - `broken_down_vehicle` - Disabled vehicle blocking traffic\n *\n * @group Traffic Incidents\n */\nexport type IncidentCategory = (typeof incidentCategories)[number];\n\n/**\n * @ignore\n */\nexport const incidentCategoriesMapping: Record<IncidentCategory, number> = {\n unknown: 0,\n accident: 1,\n fog: 2,\n dangerous_conditions: 3,\n rain: 4,\n ice: 5,\n jam: 6,\n lane_closed: 7,\n road_closed: 8,\n road_works: 9,\n wind: 10,\n flooding: 11,\n broken_down_vehicle: 14,\n} as const;\n\n/**\n * Available road hierarchy category identifiers.\n *\n * @remarks\n * These categories represent different levels in the road network hierarchy,\n * from major highways to local streets.\n *\n * @group Traffic\n */\nexport const roadCategories = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary', 'street'] as const;\n\n/**\n * Road hierarchy category type.\n *\n * @remarks\n * Classifies roads by their importance and capacity in the transportation network.\n * Used for filtering traffic data display based on road significance.\n *\n * Road hierarchy (from highest to lowest):\n * - `motorway` - High-capacity highways with restricted access\n * - `trunk` - Major inter-city roads\n * - `primary` - Primary through routes\n * - `secondary` - Secondary through routes\n * - `tertiary` - Connecting roads (see {@link TertiaryRoadCategory})\n * - `street` - Local streets (see {@link StreetRoadCategory})\n *\n * @group Traffic\n */\nexport type RoadCategory = (typeof roadCategories)[number];\n\n/**\n * Available tertiary road sub-category identifiers.\n *\n * @remarks\n * Provides finer granularity for classifying tertiary roads.\n *\n * @group Traffic\n */\nexport const tertiaryRoadCategories = ['connecting', 'major_local'] as const;\n\n/**\n * Tertiary road sub-category type.\n *\n * @remarks\n * Further classifies tertiary roads into specific sub-types for more granular filtering.\n *\n * Sub-categories:\n * - `connecting` - Roads connecting different areas\n * - `major_local` - Major roads within local areas\n *\n * @group Traffic\n */\nexport type TertiaryRoadCategory = (typeof tertiaryRoadCategories)[number];\n\n/**\n * Available street road sub-category identifiers.\n *\n * @remarks\n * Provides finer granularity for classifying local streets.\n *\n * @group Traffic\n */\nexport const streetRoadCategories = ['local', 'minor_local'] as const;\n\n/**\n * Street road sub-category type.\n *\n * @remarks\n * Further classifies local streets into specific sub-types for more granular filtering.\n *\n * Sub-categories:\n * - `local` - Standard local streets\n * - `minor_local` - Minor residential streets\n *\n * @group Traffic\n */\nexport type StreetRoadCategory = (typeof streetRoadCategories)[number];\n\n/**\n * Configuration for filtering traffic incidents by delay duration.\n *\n * @remarks\n * Allows filtering incidents based on whether they cause delays and the severity of those delays.\n * Useful for focusing on incidents with the most significant traffic impact.\n *\n * @group Traffic\n */\nexport type DelayFilter = {\n /**\n * Requires incidents to have an associated delay.\n *\n * @remarks\n * When `true`, incidents without delay information will be hidden from the map.\n * When `false` or omitted, incidents are shown regardless of delay data availability.\n *\n * @defaultValue `false`\n */\n mustHaveDelay?: boolean;\n\n /**\n * Minimum delay threshold in minutes.\n *\n * @remarks\n * Only incidents causing delays of at least this duration will be shown.\n *\n * **Behavior:**\n * - If `mustHaveDelay` is `false` or not set, this filter only applies to incidents that have delay data\n * - Incidents without delay data are still shown (unless `mustHaveDelay` is `true`)\n *\n * @example\n * ```ts\n * // Show only incidents with delays of 5 minutes or more\n * delays: { minDelayMinutes: 5 }\n * ```\n */\n minDelayMinutes?: number;\n};\n\n/**\n * Common filter configuration shared between traffic incidents and flow visualization.\n *\n * @remarks\n * Provides road category filtering capabilities used by both incident and flow modules.\n *\n * @group Traffic\n */\nexport type TrafficCommonFilter = {\n /**\n * Filters traffic data by road hierarchy categories.\n *\n * @remarks\n * Controls which road types display traffic information.\n * Use the `mode` field to specify whether to show or hide the selected categories.\n *\n * @example\n * ```ts\n * // Show only motorways and trunk roads\n * roadCategories: { mode: 'show', values: ['motorway', 'trunk'] }\n * ```\n */\n roadCategories?: ValuesFilter<RoadCategory>;\n\n /**\n * Filters traffic data by road sub-categories.\n *\n * @remarks\n * Provides finer-grained control for tertiary roads and streets.\n * Applies to sub-categories of {@link TertiaryRoadCategory} and {@link StreetRoadCategory}.\n *\n * @example\n * ```ts\n * // Hide minor local streets\n * roadSubCategories: { mode: 'hide', values: ['minor_local'] }\n * ```\n */\n roadSubCategories?: ValuesFilter<TertiaryRoadCategory | StreetRoadCategory>;\n};\n\n/**\n * Filter configuration for traffic incidents visualization.\n *\n * @remarks\n * Extends common traffic filters with incident-specific filtering options\n * including category, severity, and delay-based filtering.\n *\n * @group Traffic Incidents\n */\nexport type TrafficIncidentsFilter = TrafficCommonFilter & {\n /**\n * Filters incidents by category type.\n *\n * @remarks\n * Controls which types of incidents are displayed on the map.\n *\n * @example\n * ```ts\n * // Show only accidents and road closures\n * incidentCategories: { mode: 'show', values: ['accident', 'road_closed'] }\n * ```\n */\n incidentCategories?: ValuesFilter<IncidentCategory>;\n\n /**\n * Filters incidents by delay severity magnitude.\n *\n * @remarks\n * Controls display based on the severity of traffic delays caused by incidents.\n *\n * Magnitude levels:\n * - `0` - Unknown\n * - `1` - Minor\n * - `2` - Moderate\n * - `3` - Major\n * - `4` - Undefined\n *\n * @example\n * ```ts\n * // Show only major incidents\n * magnitudes: { mode: 'show', values: [3] }\n * ```\n */\n magnitudes?: ValuesFilter<DelayMagnitude>;\n\n /**\n * Filters incidents by delay duration.\n *\n * @remarks\n * Allows filtering based on whether incidents have delays and minimum delay thresholds.\n */\n delays?: DelayFilter;\n};\n\n/**\n * Collection of traffic incident filters with OR logic.\n *\n * @remarks\n * Combines multiple incident filter configurations where an incident is shown\n * if it matches **any** of the provided filter criteria (logical OR).\n *\n * This allows for complex filtering scenarios where incidents from different\n * categories or with different characteristics can all be displayed.\n *\n * @example\n * ```ts\n * // Show major incidents OR road closures\n * filters: {\n * any: [\n * { magnitudes: { mode: 'show', values: [3] } },\n * { incidentCategories: { mode: 'show', values: ['road_closed'] } }\n * ]\n * }\n * ```\n *\n * @group Traffic Incidents\n */\nexport type TrafficIncidentsFilters = {\n /**\n * Array of incident filters combined with OR logic.\n *\n * @remarks\n * An incident is displayed if it satisfies at least one of the filter configurations.\n */\n any: TrafficIncidentsFilter[];\n};\n\n/**\n * Filter configuration for traffic flow visualization.\n *\n * @remarks\n * Extends common traffic filters with flow-specific options,\n * particularly for highlighting road closures in the flow layer.\n *\n * @group Traffic Flow\n */\nexport type TrafficFlowFilter = TrafficCommonFilter & {\n /**\n * Controls road closure display in the traffic flow layer.\n *\n * @remarks\n * Determines whether to exclusively show road closures or exclude them from display.\n *\n * - `'show'` - Display only road closures\n * - `'hide'` - Display everything except road closures\n *\n * @example\n * ```ts\n * // Highlight only road closures\n * showRoadClosures: 'show'\n * ```\n */\n showRoadClosures?: FilterShowMode;\n};\n\n/**\n * Collection of traffic flow filters with OR logic.\n *\n * @remarks\n * Combines multiple flow filter configurations where traffic flow data is shown\n * if it matches **any** of the provided filter criteria (logical OR).\n *\n * @example\n * ```ts\n * // Show flow on motorways OR show road closures on any road\n * filters: {\n * any: [\n * { roadCategories: { mode: 'show', values: ['motorway'] } },\n * { showRoadClosures: 'show' }\n * ]\n * }\n * ```\n *\n * @group Traffic Flow\n */\nexport type TrafficFlowFilters = {\n /**\n * Array of flow filters combined with OR logic.\n *\n * @remarks\n * Traffic flow data is displayed if it satisfies at least one of the filter configurations.\n */\n any: TrafficFlowFilter[];\n};\n\n/**\n * Common configuration for traffic incident visualization components.\n *\n * @remarks\n * Provides shared styling and filtering options used by both incident lines and icons.\n * Extends base style module configuration with traffic incident-specific filters.\n *\n * @group Traffic Incidents\n */\nexport type IncidentsCommonConfig = {\n /**\n * Controls the visibility of the traffic incident layers.\n *\n * @default false\n */\n visible?: boolean;\n\n /**\n * Filter configuration for traffic incidents.\n *\n * @remarks\n * Controls which incidents are displayed based on category, severity, delay, and road type.\n */\n filters?: TrafficIncidentsFilters;\n};\n\n/**\n * Configuration for traffic incidents module.\n *\n * @remarks\n * Provides complete configuration for displaying traffic incidents on the map,\n * including separate styling for incident lines and icons.\n *\n * @group Traffic Incidents\n */\nexport type IncidentsConfig = MapModuleCommonConfig &\n IncidentsCommonConfig & {\n /**\n * Configuration specific to incident icon display.\n *\n * @remarks\n * Allows separate styling and filtering for incident marker icons,\n * independent of the incident line styling.\n */\n icons?: IncidentsCommonConfig;\n };\n\n/**\n * Configuration for traffic flow visualization module.\n *\n * @remarks\n * Controls the display of real-time traffic flow data on road segments,\n * including styling and filtering options.\n *\n * @group Traffic Flow\n */\nexport type FlowConfig = MapModuleCommonConfig & {\n /**\n * Controls the visibility of the traffic flow layers.\n *\n * @default false\n */\n visible?: boolean;\n\n /**\n * Filter configuration for traffic flow data.\n *\n * @remarks\n * Controls which road segments display traffic flow information\n * based on road category and closure status.\n */\n filters?: TrafficFlowFilters;\n};\n","import { indexedMagnitudes } from '@tomtom-org/maps-sdk/core';\nimport { isNil } from 'lodash-es';\nimport type {\n ExpressionFilterSpecification,\n FilterSpecification,\n LayerSpecification,\n LegacyFilterSpecification,\n Map,\n} from 'maplibre-gl';\nimport type { MultiSyntaxFilter, ValuesFilter } from '../../shared';\nimport { buildValuesFilter, getMergedAllFilter, getMergedAnyFilter } from '../../shared/mapLibreFilterUtils';\nimport type {\n DelayFilter,\n TrafficCommonFilter,\n TrafficFlowFilter,\n TrafficFlowFilters,\n TrafficIncidentsFilter,\n TrafficIncidentsFilters,\n} from '../types/trafficModuleConfig';\nimport { incidentCategoriesMapping } from '../types/trafficModuleConfig';\n\nconst toMultiSyntaxAllFilter = (\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n): MultiSyntaxFilter | null => {\n if (!newSyntaxExpressions.length) {\n return null;\n }\n if (newSyntaxExpressions.length === 1) {\n return {\n expression: newSyntaxExpressions[0] as ExpressionFilterSpecification,\n legacy: legacySyntaxExpressions[0] as LegacyFilterSpecification,\n };\n }\n return {\n expression: ['all', ...newSyntaxExpressions] as ExpressionFilterSpecification,\n legacy: ['all', ...legacySyntaxExpressions] as LegacyFilterSpecification,\n };\n};\n\nconst delayFilterToMapLibre = (delayFilter: DelayFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions = [];\n const legacySyntaxExpressions = [];\n if (delayFilter.mustHaveDelay && delayFilter.minDelayMinutes) {\n // there must be a delay and with the min specified value:\n const delaySeconds = delayFilter.minDelayMinutes * 60;\n newSyntaxExpressions.push(['>=', ['get', 'delay'], delaySeconds]);\n legacySyntaxExpressions.push(['>=', 'delay', delaySeconds]);\n } else if (delayFilter.mustHaveDelay) {\n // just expects a delay of any kind\n newSyntaxExpressions.push(['>', ['get', 'delay'], 0]);\n legacySyntaxExpressions.push(['>', 'delay', 0]);\n } else if (delayFilter.minDelayMinutes) {\n // Min delay expected, but also allows for non-existing delays:\n const delaySeconds = delayFilter.minDelayMinutes * 60;\n newSyntaxExpressions.push([\n 'any',\n ['!', ['has', 'delay']],\n ['==', ['get', 'delay'], 0],\n ['>=', ['get', 'delay'], delaySeconds],\n ]);\n legacySyntaxExpressions.push(['any', ['!has', 'delay'], ['==', 'delay', 0], ['>=', 'delay', delaySeconds]]);\n }\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\nconst addFilter = (\n filter: MultiSyntaxFilter | undefined | null,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n) => {\n if (filter) {\n newSyntaxExpressions.push(filter.expression);\n legacySyntaxExpressions.push(filter.legacy);\n }\n};\n\nconst addValuesFilter = (\n valuesFilter: ValuesFilter<string> | undefined,\n propName: string,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n) => {\n if (valuesFilter) {\n addFilter(buildValuesFilter(propName, valuesFilter), newSyntaxExpressions, legacySyntaxExpressions);\n }\n};\n\nconst addCommonFilterExpressions = (\n sdkFilter: TrafficCommonFilter,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n): void => {\n addValuesFilter(sdkFilter.roadCategories, 'road_category', newSyntaxExpressions, legacySyntaxExpressions);\n addValuesFilter(sdkFilter.roadSubCategories, 'road_subcategory', newSyntaxExpressions, legacySyntaxExpressions);\n};\n\nconst buildMapLibreIncidentsFilter = (sdkFilter: TrafficIncidentsFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions: unknown[] = [];\n const legacySyntaxExpressions: unknown[] = [];\n\n addCommonFilterExpressions(sdkFilter, newSyntaxExpressions, legacySyntaxExpressions);\n\n if (sdkFilter.incidentCategories) {\n const incidentCategoryFilter = buildValuesFilter(\n 'icon_category_0',\n sdkFilter.incidentCategories,\n (value) => incidentCategoriesMapping[value],\n );\n addFilter(incidentCategoryFilter, newSyntaxExpressions, legacySyntaxExpressions);\n }\n if (sdkFilter.magnitudes) {\n const magnitudesFilter = buildValuesFilter('magnitude', sdkFilter.magnitudes, (magnitude) =>\n indexedMagnitudes.indexOf(magnitude),\n );\n addFilter(magnitudesFilter, newSyntaxExpressions, legacySyntaxExpressions);\n }\n if (sdkFilter.delays) {\n addFilter(delayFilterToMapLibre(sdkFilter.delays), newSyntaxExpressions, legacySyntaxExpressions);\n }\n\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\n/**\n * @ignore\n */\nexport const buildMapLibreIncidentFilters = (incidentFilters: TrafficIncidentsFilters): MultiSyntaxFilter | null => {\n if (!incidentFilters?.any?.length) {\n return null;\n }\n const mapLibreFilters = incidentFilters.any\n .map(buildMapLibreIncidentsFilter)\n .filter((mapLibreFilter) => !isNil(mapLibreFilter));\n return getMergedAnyFilter(mapLibreFilters);\n};\n\nconst buildMapLibreFlowFilter = (sdkFilter: TrafficFlowFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions: unknown[] = [];\n const legacySyntaxExpressions: unknown[] = [];\n\n addCommonFilterExpressions(sdkFilter, newSyntaxExpressions, legacySyntaxExpressions);\n if (sdkFilter.showRoadClosures) {\n const operator = sdkFilter.showRoadClosures === 'only' ? '==' : '!=';\n newSyntaxExpressions.push([operator, ['get', 'road_closure'], true]);\n legacySyntaxExpressions.push([operator, 'road_closure', true]);\n }\n\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\n/**\n * @ignore\n */\nexport const buildMapLibreFlowFilters = (flowFilters: TrafficFlowFilters): MultiSyntaxFilter | null => {\n if (!flowFilters?.any?.length) {\n return null;\n }\n const mapLibreFilters = flowFilters.any\n .map(buildMapLibreFlowFilter)\n .filter((mapLibreFilter) => !isNil(mapLibreFilter));\n return getMergedAnyFilter(mapLibreFilters);\n};\n\n/**\n * @ignore\n * @param filter\n * @param layers\n * @param mapLibreMap\n * @param originalFilters\n */\nexport const applyFilter = (\n filter: MultiSyntaxFilter | undefined,\n layers: LayerSpecification[],\n mapLibreMap: Map,\n originalFilters: Record<string, FilterSpecification | undefined>,\n) => {\n for (const layer of layers) {\n mapLibreMap.setFilter(\n layer.id,\n filter ? getMergedAllFilter(filter, originalFilters[layer.id]) : originalFilters[layer.id],\n );\n }\n};\n","import { isNil, omitBy } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport type { LayerSpecWithSource } from '../shared';\nimport {\n AbstractMapModule,\n EventsModule,\n filterLayersBySources,\n StyleSourceWithLayers,\n TRAFFIC_FLOW_SOURCE_ID,\n} from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { applyFilter, buildMapLibreFlowFilters } from './filters/trafficFilters';\nimport type { FlowConfig, TrafficFlowFilters } from './types/trafficModuleConfig';\n\n/**\n * IDs of sources and layers for traffic flow module.\n */\ntype TrafficFlowSourcesWithLayers = {\n trafficFlow: StyleSourceWithLayers;\n};\n\n/**\n * Traffic Flow Module for displaying and configuring real-time traffic flow information on the map.\n *\n * This module controls the vector tile traffic flow layers that visualize current\n * traffic speed conditions using color-coded road segments.\n *\n * @remarks\n * **Features:**\n * - Toggle traffic flow visibility on/off\n * - Filter by road categories and types\n * - Color-coded speed visualization (green = free flow, red = congestion)\n * - Real-time traffic data from vector tiles\n * - Filter road closures\n *\n * **Visual Representation:**\n * - Green: Free-flowing traffic\n * - Yellow/Orange: Slow traffic\n * - Red: Heavy congestion\n * - Dark gray: Road closures\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { TrafficFlowModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module (auto-add to style if needed)\n * const trafficFlow = await TrafficFlowModule.get(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * trafficFlow.setVisible(false);\n * trafficFlow.setVisible(true);\n * ```\n *\n * @example\n * Filter by road type:\n * ```typescript\n * // Show only highway traffic\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk']\n * }\n * }]\n * });\n *\n * // Hide local streets\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'all_except',\n * values: ['street']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Show only road closures:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * showRoadClosures: 'only'\n * }]\n * });\n * ```\n *\n * @see [Traffic Flow Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-flow)\n * @see [Traffic Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic)\n *\n * @group Traffic Flow\n */\nexport class TrafficFlowModule extends AbstractMapModule<TrafficFlowSourcesWithLayers, FlowConfig> {\n private originalFilters!: Record<string, FilterSpecification | undefined>;\n\n /**\n * Retrieves a TrafficFlowModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization, visibility, and filters.\n *\n * @returns A promise that resolves to the initialized TrafficFlowModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `ensureAddedToStyle`: Auto-add traffic flow to style if missing\n * - `filters`: Road category and type filters\n *\n * **Style Requirement:**\n * Traffic flow must be included in the map style or added via `ensureAddedToStyle`.\n *\n * @throws Error if traffic flow source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const trafficFlowModule = await TrafficFlowModule.get(map);\n * ```\n *\n * @example\n * Auto-add to style:\n * ```typescript\n * const trafficFlowModule = await TrafficFlowModule.get(map, {\n * visible: true,\n * filters: {\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk', 'primary']\n * }\n * }]\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: FlowConfig): Promise<TrafficFlowModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, TRAFFIC_FLOW_SOURCE_ID, 'trafficFlow');\n return new TrafficFlowModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: FlowConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const flowSource = this.mapLibreMap.getSource(TRAFFIC_FLOW_SOURCE_ID);\n if (!flowSource) {\n throw notInTheStyle(`init ${TrafficFlowModule.name} with source ID ${TRAFFIC_FLOW_SOURCE_ID}`);\n }\n this.originalFilters = {};\n for (const layer of this.getLayers()) {\n this.originalFilters[layer.id] = layer.filter;\n }\n return { trafficFlow: new StyleSourceWithLayers(this.mapLibreMap, flowSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: FlowConfig | undefined) {\n this.setVisible(config?.visible ?? false);\n this._filter(config?.filters, false);\n return config;\n }\n\n private getLayers(): LayerSpecWithSource[] {\n return filterLayersBySources(this.tomtomMap.mapLibreMap, [TRAFFIC_FLOW_SOURCE_ID]);\n }\n\n /**\n * Applies filters to traffic flow display.\n *\n * @param filters - Filter configuration for road types, categories, and closures.\n * Pass `undefined` to reset to defaults (show all).\n *\n * @remarks\n * **Filter Options:**\n * - `roadCategories`: Filter by road importance (motorway, trunk, primary, etc.)\n * - `roadSubCategories`: Filter by specific street types\n * - `showRoadClosures`: Show only closures or exclude them\n *\n * **Available Road Categories:**\n * - `motorway`: Major highways\n * - `trunk`: Major roads\n * - `primary`: Primary roads\n * - `secondary`: Secondary roads\n * - `tertiary`: Tertiary roads\n * - `street`: Local streets\n *\n * **Filter Logic:**\n * Uses \"any\" (OR) logic - traffic matching any filter is shown.\n *\n * @example\n * Show only major roads:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk', 'primary']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Hide street-level traffic:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'all_except',\n * values: ['street']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Multiple filter criteria:\n * ```typescript\n * trafficFlow.filter({\n * any: [\n * {\n * roadCategories: { show: 'only', values: ['motorway'] }\n * },\n * {\n * showRoadClosures: 'only'\n * }\n * ]\n * });\n * ```\n *\n * @example\n * Reset filters:\n * ```typescript\n * trafficFlow.filter(undefined);\n * ```\n */\n filter(filters?: TrafficFlowFilters) {\n this._filter(filters);\n }\n\n private _filter(filters: TrafficFlowFilters | undefined, updateConfig = true) {\n if (this.tomtomMap.mapReady) {\n if (filters?.any?.length) {\n const filterExpression = buildMapLibreFlowFilters(filters);\n if (filterExpression) {\n applyFilter(filterExpression, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n } else if (this.config?.filters?.any?.length) {\n applyFilter(undefined, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n }\n\n if (updateConfig) {\n this.config = omitBy({ ...this.config, filters }, isNil);\n }\n }\n\n /**\n * Sets the visibility of traffic flow layers.\n *\n * @param visible - `true` to show traffic flow, `false` to hide it.\n *\n * @example\n * ```typescript\n * trafficFlow.setVisible(true); // Show traffic\n * trafficFlow.setVisible(false); // Hide traffic\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = { ...this.config, visible };\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficFlow.setLayersVisible(visible);\n }\n }\n\n /**\n * Returns if any layer for traffic flow is visible or not.\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.trafficFlow.isAnyLayerVisible();\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.trafficFlow, this.config?.events);\n }\n}\n","import { isEmpty, isNil, omitBy } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport type { LayerSpecWithSource } from '../shared';\nimport {\n AbstractMapModule,\n EventsModule,\n filterLayersBySources,\n StyleSourceWithLayers,\n TRAFFIC_INCIDENTS_SOURCE_ID,\n} from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { applyFilter, buildMapLibreIncidentFilters } from './filters/trafficFilters';\nimport type { IncidentsConfig, TrafficIncidentsFilters } from './types/trafficModuleConfig';\n\n/**\n * IDs of sources and layers for traffic incidents module.\n */\ntype TrafficIncidentsSourcesWithLayers = {\n trafficIncidents: StyleSourceWithLayers;\n};\n\n/**\n * Traffic Incidents Module for displaying and configuring real-time traffic incidents on the map.\n *\n * This module controls the vector tile traffic incidents layers that show traffic\n * events like accidents, road closures, construction, and hazards.\n *\n * @remarks\n * **Features:**\n * - Toggle incidents visibility on/off\n * - Separate control for incident icons\n * - Filter by incident type (accident, construction, etc.)\n * - Filter by severity/delay magnitude\n * - Filter by road categories\n * - Icon and line/polygon visualization\n *\n * **Incident Types:**\n * - Accidents\n * - Road closures\n * - Construction/road works\n * - Weather conditions (fog, ice, rain, etc.)\n * - Lane closures\n * - Traffic jams\n * - Broken down vehicles\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { TrafficIncidentsModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module (auto-add to style if needed)\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * trafficIncidentsModule.setVisible(false);\n * trafficIncidentsModule.setVisible(true);\n *\n * // Control icons separately\n * trafficIncidentsModule.setIconsVisible(false);\n * ```\n *\n * @example\n * Filter by incident type:\n * ```typescript\n * // Show only accidents and road closures\n * trafficIncidentsModule.filter({\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed']\n * }\n * }]\n * });\n *\n * // Hide construction\n * trafficIncidentsModule.filter({\n * any: [{\n * incidentCategories: {\n * show: 'all_except',\n * values: ['road_works']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter by severity:\n * ```typescript\n * // Show only major delays\n * incidents.filter({\n * any: [{\n * magnitudes: {\n * show: 'only',\n * values: ['major']\n * }\n * }]\n * });\n *\n * // Show incidents with at least 10 minutes delay\n * incidents.filter({\n * any: [{\n * delays: {\n * mustHaveDelay: true,\n * minDelayMinutes: 10\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter icons separately from incident areas:\n * ```typescript\n * // Show all incidents but only major icons\n * incidents.filter(\n * {\n * any: [{}] // Show all incidents\n * },\n * {\n * any: [{\n * magnitudes: { show: 'only', values: ['major'] }\n * }]\n * }\n * );\n * ```\n *\n * @see [Traffic Incidents Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-incidents)\n * @see [Traffic Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic)\n *\n * @group Traffic Incidents\n */\nexport class TrafficIncidentsModule extends AbstractMapModule<TrafficIncidentsSourcesWithLayers, IncidentsConfig> {\n private originalFilters!: Record<string, FilterSpecification | undefined>;\n\n /**\n * Retrieves a TrafficIncidentsModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization, visibility, and filters.\n *\n * @returns A promise that resolves to the initialized TrafficIncidentsModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state for all incidents\n * - `icons.visible`: Initial visibility for incident icons\n * - `ensureAddedToStyle`: Auto-add traffic incidents to style if missing\n * - `filters`: Incident type, severity, and delay filters\n * - `icons.filters`: Separate filters for icons\n *\n * @throws Error if traffic incidents source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map);\n * ```\n *\n * @example\n * With configuration:\n * ```typescript\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map, {\n * visible: true,\n * icons: { visible: true },\n * filters: {\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed', 'jam']\n * }\n * }]\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: IncidentsConfig): Promise<TrafficIncidentsModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, TRAFFIC_INCIDENTS_SOURCE_ID, 'trafficIncidents');\n return new TrafficIncidentsModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: IncidentsConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const incidentsSource = this.mapLibreMap.getSource(TRAFFIC_INCIDENTS_SOURCE_ID);\n if (!incidentsSource) {\n throw notInTheStyle(`init ${TrafficIncidentsModule.name} with source ID ${TRAFFIC_INCIDENTS_SOURCE_ID}`);\n }\n this.originalFilters = {};\n for (const layer of this.getLayers()) {\n this.originalFilters[layer.id] = layer.filter;\n }\n return { trafficIncidents: new StyleSourceWithLayers(this.mapLibreMap, incidentsSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: IncidentsConfig | undefined) {\n // We do not update config in setVisible since it could override icons visibility setting:\n this._setVisible(config?.visible ?? false, { updateConfig: false });\n if (!isNil(config?.icons?.visible)) {\n this.setIconsVisible(config.icons.visible);\n }\n this._filter(config?.filters, config?.icons?.filters, false);\n return config;\n }\n\n /**\n * Applies filters to traffic incidents display.\n *\n * @param incidentFilters - Filter for incident areas/lines. Pass `undefined` to reset.\n * @param iconFilters - Optional separate filter for incident icons. Pass `undefined` to reset.\n *\n * @remarks\n * **Filter Options:**\n * - `incidentCategories`: Filter by incident type\n * - `magnitudes`: Filter by delay severity (minor/moderate/major/unknown)\n * - `delays`: Filter by delay duration\n * - `roadCategories`: Filter by road importance\n * - `roadSubCategories`: Filter by specific road types\n *\n * **Available Incident Categories:**\n * - `accident`, `road_closed`, `lane_closed`\n * - `road_works` (construction)\n * - `jam` (traffic jam)\n * - `fog`, `rain`, `ice`, `wind`, `flooding`\n * - `dangerous_conditions`\n * - `broken_down_vehicle`\n * - `unknown`\n *\n * **Delay Magnitudes:**\n * - `minor`: Small delays\n * - `moderate`: Moderate delays\n * - `major`: Significant delays\n * - `unknown`: Unknown or no delay info\n *\n * @example\n * Filter by type:\n * ```typescript\n * incidents.filter({\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter by severity and delay:\n * ```typescript\n * incidents.filter({\n * any: [{\n * magnitudes: { show: 'only', values: ['major', 'moderate'] },\n * delays: {\n * mustHaveDelay: true,\n * minDelayMinutes: 5\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Different filters for icons and areas:\n * ```typescript\n * // Show all incidents on roads\n * const incidentFilter = {\n * any: [{\n * roadCategories: { show: 'only', values: ['motorway', 'trunk'] }\n * }]\n * };\n *\n * // But only show icons for major incidents\n * const iconFilter = {\n * any: [{\n * magnitudes: { show: 'only', values: ['major'] }\n * }]\n * };\n *\n * incidents.filter(incidentFilter, iconFilter);\n * ```\n */\n filter(incidentFilters?: TrafficIncidentsFilters, iconFilters?: TrafficIncidentsFilters) {\n this._filter(incidentFilters, iconFilters);\n }\n\n private _filter(\n incidentFilters: TrafficIncidentsFilters | undefined,\n iconFilters: TrafficIncidentsFilters | undefined,\n updateConfig = true,\n ) {\n if (this.tomtomMap.mapReady) {\n if (incidentFilters?.any?.length) {\n const incidentFilterExpression = buildMapLibreIncidentFilters(incidentFilters);\n if (incidentFilterExpression) {\n const layers = iconFilters ? this.getNonSymbolLayers() : this.getLayers();\n applyFilter(incidentFilterExpression, layers, this.mapLibreMap, this.originalFilters);\n }\n } else if (this.config?.filters?.any?.length) {\n applyFilter(undefined, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n if (iconFilters?.any?.length) {\n const iconFilterExpression = buildMapLibreIncidentFilters(iconFilters);\n if (iconFilterExpression) {\n applyFilter(iconFilterExpression, this.getSymbolLayers(), this.mapLibreMap, this.originalFilters);\n }\n }\n }\n\n // else: default incidents visibility has been set already if necessary\n if (updateConfig) {\n this.config = omitBy(\n {\n ...this.config,\n filters: incidentFilters,\n icons: { ...this.config?.icons, filters: iconFilters },\n },\n isNil,\n );\n }\n }\n\n private getLayers(): LayerSpecWithSource[] {\n return filterLayersBySources(this.tomtomMap.mapLibreMap, [TRAFFIC_INCIDENTS_SOURCE_ID]);\n }\n\n private getSymbolLayers(): LayerSpecWithSource[] {\n return this.getLayers().filter((layer) => layer.type === 'symbol');\n }\n\n private getNonSymbolLayers(): LayerSpecWithSource[] {\n return this.getLayers().filter((layer) => layer.type != 'symbol');\n }\n\n /**\n * Sets the visibility of incident icon layers.\n *\n * @param visible - `true` to show icons, `false` to hide them.\n *\n * @remarks\n * This controls only the icon/symbol layers, not the incident area polygons or lines.\n *\n * @example\n * ```typescript\n * // Hide icons but keep incident areas visible\n * incidents.setIconsVisible(false);\n *\n * // Show icons\n * incidents.setIconsVisible(true);\n * ```\n */\n setIconsVisible(visible: boolean): void {\n // We adjust the config for this change (but it might be overwritten if it's part of an \"applyConfig\" call)\n this.config = { ...this.config, icons: { ...this.config?.icons, visible } };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficIncidents.setLayersVisible(\n visible,\n (layerSpec) => layerSpec.type === 'symbol',\n );\n }\n }\n\n /**\n * Sets the visibility of all traffic incident layers.\n *\n * @param visible - `true` to show incidents, `false` to hide them.\n *\n * @remarks\n * This controls all incident layers including icons, lines, and polygons.\n *\n * @example\n * ```typescript\n * incidents.setVisible(false); // Hide all incidents\n * incidents.setVisible(true); // Show all incidents\n * ```\n */\n setVisible(visible: boolean): void {\n this._setVisible(visible);\n }\n\n private _setVisible(visible: boolean, options?: { updateConfig: boolean }): void {\n const updateConfig = options?.updateConfig ?? true;\n if (updateConfig) {\n // setting all traffic visible also nullifies the icons visible setting\n delete this.config?.icons?.visible;\n // we remove empty values from config to avoid confusion (in case icons part is just empty after deleting visible)\n this.config = { ...omitBy({ ...this.config }, isEmpty), visible };\n }\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficIncidents.setLayersVisible(visible);\n }\n }\n\n /**\n * Checks if any traffic incident layers are currently visible.\n *\n * @returns `true` if any incident layer is visible, `false` if all are hidden.\n *\n * @example\n * ```typescript\n * if (incidents.isVisible()) {\n * console.log('Incidents are displayed');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.trafficIncidents.isAnyLayerVisible();\n }\n\n /**\n * Checks if any incident icon layers are currently visible.\n *\n * @returns `true` if any icon layer is visible, `false` if all icons are hidden.\n *\n * @example\n * ```typescript\n * if (incidents.anyIconLayersVisible()) {\n * console.log('Incident icons are shown');\n * }\n * ```\n */\n anyIconLayersVisible(): boolean {\n return !!this.sourcesWithLayers.trafficIncidents?.isAnyLayerVisible((layerSpec) => layerSpec.type === 'symbol');\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.trafficIncidents,\n this.config?.events,\n );\n }\n}\n","import type { BBox } from '@tomtom-org/maps-sdk/core';\nimport type { Position } from 'geojson';\nimport type { Map } from 'maplibre-gl';\nimport type { TomTomMap } from '../TomTomMap';\nimport type {\n CalculateFittingBBoxOptions,\n CalculateMapBoundsOptions,\n CalculateMapCenterOptions,\n} from './types/paddedBounds';\n\n// (Originally mostly AI-generated)\n\ntype BoundsPX = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n};\n\nconst getRelativeElementBounds = (elementRect: DOMRect, containerRect: DOMRect): BoundsPX => ({\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n right: elementRect.right - containerRect.left,\n bottom: elementRect.bottom - containerRect.top,\n});\n\nconst isElementOutsideContainer = (bounds: BoundsPX, containerWidth: number, containerHeight: number): boolean =>\n bounds.right <= 0 || bounds.left >= containerWidth || bounds.bottom <= 0 || bounds.top >= containerHeight;\n\n// Adjusts the current visible bounds to account for a horizontal bar element (that spans the whole width)\nconst adjustForHorizontalBar = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerHeight: number,\n padding: number,\n): void => {\n const distanceFromTop = bounds.top;\n const distanceFromBottom = containerHeight - bounds.bottom;\n if (distanceFromTop <= distanceFromBottom) {\n currentVisible.top = Math.max(currentVisible.top, bounds.bottom + padding);\n } else {\n currentVisible.bottom = Math.min(currentVisible.bottom, bounds.top - padding);\n }\n};\n\n// Adjusts the current visible bounds to account for a vertical bar element (that spans the whole height)\nconst adjustForVerticalBar = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerWidth: number,\n padding: number,\n): void => {\n const distanceFromLeft = bounds.left;\n const distanceFromRight = containerWidth - bounds.right;\n if (distanceFromLeft <= distanceFromRight) {\n currentVisible.left = Math.max(currentVisible.left, bounds.right + padding);\n } else {\n currentVisible.right = Math.min(currentVisible.right, bounds.left - padding);\n }\n};\n\n// Adjusts the current visible bounds to account for a floating element (that does not span full width or height)\nconst adjustForFloatingElement = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerWidth: number,\n containerHeight: number,\n padding: number,\n): void => {\n const distanceFromLeft = bounds.left;\n const distanceFromRight = containerWidth - bounds.right;\n const distanceFromTop = bounds.top;\n const distanceFromBottom = containerHeight - bounds.bottom;\n const minDistance = Math.min(distanceFromLeft, distanceFromRight, distanceFromTop, distanceFromBottom);\n\n if (minDistance === distanceFromLeft) {\n currentVisible.left = Math.max(currentVisible.left, bounds.right + padding);\n } else if (minDistance === distanceFromRight) {\n currentVisible.right = Math.min(currentVisible.right, bounds.left - padding);\n } else if (minDistance === distanceFromTop) {\n currentVisible.top = Math.max(currentVisible.top, bounds.bottom + padding);\n } else {\n currentVisible.bottom = Math.min(currentVisible.bottom, bounds.top - padding);\n }\n};\n\n/**\n * Clamps the element bounds to the container boundaries.\n * This handles cases where UI elements extend beyond the visible container\n * (e.g., a sidebar that goes past the screen edge).\n */\nconst clampBoundsToContainer = (bounds: BoundsPX, containerWidth: number, containerHeight: number): BoundsPX => ({\n left: Math.max(0, bounds.left),\n top: Math.max(0, bounds.top),\n right: Math.min(containerWidth, bounds.right),\n bottom: Math.min(containerHeight, bounds.bottom),\n});\n\nconst adjustVisibleBoundsForElement = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n mapWidthPX: number,\n mapHeightPX: number,\n padding: number,\n): void => {\n // Clamp bounds to container to handle elements that extend beyond the screen\n const clampedBounds = clampBoundsToContainer(bounds, mapWidthPX, mapHeightPX);\n\n // Determine if the element touches or extends beyond the full width or height of the container\n // An element \"spans full width\" if it touches both left and right edges (or extends beyond)\n const spansFullWidth = bounds.left <= 0 && bounds.right >= mapWidthPX;\n const spansFullHeight = bounds.top <= 0 && bounds.bottom >= mapHeightPX;\n\n // For elements spanning full width (horizontal bars), only consider vertical adjustment\n if (spansFullWidth && !spansFullHeight) {\n adjustForHorizontalBar(clampedBounds, currentVisible, mapHeightPX, padding);\n return;\n }\n\n // For elements spanning full height (vertical bars), only consider horizontal adjustment\n if (spansFullHeight && !spansFullWidth) {\n adjustForVerticalBar(clampedBounds, currentVisible, mapWidthPX, padding);\n return;\n }\n\n // Check if element touches/extends beyond an edge (makes it act like a bar on that side)\n const touchesLeft = bounds.left <= 0;\n const touchesRight = bounds.right >= mapWidthPX;\n const touchesTop = bounds.top <= 0;\n const touchesBottom = bounds.bottom >= mapHeightPX;\n\n // If element touches opposite edges in one dimension but not the other,\n // treat it as a bar in that dimension\n if ((touchesLeft || touchesRight) && !touchesTop && !touchesBottom) {\n // Element extends horizontally but not vertically - treat as horizontal bar\n adjustForHorizontalBar(clampedBounds, currentVisible, mapHeightPX, padding);\n return;\n }\n if ((touchesTop || touchesBottom) && !touchesLeft && !touchesRight) {\n // Element extends vertically but not horizontally - treat as vertical bar\n adjustForVerticalBar(clampedBounds, currentVisible, mapWidthPX, padding);\n return;\n }\n\n // For corner elements (touching edges in both dimensions) or floating elements\n // determine the best adjustment based on which edge the element is closest to\n adjustForFloatingElement(clampedBounds, currentVisible, mapWidthPX, mapHeightPX, padding);\n};\n\n/**\n * Resolves a surrounding element reference to an HTMLElement.\n * If the reference is a string, it's treated as a DOM selector.\n * @param ref - Either an HTMLElement or a DOM selector string\n * @returns The resolved HTMLElement, or null if not found\n */\nconst toElement = (ref: HTMLElement | string): HTMLElement | null => {\n if (typeof ref === 'string') {\n return document.querySelector(ref);\n }\n return ref;\n};\n\n/**\n * Resolves a map reference to a MapLibre Map instance.\n * If the reference is a TomTomMap, it extracts the underlying mapLibreMap.\n * @param map - Either a TomTomMap or a MapLibre Map instance\n * @returns The MapLibre Map instance\n */\nconst getMapLibreMap = (map: TomTomMap | Map): Map => {\n if ('mapLibreMap' in map) {\n return map.mapLibreMap;\n }\n return map;\n};\n\ntype VisibleAreaResult = {\n visibleAreaBounds: BoundsPX;\n mapWidthPX: number;\n mapHeightPX: number;\n} | null;\n\n/**\n * Calculates the visible area bounds in pixel coordinates after accounting for\n * surrounding UI elements and padding.\n */\nconst calculateVisibleAreaBounds = (\n map: TomTomMap | Map,\n surroundingElements: (HTMLElement | string)[],\n paddingPX: number,\n): VisibleAreaResult => {\n const containerRect = getMapLibreMap(map).getContainer().getBoundingClientRect();\n const { width: mapWidthPX, height: mapHeightPX } = containerRect;\n\n // Initialize visible bounds with padding applied to all edges (will be mutated)\n const visibleAreaBounds: BoundsPX = {\n left: paddingPX,\n top: paddingPX,\n right: mapWidthPX - paddingPX,\n bottom: mapHeightPX - paddingPX,\n };\n\n for (const elementRef of surroundingElements) {\n const element = toElement(elementRef);\n if (!element) {\n continue;\n }\n const elementRect = element.getBoundingClientRect();\n const elementBounds = getRelativeElementBounds(elementRect, containerRect);\n\n if (isElementOutsideContainer(elementBounds, mapWidthPX, mapHeightPX)) {\n continue;\n }\n\n adjustVisibleBoundsForElement(elementBounds, visibleAreaBounds, mapWidthPX, mapHeightPX, paddingPX);\n }\n\n if (visibleAreaBounds.left >= visibleAreaBounds.right || visibleAreaBounds.top >= visibleAreaBounds.bottom) {\n return null;\n }\n\n return { visibleAreaBounds, mapWidthPX, mapHeightPX };\n};\n\n/**\n * Calculates the bounding box in lng-lat coordinates of the visible map area\n * that does not overlap with the given UI HTML elements.\n *\n * @remarks\n * This is useful for determining the area of the map that is not obscured by UI components.\n *\n * @param options - The options for calculating map bounds\n * @returns The padded bounding box as [west, south, east, north], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculatePaddedBBox = (options: CalculateMapBoundsOptions): BBox | null => {\n const { map, surroundingElements, paddingPX = 0 } = options;\n\n const result = calculateVisibleAreaBounds(map, surroundingElements, paddingPX);\n if (!result) {\n return null;\n }\n\n const { visibleAreaBounds } = result;\n const mapLibreMap = getMapLibreMap(map);\n const sw = mapLibreMap.unproject([visibleAreaBounds.left, visibleAreaBounds.bottom]);\n const ne = mapLibreMap.unproject([visibleAreaBounds.right, visibleAreaBounds.top]);\n\n return [sw.lng, sw.lat, ne.lng, ne.lat];\n};\n\n/**\n * Calculates the center point in lng-lat coordinates of the visible map area\n * that does not overlap with the given UI HTML elements.\n *\n * @remarks\n * * This is useful to offset the map center in a way that it looks harmonious with surrounding UI components.\n * * It's equivalent to the center of calculatePaddedBBox.\n *\n * @param options - The options for calculating map center\n * @returns The center as [lng, lat], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculatePaddedCenter = (options: CalculateMapCenterOptions): Position | null => {\n const { map, surroundingElements } = options;\n const bbox = calculatePaddedBBox({ map, surroundingElements });\n if (!bbox) {\n return null;\n }\n const [west, south, east, north] = bbox;\n return [(west + east) / 2, (south + north) / 2];\n};\n\n/**\n * Calculates an expanded bounding box that, when the map is zoomed to it, ensures that the given to-be-contained bounding box\n * is visible within the area not obscured by surrounding UI elements, including optional padding.\n * * In other words, calculates a bounding box that ensure the to-be-contained bbox fits within the visible area of the map.\n *\n * @remarks\n * This is useful when you have a specific geographic area (containedBBox) that you want to be fully visible\n * in the unobscured portion of the map (the area not covered by UI components).\n * The function returns a larger bounding box that accounts for the space taken by UI elements.\n *\n * @param options - The options for calculating expanded bounds\n * @returns The expanded bounding box as [west, south, east, north], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculateFittingBBox = (options: CalculateFittingBBoxOptions): BBox | null => {\n const { map, toBeContainedBBox, surroundingElements, paddingPX = 0 } = options;\n\n const result = calculateVisibleAreaBounds(map, surroundingElements, paddingPX);\n if (!result) {\n return null;\n }\n\n const { visibleAreaBounds, mapWidthPX, mapHeightPX } = result;\n\n // Calculate the ratios of how much the visible area is offset from the full container\n // These represent what fraction of the full map the visible area occupies\n const leftRatio = visibleAreaBounds.left / mapWidthPX;\n const rightRatio = visibleAreaBounds.right / mapWidthPX;\n const topRatio = visibleAreaBounds.top / mapHeightPX;\n const bottomRatio = visibleAreaBounds.bottom / mapHeightPX;\n\n // Calculate the width and height ratios of the visible area\n const widthRatio = rightRatio - leftRatio;\n const heightRatio = bottomRatio - topRatio;\n\n // Target bbox coordinates\n const [west, south, east, north] = toBeContainedBBox;\n const targetWidth = east - west;\n const targetHeight = north - south;\n\n // Calculate the full map extent needed so that when cropped by the visible area,\n // the target bbox fits exactly\n const fullWidth = targetWidth / widthRatio;\n const fullHeight = targetHeight / heightRatio;\n\n // Calculate the fitting expanded bounds\n // The visible area starts at leftRatio of the full width, so we need to extend west\n const expandedWest = west - leftRatio * fullWidth;\n const expandedEast = expandedWest + fullWidth;\n\n // For latitude, remember that in pixel coordinates, top is smaller Y but higher latitude\n // topRatio represents the fraction from top, which corresponds to north\n const expandedNorth = north + topRatio * fullHeight;\n const expandedSouth = expandedNorth - fullHeight;\n\n return [expandedWest, expandedSouth, expandedEast, expandedNorth];\n};\n"],"names":["freeGlobal","global","Object","freeSelf","self","root","Function","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","baseGetTag","value","isOwn","call","tag","unmasked","e","result","getRawTag","objectToString","isObjectLike","isSymbol","arrayMap","array","iteratee","index","length","Array","isArray","symbolProto","symbolToString","baseToString","isObject","type","identity","isFunction","uid","coreJsData","maskSrcKey","exec","keys","IE_PROTO","funcToString","toSource","func","reIsHostCtor","funcProto","reIsNative","RegExp","replace","baseIsNative","test","getNative","object","key","getValue","WeakMap","nativeNow","Date","now","count","lastCalled","defineProperty","baseSetToString","string","configurable","enumerable","writable","setToString","stamp","remaining","arguments","apply","reIsUint","isIndex","baseAssignValue","eq","other","assignValue","objValue","nativeMax","Math","max","isLength","isArrayLike","isPrototype","Ctor","constructor","baseIsArguments","propertyIsEnumerable","isArguments","freeExports","exports","nodeType","freeModule","module","Buffer","isBuffer","typedArrayTags","baseUnary","freeProcess","process","nodeUtil","types","require","binding","nodeIsTypedArray","isTypedArray","arrayLikeKeys","inherited","isArr","isArg","isBuff","isType","skipIndexes","n","baseTimes","String","push","overArg","transform","arg","nativeKeys","baseKeys","baseKeysIn","nativeKeysIn","isProto","keysIn","reIsDeepProp","reIsPlainProp","isKey","nativeCreate","Hash","entries","this","clear","entry","set","assocIndexOf","__data__","size","has","get","data","splice","ListCache","pop","Map","getMapData","map","MapCache","hash","memoize","resolver","TypeError","memoized","args","cache","Cache","rePropName","reEscapeChar","stringToPath","memoizeCapped","charCodeAt","match","number","quote","subString","castPath","toKey","baseGet","path","arrayPush","values","offset","spreadableSymbol","isConcatSpreadable","isFlattenable","flatten","depth","predicate","isStrict","baseFlatten","getPrototype","getPrototypeOf","objectCtorString","Stack","pairs","LARGE_ARRAY_SIZE","stubArray","allocUnsafe","nativeGetSymbols","getOwnPropertySymbols","getSymbols","resIndex","arrayFilter","symbol","getSymbolsIn","baseGetAllKeys","keysFunc","symbolsFunc","getAllKeys","getAllKeysIn","DataView","Promise","Set","mapTag","promiseTag","setTag","weakMapTag","dataViewTag","dataViewCtorString","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","getTag","ArrayBuffer","resolve","ctorString","Uint8Array","cloneArrayBuffer","arrayBuffer","byteLength","reFlags","symbolValueOf","valueOf","initCloneByTag","isDeep","regexp","dataView","buffer","byteOffset","typedArray","cloneTypedArray","source","lastIndex","nodeIsMap","isMap","nodeIsSet","isSet","argsTag","funcTag","objectTag","cloneableTags","baseClone","bitmask","customizer","stack","input","initCloneArray","isFunc","slice","stacked","forEach","subValue","add","props","arrayEach","SetCache","arraySome","equalArrays","equalFunc","isPartial","arrLength","othLength","arrStacked","othStacked","seen","arrValue","othValue","compared","othIndex","mapToArray","setToArray","arrayTag","baseIsEqualDeep","objIsArr","othIsArr","objTag","othTag","objIsObj","othIsObj","isSameTag","name","message","convert","equalByTag","objIsWrapped","othIsWrapped","objUnwrapped","othUnwrapped","objProps","objLength","objStacked","skipCtor","objCtor","othCtor","equalObjects","baseIsEqual","isStrictComparable","matchesStrictComparable","srcValue","baseMatches","matchData","getMatchData","COMPARE_PARTIAL_FLAG","baseIsMatch","baseHasIn","hasIn","hasFunc","hasPath","baseMatchesProperty","defaultValue","property","basePropertyDeep","baseIteratee","parent","start","end","baseSlice","isEmpty","isEqual","isNil","baseUnset","isRootPrimitive","obj","last","customOmitClone","proto","isPlainObject","omit","otherArgs","thisArg","overRest","flatRest","paths","isNew","newValue","copyObject","CLONE_DEEP_FLAG","baseSet","nested","pickBy","prop","basePickBy","omitBy","negate","remove","indexes","previous","basePullAt","notInTheStyle","actionText","Error","isDOMImageSupported","document","DOMParser","btoa","svgToImg","svgDomElement","img","createElement","src","XMLSerializer","serializeToString","parseSvg","svgString","parseFromString","documentElement","pinSvg","options","element","fillColor","querySelector","setAttribute","outlineColor","outlineOpacity","asDefined","assertDefined","TomTomMapSource","id","spec","runtimeSource","ensureAddedToMap","getSource","addSource","AbstractSourceWithLayers","layerSpecs","_layerSpecs","_updateSourceAndLayerIDs","isAnyLayerVisible","filter","getLayerSpecs","some","layer","isLayerVisible","areAllLayersVisible","every","_sourceAndLayerIDs","sourceID","layerIDs","getLayoutProperty","setLayersVisible","visible","layerSpec","setLayoutProperty","validate","sourceAndLayerIDs","equalSourceAndLayerIDs","filterLayersBySources","loadedMap","sourceIDs","getStyle","layers","includes","StyleSourceWithLayers","super","sources","AddedSourceWithLayers","sourceId","sourceSpec","ensureLayersAddedToMap","getLayer","addLayer","beforeID","ensureAddedToMapWithVisibility","addLayersToMap","emptyFeatureCollection","features","GeoJSONSourceWithLayers","promoteId","shownFeatures","show","featureCollection","setData","findFeature","find","f","putEventState","mode","feature","properties","eventState","state","cleanEventState","cleanEventStates","changed","states","waitUntilMapIsReady","async","tomtomMap","mapReady","mapLibreMap","once","deserializeFeatures","JSON","parse","_e","changeLayerProps","newLayerProps","prevLayerProps","layerId","maxzoom","minzoom","setLayerZoomRange","getMinZoom","getMaxZoom","setFilter","layout","paint","setPaintProperty","changeLayersProps","layoutPaint","addLayers","layersToAdd","layerIdsAlreadyOnMap","visibility","mapIdDependency","idsWeCanProcess","stringify","updateStyleWithModule","style","styleModule","include","cannotAddStyleModuleToCustomStyle","ensureAddedToStyle","isStyleLoaded","setStyle","isSourceLoaded","waitUntilSourceIsLoaded","addOrUpdateImage","imageId","imageToLoad","console","warn","addOrUpdateToMap","imgElement","hasImage","addImage","ensureImageLoaded","complete","naturalWidth","onload","onerror","loadImage","getStandardStyleTheme","standardStyleID","getStyleLightDarkTheme","styleInput","standardStyle","AbstractMapModule","sourceType","config","_initializing","moduleReady","eventsProxy","_eventsProxy","initSourcesWithLayers","applyConfig","addStyleChangeHandler","onStyleAboutToChange","onStyleChanged","restoreDataAndConfig","restore","sourcesWithLayers","_initSourcesWithLayers","fromEntries","sourceWithLayers","updateIfRegistered","waitUntilModuleReady","interval","setInterval","clearInterval","_applyConfig","resetConfig","setTimeout","restoreDataAndConfigImpl","getConfig","EventsModule","eventProxy","on","handler","addEventHandler","off","AbstractEventProxy","interactiveLayerIDs","handlers","findHandlers","flatMap","sourceEventTypeHandlers","ensureInteractiveLayerIDsAdded","handlerFn","fn","matchesLayers","removeAll","hasSourceID","sourceHandlers","isHighPriority","eventType","featureId","featuresToUpdate","i","findFeatureById","updatedFeature","removeEventStateAndShow","newEventType","rawFeature","prevFeaturesToUpdate","updateEventState","eventFeature","prevEventFeature","prevSourceWithLayers","updatedIndex","featureB","featureA","eventsProxyDefaultConfig","precisionMode","paddingBoxPx","cursorOnHover","cursorOnMouseDown","cursorOnMap","longHoverDelayAfterMapMoveMS","longHoverDelayOnStillMapMS","EventsProxy","enabled","firstDelayedHoverSinceMapMove","mapCanvas","getCanvas","cursor","lastCursorStyle","listenToEvents","ev","onMouseMove","onMouseStart","onMouseOut","onMouseDown","onMouseUp","onMapClick","enable","clearLongHoverTimeout","toPaddedBounds","point","padding","x","y","isEnabled","isMoving","getRenderedFeatures","precision","renderedFeatures","queryRenderedFeatures","window","clearTimeout","longHoverTimeoutHandlerID","restartLongHoverTimeout","handleLongHoverTimeout","hoveringSourceWithLayers","hoveringFeature","hoveringLngLat","hoveringFeatures","hoveredTopFeature","hoverChanged","mouseInMotionOverHoveredFeature","hoveringPoint","prevHoveredPoint","prevHoveredFeature","detectHoverState","lngLat","prevHoveredSourceWithLayers","firstHandler","updateHoverCursor","hoverHandlers","clickType","clickedFeatures","prevClickedFeature","lastClickedFeature","prevClickedSourceWithLayers","lastClickedSourceWithLayers","clickHandlers","mapStyleLayerIDs","country","lowestPlaceLabel","poi","lowestLabel","lowestRoadLine","lowestBuilding","POI_SOURCE_ID","HILLSHADE_SOURCE_ID","BASE_MAP_SOURCE_ID","TRAFFIC_INCIDENTS_SOURCE_ID","TRAFFIC_FLOW_SOURCE_ID","poiLayerIDs","mapDisplayPoiCategoryMappings","ACCESS_GATEWAY","ADVENTURE_SPORTS_FACILITY","ADVENTURE_SPORTS_VENUE","AGRICULTURE","AIRPORT","AMUSEMENT_PARK","AQUATIC_ZOO","ASHRAM","ATM","AUTOMOTIVE_DEALER","BANK","BEACH","BUS_STOP","BUSINESS_PARK","CAFE_PUB","CAMPING_GROUND","CAR_WASH","CASH_DISPENSER","CASINO","CHURCH","CINEMA","CLOTHING_SHOP","CLUB_ASSOCIATION","COLLEGE_UNIVERSITY","COMMERCIAL_BUILDING","COMMUNITY_CENTER","COMPANY","CONCERT_HALL","COURTHOUSE","CULTURAL_CENTER","DENTIST","DEPARTMENT_STORE","DOCTOR","ELECTRIC_VEHICLE_STATION","EMBASSY","EMERGENCY_MEDICAL_SERVICE","EMERGENCY_ROOM","ENTERTAINMENT","EXCHANGE","EXHIBITION_CONVENTION_CENTER","FERRY_TERMINAL","FIRE_STATION_BRIGADE","FRONTIER_CROSSING","FUEL_FACILITIES","GAS_STATION","GEOGRAPHIC_FEATURE","GOLD_EXCHANGE","GOLF_COURSE","GOVERNMENT_OFFICE","GURUDWARA","HEALTH_CARE_SERVICE","HELIPAD_HELICOPTER_LANDING","HILL","HOLIDAY_RENTAL","HOSPITAL","HOSPITAL_POLYCLINIC","HOTEL_MOTEL","ICE_SKATING_RINK","IMPORTANT_TOURIST_ATTRACTION","INDUSTRIAL_BUILDING","LEISURE_CENTER","LIBRARY","MANUFACTURING_FACILITY","MARINA","MARKET","MEDIA_FACILITY","MILITARY_INSTALLATION","MOSQUE","MOTORING_ORGANIZATION_OFFICE","MOUNTAIN_PASS","MOUNTAIN_PEAK","MOVIE_THEATER","MUSEUM","NATIVE_RESERVATION","NIGHTLIFE","NON_GOVERNMENTAL_ORGANIZATION","OPEN_PARKING_AREA","OPERA_HOUSE","PAGODA","PARK_RECREATION_AREA","PARKING_GARAGE","PETROL_STATION","PHARMACY","PLACE_OF_WORSHIP","POLICE_STATION","PORT_WAREHOUSE_FACILITY","POST_OFFICE","PRIMARY_RESOURCE_UTILITY","PRISON_CORRECTIONAL_FACILITY","PUBLIC_AMENITY","PUBLIC_TRANSPORT_STOP","RAILWAY_STATION","RENT_A_CAR_FACILITY","RENT_A_CAR_PARKING","REPAIR_FACILITY","RESEARCH_FACILITY","RESIDENTIAL_ACCOMMODATION","REST_AREA","RESTAURANT","RESTAURANT_AREA","SCENIC_PANORAMIC_VIEW","SCHOOL","SHOP","SHOPPING_CENTER","SPORTS_CENTER","STADIUM","SUPERMARKETS_HYPERMARKETS","SWIMMING_POOL","SYNAGOG","TAXI_STAND","TEMPLE","TENNIS_COURT","THEATER","TOLL_GATE","TOURIST_INFORMATION_OFFICE","TRAFFIC_CONTROL_DEPARTMENT","TRAFFIC_SERVICE_CENTER","TRAIL_SYSTEM","TRAILS","TRANSPORT_AUTHORITY_VEHICLE_REGISTRATION","TRUCK_STOP","VACATION_RENTAL","VETERINARIAN","WATER_SPORT","WEIGH_STATION","WELFARE_ORGANIZATION","WINERY","ZOOS_ARBORETA_BOTANICAL_GARDEN","completeMapDisplayPoiCategoryMappings","SECURED_ENTRANCE","AGRICULTURAL_BUSINESS","FARM","HORTICULTURE","PRIMARY_PRODUCER","AIRFIELD","AIRLINE_ACCESS","MILITARY_AIRPORT","PRIVATE_AIRPORT","PUBLIC_AIRPORT","ATV_DEALER","BOAT_DEALER","BUS_DEALER","CAR_DEALER","MOTORCYCLE_DEALER","RECREATIONAL_VEHICLE_DEALER","TRUCK_DEALER","VAN_DEALER","DIVERSIFIED_FINANCIALS","SAVINGS_INSTITUTION","BEACH_CLUB","BAR","CAFE","COCKTAIL_BAR","COFFEE_SHOP","INTERNET_CAFE","PUB","TEA_HOUSE","WINE_BAR","CARAVAN_SITE","RECREATIONAL_CAMPING_GROUND","REST_CAMP","TRUCK_WASH","DRIVE_IN_MOVIES","CHILDRENS_CLOTHES","MENS_CLOTHING","SPECIALTY_CLOTHING_SHOP","WOMENS_CLOTHING","PRIVATE_CLUB","JUNIOR_COLLEGE_COMMUNITY_COLLEGE","BUILDING","ADVERTISING_COMPANY","AGRICULTURAL_TECHNOLOGY","AIRLINE_COMPANY","AUTOMOBILE_COMPANY","BUSINESS_SERVICES","BUS_CHARTER_COMPANY","CABLE_TELEPHONE_COMPANY","CLEANING_SERVICES","COMPUTER_DATA_SERVICES","CONSTRUCTION_COMPANY","DELIVERY_SERVICE","ELECTRONICS_COMPANY","EQUIPMENT_RENTAL","FUNERAL_SERVICE_MORTUARIES","IMPORT_EXPORT_AND_DISTRIBUTION","INSURANCE_COMPANY","INVESTMENT_ADVISOR","LEGAL_SERVICES","MINING_COMPANY","MOVING_STORAGE_COMPANY","OIL_NATURAL_GAS","PHARMACEUTICAL_COMPANY","PUBLIC_HEALTH_TECHNOLOGY_COMPANY","PUBLISHING_TECHNOLOGIES","REAL_ESTATE_AGENT","REAL_ESTATE_COMPANY","SERVICE_COMPANY","SOFTWARE_COMPANY","TAX_SERVICES","TELECOMMUNICATIONS","TRANSPORT_COMPANY","TRAVEL_AGENT","WEDDING_SERVICES","GENERAL_PRACTITIONER","SPECIALIST","RIDGE","AMBULANCE_UNIT","ROAD_RESCUE","AMUSEMENT_ARCADE","AMUSEMENT_PLACE","BETTING_STATION","FAIRGROUND","MUSIC_CENTER","CHECKPOINT","BAY","BRIDGE","BRIDGE_TUNNEL_OPERATIONS","CAPE","COVE","DAM","DUNE","ISLAND","LAGOON","LAKESHORE","LOCALE","MARSH","OASIS","PAN","PARKWAY","PLAIN_FLAT","PLATEAU","RAPIDS","REEF","RESERVOIR","RIVER_CROSSING","RIVER_SCENIC_AREA","ROCKS","SEASHORE","TUNNEL","VALLEY","WATER_HOLE","WELL","BUNGALOW_RENTAL","CABINS_LODGES","CHALET_RENTAL","COTTAGE_RENTAL","VILLA_RENTAL","BLOOD_BANK","HOSPITAL_FOR_WOMEN_AND_CHILDREN","HOSPITAL_OF_CHINESE_MEDICINE","SPECIAL_HOSPITAL","B_B_GUEST_HOUSE","HOSTEL","HOTEL","MOTEL","RESORT","QUARRY","AUTOMOBILE_MANUFACTURING","CHEMICAL_COMPANY","MANUFACTURING_COMPANY","MECHANICAL_ENGINEERING","MICROBREWERY","OEM","BOAT_LAUNCHING_RAMP","HARBOR","YACHT_BASIN","FARMERS_MARKET","FOOD_MARKET","INFORMAL_MARKET","PUBLIC_MARKET","PLANETARIUM","CABARET_THEATER","COMEDY_CLUB","DISCO_CLUB","JAZZ_CLUB","KARAOKE_CLUB","FISHING_HUNTING_AREA","FOREST_AREA","HISTORICAL_PARK","NATURAL_RECREATION_ATTRACTION","PARK","PICNIC_AREA","PRESERVE","RECREATION_AREA","WILDERNESS_AREA","OPEN_CAR_PARKING_AREA","DRUG_STORE","MARIJUANA_DISPENSARY","MEDICINAL_MARIJUANA_DISPENSARY","RECREATIONAL_MARIJUANA_DISPENSARY","COURIER_DROP_BOX","LOCAL_POST_OFFICE","PUBLIC_CALL_BOX","PUBLIC_TOILET","BUS_LINES","COACH_STOP","PASSENGER_TRANSPORT_TICKET_OFFICE","PEDESTRIAN_SUBWAY","STREETCAR_STOP","SUBWAY_STATION","INTERNATIONAL_RAILROAD_STATION","NATIONAL_RAILROAD_STATION","RAILROAD_SIDING","STATION_ACCESS","URBAN_STATION","BODYSHOP","CAR_GLASS_REPLACEMENT_SHOP","CAR_REPAIR_AND_SERVICE","HOME_APPLIANCE_REPAIR","MOTORCYCLE_REPAIR","OTHER_REPAIR_SHOPS","REPAIR_SHOP","TIRE_SERVICE","TRUCK_REPAIR_AND_SERVICE","AFGHAN_RESTAURANT","AFRICAN_RESTAURANT","ALGERIAN_RESTAURANT","AMERICAN_RESTAURANT","ARABIAN_RESTAURANT","ARGENTINIAN_RESTAURANT","ARMENIAN_RESTAURANT","ASIAN_RESTAURANT","AUSTRALIAN_RESTAURANT","AUSTRIAN_RESTAURANT","BANQUET_ROOMS","BARBECUE_RESTAURANT","BASQUE_RESTAURANT","BELGIAN_RESTAURANT","BISTRO","BOLIVIAN_RESTAURANT","BOSNIAN_RESTAURANT","BRAZILIAN_RESTAURANT","BRITISH_RESTAURANT","BUFFET_RESTAURANT","BULGARIAN_RESTAURANT","BURMESE_RESTAURANT","CAFETERIA","CALIFORNIAN_RESTAURANT","CAMBODIAN_RESTAURANT","CANADIAN_RESTAURANT","CARIBBEAN_RESTAURANT","CATERING_SERVICES","CHICKEN_RESTAURANT","CHILEAN_RESTAURANT","CHINESE_RESTAURANT","COLOMBIAN_RESTAURANT","CORSICAN_RESTAURANT","CREOLE_RESTAURANT","CREPERIE","CUBAN_RESTAURANT","CYPRIOT_RESTAURANT","CZECH_RESTAURANT","DANISH_RESTAURANT","DINNER_THEATER","DOMINICAN_RESTAURANT","DONGBEI_RESTAURANT","DOUGHNUT_RESTAURANT","DUTCH_RESTAURANT","EGYPTIAN_RESTAURANT","ENGLISH_RESTAURANT","EROTIC_RESTAURANT","ETHIOPIAN_RESTAURANT","EXOTIC_RESTAURANT","FAST_FOOD","FINNISH_RESTAURANT","FONDUE_RESTAURANT","FRENCH_RESTAURANT","FUSION_RESTAURANT","GERMAN_RESTAURANT","GREEK_RESTAURANT","GRILL_RESTAURANT","GUANGDONG_RESTAURANT","HAMBURGER_RESTAURANT","HAWAIIAN_RESTAURANT","HOT_POT_RESTAURANT","HUNAN_RESTAURANT","HUNGARIAN_RESTAURANT","ICE_CREAM_PARLOR","INDIAN_RESTAURANT","INDONESIAN_RESTAURANT","INTERNATIONAL_RESTAURANT","IRANIAN_RESTAURANT","IRISH_RESTAURANT","ISRAELI_RESTAURANT","ITALIAN_RESTAURANT","JAMAICAN_RESTAURANT","JAPANESE_RESTAURANT","JEWISH_RESTAURANT","KOREAN_RESTAURANT","KOSHER_RESTAURANT","LATIN_AMERICAN_RESTAURANT","LEBANESE_RESTAURANT","LUXEMBOURGIAN_RESTAURANT","MACROBIOTIC_RESTAURANT","MAGHRIB_RESTAURANT","MALTESE_RESTAURANT","MAURITIAN_RESTAURANT","MEDITERRANEAN_RESTAURANT","MEXICAN_RESTAURANT","MIDDLE_EASTERN_RESTAURANT","MONGOLIAN_RESTAURANT","MOROCCAN_RESTAURANT","MUSSELS_RESTAURANT","NEPALESE_RESTAURANT","NORWEGIAN_RESTAURANT","ORGANIC_FOOD_RESTAURANT","ORIENTAL_RESTAURANT","PAKISTANI_RESTAURANT","PERUVIAN_RESTAURANT","PHILIPPINE_RESTAURANT","PIZZERIA","POLISH_RESTAURANT","POLYNESIAN_RESTAURANT","PORTUGUESE_RESTAURANT","PROVENCAL_RESTAURANT","PUB_FOOD","ROADSIDE_RESTAURANT","ROMANIAN_RESTAURANT","RUSSIAN_RESTAURANT","SALAD_BAR","SANDWICH_RESTAURANT","SAVOY_RESTAURANT","SCANDINAVIAN_RESTAURANT","SCOTTISH_RESTAURANT","SEAFOOD","SHANDONG_RESTAURANT","SHANGHAI_RESTAURANT","SICHUAN_RESTAURANT","SICILIAN_RESTAURANT","SLAVIC_RESTAURANT","SLOVAK_RESTAURANT","SNACKS_RESTAURANT","SOUL_FOOD","SOUP_RESTAURANT","SPANISH_RESTAURANT","STEAK_HOUSE","SUDANESE_RESTAURANT","SURINAMESE_RESTAURANT","SUSHI_RESTAURANT","SWEDISH_RESTAURANT","SWISS_RESTAURANT","SYRIAN_RESTAURANT","TAIWANESE_RESTAURANT","TAKEOUT_FOOD","TAPAS_RESTAURANT","TEPPANYAKI_RESTAURANT","THAI_RESTAURANT","TIBETAN_RESTAURANT","TUNISIAN_RESTAURANT","TURKISH_RESTAURANT","URUGUAYAN_RESTAURANT","VEGETARIAN_RESTAURANT","VENEZUELAN_RESTAURANT","VIETNAMESE_RESTAURANT","WELSH_RESTAURANT","WESTERN_RESTAURANT","YOGURT_JUICE_BAR","ART_SCHOOL","CHILD_CARE_FACILITY","CULINARY_SCHOOL","DANCE_STUDIO_SCHOOL","DRIVING_SCHOOL","HIGH_SCHOOL","LANGUAGE_SCHOOL","MIDDLE_SCHOOL","PRE_SCHOOL","PRIMARY_SCHOOL","SENIOR_HIGH_SCHOOL","SPECIAL_SCHOOL","SPORT_SCHOOL","TECHNICAL_SCHOOL","VOCATIONAL_SCHOOL","AGRICULTURAL_SUPPLIES","ANTIQUE_ART_SHOP","BAGS_LEATHERWEAR","BAKERY","BEAUTY_SALON","BEAUTY_SUPPLIES","BOATING_EQUIPMENT_ACCESSORIES","BOOK_SHOP","BUTCHER","CAMERAS_PHOTOGRAPHY","CARPET_FLOOR_COVERINGS","CAR_ACCESSORIES","CHRISTMAS_HOLIDAY_SHOP","COMPUTER_COMPUTER_SUPPLIES","CONSTRUCTION_MATERIAL_EQUIPMENT","CONSUMER_ELECTRONICS","CONVENIENCE_STORE","CURTAINS_TEXTILES","C_DS_DVD_VIDEOS","DELICATESSEN","DO_IT_YOURSELF_CENTERS","DRIVE_THROUGH_BOTTLE_SHOP","DRY_CLEANER","ELECTRICAL_APPLIANCES_SHOP","FACTORY_OUTLET","FISHMONGER","FLORISTS","FOOTWEAR_SHOE_REPAIRS","FURNITURE_HOME_FURNISHINGS","GARDEN_CENTERS_SERVICES","GIFTS_CARDS_NOVELTIES_SOUVENIRS","GLASSWARE_CERAMIC_SHOP","GLASS_WINDOWS_STORE","GREENGROCER","GROCERY_STORE","HAIRDRESSER","HARDWARE_STORE","HOBBY_SHOP","HOUSE_GARDEN_FURNITURE_FITTINGS","JEWELRY_CLOCKS_WATCHES","KITCHENS_BATHROOMS","LAUNDRY","LIGHTING_SHOPS","LOCAL_SPECIALITIES_SHOP","LOTTERY_SHOP","MARINE_ELECTRONIC_EQUIPMENT","MEDICAL_SUPPLIES_EQUIPMENT","MOBILE_PHONE_SHOP","MUSIC_INSTRUMENTS_STORE","NAIL_SALON","NEWSAGENTS_TOBACCONISTS","OFFICE_EQUIPMENT","OPTICIAN","OTHER_FOOD_SHOPS","PAINTING_DECORATING","PAWN_SHOP","PERSONAL_CARE_FACILITY","PERSONAL_SERVICE","PET_SUPPLIES","PHOTOCOPY_SHOP","PHOTO_LAB_DEVELOPMENT","RECYCLING_SHOP","RETAIL_OUTLET","SAUNA_SOLARIUM_MASSAGE","SECURITY_PRODUCTS","SHOPPING_SERVICE","SPECIALTY_FOODS","SPORTS_EQUIPMENT_CLOTHING","STAMP_SHOP","TAILOR_SHOP","TOYS_GAMES_SHOP","VARIETY_STORE","VIDEO_RENTAL_SHOP","WHOLESALE_CLUB","WINE_SPIRITS","ATHLETICS_TRACK","BASEBALL_PARK","BASKETBALL_ARENA","BOWLING_CENTER","CRICKET_GROUND","FITNESS_CLUB_CENTER","FLYING_CLUB","HOCKEY_CLUB","HORSE_RACING_TRACK","HORSE_RIDING_CENTER","ICE_HOCKEY_ARENA","OTHER_WINTER_SPORT","RACE_TRACK","RUGBY_GROUND","SKI_RESORT","SNOOKER_POOL_BILLIARD","THEMATIC_SPORT_CENTER","FOOTBALL_STADIUM","MOTOR_RACING_STADIUM","MULTI_PURPOSE_STADIUM","NETBALL_STADIUM","SOCCER_STADIUM","STOCK_EXCHANGE","TAXI_LIMOUSINE_SHUTTLE_SERVICE","AMPHITHEATER","ARCH","BATTLEFIELD","CAVE","CEMETERY","HISTORIC_SITE","MAUSOLEUM_GRAVE","MEMORIAL","MINERAL_HOT_SPRINGS","MONUMENT","NATURAL_TOURIST_ATTRACTION","OBSERVATORY","STATUE","TOURIST_ATTRACTION","TOWER","ROAD_TRAFFIC_CONTROL_CENTER","ADVENTURE_VEHICLE_TRAIL","HIKING_TRAIL","HORSE_RIDING_TRAIL","MOUNTAIN_BIKE_TRAIL","ROCK_CLIMBING_TRAIL","APARTMENT_RENTAL","CONDOMINIUM_COMPLEX","FLATS_APARTMENT_COMPLEX","RESIDENTIAL_ESTATE","RETIREMENT_COMMUNITY","TOWNHOUSE_COMPLEX","ANIMAL_SERVICES","ANIMAL_SHELTER","WEIGH_SCALES","WILDLIFE_PARK","ZOO","toBaseMapPOICategory","category","MAP_BOLD_FONT","TITLE","ICON_ID","DEFAULT_PLACE_ICON_ID","pinIconBaseLayout","pinIconBasePaint","pinTextBaseLayout","pinTextBasePaint","pinLayerBaseSpec","suffixNumber","text","numberToSuffix","isClickEventState","hasEventState","SELECTED_COLOR","pinLayerSpec","selectedPinLayerSpec","withConfig","layerName","textConfig","customLayer","font","title","color","haloColor","haloWidth","getTextSizeSpec","textSize","buildPlacesLayerSpecs","layerSpecTemplates","theme","poiLikeLayerSpec","poiLayer","buildPoiLikeLayerSpec","main","selected","additional","defaultPin","supportedPinSubcategories","buildPlaceTitle","place","address","freeformAddress","toImageID","poiCategory","iconTheme","defaultPlaceIconID","categoryID","substring","toPinImageID","poiCategoriesToID","imageID","getIconIDForPlace","instanceIndex","imageMapping","icon","mapping","to","classifications","code","matchingCustomIcon","categoryIcons","customIcon","getPOILayerCategoryForPlace","toPlaces","places","preparePlacesForDisplay","placesInput","extraFeatureProps","generateId","geometry","bbox","iconID","_PlacesModule","lastInstanceIndex","layerIDPrefix","buildLayerSpecs","updateLayersAndData","previousShownFeatures","applyTheme","applyConfigPart","applyIconConfig","iconConfig","applyTextConfig","partialConfig","applyExtraFeatureProps","updateData","setupImages","newLayerSpecs","newLayerSpecsArray","oldLayerSpecsArray","image","pixelRatio","default","events","PlacesModule","isExpressionFilter","getMergedAnyFilter","filters","expression","legacy","getMergedAllFilter","filterToAdd","originalFilter","buildMappedValuesFilter","propName","showMode","comparator","filterArrayNew","buildValuesFilter","valuesMapping","poiCategoryGroups","FOOD_DRINKS_GROUP","SHOPPING_GROUP","TRANSPORTATION_GROUP","HEALTH_GROUP","PARKING_GROUP","HOLIDAY_TOURISM_GROUP","EV_CHARGING_STATIONS_GROUP","GAS_STATIONS_GROUP","ACCOMMODATION_GROUP","ENTERTAINMENT_GROUP","SPORTS_LEISURE_GROUP","EDUCATION_GROUP","GOVERNMENT_GROUP","getStyleCategories","categories","categoryIds","POIsModule","poiRuntimeSource","mainLayer","getFilter","setVisible","isVisible","filterCategories","categoriesFilter","poiFilter","layerGroupMappings","land","layerIDMatches","layerTypes","borders","water","buildings2D","buildings3D","houseNumbers","roadLines","roadLabels","roadShields","placeLabels","smallerTownLabels","cityLabels","capitalLabels","stateLabels","countryLabels","isMatching","group","part","toLowerCase","buildBaseMapLayerGroupFilter","layerGroupsFilter","layerGroups","groups","names","filterLayerByGroups","BaseMapModule","vectorTiles","layerGroupsVisibility","error","buildLayerGroupFilter","baseMapLayerGroupNames","GEOMETRY_TITLE_PROP","GEOMETRY_COLOR_PROP","colorPalettes","warm","browns","cold","fadedBlues","blues","greens","fadedGreenToBlue","blueToRed","greenToYellow","pastel","retro","contrastRetro","fadedRainbow","pastelRainbow","defaultColor","geometryFillSpec","geometryOutlineSpec","buildGeometryLayerSpecs","fillLayerId","outlineLayerId","colorConfig","lineConfig","fillOpacity","lineColor","lineWidth","lineOpacity","buildGeometryTitleLayerSpec","textField","prepareGeometryForDisplay","buildTitle","palette","buildColor","prepareTitleForDisplay","geometries","coordinates","placeCoordinates","biggestPolygon","flat","reduce","coord","getLongestArray","bboxFromCoordsArray","bboxCenter","_GeometriesModule","titleSourceID","layerIdPrefix","fillLayerID","outlineLayerID","titleLayerID","titleLayerSpec","titleLayerSpecs","geometryFillLayerSpecs","geometryOutlineLayerSpecs","geometryLabel","updateLayerAndData","beforeLayerConfig","moveBeforeLayer","moveBeforeLayerID","beforeLayerId","moveLayer","layerConfig","newTitleLayerSpecs","GeometriesModule","HillshadeModule","hillshadeSource","hillshade","standardStyleIDs","styleModules","ROUTE_LINE_FOREGROUND_COLOR","ROUTE_LINE_OUTLINE_COLOR","DESELECTED_FOREGROUND_COLOR","DESELECTED_OUTLINE_COLOR","DESELECTED_SECONDARY_COLOR","ROUTE_LINE_FOREGROUND_WIDTH","SELECTED_ROUTE_FILTER","DESELECTED_ROUTE_FILTER","MAJOR_DELAY_COLOR","MODERATE_DELAY_COLOR","MINOR_DELAY_LABEL_COLOR","UNKNOWN_DELAY_COLOR","chargingStopTextField","chargingStopSymbol","commonProps","commonLineProps","instructionOutline","instructionLine","INSTRUCTION_ARROW_IMAGE_ID","instructionArrow","routeFerriesLine","routeFerriesSymbol","routeLineBaseTemplate","outlineLineWidth","routeDeselectedOutline","routeDeselectedLine","routeOutline","routeLineArrows","SELECTED_SUMMARY_POPUP_IMAGE_ID","DESELECTED_SUMMARY_POPUP_IMAGE_ID","routeTollRoadsOutline","routeTollRoadsSymbol","EXTRA_FOREGROUND_LINE_WIDTH","routeIncidentsBGLine","routeIncidentsDashedLine","magnitudeOfDelayTextColor","routeIncidentsSymbolBase","routeIncidentsJamSymbol","routeIncidentsCauseSymbol","routeTunnelsLine","routeVehicleRestrictedBackgroundLine","routeVehicleRestrictedDottedLine","TRAFFIC_CLEAR_IMAGE_ID","TRAFFIC_MAJOR_IMAGE_ID","TRAFFIC_MODERATE_IMAGE_ID","TRAFFIC_MINOR_IMAGE_ID","hasFormattedTraffic","buildSummaryBubbleSymbolPoint","selectedImageID","deselectedImageID","trafficClearID","trafficMajorID","trafficModerateID","trafficMinorID","summaryBubbleSymbolPoint","START_INDEX","MIDDLE_INDEX","FINISH_INDEX","INDEX_TYPE","STOP_DISPLAY_INDEX","WAYPOINT_START_IMAGE_ID","WAYPOINT_STOP_IMAGE_ID","WAYPOINT_SOFT_IMAGE_ID","WAYPOINT_FINISH_IMAGE_ID","pinIndexLabelLayout","waypointSymbols","waypointLabels","prefixBeforeID","startsWith","prefixBeforeIDs","suffixImageID","buildRoutingLayers","configLayers","configSectionLayers","sections","mainColor","mainLines","routeLine","waypoints","routeWaypointSymbol","routeWaypointLabel","chargingStops","routeChargingStopSymbol","incident","routeIncidentJamSymbol","routeIncidentCauseSymbol","routeIncidentBackgroundLine","routeIncidentDashedLine","ferry","routeFerryLine","routeFerrySymbol","tollRoad","routeTollRoadOutline","routeTollRoadSymbol","tunnel","routeTunnelLine","vehicleRestricted","routeVehicleRestrictedForegroundLine","instructionLines","routeInstructionLine","routeInstructionOutline","instructionArrows","routeInstructionArrowSymbol","summaryBubbles","routeSummaryBubbleSymbol","defaultRoutingLayers","instructionArrowIconImg","summaryMapBubbleImg","svg","summaryBubbleImageOptions","stretchX","stretchY","content","trafficImg","waypointIcon","foregroundSvg","svgOptions","appendChild","mapLayerSpecs","createLayersSpecs","layerConfigs","ferries","incidents","tollRoads","tunnels","routeModuleConfigWithDefaults","globalDisplayUnits","TomTomConfig","instance","displayUnits","getIconID","chargingStop","basedOn","chargingConnectionInfo","chargingSpeed","formatTitle","chargingParkName","chargingParkOperatorName","toDisplayChargingStops","routes","displayChargingStops","route","leg","summary","chargingInformationAtEndOfLeg","chargingParkId","chargingPower","chargingPowerInkW","chargingDuration","formatDuration","chargingTimeInSeconds","time","routeState","hasJam","sectionProps","toDisplayTrafficSectionProps","delayInSeconds","jamIconID","magnitudeOfDelay","toTrafficJamIconSuffix","toJamIconID","causeIconID","toCauseIconID","getImageIDForWaypoint","waypoint","indexType","radiusMeters","baseImageID","toDisplayWaypoints","hardWaypointIndex","waypointInput","asWaypoint","arrayLength","indexTypeFor","hardWaypoint","isHardWaypoint","placeProperties","buildWaypointTitle","entryPoints","getPosition","useEntryPoint","stopDisplayIndex","degreesToRadians","degrees","PI","getCoord","bearing","final","bear","calculateFinalBearing","coordinates1","coordinates2","lon1","lon2","lat1","lat2","a","sin","cos","b","atan2","index_default","toDisplayRouteSections","sectionType","displaySectionPropsBuilder","startPointIndex","endPointIndex","routeIndex","buildRouteSectionsFromRoute","showFeaturesWithRouteSelection","routesWithSelection","toDisplayRoutes","selectedIndex","routesCollection","hasMagnitude","magnitude","section","toDisplayRouteSummaries","routeCoordinates","formattedTraffic","trafficDelayInSeconds","trafficSections","traffic","summaryDelayMagnitude","round","formattedDistance","formatDistance","lengthInMeters","distance","formattedDuration","travelTimeInSeconds","_RoutingModule","createSourcesWithLayers","layersSpecs","sourcePrefix","routingSourcesWithLayers","svgIconOptions","waypointStartImageId","waypointStopImageId","waypointSoftImageId","waypointFinishImageId","instructionArrowImageId","selectedSummaryPopupImageId","deselectedSummaryPopupImageId","trafficClearImageId","trafficMajorImageId","trafficModerateImageId","trafficMinorImageId","addImageIfNotExisting","waypointStartIcon","softWaypointIcon","waypointFinishIcon","customChargingStopIcon","customIcons","mergedConfig","newLayersSpecs","layersSpecID","oldLayersSpecs","newLayersMap","acc","cur","oldLayersMap","layersToRemove","newLayersToUpdate","oldLayersToUpdate","removeLayer","toBeAddedLayerSpec","updateLayersAndSource","listOfSources","previouslyShown","item","showRoutes","displayRoutes","guidance","instructions","instruction","routePath","pathPoint","toDisplayInstructions","instructionLastSegment","lastPointBearingDegrees","calcBearing","toDisplayInstructionArrows","clearRoutes","selectRoute","updatedRoutes","showWaypoints","displayWaypoints","clearWaypoints","getLayerToRenderLinesUnder","RoutingModule","DEFAULT_STANDARD_STYLE_ID","standardStyleModulesValues","standardLight","trafficIncidents","trafficFlow","standardDark","drivingLight","drivingDark","monoLight","monoDark","satellite","baseMapStyleUrlTemplate","suffix","baseMapStyleUrlTemplates","buildStandardStyleUrl","baseUrl","apiKey","styleURL","URL","version","searchParams","append","buildStyleInput","mapParams","commonBaseURL","url","givenUrl","withApiKey","json","TomTomMap","tomtomMapParams","params","styleChangeHandlers","keepState","effectiveStyle","previousStyle","withPreviousStyleParts","_params","styleLightDarkTheme","handleStyleData","mergeFromGlobal","ensureMapLibreCSSLoaded","validateStyle","maxTileCacheZoomLevels","cancelPendingTileRequestsWhileZooming","mapLibre","attributionControl","compact","transformRequest","resourceType","headers","generateTomTomHeaders","loadRTLTextPlugin","getRTLTextPluginStatus","setRTLTextPlugin","catch","from","querySelectorAll","textContent","link","rel","href","head","_setLanguage","language","mapLanguage","split","isLayerLocalizable","textFieldValue","setLanguage","getBBox","getBounds","toArray","setSprite","addPinCategoriesSpriteToStyle","incidentCategories","incidentCategoriesMapping","unknown","accident","fog","dangerous_conditions","rain","ice","jam","lane_closed","road_closed","road_works","wind","flooding","broken_down_vehicle","roadCategories","tertiaryRoadCategories","streetRoadCategories","toMultiSyntaxAllFilter","newSyntaxExpressions","legacySyntaxExpressions","addFilter","addValuesFilter","valuesFilter","addCommonFilterExpressions","sdkFilter","roadSubCategories","buildMapLibreIncidentsFilter","incidentCategoryFilter","magnitudes","magnitudesFilter","indexedMagnitudes","indexOf","delays","delayFilter","mustHaveDelay","minDelayMinutes","delaySeconds","delayFilterToMapLibre","buildMapLibreIncidentFilters","incidentFilters","any","mapLibreFilters","mapLibreFilter","buildMapLibreFlowFilter","showRoadClosures","operator","applyFilter","originalFilters","TrafficFlowModule","flowSource","getLayers","_filter","updateConfig","filterExpression","flowFilters","buildMapLibreFlowFilters","TrafficIncidentsModule","incidentsSource","_setVisible","icons","setIconsVisible","iconFilters","incidentFilterExpression","getNonSymbolLayers","iconFilterExpression","getSymbolLayers","anyIconLayersVisible","getRelativeElementBounds","elementRect","containerRect","left","top","right","bottom","isElementOutsideContainer","bounds","containerWidth","containerHeight","adjustForHorizontalBar","currentVisible","min","adjustForVerticalBar","adjustVisibleBoundsForElement","mapWidthPX","mapHeightPX","clampedBounds","clampBoundsToContainer","spansFullWidth","spansFullHeight","touchesLeft","touchesRight","touchesTop","touchesBottom","distanceFromLeft","distanceFromRight","distanceFromTop","distanceFromBottom","minDistance","adjustForFloatingElement","toElement","ref","getMapLibreMap","calculateVisibleAreaBounds","surroundingElements","paddingPX","getContainer","getBoundingClientRect","width","height","visibleAreaBounds","elementRef","elementBounds","calculatePaddedBBox","sw","unproject","ne","lng","lat","calculatePaddedCenter","west","south","east","north","calculateFittingBBox","toBeContainedBBox","leftRatio","rightRatio","topRatio","widthRatio","heightRatio","fullWidth","fullHeight","expandedWest","expandedNorth"],"mappings":"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ClC,MAAMp9B,EAAOo9B,EAAYp9B,KACnBq9B,EAASD,EAAYE,MAC3B,MAAa,YAATt9B,EACQ7C,GAAUkgC,EAAOngC,KAAM6/B,GAAUD,GAAWC,EAAO5/B,IAElD,YAAT6C,EACQ7C,IAAWkgC,EAAOngC,KAAM6/B,GAAUD,GAAWC,EAAO5/B,KAGhEmG,QAAQq6B,MAAM,iCAAkC39B,GACzC,KAAM,ICoMuB49B,CAAsBjiC,EAAQyhC,aAGlE,CA8CA,UAAInE,GACA,OAAO,IAAI9yB,GAAarZ,KAAK6T,UAAUkE,aAAc/X,KAAKuY,kBAAkBo4B,YAAa3wC,KAAK2X,QAAQw0B,OAC1G,ECzUG,MAAM4E,GAAyB,CAClC,OACA,QACA,UACA,cACA,cACA,eACA,YACA,aACA,cACA,cACA,oBACA,aACA,gBACA,cACA,iBC6FSC,GAAsB,QAKtBC,GAAsB,QC1HtBC,GAAgB,CACzBC,KAAM,CACF,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,OAAQ,CACJ,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,KAAM,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WAC/FC,WAAY,CACR,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,MAAO,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WAChGC,OAAQ,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WACtFC,iBAAkB,CACd,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,UAAW,CACP,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,cAAe,CACX,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,OAAQ,CACJ,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,MAAO,CACH,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,cAAe,CACX,U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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,224,225,226]}
|
|
1
|
+
{"version":3,"file":"map.es.js","sources":["../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_freeGlobal.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_root.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Symbol.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getRawTag.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_objectToString.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseGetTag.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isObjectLike.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isSymbol.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arrayMap.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseToString.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isObject.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/identity.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isFunction.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_coreJsData.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isMasked.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_toSource.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsNative.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getNative.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getValue.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_WeakMap.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_shortOut.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_defineProperty.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseSetToString.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/constant.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_setToString.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isIndex.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseAssignValue.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/eq.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_assignValue.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_overRest.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isLength.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isArrayLike.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isPrototype.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsArguments.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isArguments.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/stubFalse.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseUnary.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_nodeUtil.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arrayLikeKeys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseTimes.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_overArg.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_nativeKeys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseKeys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/keys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_nativeKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/keysIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isKey.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_nativeCreate.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hashGet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hashHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Hash.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_assocIndexOf.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hashClear.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hashDelete.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hashSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_listCacheDelete.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_ListCache.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_listCacheClear.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_listCacheGet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_listCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_listCacheSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Map.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getMapData.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isKeyable.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_MapCache.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapCacheClear.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapCacheDelete.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapCacheGet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapCacheSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/memoize.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stringToPath.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_memoizeCapped.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_castPath.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/toString.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_toKey.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseGet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arrayPush.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isFlattenable.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/flatten.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseFlatten.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getPrototype.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isPlainObject.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Stack.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stackClear.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stackDelete.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stackGet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stackHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_stackSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/stubArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getSymbols.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arrayFilter.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getSymbolsIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseGetAllKeys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getAllKeys.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getAllKeysIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_DataView.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Promise.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Set.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getTag.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_initCloneArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_Uint8Array.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneArrayBuffer.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneRegExp.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneSymbol.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_initCloneByTag.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneDataView.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cloneTypedArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isMap.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsMap.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseClone.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arrayEach.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_SetCache.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_arraySome.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_setCacheAdd.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_setCacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_equalArrays.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_cacheHas.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_mapToArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_setToArray.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_equalByTag.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_equalObjects.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsEqualDeep.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsEqual.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_isStrictComparable.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_matchesStrictComparable.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseMatches.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_getMatchData.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIsMatch.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseHasIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/hasIn.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_hasPath.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseMatchesProperty.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/get.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/property.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseProperty.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_basePropertyDeep.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseIteratee.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_parent.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseSlice.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isEmpty.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isEqual.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/isNil.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseUnset.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/last.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_customOmitClone.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/omit.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_flatRest.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_apply.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_copyObject.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_baseSet.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/pickBy.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_basePickBy.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/omitBy.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/negate.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/_basePullAt.js","../../node_modules/.pnpm/lodash-es@4.17.23/node_modules/lodash-es/remove.js","../src/shared/errorMessages.ts","../src/shared/imageUtils.ts","../src/shared/resources/index.ts","../src/shared/resources/pin.svg?raw","../src/shared/assertionUtils.ts","../src/shared/TomTomMapSource.ts","../src/shared/SourceWithLayers.ts","../src/shared/mapUtils.ts","../src/shared/AbstractMapModule.ts","../src/shared/EventsModule.ts","../src/shared/AbstractEventProxy.ts","../src/shared/eventUtils.ts","../src/shared/EventsProxy.ts","../src/shared/layers/layerIDs.ts","../src/shared/layers/sourcesIDs.ts","../src/pois/layers/poisLayers.ts","../src/pois/poiCategoryMapping.ts","../src/shared/layers/commonLayerProps.ts","../src/shared/layers/symbolLayers.ts","../src/shared/layers/utils.ts","../src/places/utils/customIconScales.ts","../src/places/utils/evAvailabilityHelpers.ts","../src/places/utils/textOffsetCalculator.ts","../src/places/utils/layerConfiguration.ts","../src/places/utils/themeAdaptation.ts","../src/shared/layers/eventState.ts","../src/places/utils/layerSpecBuilders.ts","../src/places/layers/placesLayers.ts","../src/places/resources/index.ts","../src/places/utils/toPinImageID.ts","../src/places/utils/preparePlacesForDisplay.ts","../src/places/PlacesModule.ts","../src/shared/mapLibreFilterUtils.ts","../src/pois/poiCategoryGroups.ts","../src/pois/POIsModule.ts","../src/base/layerGroups.ts","../src/base/BaseMapModule.ts","../src/base/types/baseMapModuleConfig.ts","../src/geometry/types/geometryDisplayProps.ts","../src/geometry/layers/geometryLayers.ts","../src/geometry/prepareGeometryForDisplay.ts","../src/geometry/GeometriesModule.ts","../src/hillshade/HillshadeModule.ts","../src/init/types/mapInit.ts","../src/routing/layers/shared.ts","../src/routing/layers/chargingStopLayers.ts","../src/routing/layers/guidanceLayers.ts","../src/routing/layers/routeFerrySectionLayers.ts","../src/routing/layers/routeMainLineLayers.ts","../src/routing/layers/routeTollRoadLayers.ts","../src/routing/layers/routeTrafficSectionLayers.ts","../src/routing/layers/routeTunnelSectionLayers.ts","../src/routing/layers/routeVehicleRestrictedLayers.ts","../src/routing/layers/summaryBubbleLayers.ts","../src/routing/types/waypointDisplayProps.ts","../src/routing/layers/waypointLayers.ts","../src/routing/layers/routingLayers.ts","../src/routing/resources/index.ts","../src/routing/resources/instruction-line-arrow.svg?raw","../src/routing/resources/summary-map-bubble.svg?raw","../src/routing/resources/traffic.svg?raw","../src/routing/util/config.ts","../src/routing/util/displayChargingStops.ts","../src/routing/util/displayTrafficSectionProps.ts","../src/routing/util/displayWaypoints.ts","../../node_modules/.pnpm/@turf+helpers@7.3.3/node_modules/@turf/helpers/dist/esm/index.js","../../node_modules/.pnpm/@turf+invariant@7.3.3/node_modules/@turf/invariant/dist/esm/index.js","../../node_modules/.pnpm/@turf+bearing@7.3.3/node_modules/@turf/bearing/dist/esm/index.js","../src/routing/util/guidance.ts","../src/routing/util/routeSections.ts","../src/routing/util/routeSelection.ts","../src/routing/util/routes.ts","../src/routing/RoutingModule.ts","../src/routing/resources/start.svg?raw","../src/routing/resources/circle.svg?raw","../src/routing/resources/finish.svg?raw","../src/init/styleInputBuilder.ts","../src/TomTomMap.ts","../src/init/buildMapOptions.ts","../src/shared/localization.ts","../src/traffic/types/trafficModuleConfig.ts","../src/traffic/filters/trafficFilters.ts","../src/traffic/TrafficFlowModule.ts","../src/traffic/TrafficIncidentsModule.ts","../src/utils/paddedBounds.ts"],"sourcesContent":["/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n","import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","import Symbol from './_Symbol.js';\nimport arrayMap from './_arrayMap.js';\nimport isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","import baseGetTag from './_baseGetTag.js';\nimport isObject from './isObject.js';\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nexport default isFunction;\n","import root from './_root.js';\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nexport default coreJsData;\n","import coreJsData from './_coreJsData.js';\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nexport default isMasked;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","import isFunction from './isFunction.js';\nimport isMasked from './_isMasked.js';\nimport isObject from './isObject.js';\nimport toSource from './_toSource.js';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nexport default baseIsNative;\n","import baseIsNative from './_baseIsNative.js';\nimport getValue from './_getValue.js';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nexport default getNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","import getNative from './_getNative.js';\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nexport default defineProperty;\n","import constant from './constant.js';\nimport defineProperty from './_defineProperty.js';\nimport identity from './identity.js';\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nexport default baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","import baseSetToString from './_baseSetToString.js';\nimport shortOut from './_shortOut.js';\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nexport default setToString;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","import defineProperty from './_defineProperty.js';\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nexport default baseAssignValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nexport default assignValue;\n","import apply from './_apply.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nexport default overRest;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","import isFunction from './isFunction.js';\nimport isLength from './isLength.js';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nexport default isArrayLike;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nexport default baseIsArguments;\n","import baseIsArguments from './_baseIsArguments.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nexport default isArguments;\n","import root from './_root.js';\nimport stubFalse from './stubFalse.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nexport default isBuffer;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","import baseGetTag from './_baseGetTag.js';\nimport isLength from './isLength.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nexport default baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nexport default nodeUtil;\n","import baseIsTypedArray from './_baseIsTypedArray.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nexport default isTypedArray;\n","import baseTimes from './_baseTimes.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isIndex from './_isIndex.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","import overArg from './_overArg.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nexport default nativeKeys;\n","import isPrototype from './_isPrototype.js';\nimport nativeKeys from './_nativeKeys.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeys;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n","import isObject from './isObject.js';\nimport isPrototype from './_isPrototype.js';\nimport nativeKeysIn from './_nativeKeysIn.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeysIn from './_baseKeysIn.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nexport default keysIn;\n","import isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nexport default isKey;\n","import getNative from './_getNative.js';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n","import hashClear from './_hashClear.js';\nimport hashDelete from './_hashDelete.js';\nimport hashGet from './_hashGet.js';\nimport hashHas from './_hashHas.js';\nimport hashSet from './_hashSet.js';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n","import eq from './eq.js';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nexport default assocIndexOf;\n","import nativeCreate from './_nativeCreate.js';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nexport default hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nexport default hashSet;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nexport default listCacheDelete;\n","import listCacheClear from './_listCacheClear.js';\nimport listCacheDelete from './_listCacheDelete.js';\nimport listCacheGet from './_listCacheGet.js';\nimport listCacheHas from './_listCacheHas.js';\nimport listCacheSet from './_listCacheSet.js';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n","import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nexport default listCacheSet;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n","import isKeyable from './_isKeyable.js';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nexport default getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","import mapCacheClear from './_mapCacheClear.js';\nimport mapCacheDelete from './_mapCacheDelete.js';\nimport mapCacheGet from './_mapCacheGet.js';\nimport mapCacheHas from './_mapCacheHas.js';\nimport mapCacheSet from './_mapCacheSet.js';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n","import Hash from './_Hash.js';\nimport ListCache from './_ListCache.js';\nimport Map from './_Map.js';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nexport default mapCacheClear;\n","import getMapData from './_getMapData.js';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default mapCacheDelete;\n","import getMapData from './_getMapData.js';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n","import getMapData from './_getMapData.js';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n","import getMapData from './_getMapData.js';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nexport default mapCacheSet;\n","import MapCache from './_MapCache.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nexport default memoize;\n","import memoizeCapped from './_memoizeCapped.js';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nexport default stringToPath;\n","import memoize from './memoize.js';\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nexport default memoizeCapped;\n","import isArray from './isArray.js';\nimport isKey from './_isKey.js';\nimport stringToPath from './_stringToPath.js';\nimport toString from './toString.js';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nexport default castPath;\n","import baseToString from './_baseToString.js';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n","import isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n","import castPath from './_castPath.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","import Symbol from './_Symbol.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nexport default isFlattenable;\n","import baseFlatten from './_baseFlatten.js';\n\n/**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\nfunction flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n}\n\nexport default flatten;\n","import arrayPush from './_arrayPush.js';\nimport isFlattenable from './_isFlattenable.js';\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nexport default baseFlatten;\n","import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n","import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n","import ListCache from './_ListCache.js';\nimport stackClear from './_stackClear.js';\nimport stackDelete from './_stackDelete.js';\nimport stackGet from './_stackGet.js';\nimport stackHas from './_stackHas.js';\nimport stackSet from './_stackSet.js';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n","import ListCache from './_ListCache.js';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nexport default stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","import ListCache from './_ListCache.js';\nimport Map from './_Map.js';\nimport MapCache from './_MapCache.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nexport default stackSet;\n","import root from './_root.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nexport default cloneBuffer;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nexport default getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nexport default getSymbolsIn;\n","import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n","import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n","import DataView from './_DataView.js';\nimport Map from './_Map.js';\nimport Promise from './_Promise.js';\nimport Set from './_Set.js';\nimport WeakMap from './_WeakMap.js';\nimport baseGetTag from './_baseGetTag.js';\nimport toSource from './_toSource.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nexport default getTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n","import Uint8Array from './_Uint8Array.js';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nexport default cloneArrayBuffer;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n","import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n","import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n","import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n","import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\nimport keysIn from './keysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n","import MapCache from './_MapCache.js';\nimport setCacheAdd from './_setCacheAdd.js';\nimport setCacheHas from './_setCacheHas.js';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","import SetCache from './_SetCache.js';\nimport arraySome from './_arraySome.js';\nimport cacheHas from './_cacheHas.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nexport default equalArrays;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","import Symbol from './_Symbol.js';\nimport Uint8Array from './_Uint8Array.js';\nimport eq from './eq.js';\nimport equalArrays from './_equalArrays.js';\nimport mapToArray from './_mapToArray.js';\nimport setToArray from './_setToArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nexport default equalByTag;\n","import getAllKeys from './_getAllKeys.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nexport default equalObjects;\n","import Stack from './_Stack.js';\nimport equalArrays from './_equalArrays.js';\nimport equalByTag from './_equalByTag.js';\nimport equalObjects from './_equalObjects.js';\nimport getTag from './_getTag.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nexport default baseIsEqualDeep;\n","import baseIsEqualDeep from './_baseIsEqualDeep.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nexport default baseIsEqual;\n","import isObject from './isObject.js';\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nexport default isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","import baseIsMatch from './_baseIsMatch.js';\nimport getMatchData from './_getMatchData.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nexport default baseMatches;\n","import isStrictComparable from './_isStrictComparable.js';\nimport keys from './keys.js';\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nexport default getMatchData;\n","import Stack from './_Stack.js';\nimport baseIsEqual from './_baseIsEqual.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport default baseIsMatch;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","import baseHasIn from './_baseHasIn.js';\nimport hasPath from './_hasPath.js';\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nexport default hasIn;\n","import castPath from './_castPath.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isIndex from './_isIndex.js';\nimport isLength from './isLength.js';\nimport toKey from './_toKey.js';\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nexport default hasPath;\n","import baseIsEqual from './_baseIsEqual.js';\nimport get from './get.js';\nimport hasIn from './hasIn.js';\nimport isKey from './_isKey.js';\nimport isStrictComparable from './_isStrictComparable.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\nimport toKey from './_toKey.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nexport default baseMatchesProperty;\n","import baseGet from './_baseGet.js';\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nexport default get;\n","import baseProperty from './_baseProperty.js';\nimport basePropertyDeep from './_basePropertyDeep.js';\nimport isKey from './_isKey.js';\nimport toKey from './_toKey.js';\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nexport default property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","import baseGet from './_baseGet.js';\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nexport default basePropertyDeep;\n","import baseMatches from './_baseMatches.js';\nimport baseMatchesProperty from './_baseMatchesProperty.js';\nimport identity from './identity.js';\nimport isArray from './isArray.js';\nimport property from './property.js';\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nexport default baseIteratee;\n","import baseGet from './_baseGet.js';\nimport baseSlice from './_baseSlice.js';\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nexport default parent;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","import baseKeys from './_baseKeys.js';\nimport getTag from './_getTag.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isArrayLike from './isArrayLike.js';\nimport isBuffer from './isBuffer.js';\nimport isPrototype from './_isPrototype.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n setTag = '[object Set]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\nfunction isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArrayLike(value) &&\n (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n return !value.length;\n }\n var tag = getTag(value);\n if (tag == mapTag || tag == setTag) {\n return !value.size;\n }\n if (isPrototype(value)) {\n return !baseKeys(value).length;\n }\n for (var key in value) {\n if (hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n}\n\nexport default isEmpty;\n","import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nexport default isEqual;\n","/**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\nfunction isNil(value) {\n return value == null;\n}\n\nexport default isNil;\n","import castPath from './_castPath.js';\nimport last from './last.js';\nimport parent from './_parent.js';\nimport toKey from './_toKey.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\nfunction baseUnset(object, path) {\n path = castPath(path, object);\n\n // Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg\n var index = -1,\n length = path.length;\n\n if (!length) {\n return true;\n }\n\n var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');\n\n while (++index < length) {\n var key = path[index];\n\n // skip non-string keys (e.g., Symbols, numbers)\n if (typeof key !== 'string') {\n continue;\n }\n\n // Always block \"__proto__\" anywhere in the path if it's not expected\n if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {\n return false;\n }\n\n // Block \"constructor.prototype\" chains\n if (key === 'constructor' &&\n (index + 1) < length &&\n typeof path[index + 1] === 'string' &&\n path[index + 1] === 'prototype') {\n\n // Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')\n if (isRootPrimitive && index === 0) {\n continue;\n }\n\n return false;\n }\n }\n\n var obj = parent(object, path);\n return obj == null || delete obj[toKey(last(path))];\n}\n\nexport default baseUnset;\n","/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n","import isPlainObject from './isPlainObject.js';\n\n/**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\nfunction customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n}\n\nexport default customOmitClone;\n","import arrayMap from './_arrayMap.js';\nimport baseClone from './_baseClone.js';\nimport baseUnset from './_baseUnset.js';\nimport castPath from './_castPath.js';\nimport copyObject from './_copyObject.js';\nimport customOmitClone from './_customOmitClone.js';\nimport flatRest from './_flatRest.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\nvar omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n});\n\nexport default omit;\n","import flatten from './flatten.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\nfunction flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n}\n\nexport default flatRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","import assignValue from './_assignValue.js';\nimport baseAssignValue from './_baseAssignValue.js';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nexport default copyObject;\n","import assignValue from './_assignValue.js';\nimport castPath from './_castPath.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return object;\n }\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nexport default baseSet;\n","import arrayMap from './_arrayMap.js';\nimport baseIteratee from './_baseIteratee.js';\nimport basePickBy from './_basePickBy.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\n\n/**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\nfunction pickBy(object, predicate) {\n if (object == null) {\n return {};\n }\n var props = arrayMap(getAllKeysIn(object), function(prop) {\n return [prop];\n });\n predicate = baseIteratee(predicate);\n return basePickBy(object, props, function(value, path) {\n return predicate(value, path[0]);\n });\n}\n\nexport default pickBy;\n","import baseGet from './_baseGet.js';\nimport baseSet from './_baseSet.js';\nimport castPath from './_castPath.js';\n\n/**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\nfunction basePickBy(object, paths, predicate) {\n var index = -1,\n length = paths.length,\n result = {};\n\n while (++index < length) {\n var path = paths[index],\n value = baseGet(object, path);\n\n if (predicate(value, path)) {\n baseSet(result, castPath(path, object), value);\n }\n }\n return result;\n}\n\nexport default basePickBy;\n","import baseIteratee from './_baseIteratee.js';\nimport negate from './negate.js';\nimport pickBy from './pickBy.js';\n\n/**\n * The opposite of `_.pickBy`; this method creates an object composed of\n * the own and inherited enumerable string keyed properties of `object` that\n * `predicate` doesn't return truthy for. The predicate is invoked with two\n * arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omitBy(object, _.isNumber);\n * // => { 'b': '2' }\n */\nfunction omitBy(object, predicate) {\n return pickBy(object, negate(baseIteratee(predicate)));\n}\n\nexport default omitBy;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","import baseUnset from './_baseUnset.js';\nimport isIndex from './_isIndex.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\nfunction basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n } else {\n baseUnset(array, index);\n }\n }\n }\n return array;\n}\n\nexport default basePullAt;\n","import baseIteratee from './_baseIteratee.js';\nimport basePullAt from './_basePullAt.js';\n\n/**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\nfunction remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = baseIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n}\n\nexport default remove;\n","import type { StyleModule } from '../init';\n\n/**\n * @ignore\n */\nexport const notInTheStyle = (actionText: string): Error =>\n new Error(`Trying to ${actionText} while it is not in the map style. Did you exclude it when loading the map?`);\n\n/**\n * @ignore\n */\nexport const cannotAddStyleModuleToCustomStyle = (styleModule: StyleModule): Error =>\n new Error(`Trying to add style module ${styleModule} to the custom style!`);\n","/**\n * @ignore\n */\nexport const isDOMImageSupported = (): boolean =>\n typeof document != 'undefined' && typeof DOMParser != 'undefined' && typeof btoa != 'undefined';\n\n/**\n * @ignore\n */\nexport const svgToImg = (svgDomElement: SVGElement): HTMLImageElement => {\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const img = document.createElement('img');\n img.src = `data:image/svg+xml;base64,${btoa(new XMLSerializer().serializeToString(svgDomElement))}`;\n return img;\n};\n","import { SVGIconStyleOptions } from '../types';\nimport pinSvgRaw from './pin.svg?raw';\n\n/**\n * Helper function to parse SVG string (typically imported from ...svg?raw) to SVGElement\n * @ignore\n */\nexport const parseSvg = (svgString: string): SVGElement =>\n new DOMParser().parseFromString(svgString, 'image/svg+xml').documentElement as unknown as SVGElement;\n\n/**\n * @ignore\n */\nexport const pinSvg = (options: SVGIconStyleOptions | undefined): SVGElement => {\n const element = parseSvg(pinSvgRaw);\n // see pin.svg structure\n if (options?.fillColor) {\n element.querySelector('#background')?.setAttribute('fill', options.fillColor);\n }\n if (options?.outlineColor) {\n element.querySelector('#outline')?.setAttribute('fill', options.outlineColor);\n }\n if (options?.outlineOpacity !== undefined) {\n element.querySelector('#outline')?.setAttribute('fill-opacity', options.outlineOpacity.toString());\n }\n return element;\n};\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path id=\\\"background\\\" d=\\\"M63.95 137.516c6.556-12.737 19.098-21.09 30.828-29.388C110.046 97.324 120 79.603 120 59.574 120 26.671 93.138 0 60 0S0 26.671 0 59.574c0 20.029 9.954 37.75 25.22 48.55 11.734 8.302 24.274 16.652 30.83 29.388 1.706 3.316 6.194 3.316 7.9 0z\\\"\\n fill=\\\"#1988cf\\\"/>\\n <path id=\\\"outline\\\" d=\\\"M91.298 103.272C105.052 93.544 114 77.596 114 59.574c0-29.61-24.176-53.617-54-53.617S6 29.964 6 59.574c0 18.022 8.95 33.97 22.7 43.698l2.27 1.601c10.172 7.153 21.922 15.423 29.03 27.416 7.104-11.993 18.858-20.259 29.03-27.416l2.268-1.601zm1.468 6.274c-11.13 7.845-22.632 15.957-28.816 27.966-1.706 3.316-6.194 3.316-7.9 0-6.182-12.009-17.686-20.121-28.816-27.966l-2.016-1.422C9.954 97.324 0 79.603 0 59.574 0 26.671 26.862 0 60 0s60 26.671 60 59.574c0 20.029-9.954 37.75-25.222 48.55l-2.016 1.422z\\\"\\n fill-opacity=\\\".3\\\"/>\\n</svg>\\n\"","import { isNil } from 'lodash-es';\n\n/**\n * Throws an error if the given value is not defined.\n * @ignore\n */\nexport function assertDefined<T>(value: T | null | undefined): asserts value is T {\n if (isNil(value)) {\n throw new Error(`${value} must not be null/undefined. Something went wrong with its initialization.`);\n }\n}\n\n/**\n * Returns the given value as its defined type, or throws an error if it isn't defined.\n * @ignore\n * @throws\n */\nexport const asDefined = <T>(value: T | null | undefined): T => {\n assertDefined(value);\n return value;\n};\n","import type { Map, Source, SourceSpecification } from 'maplibre-gl';\n\n/**\n * Contains a source relevant for TomTom Maps SDK JS.\n * * The source might already be initialized from the map style, or it might be initialized here.\n * @ignore\n */\nexport class TomTomMapSource<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> {\n constructor(\n readonly id: string,\n readonly spec?: SOURCE_SPEC,\n public runtimeSource?: RUNTIME_SOURCE,\n ) {}\n\n ensureAddedToMap(map: Map) {\n if (!this.runtimeSource) {\n if (!map.getSource(this.id) && this.spec) {\n map.addSource(this.id, this.spec);\n }\n this.runtimeSource = map.getSource(this.id) as RUNTIME_SOURCE;\n }\n }\n}\n","import type { FeatureCollection } from 'geojson';\nimport type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n LayerSpecification,\n Map,\n Source,\n SourceSpecification,\n} from 'maplibre-gl';\nimport { asDefined } from './assertionUtils';\nimport { TomTomMapSource } from './TomTomMapSource';\nimport type {\n ByIdOrIndex,\n CleanEventStateOptions,\n CleanEventStatesOptions,\n LayerSpecFilter,\n LayerSpecWithSource,\n PutEventStateOptions,\n SourceWithLayerIDs,\n SourceWithLayers,\n ToBeAddedLayerSpec,\n ToBeAddedLayerSpecWithoutSource,\n} from './types';\n\n/**\n * Contains a source and the layers to render its data.\n * @ignore\n */\nexport abstract class AbstractSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n LAYER_SPEC extends LayerSpecification = LayerSpecification,\n> {\n readonly _layerSpecs: LAYER_SPEC[];\n private _sourceAndLayerIDs!: SourceWithLayerIDs;\n\n constructor(\n readonly map: Map,\n readonly source: TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>,\n layerSpecs: LAYER_SPEC[],\n ) {\n this._layerSpecs = layerSpecs;\n this._updateSourceAndLayerIDs();\n }\n\n isAnyLayerVisible(filter?: LayerSpecFilter): boolean {\n return this.getLayerSpecs(filter).some((layer) => this.isLayerVisible(layer));\n }\n\n areAllLayersVisible(filter?: LayerSpecFilter): boolean {\n return this.getLayerSpecs(filter).every((layer) => this.isLayerVisible(layer));\n }\n\n private getLayerSpecs(filter?: LayerSpecFilter) {\n return filter ? this._layerSpecs.filter(filter) : this._layerSpecs;\n }\n\n _updateSourceAndLayerIDs(): void {\n this._sourceAndLayerIDs = { sourceID: this.source.id, layerIDs: this._layerSpecs.map((layer) => layer.id) };\n }\n\n private isLayerVisible(layer: LayerSpecification): boolean {\n return this.map.getLayoutProperty(layer.id, 'visibility') !== 'none';\n }\n\n setLayersVisible(visible: boolean, filter?: LayerSpecFilter): void {\n for (const layerSpec of this.getLayerSpecs(filter)) {\n this.map.setLayoutProperty(layerSpec.id, 'visibility', visible ? 'visible' : 'none', { validate: false });\n }\n }\n\n get sourceAndLayerIDs(): SourceWithLayerIDs {\n return this._sourceAndLayerIDs;\n }\n\n equalSourceAndLayerIDs(other: SourceWithLayers): boolean {\n return (\n this.sourceAndLayerIDs.sourceID === other.sourceAndLayerIDs.sourceID &&\n this.sourceAndLayerIDs.layerIDs.length === other.sourceAndLayerIDs.layerIDs.length &&\n this.sourceAndLayerIDs.layerIDs.every((id, index) => id === other.sourceAndLayerIDs.layerIDs[index])\n );\n }\n}\n\n/**\n * @ignore\n * @param loadedMap\n * @param sourceIDs\n */\nexport const filterLayersBySources = (loadedMap: Map, sourceIDs: string[]): LayerSpecWithSource[] =>\n loadedMap\n .getStyle()\n .layers.filter((layer) => sourceIDs.includes((layer as LayerSpecWithSource)?.source)) as LayerSpecWithSource[];\n\n/**\n * Source with layers which are coming from the downloaded TT map style.\n * * Examples are parts of the base map, traffic, pois, and hillshade.\n * @ignore\n */\nexport class StyleSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> extends AbstractSourceWithLayers<SourceSpecification, RUNTIME_SOURCE> {\n constructor(map: Map, runtimeSource: RUNTIME_SOURCE, filter?: LayerSpecFilter) {\n let layers = filterLayersBySources(map, [runtimeSource.id]);\n if (filter) {\n layers = layers.filter(filter);\n }\n super(\n map,\n new TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>(\n runtimeSource.id,\n map.getStyle().sources[runtimeSource.id] as SOURCE_SPEC,\n runtimeSource,\n ),\n layers,\n );\n }\n}\n\n/**\n * Source with layers which originally is not in the map style, but it's to be added after the map is initialized.\n * @ignore\n */\nexport class AddedSourceWithLayers<\n SOURCE_SPEC extends SourceSpecification = SourceSpecification,\n RUNTIME_SOURCE extends Source = Source,\n> extends AbstractSourceWithLayers<SOURCE_SPEC, RUNTIME_SOURCE, ToBeAddedLayerSpec> {\n constructor(map: Map, sourceId: string, sourceSpec: SOURCE_SPEC, layerSpecs: ToBeAddedLayerSpecWithoutSource[]) {\n super(\n map,\n new TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>(sourceId, sourceSpec),\n // We ensure the source ID is assigned to the layers:\n layerSpecs.map((layerSpec) => ({ ...layerSpec, source: sourceId }) as ToBeAddedLayerSpec),\n );\n }\n\n private ensureLayersAddedToMap(): void {\n for (const layerSpec of this._layerSpecs) {\n if (!this.map.getLayer(layerSpec.id)) {\n this.map.addLayer(layerSpec, layerSpec.beforeID);\n }\n }\n }\n\n ensureAddedToMapWithVisibility(visible: boolean, addLayersToMap: boolean): void {\n this.source.ensureAddedToMap(this.map);\n if (addLayersToMap) {\n this.ensureLayersAddedToMap();\n this.setLayersVisible(visible);\n }\n }\n}\n\nconst emptyFeatureCollection: FeatureCollection = { type: 'FeatureCollection', features: [] };\n\n/**\n * @ignore\n */\nexport class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<\n GeoJSONSourceSpecification,\n GeoJSONSource\n> {\n shownFeatures: T = emptyFeatureCollection as T;\n\n constructor(map: Map, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap = true) {\n // MapLibre does not reuse the given feature ID. Either we generate it on the fly or use the one from properties via promotedId value.\n // We must generate \"id\" property based on the feature id on the fly on \"prepareForDisplay\" functions.\n super(map, sourceId, { type: 'geojson', data: emptyFeatureCollection, promoteId: 'id' }, layerSpecs);\n this.ensureAddedToMapWithVisibility(false, addLayersToMap);\n }\n\n show(featureCollection: T): void {\n this.shownFeatures = featureCollection;\n asDefined(this.source.runtimeSource).setData(featureCollection);\n this.setLayersVisible(!!featureCollection.features.length);\n }\n\n clear(): void {\n this.show(emptyFeatureCollection as T);\n }\n\n private findFeature(options: ByIdOrIndex) {\n if ('index' in options) {\n return this.shownFeatures.features[options.index];\n } else if ('id' in options) {\n return this.shownFeatures.features.find((f) => f.id === options.id);\n }\n return undefined;\n }\n\n putEventState(options: PutEventStateOptions) {\n const mode = options.mode ?? 'put';\n if (mode === 'put') {\n for (const feature of this.shownFeatures.features) {\n if (feature.properties?.eventState === options.state) {\n delete feature.properties.eventState;\n }\n }\n }\n\n const feature = this.findFeature(options);\n if (feature) {\n feature.properties = { ...feature.properties, eventState: options.state };\n }\n\n if (options.show !== false) {\n this.show(this.shownFeatures);\n }\n }\n\n cleanEventState(options: CleanEventStateOptions) {\n const feature = this.findFeature(options);\n\n if (feature?.properties?.eventState) {\n delete feature?.properties?.eventState;\n if (options?.show !== false) {\n this.show(this.shownFeatures);\n }\n }\n }\n\n cleanEventStates(options?: CleanEventStatesOptions) {\n let changed = false;\n for (const feature of this.shownFeatures.features) {\n if (!options?.states || options.states.includes(feature.properties?.eventState)) {\n delete feature.properties?.eventState;\n changed = true;\n }\n }\n\n if (options?.show !== false && changed) {\n this.show(this.shownFeatures);\n }\n }\n}\n","import type { GlobalConfig } from '@tomtom-org/maps-sdk/core';\nimport { generateTomTomHeaders } from '@tomtom-org/maps-sdk/core';\nimport type {\n FilterSpecification,\n Map,\n MapGeoJSONFeature,\n RequestParameters,\n ResourceType,\n StyleImageMetadata,\n} from 'maplibre-gl';\nimport { InternalTomTomMapParams, StandardStyle, StandardStyleID, StyleInput, StyleModule } from '../init';\nimport type { TomTomMap } from '../TomTomMap';\nimport { cannotAddStyleModuleToCustomStyle } from './errorMessages';\nimport { svgToImg } from './imageUtils';\nimport { parseSvg } from './resources';\nimport { AbstractSourceWithLayers, filterLayersBySources } from './SourceWithLayers';\nimport type { LightDark, ToBeAddedLayerSpec, ToBeAddedLayerSpecWithoutSource } from './types';\n\n/**\n * Wait until the map is ready.\n * @param tomtomMap The TomTomMap instance.\n * @returns {Promise<boolean>} Returns a Promise<boolean>\n */\nexport const waitUntilMapIsReady = async (tomtomMap: TomTomMap): Promise<void> => {\n if (!tomtomMap.mapReady) {\n await tomtomMap.mapLibreMap.once('styledata');\n // Recursively waiting for map to be ready (in case of style changes quickly in succession):\n await waitUntilMapIsReady(tomtomMap);\n }\n};\n\n/**\n * Wait until the source is ready.\n * @param tomtomMap The TomTomMap instance.\n * @param sourceId we want to check for.\n * @returns {Promise<boolean>} Returns a Promise<boolean>\n */\nexport const waitUntilSourceIsLoaded = async (tomtomMap: TomTomMap, sourceId: string): Promise<void> => {\n if (!tomtomMap.mapLibreMap.getSource(sourceId) || !tomtomMap.mapLibreMap.isSourceLoaded(sourceId)) {\n await tomtomMap.mapLibreMap.once('sourcedata');\n }\n};\n\n/**\n * Deserializes the properties from MapLibre features.\n * * Maplibre has a bug where all properties from a feature are stringified.\n * See: {@link} https://github.com/maplibre/maplibre-gl-js/issues/1325\n *\n * @param features An Array with MapGeoJSONFeatures objects\n *\n * @ignore\n */\nexport const deserializeFeatures = (features: MapGeoJSONFeature[]): void => {\n for (const feature of features) {\n if (!feature || !Object.keys(feature.properties).length) {\n continue;\n }\n\n for (const key in feature.properties) {\n if (typeof feature.properties[key] === 'string') {\n try {\n feature.properties[key] = JSON.parse(feature.properties[key]);\n } catch (_e) {\n // We ignore the error if the object can't be parsed and continue.\n // console.debug('Cannot deserialize feature property', key, 'with value', feature.properties[key], e);\n }\n }\n }\n }\n};\n\n/**\n * Inject TomTom custom headers to requests to TomTom.\n *\n * @ignore\n * @param params Global SDK Map configuration\n */\nexport const injectTomTomHeaders =\n (params: Partial<GlobalConfig>) =>\n (url: string, resourceType?: ResourceType): RequestParameters => {\n if (url.includes('tomtom.com')) {\n if (resourceType === 'Image') {\n return { url };\n }\n return { url, headers: { ...generateTomTomHeaders(params) } };\n }\n return { url };\n };\n\n/**\n * Compares two MapLibre features by ID.\n * @ignore\n */\nexport const areBothDefinedAndEqual = (\n featureA: MapGeoJSONFeature | undefined,\n featureB: MapGeoJSONFeature | undefined,\n): boolean => !!featureA && !!featureB && featureA.id === featureB.id;\n\ntype LayerProps = {\n id: string;\n layout?: any;\n paint?: any;\n minzoom?: number;\n maxzoom?: number;\n filter?: FilterSpecification;\n};\n\n/**\n * Applies the layout and paint properties from newLayoutPaint\n * while unsetting (setting as undefined) the ones from previousSpec which no longer exist in newLayoutPaint.\n * * This allows for a quick change of a layer visuals without removing-re-adding the layer.\n * @ignore\n * @param newLayerProps The new layer from which to apply layout/pain props.\n * @param prevLayerProps The previous layer to ensure layout/paint props are removed.\n * @param map\n */\nexport const changeLayerProps = (newLayerProps: LayerProps, prevLayerProps: LayerProps, map: Map) => {\n const layerId = newLayerProps.id;\n if (newLayerProps.maxzoom !== prevLayerProps.maxzoom || newLayerProps.minzoom !== prevLayerProps.minzoom) {\n map.setLayerZoomRange(\n layerId,\n newLayerProps.minzoom ?? map.getMinZoom(),\n newLayerProps.maxzoom ?? map.getMaxZoom(),\n );\n }\n map.setFilter(layerId, newLayerProps.filter, { validate: false });\n for (const property of Object.keys(prevLayerProps.layout ?? [])) {\n if (!newLayerProps.layout?.[property]) {\n map.setLayoutProperty(layerId, property, undefined, { validate: false });\n }\n }\n for (const property of Object.keys(prevLayerProps.paint ?? [])) {\n if (!newLayerProps.paint?.[property]) {\n map.setPaintProperty(layerId, property, undefined, { validate: false });\n }\n }\n for (const [property, value] of Object.entries(newLayerProps.paint ?? [])) {\n map.setPaintProperty(layerId, property, value, { validate: false });\n }\n\n for (const [property, value] of Object.entries(newLayerProps.layout ?? [])) {\n map.setLayoutProperty(layerId, property, value, { validate: false });\n }\n};\n\n/**\n * Applies the layer properties from each layer of newLayoutPaints\n * while unsetting (setting as undefined) the ones from the corresponding layer from prevLayoutPaints\n * which no longer exist in the new one.\n * * The two layer inputs are expected to be parallel arrays.\n * * This allows for quick changes of layer visuals without removing-re-adding the layers.\n * @ignore\n */\nexport const changeLayersProps = (newLayerProps: LayerProps[], prevLayerProps: LayerProps[], map: Map) => {\n newLayerProps.forEach((layoutPaint, index) => changeLayerProps(layoutPaint, prevLayerProps[index], map));\n};\n\n/**\n * Handles new layer specs for the provided source. It will remove layers no longer present,\n * update existing layers and add new one if needed to the source.\n * Adding layers to the map needs to be done correctly, so after calling this method, you should call addLayersInCorrectOrder.\n * If ID of layer to be added already is present on map, MapLibre will through exception.\n * @param newLayersSpecs new layer specification for provided source.\n * @param oldLayersSpecs current layer specification for provided source.\n * @param sourceWithLayers provided source that contains layers.\n * @param map provided map libre map object.\n * @ignore\n */\nexport const updateLayersAndSource = (\n newLayersSpecs: ToBeAddedLayerSpecWithoutSource[],\n oldLayersSpecs: ToBeAddedLayerSpecWithoutSource[],\n sourceWithLayers: AbstractSourceWithLayers,\n map: Map,\n): void => {\n // map layers by id in object for easier access, reduces number of loops\n const newLayersMap: Record<string, ToBeAddedLayerSpecWithoutSource> = newLayersSpecs.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {},\n );\n const oldLayersMap: Record<string, ToBeAddedLayerSpecWithoutSource> = oldLayersSpecs.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {},\n );\n\n // we need to store layers in four arrays, layers to add ID, layers to remove ID and layers to update\n const layersToAdd: string[] = [];\n const layersToRemove: string[] = [];\n const newLayersToUpdate: ToBeAddedLayerSpecWithoutSource[] = [];\n const oldLayersToUpdate: ToBeAddedLayerSpecWithoutSource[] = [];\n Object.keys(newLayersMap).forEach((key) => {\n if (oldLayersMap[key]) {\n newLayersToUpdate.push(newLayersMap[key]);\n oldLayersToUpdate.push(oldLayersMap[key]);\n } else {\n layersToAdd.push(key);\n }\n });\n Object.keys(oldLayersMap).forEach((key) => {\n if (!newLayersMap[key]) {\n layersToRemove.push(key);\n }\n });\n\n // remove the old layers no longer present in new layer specification\n const layerSpecs: ToBeAddedLayerSpec[] = sourceWithLayers._layerSpecs;\n layersToRemove.forEach((layerId) => {\n map.removeLayer(layerId);\n for (let i = 0; i < layerSpecs.length; i++) {\n if (layerSpecs[i].id === layerId) {\n layerSpecs.splice(i, 1);\n break;\n }\n }\n });\n // add new layers\n layersToAdd.forEach((layerId) => {\n // add layer spec and map\n const toBeAddedLayerSpec: ToBeAddedLayerSpec = {\n ...newLayersMap[layerId],\n source: sourceWithLayers.source.id,\n } as ToBeAddedLayerSpec;\n layerSpecs.push(toBeAddedLayerSpec);\n });\n sourceWithLayers._updateSourceAndLayerIDs();\n // update existing layers\n changeLayersProps(newLayersToUpdate, oldLayersToUpdate, map);\n};\n\n/**\n * Adds the given layers to the map ensuring they respect their \"beforeID\" properties.\n * * We need to make sure that layers are added in the correct Z order because one layer may depend on another layer.\n * @param layersToAdd\n * @param map MapLibre map\n * @ignore\n */\nexport const addLayers = (layersToAdd: ToBeAddedLayerSpec[], map: Map): void => {\n const layerIdsAlreadyOnMap = new Set<string>();\n const addLayer = (layer: ToBeAddedLayerSpec): void => {\n // we can safely add this layer\n if (!map.getLayer(layer.id)) {\n map.addLayer({ ...layer, layout: { ...layer.layout, visibility: 'none' } }, layer.beforeID);\n }\n layerIdsAlreadyOnMap.add(layer.id);\n };\n\n const mapIdDependency: Record<string, ToBeAddedLayerSpec[]> = {};\n\n layersToAdd.forEach((layer) => {\n if (layer.beforeID) {\n if (layerIdsAlreadyOnMap.has(layer.beforeID) || map.getLayer(layer.beforeID)) {\n layerIdsAlreadyOnMap.add(layer.beforeID);\n addLayer(layer);\n } else if (mapIdDependency[layer.beforeID]) {\n // we cannot add this layer yet\n mapIdDependency[layer.beforeID].push(layer);\n } else {\n mapIdDependency[layer.beforeID] = [layer];\n }\n } else {\n addLayer(layer);\n }\n });\n\n // try to process the rest of layers\n while (Object.keys(mapIdDependency).length > 0) {\n const idsWeCanProcess = Object.keys(mapIdDependency).filter((id) => layerIdsAlreadyOnMap.has(id));\n if (!idsWeCanProcess.length) {\n console.error(\n `Some layers cannot be added. Check for non-existing layers, or circular beforeID dependencies for the following: ${JSON.stringify(Object.keys(mapIdDependency))}`,\n );\n return;\n }\n idsWeCanProcess.forEach((id) => {\n mapIdDependency[id].forEach((layer) => addLayer(layer));\n delete mapIdDependency[id];\n });\n }\n};\n\n/**\n * Adding a style-based module to the given style input, if possible.\n * * This results in a style input which will include such style-based module (e.g. include traffic layers).\n * @param style which we want to update.\n * @param styleModule module we want to add.\n * @ignore\n */\nexport const updateStyleWithModule = (style: StyleInput | undefined, styleModule: StyleModule): StyleInput => {\n switch (typeof style) {\n case 'undefined':\n return { type: 'standard', include: [styleModule] };\n case 'string':\n // this is a standard style\n return { type: 'standard', id: style, include: [styleModule] };\n default:\n if (style.type === 'standard') {\n if (style.include) {\n return { ...style, include: [...style.include, styleModule] };\n }\n return { ...style, include: [styleModule] };\n }\n throw cannotAddStyleModuleToCustomStyle(styleModule);\n }\n};\n\n/**\n * Checks if the source is missing and try to add it to the map by reloading its style.\n * @param map the TomTom map instance.\n * @param sourceId id of the source.\n * @param styleModule style module of the source.\n * @ignore\n */\nexport const ensureAddedToStyle = async (map: TomTomMap, sourceId: string, styleModule: StyleModule): Promise<void> => {\n if (!map.mapLibreMap.getSource(sourceId)) {\n const mapLibreMap = map.mapLibreMap;\n if (!mapLibreMap.isStyleLoaded()) {\n // we let the map settle before changing its style again, so the previous style/data load goes smoother:\n await mapLibreMap.once('idle');\n }\n map.setStyle(updateStyleWithModule(map.getStyle(), styleModule));\n await waitUntilSourceIsLoaded(map, sourceId);\n\n await mapLibreMap.once('styledata');\n // we're loading a bunch of style layers to the map, and we hide them all by default:\n // see TomTomMap.handleStyleData for similar logic\n for (const layer of filterLayersBySources(mapLibreMap, [sourceId])) {\n mapLibreMap.setLayoutProperty(layer.id, 'visibility', 'none', { validate: false });\n }\n // Since we just changed the style visibility, we ensure to wait until the style data is changed before returning to prevent race conditions:\n await mapLibreMap.once('styledata');\n }\n};\n\n/**\n * Sets the given image on the map (loading it if necessary), either adding or updating it.\n * @ignore\n */\nexport const addOrUpdateImage = async (\n mode: 'if-not-in-sprite' | 'add-or-update',\n imageId: string,\n imageToLoad: string | HTMLImageElement,\n map: Map,\n options?: Partial<StyleImageMetadata>,\n) => {\n // defensive check (should not happen but we cannot let it crash):\n if (!imageToLoad) {\n console.warn(`addOrUpdateImage called with empty image for ID ${imageId}`);\n return;\n }\n\n // Helper function to add or update the image\n const addOrUpdateToMap = (imgElement: HTMLImageElement | ImageData | ImageBitmap) => {\n const imageExists = map.hasImage(imageId);\n if (imageExists && mode == 'add-or-update') {\n map.updateImage(imageId, imgElement);\n } else if (!imageExists) {\n map.addImage(imageId, imgElement, options);\n }\n };\n\n const ensureImageLoaded = (imgElement: HTMLImageElement) => {\n // An image is successfully loaded if it's complete AND has valid dimensions\n // (naturalWidth > 0 ensures the image didn't fail to load)\n if (imgElement.complete) {\n if (imgElement.naturalWidth > 0) {\n addOrUpdateToMap(imgElement);\n } else {\n // Image is complete but failed to load\n console.warn(`Failed to load image for ID ${imageId}`);\n }\n } else {\n imgElement.onload = () => addOrUpdateToMap(imgElement);\n imgElement.onerror = () => console.warn(`Failed to load image for ID ${imageId}`);\n }\n };\n\n if (typeof imageToLoad === 'string') {\n if (imageToLoad.includes('<svg')) {\n // Supporting raw SVGs:\n const imgElement = svgToImg(parseSvg(imageToLoad));\n ensureImageLoaded(imgElement);\n } else {\n // Expecting image URL, so the image needs to be downloaded first:\n addOrUpdateToMap((await map.loadImage(imageToLoad)).data);\n }\n } else {\n // Expecting HTMLImageElement, wait for it to be loaded\n ensureImageLoaded(imageToLoad);\n }\n};\n\n/**\n * Returns the light/dark theme for a known standard style.\n * @param standardStyleID\n */\nconst getStandardStyleTheme = (standardStyleID: StandardStyleID): LightDark => {\n switch (standardStyleID) {\n case 'standardDark':\n case 'drivingDark':\n case 'monoDark':\n case 'satellite':\n return 'dark';\n default:\n return 'light';\n }\n};\n\n/**\n * Returns the light/dark theme for a given style input.\n * * Unknown standard styles and custom styles are considered as 'light' theme.\n * @param styleInput The style input to check. If not provided, 'light' is returned.\n * @ignore\n */\nexport const getStyleLightDarkTheme = (styleInput?: StyleInput): LightDark => {\n if (typeof styleInput === 'string') {\n return getStandardStyleTheme(styleInput);\n }\n const standardStyle = styleInput as StandardStyle;\n if (standardStyle?.id) {\n return getStandardStyleTheme(standardStyle.id);\n }\n return 'light';\n};\n\n/**\n * Adds the large POI sprite to the map style.\n * @ignore\n */\nexport const addPinCategoriesSpriteToStyle = async (mapParams: InternalTomTomMapParams, mapLibreMap: Map) => {\n mapLibreMap.setSprite(\n `${mapParams.commonBaseURL}/maps/orbis/assets/sprites/2.*/sprite?key=${mapParams.apiKey}&poi=poi_${getStyleLightDarkTheme(mapParams.style)}&apiVersion=1&apiChannel=preview`,\n { validate: false },\n );\n};\n","import type { Map } from 'maplibre-gl';\nimport type { TomTomMap } from '../TomTomMap';\nimport type { EventsProxy } from './EventsProxy';\nimport { waitUntilMapIsReady } from './mapUtils';\nimport type { MapModuleCommonConfig, SourcesWithLayers, SourceWithLayerIDs } from './types';\n\n/**\n * Whether a map module is based on a map style or on added GeoJSON data.\n */\ntype MapModuleSource = 'style' | 'geojson';\n\n/**\n * Base class for all Maps SDK map modules.\n *\n * This abstract class provides the foundation for creating map modules that can display\n * and manage various types of data on a TomTom map. It handles module lifecycle management,\n * including initialization, configuration updates, and automatic restoration after map style changes.\n *\n * @remarks\n * All map modules extend this class to ensure consistent behavior across the SDK.\n * The class manages the module's sources, layers, and configuration, automatically\n * handling map style changes by restoring the module's state when needed.\n *\n * @typeParam SOURCES_WITH_LAYERS - The type defining the sources and layers used by this module\n * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed. When defined, must extend MapModuleCommonConfig.\n *\n * @example\n * ```typescript\n * class CustomModule extends AbstractMapModule<MySourcesWithLayers, MyConfig> {\n * constructor(tomtomMap: TomTomMap, config?: MyConfig) {\n * super('geojson', tomtomMap, config);\n * }\n * // Implement abstract methods...\n * }\n * ```\n *\n * @group Shared\n */\nexport abstract class AbstractMapModule<\n SOURCES_WITH_LAYERS extends SourcesWithLayers,\n CFG extends MapModuleCommonConfig | undefined = undefined,\n> {\n private readonly sourceType: MapModuleSource;\n /**\n * @ignore\n */\n protected readonly tomtomMap: TomTomMap;\n /**\n * @ignore\n */\n protected readonly eventsProxy: EventsProxy;\n /**\n * @ignore\n */\n protected readonly mapLibreMap: Map;\n /**\n * @ignore\n */\n protected sourcesWithLayers!: SOURCES_WITH_LAYERS;\n /**\n * @ignore\n */\n protected _sourceAndLayerIDs!: Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;\n /**\n * @ignore\n */\n protected config?: CFG;\n /**\n * @ignore\n */\n protected _initializing = true;\n\n /**\n * Indicates that this module is currently adding its sources and layers to the map, so during this time it might not function properly.\n * @see waitUntilModuleReady\n * @private\n */\n private moduleReady = false;\n\n /**\n * Builds this module based on a given Maps SDK map.\n * @param tomtomMap The map. It may or may not be initialized at this stage,\n * but the module ensures to initialize itself once it is.\n * @param sourceType Whether the module is based on a map style or on added GeoJSON data.\n * @param config Optional configuration to initialize directly as soon as the map is ready.\n */\n protected constructor(sourceType: MapModuleSource, tomtomMap: TomTomMap, config?: CFG) {\n this.sourceType = sourceType;\n this.tomtomMap = tomtomMap;\n this.eventsProxy = tomtomMap._eventsProxy;\n this.mapLibreMap = tomtomMap.mapLibreMap;\n // TODO: we need to find a cleaner separation between initSourcesWithLayers and applyConfig for most modules to prevent double work, particularly with adding layers\n this.initSourcesWithLayers(config);\n this.applyConfig(config);\n this.tomtomMap.addStyleChangeHandler({\n onStyleAboutToChange: () => {\n this.moduleReady = false;\n },\n onStyleChanged: () => this.restoreDataAndConfig(),\n });\n this._initializing = false;\n }\n\n /**\n * Initializes the sources with layers of this module.\n * @param config The optional configuration for the module.\n * @param restore Whether we are restoring an existing module after the map style got reloaded.\n * @protected\n * @ignore\n */\n protected initSourcesWithLayers(config?: CFG, restore?: boolean): void {\n this.moduleReady = false;\n this.sourcesWithLayers = this._initSourcesWithLayers(config, restore);\n this._sourceAndLayerIDs = Object.fromEntries(\n Object.entries(this.sourcesWithLayers).map(([name, sourceWithLayers]) => [\n name,\n sourceWithLayers.sourceAndLayerIDs,\n ]),\n ) as Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;\n if (restore) {\n this.eventsProxy.updateIfRegistered(this.sourcesWithLayers);\n }\n // Only if the map is still ready, we consider that the module is ready.\n // Otherwise, we assume there's a quick style change in progress and expect that'll trigger the module to restore itself again.\n if (this.tomtomMap.mapReady) {\n this.moduleReady = true;\n }\n }\n\n /**\n * Initializes the sources with layers for the specific module.\n * @protected\n * @ignore\n */\n protected abstract _initSourcesWithLayers(config?: CFG, restore?: boolean): SOURCES_WITH_LAYERS;\n\n protected async waitUntilModuleReady(): Promise<void> {\n await waitUntilMapIsReady(this.tomtomMap);\n if (!this.moduleReady) {\n await new Promise<void>((resolve) => {\n const interval = setInterval(() => {\n if (this.tomtomMap.mapReady && this.moduleReady) {\n clearInterval(interval);\n resolve();\n }\n }, 200);\n });\n }\n }\n\n /**\n * Applies a configuration to this module.\n *\n * This method updates the module's behavior and appearance based on the provided configuration.\n * The configuration is stored internally and will be automatically reapplied if the map style changes.\n *\n * @param config - The configuration object to apply to the module. Pass `undefined` to reset\n * the configuration to default values.\n *\n * @remarks\n * When a configuration is applied, the module updates its visual representation and behavior\n * accordingly. The configuration persists across map style changes, ensuring consistent\n * module behavior even when the map's base style is modified.\n *\n * @example\n * ```typescript\n * // Apply a new configuration\n * myModule.applyConfig({ visible: true, opacity: 0.8 });\n *\n * // Reset to default configuration\n * myModule.applyConfig(undefined);\n * ```\n *\n * @see {@link resetConfig} for a convenience method to reset configuration\n * @see {@link getConfig} to retrieve the current configuration\n */\n applyConfig(config: CFG | undefined) {\n this.config = this._applyConfig(config);\n }\n\n /**\n * Internal implementation to apply config for the specific module.\n * @param config The config to apply. this.config contains the previous configuration (if any).\n * Once the method returns config, it will be assigned to this.config.\n * @protected\n * @ignore\n */\n protected abstract _applyConfig(config: CFG | undefined): CFG | undefined;\n\n /**\n * Resets the configuration of this module to its default values.\n *\n * This is a convenience method that clears any previously applied configuration\n * and restores the module to its initial state. This is equivalent to calling\n * `applyConfig(undefined)`.\n *\n * @remarks\n * After calling this method, the module will behave as if no configuration was ever applied.\n * Any custom settings, styling, or behavior modifications will be removed and replaced\n * with default values.\n *\n * @example\n * ```typescript\n * // Apply some configuration\n * myModule.applyConfig({ visible: true, opacity: 0.5 });\n *\n * // Later, reset to defaults\n * myModule.resetConfig();\n * ```\n *\n * @see {@link applyConfig} to apply a new configuration\n * @see {@link getConfig} to retrieve the current configuration before resetting\n */\n resetConfig(): void {\n this.applyConfig(undefined);\n }\n\n private async restoreDataAndConfig() {\n // defensively declaring the module as not ready to prevent race conditions:\n this.moduleReady = false;\n if (this.sourceType === 'geojson') {\n // (We use setTimeout to compensate for a MapLibre glitch where symbol layers can't get added right after\n // a styledata event. With this setTimeout, we wait just a tiny bit more which mitigates the issue)\n setTimeout(() => this.restoreDataAndConfigImpl(), 400);\n } else {\n this.restoreDataAndConfigImpl();\n }\n }\n\n /**\n * implementation needed to restore the module state (data and config applied to the module).\n * to be used to restore module state after map style change\n * @protected\n * @ignore\n */\n protected restoreDataAndConfigImpl(): void {\n this.initSourcesWithLayers(this.config, true);\n this._applyConfig(this.config);\n }\n\n /**\n * Retrieves a copy of the current module configuration.\n *\n * This method returns a shallow copy of the configuration object that is currently\n * applied to the module. If no configuration has been applied, it returns `undefined`.\n *\n * @returns A shallow copy of the current configuration object, or `undefined` if no\n * configuration is currently applied. The returned object is a copy to prevent\n * unintended modifications to the internal state.\n *\n * @remarks\n * The returned configuration object is a shallow copy, which means that while the\n * top-level properties are copied, any nested objects or arrays are still referenced\n * from the original configuration. This is sufficient for most use cases but should\n * be kept in mind when dealing with complex configurations.\n *\n * @example\n * ```typescript\n * // Apply a configuration\n * myModule.applyConfig({ visible: true, opacity: 0.8 });\n *\n * // Later, retrieve the current configuration\n * const currentConfig = myModule.getConfig();\n * console.log(currentConfig); // { visible: true, opacity: 0.8 }\n *\n * // When no config is applied\n * myModule.resetConfig();\n * console.log(myModule.getConfig()); // undefined\n * ```\n *\n * @see {@link applyConfig} to modify the configuration\n * @see {@link resetConfig} to clear the configuration\n */\n getConfig() {\n return this.config && { ...this.config };\n }\n\n /**\n * Gets the source and layer identifiers for all sources managed by this module.\n *\n * This property provides access to the MapLibre source and layer IDs that were created\n * and are managed by this module. These IDs can be used to interact directly with\n * MapLibre's API or to identify which layers belong to this module.\n *\n * @returns A record mapping each source name to its corresponding source ID and layer IDs.\n * Each entry contains the MapLibre source identifier and an array of layer identifiers\n * associated with that source.\n *\n * @remarks\n * The returned IDs are useful when you need to:\n * - Directly manipulate layers using MapLibre's native API\n * - Identify which layers on the map belong to this module\n * - Set layer ordering or positioning relative to other layers\n * - Access source or layer properties through MapLibre methods\n *\n * @example\n * ```typescript\n * const ids = myModule.sourceAndLayerIDs;\n * console.log(ids);\n * // {\n * // mySource: {\n * // sourceID: 'my-source-id',\n * // layerIDs: ['layer-1', 'layer-2']\n * // }\n * // }\n *\n * // Use with MapLibre API\n * const map = myModule.mapLibreMap;\n * ids.mySource.layerIDs.forEach(layerId => {\n * map.setLayoutProperty(layerId, 'visibility', 'visible');\n * });\n * ```\n */\n get sourceAndLayerIDs(): Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs> {\n return this._sourceAndLayerIDs;\n }\n}\n","import type { MapGeoJSONFeature } from 'maplibre-gl';\nimport type { EventsProxy } from './EventsProxy';\nimport type { EventHandlerConfig, EventType, SourceWithLayers, UserEventHandler } from './types';\n\n/**\n * Event handling interface for map features.\n *\n * Provides a simple API for attaching and removing event handlers for user interactions\n * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,\n * Places, etc.) exposes an `events` property that returns an EventsModule instance.\n *\n * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)\n *\n * @remarks\n * **Supported Event Types:**\n * - `click`: User clicks/taps on a feature\n * - `contextmenu`: User right-clicks on a feature (or long-press on mobile)\n * - `hover`: Mouse enters a feature\n * - `long-hover`: Mouse hovers over feature for configured duration (300-800ms)\n *\n * **Event Handler Signature:**\n * ```typescript\n * (feature: T, lngLat: LngLat, features: T[]) => void\n * ```\n *\n * **Parameters:**\n * - `feature`: The primary feature under the cursor\n * - `lngLat`: Geographic coordinates of the event\n * - `features`: All features at this location (when multiple overlap)\n *\n * **Key Features:**\n * - Automatic cursor management (pointer on hover)\n * - Smart event handling for overlapping features\n * - Configurable hover delays\n * - Memory-safe cleanup when removing handlers\n *\n * @example\n * ```typescript\n * // POI click handler\n * const pois = map.pois();\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('Clicked POI:', feature.properties.name);\n * console.log('Location:', lngLat);\n * showInfoWindow(feature.properties);\n * });\n *\n * // Route waypoint hover\n * const routing = map.routing();\n * routing.events.waypoints.on('hover', (waypoint) => {\n * showTooltip(`Waypoint ${waypoint.properties.index}`);\n * });\n *\n * // Long-hover for detailed info\n * pois.events.on('long-hover', (feature) => {\n * loadAndShowDetailedInfo(feature.properties.id);\n * });\n *\n * // Context menu (right-click)\n * routing.events.mainLines.on('contextmenu', (route, lngLat) => {\n * showContextMenu(lngLat, [\n * { label: 'Add waypoint here', action: () => addWaypoint(lngLat) },\n * { label: 'View route details', action: () => showDetails(route) }\n * ]);\n * });\n *\n * // Remove all click handlers\n * pois.events.off('click');\n * ```\n *\n * @example\n * ```typescript\n * // Complete interaction example\n * const places = map.places();\n *\n * // Show name on hover\n * places.events.on('hover', (place) => {\n * tooltip.show(place.properties.name);\n * });\n *\n * // Show details on click\n * places.events.on('click', (place, lngLat) => {\n * sidebar.show({\n * title: place.properties.name,\n * address: place.properties.address.freeformAddress,\n * coordinates: lngLat\n * });\n * });\n *\n * // Cleanup on component unmount\n * onUnmount(() => {\n * places.events.off('hover');\n * places.events.off('click');\n * });\n * ```\n *\n * @group User Interaction Events\n */\nexport class EventsModule<T = MapGeoJSONFeature> {\n constructor(\n private readonly eventProxy: EventsProxy,\n private readonly sourceWithLayers: SourceWithLayers,\n private readonly config: EventHandlerConfig | undefined,\n ) {}\n\n /**\n * Register an event handler for user interactions with map features.\n *\n * Attaches a callback function that will be invoked when users interact with\n * features in this module (e.g., clicking on a POI, hovering over a route).\n *\n * @param type The type of event to listen for (click, contextmenu, hover, long-hover)\n * @param handler Callback function invoked when the event occurs\n *\n * @remarks\n * **Handler Parameters:**\n * - `feature`: The primary feature that triggered the event\n * - `lngLat`: Geographic coordinates [longitude, latitude] of the event\n * - `features`: Array of all features at the event location (for overlapping features)\n *\n * **Behavior:**\n * - Only one handler per event type (calling `on()` again replaces the previous handler)\n * - Handlers are preserved across map style changes\n * - Cursor automatically changes to pointer on hover\n * - Events respect module visibility (hidden features don't trigger events)\n *\n * **Performance:**\n * - Hover events use spatial indexing for fast lookup\n * - Long-hover has configurable delay to prevent accidental triggers\n * - Event handlers should be lightweight to maintain smooth interaction\n *\n * @example\n * ```typescript\n * // Basic click handler\n * module.events.on('click', (feature, lngLat, features) => {\n * console.log('Clicked feature:', feature.properties);\n * console.log('Location:', lngLat);\n * console.log('All features here:', features.length);\n * });\n *\n * // Hover with tooltip\n * module.events.on('hover', (feature) => {\n * const name = feature.properties.name || 'Unnamed';\n * tooltip.show(name);\n * });\n *\n * // Long-hover for detailed preview\n * module.events.on('long-hover', (feature) => {\n * // Only triggered after hovering for 300-800ms\n * loadPreview(feature.properties.id);\n * });\n *\n * // Right-click context menu\n * module.events.on('contextmenu', (feature, lngLat) => {\n * event.preventDefault(); // Prevent browser context menu\n * showCustomMenu(lngLat, feature);\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Route-specific handlers\n * const routing = map.routing();\n *\n * // Handle route line clicks\n * routing.events.mainLines.on('click', (route) => {\n * highlightRoute(route.properties.routeID);\n * showRouteSummary(route.properties.summary);\n * });\n *\n * // Handle waypoint interactions\n * routing.events.waypoints.on('hover', (waypoint) => {\n * const index = waypoint.properties.index;\n * showTooltip(`Stop ${index + 1}`);\n * });\n * ```\n */\n on(type: EventType, handler: UserEventHandler<T>) {\n this.eventProxy.addEventHandler(this.sourceWithLayers, handler, type, this.config);\n }\n\n /**\n * Remove all event handlers for a specific event type.\n *\n * Unregisters the callback function for the specified event type, stopping\n * further event notifications. This is important for cleanup to prevent\n * memory leaks and unwanted behavior.\n *\n * @param type The type of event to stop listening for\n *\n * @remarks\n * **Cleanup Behavior:**\n * - Removes only the specified event type (other types remain active)\n * - Resets cursor behavior for this module\n * - Safe to call multiple times (no error if no handler exists)\n * - Does not affect other modules' event handlers\n *\n * **When to Use:**\n * - Component unmounting/cleanup\n * - Switching between interaction modes\n * - Temporarily disabling interactions\n * - Replacing an existing handler (call `off()` then `on()`)\n *\n * **Best Practices:**\n * - Always clean up event handlers when component unmounts\n * - Remove handlers before removing features from the map\n * - Use framework lifecycle hooks for automatic cleanup\n *\n * @example\n * ```typescript\n * // Remove click handlers\n * module.events.off('click');\n *\n * // Remove all handlers\n * module.events.off('click');\n * module.events.off('hover');\n * module.events.off('long-hover');\n * module.events.off('contextmenu');\n * ```\n *\n * @example\n * ```typescript\n * // React component cleanup\n * useEffect(() => {\n * const pois = map.pois();\n *\n * pois.events.on('click', handlePoiClick);\n * pois.events.on('hover', handlePoiHover);\n *\n * return () => {\n * // Cleanup on unmount\n * pois.events.off('click');\n * pois.events.off('hover');\n * };\n * }, [map]);\n * ```\n *\n * @example\n * ```typescript\n * // Replace handler\n * module.events.off('click'); // Remove old handler\n * module.events.on('click', newHandler); // Add new handler\n *\n * // Disable interactions temporarily\n * const savedHandler = currentHandler;\n * module.events.off('click'); // Disable\n * // ... later ...\n * module.events.on('click', savedHandler); // Re-enable\n * ```\n */\n off(type: EventType) {\n this.eventProxy.remove(this.sourceWithLayers, type);\n }\n}\n","import { isEmpty, remove } from 'lodash-es';\nimport type { LayerSpecification, MapGeoJSONFeature } from 'maplibre-gl';\nimport type { EventHandlerConfig, EventType, SourcesWithLayers, SourceWithLayers, UserEventHandler } from './types';\n\n// TODO: add support for multiple handlers per source, layers, and event type?\n// ... (this means multiple handlers for the same module, or repeated \"on\" calls for the same module)\ntype SourceEventTypeHandler = {\n sourceWithLayers: SourceWithLayers;\n layerIDs: string[];\n fn: UserEventHandler<any>;\n config?: EventHandlerConfig;\n};\n\ntype SourceEventHandlers = Partial<Record<EventType, SourceEventTypeHandler[]>>;\n\n// Source ID to event handlers for that source:\n// Example:\n// const handlers = {\n// vectorTiles: {\n// click: [\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [\"Buildings\", \"Roads - Major\"],\n// fn: UserEventsHandler...\n// },\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [\"Water\", \"Landuse - Parks],\n// fn: UserEventsHandler...\n// }\n// ],\n// hover: [\n// {\n// sourceWithLayers: SourceWithLayers reference,\n// layerIDs: [...],\n// fn: UserEventsHandler...\n// }\n// ]\n// },\ntype EventHandlers = Record<string, SourceEventHandlers>;\n\nconst matchesLayers = (layers: LayerSpecification[], layerIDs: string[]): boolean =>\n layerIDs.every((layerId, index) => layerId === layers[index].id);\n\n/**\n * @ignore\n */\nexport abstract class AbstractEventProxy {\n protected interactiveLayerIDs: string[] = [];\n protected handlers: EventHandlers = {};\n\n /**\n * Adds the given layers as interactive, so we'll listen to them for hover and click.\n * @param sourceWithLayers The sources and layers to listen to.\n */\n private ensureInteractiveLayerIDsAdded(sourceWithLayers: SourceWithLayers) {\n sourceWithLayers._layerSpecs.forEach((layerSpec) => {\n if (!this.interactiveLayerIDs.includes(layerSpec.id)) {\n this.interactiveLayerIDs.push(layerSpec.id);\n }\n });\n }\n\n /**\n * Register an event listener to the list.\n * @param sourceWithLayers The sources and layers to added.\n * @param handlerFn Function that will handle the event.\n * @param type Type of event to listen to.\n * @param config Optional configuration for the event handler.\n */\n addEventHandler<T = MapGeoJSONFeature>(\n sourceWithLayers: SourceWithLayers,\n handlerFn: UserEventHandler<T>,\n type: EventType,\n config: EventHandlerConfig | undefined,\n ) {\n this.ensureInteractiveLayerIDsAdded(sourceWithLayers);\n const sourceId = sourceWithLayers.source.id;\n\n if (!this.handlers[sourceId]) {\n this.handlers[sourceId] = { [type]: [] };\n }\n this.handlers[sourceId][type] ??= [];\n\n this.handlers[sourceId][type]?.push({\n sourceWithLayers,\n layerIDs: sourceWithLayers._layerSpecs.map((layer) => layer.id),\n fn: handlerFn,\n config,\n });\n }\n\n /**\n * Removes the given sources and layers from the interactive list. When not present, nothing happens.\n * @param type The event type to be removed.\n * @param sourceWithLayers The sources and layers to remove, matched by source and layer IDs.\n */\n remove(sourceWithLayers: SourceWithLayers, type: EventType) {\n const sourceEventTypeHandlers = this.handlers[sourceWithLayers.source.id]?.[type];\n if (sourceEventTypeHandlers) {\n // @ts-ignore\n remove(sourceEventTypeHandlers, (handler) => matchesLayers(sourceWithLayers._layerSpecs, handler.layerIDs));\n // cleaning up empty arrays and objects if necessary:\n if (!sourceEventTypeHandlers.length) {\n delete this.handlers[sourceWithLayers.source.id]?.[type];\n if (isEmpty(this.handlers[sourceWithLayers.source.id])) {\n delete this.handlers[sourceWithLayers.source.id];\n }\n }\n }\n for (const layer of sourceWithLayers._layerSpecs) {\n // @ts-ignore\n remove(this.interactiveLayerIDs, (id) => layer.id === id);\n }\n }\n\n /**\n * Removes all interactive sources and layers.\n */\n removeAll() {\n this.interactiveLayerIDs = [];\n this.handlers = {};\n }\n\n /**\n * Returns whether this source is registered for events (has handlers attached).\n * @param sourceId The source id (should be linked to a SourceWithLayers instance).\n */\n hasSourceID(sourceId: string): boolean {\n return !!this.handlers[sourceId];\n }\n\n /**\n * Updates the given sourcesWithLayers, if they have any handlers.\n * * (This is typically called to refresh any registered, stale sourceWithLayers references after a map style has changed).\n * @param sourcesWithLayers The new sources with layers to replace existing ones.\n */\n updateIfRegistered(sourcesWithLayers: SourcesWithLayers): void {\n for (const sourceWithLayers of Object.values(sourcesWithLayers)) {\n const sourceHandlers = this.handlers[sourceWithLayers.source.id];\n if (sourceHandlers) {\n for (const sourceEventTypeHandlers of Object.values(sourceHandlers)) {\n for (const handler of sourceEventTypeHandlers) {\n if (sourceWithLayers.equalSourceAndLayerIDs(handler.sourceWithLayers)) {\n // We keep the reference fresh:\n handler.sourceWithLayers = sourceWithLayers;\n }\n }\n }\n }\n }\n }\n\n protected findHandlers = (\n types: EventType[],\n sourceId: string | undefined,\n layerId: string | undefined,\n ): SourceEventTypeHandler[] =>\n (sourceId &&\n layerId &&\n types.flatMap((type) => {\n const sourceEventTypeHandlers = this.handlers[sourceId]?.[type];\n return sourceEventTypeHandlers?.length === 1\n ? // if there's only handler for that source and type, we just return it, no need to match layers:\n sourceEventTypeHandlers\n : this.handlers[sourceId]?.[type]?.filter((handler) => handler.layerIDs.includes(layerId)) || [];\n })) ||\n [];\n}\n","import type { Feature } from 'geojson';\nimport { isNil, omit } from 'lodash-es';\nimport type { MapGeoJSONFeature, Point2D } from 'maplibre-gl';\nimport { areBothDefinedAndEqual } from './mapUtils';\nimport { GeoJSONSourceWithLayers } from './SourceWithLayers';\nimport type { EventType, SourceWithLayers } from './types';\n\ntype IndexedFeature<F extends Feature = Feature> = { feature: F; index: number };\n\nconst findFeatureById = (features: Feature[], id: string | number | undefined): IndexedFeature | undefined => {\n for (let i = 0; i < features.length; i++) {\n const feature = features[i];\n if (feature.id === id) {\n return { feature, index: i };\n }\n }\n return undefined;\n};\n\nconst isHighPriority = (eventType: EventType): boolean => eventType === 'click' || eventType === 'contextmenu';\n\n/**\n * Puts or removes the given event state to the right feature in featuresToUpdate based on the\n * @param eventState The new event state to apply or to use as reference.\n * @param featureId The ID of the feature to update within featuresToUpdate.\n * @param featuresToUpdate The features list which will be updated.\n * @param mode If updateInProps, replaces the existing eventState. If removeFromProps, removes the existing eventState.\n * @return The index of the updated feature in the mutated featuresToUpdate array.\n * @ignore\n */\nexport const putEventState = (\n eventState: EventType,\n featureId: string | number | undefined,\n featuresToUpdate: Feature[], // \"featuresToUpdate\" will be mutated\n mode: 'updateInProps' | 'removeFromProps' = 'updateInProps',\n): number | undefined => {\n const { feature, index } = findFeatureById(featuresToUpdate, featureId) || {};\n if (feature && (!isHighPriority(feature.properties?.eventState) || isHighPriority(eventState))) {\n const updatedFeature = {\n ...feature,\n properties:\n mode === 'updateInProps'\n ? { ...feature?.properties, eventState }\n : omit(feature?.properties, 'eventState'),\n };\n featuresToUpdate.splice(index as number, 1, updatedFeature);\n return index;\n }\n return undefined;\n};\n\nconst removeEventStateAndShow = (\n newEventType: EventType,\n rawFeature: MapGeoJSONFeature,\n sourceWithLayers: GeoJSONSourceWithLayers,\n): void => {\n const prevFeaturesToUpdate = [...sourceWithLayers.shownFeatures.features];\n const updatedIndex = putEventState(newEventType, rawFeature.id, prevFeaturesToUpdate, 'removeFromProps');\n if (!isNil(updatedIndex)) {\n sourceWithLayers.show({ ...sourceWithLayers.shownFeatures, features: prevFeaturesToUpdate });\n }\n};\n\n/**\n * Updates the event state props of the given features.\n * @param eventState The type of event that is being done or undone.\n * @param eventFeature The current MapLibre feature affected by the event, if any.\n * If undefined, it means the event is being undone from prevRawFeature without going to any other one.\n * @param prevEventFeature The previous MapLibre feature affected by the event type, if any (e.g. previous one clicked or hovered).\n * @param sourceWithLayers The source with layers of eventFeature, if any.\n * @param prevSourceWithLayers The source with layers of prevEventFeature, if any.\n * @ignore\n */\nexport const updateEventState = (\n eventState: EventType,\n eventFeature: MapGeoJSONFeature | undefined,\n prevEventFeature: MapGeoJSONFeature | undefined,\n sourceWithLayers: SourceWithLayers | undefined,\n prevSourceWithLayers: SourceWithLayers | undefined,\n): Partial<IndexedFeature> => {\n if (eventFeature && sourceWithLayers instanceof GeoJSONSourceWithLayers) {\n const featuresToUpdate = [...sourceWithLayers.shownFeatures.features];\n const updatedIndex = putEventState(eventState, eventFeature.id, featuresToUpdate) as number;\n\n if (prevEventFeature && !areBothDefinedAndEqual(prevEventFeature, eventFeature)) {\n // (we have both current and prev features for this event type)\n if (prevSourceWithLayers === sourceWithLayers) {\n // we undo the event state from prev feature next to the new one (they will be shown below):\n putEventState(eventState, prevEventFeature.id, featuresToUpdate, 'removeFromProps');\n } else if (prevSourceWithLayers instanceof GeoJSONSourceWithLayers) {\n // the prev feature is in other source/layers, so we update and show them:\n removeEventStateAndShow(eventState, prevEventFeature, prevSourceWithLayers);\n }\n }\n\n sourceWithLayers.show({ ...sourceWithLayers.shownFeatures, features: featuresToUpdate });\n\n return { feature: featuresToUpdate[updatedIndex], index: updatedIndex };\n }\n if (prevEventFeature && prevSourceWithLayers instanceof GeoJSONSourceWithLayers) {\n removeEventStateAndShow(eventState, prevEventFeature, prevSourceWithLayers);\n }\n return { feature: eventFeature };\n};\n\n/**\n * Detects whether there's been a hovering change with the given event and state params.\n * @param hoveringPoint The current hovering pixel coordinates.\n * @param hoveringFeature The current feature being hovered, if any.\n * @param prevHoveredPoint The pixel coordinates from the previous hovering event, if any.\n * @param prevHoveredFeature The previous feature being hovered, if any (could be the same as hoveringFeature).\n * @ignore\n */\nexport const detectHoverState = (\n hoveringPoint: Point2D,\n hoveringFeature: MapGeoJSONFeature | undefined,\n prevHoveredPoint: Point2D | undefined,\n prevHoveredFeature: MapGeoJSONFeature | undefined,\n): {\n /**\n * Whether a hover state change happened, such as no-hover -> hover or vice-versa.\n */\n hoverChanged?: boolean;\n /**\n * Whether the mouse is moving along the hovered feature (not stopped on it).\n */\n mouseInMotionOverHoveredFeature?: boolean;\n} => {\n if (hoveringFeature) {\n if (!prevHoveredFeature) {\n return { hoverChanged: true };\n }\n if (\n (hoveringFeature.id && hoveringFeature.id !== prevHoveredFeature.id) ||\n (hoveringFeature.properties.id && hoveringFeature.properties.id !== prevHoveredFeature.properties.id) ||\n hoveringFeature.source !== prevHoveredFeature.source ||\n // comparing by layer ID is needed when two id-less features from the same source but different layers are compared\n // this can happen when e.g. hovering over different layer groups for the base map\n hoveringFeature.layer.id !== prevHoveredFeature.layer.id\n ) {\n // hovering from one feature to another one (from the same or different layer/source):\n return { hoverChanged: true };\n }\n // (else we're hovering along the same feature)\n if (\n prevHoveredPoint &&\n (hoveringPoint.x - prevHoveredPoint.x != 0 || hoveringPoint.y - prevHoveredPoint.y != 0)\n ) {\n return { mouseInMotionOverHoveredFeature: true };\n }\n } else if (prevHoveredFeature) {\n return { hoverChanged: true };\n }\n return {};\n};\n","import type { LngLat, Map, MapGeoJSONFeature, MapMouseEvent, Point2D, PointLike } from 'maplibre-gl';\nimport type { MapEventsConfig } from '../init';\nimport { AbstractEventProxy } from './AbstractEventProxy';\nimport { detectHoverState, updateEventState } from './eventUtils';\nimport { deserializeFeatures } from './mapUtils';\nimport type { ClickEventType, EventHandlerConfig, SourceWithLayers } from './types';\n\n// Default values for events\nconst eventsProxyDefaultConfig: Required<MapEventsConfig> = {\n precisionMode: 'box',\n paddingBoxPx: 5,\n cursorOnHover: 'pointer',\n cursorOnMouseDown: 'grabbing',\n cursorOnMap: 'default',\n /**\n * Delayed hover control:\n * * The first hover we do after the map moves is longer\n */\n longHoverDelayAfterMapMoveMS: 800,\n /* Followup hovers with the same non-moving map are quicker (\"hovering around mode\") */\n longHoverDelayOnStillMapMS: 300,\n};\n\n/**\n * This is the place where we handle the user events on the map (mousemove/hover and click mostly).\n * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.\n * @ignore\n */\nexport class EventsProxy extends AbstractEventProxy {\n private readonly map: Map;\n private readonly mapCanvas: HTMLCanvasElement;\n private enabled = true;\n private hoveringLngLat?: LngLat;\n private hoveringPoint?: Point2D;\n private hoveringFeature?: MapGeoJSONFeature;\n private hoveringFeatures?: MapGeoJSONFeature[];\n private hoveringSourceWithLayers?: SourceWithLayers;\n private longHoverTimeoutHandlerID?: number;\n // Control flag to indicate that the coming hover is the first one since the map is \"quiet\" again:\n private firstDelayedHoverSinceMapMove = true;\n private lastClickedFeature?: MapGeoJSONFeature;\n private lastClickedSourceWithLayers?: SourceWithLayers;\n private lastCursorStyle: string;\n // Configuration\n private readonly config: Required<MapEventsConfig>;\n\n constructor(map: Map, config: MapEventsConfig = {}) {\n super();\n this.map = map;\n this.mapCanvas = map.getCanvas();\n this.config = { ...eventsProxyDefaultConfig, ...config };\n this.mapCanvas.style.cursor = this.config.cursorOnMap;\n this.lastCursorStyle = this.config.cursorOnMap;\n this.listenToEvents();\n }\n\n private listenToEvents() {\n this.map.on('mousemove', (ev) => this.onMouseMove(ev));\n this.map.on('movestart', () => this.onMouseStart());\n this.map.on('mouseout', () => this.onMouseOut());\n this.map.on('mouseover', (ev) => this.onMouseMove(ev));\n this.map.on('mousedown', () => this.onMouseDown());\n this.map.on('mouseup', () => this.onMouseUp());\n this.map.on('click', (ev) => this.onMapClick('click', ev));\n this.map.on('contextmenu', (ev) => this.onMapClick('contextmenu', ev));\n }\n\n // Enable/Disable Events\n public enable(enabled: boolean) {\n this.enabled = enabled;\n if (!enabled) {\n this.clearLongHoverTimeout();\n }\n }\n\n private toPaddedBounds(point: Point2D): [[number, number], [number, number]] {\n const padding = this.config.paddingBoxPx;\n return [\n // sw:\n [point.x - padding, point.y + padding],\n // ne:\n [point.x + padding, point.y - padding],\n ];\n }\n\n private isEnabled() {\n return this.enabled && !this.map.isMoving();\n }\n\n private getRenderedFeatures(point: Point2D): MapGeoJSONFeature[] {\n if (!this.interactiveLayerIDs.length) {\n return [];\n }\n const options = { layers: this.interactiveLayerIDs, validate: false };\n const precision = this.config.precisionMode;\n // first optional attempt right in the given coordinates:\n const renderedFeatures =\n precision === 'point-then-box' || precision === 'point'\n ? this.map.queryRenderedFeatures(point as PointLike, options)\n : [];\n return renderedFeatures.length || precision === 'point'\n ? renderedFeatures\n : // second attempt using 'box' = padded bounds (trying to hit something slightly further from the pointer location)\n this.map.queryRenderedFeatures(this.toPaddedBounds(point), options);\n }\n\n private clearLongHoverTimeout() {\n window.clearTimeout(this.longHoverTimeoutHandlerID);\n }\n\n private restartLongHoverTimeout() {\n this.clearLongHoverTimeout();\n this.longHoverTimeoutHandlerID = window.setTimeout(\n () => this.handleLongHoverTimeout(),\n this.firstDelayedHoverSinceMapMove\n ? this.config.longHoverDelayAfterMapMoveMS\n : this.config.longHoverDelayOnStillMapMS,\n );\n }\n\n private handleLongHoverTimeout() {\n // We avoid firing long hovers when the feature is in clicked state:\n this.firstDelayedHoverSinceMapMove = false;\n\n if (this.hoveringSourceWithLayers) {\n const eventState = updateEventState(\n 'long-hover',\n this.hoveringFeature,\n undefined,\n this.hoveringSourceWithLayers,\n undefined,\n );\n\n this.findHandlers(['long-hover'], this.hoveringFeature?.source, this.hoveringFeature?.layer.id).forEach(\n (handler) =>\n handler.fn(\n eventState.feature,\n this.hoveringLngLat as LngLat,\n this.hoveringFeatures as MapGeoJSONFeature[],\n this.hoveringSourceWithLayers as SourceWithLayers,\n ),\n );\n }\n }\n\n private onMouseStart() {\n this.firstDelayedHoverSinceMapMove = true;\n this.clearLongHoverTimeout();\n }\n\n private onMouseOut() {\n // Preventing accidental de-hover event if we actually leave the map canvas.\n // Since this could potentially be about jumping into a map popup, so we leave that up to the caller.\n this.clearLongHoverTimeout();\n }\n\n private onMouseDown() {\n this.lastCursorStyle = this.mapCanvas.style.cursor;\n this.mapCanvas.style.cursor = this.config.cursorOnMouseDown;\n }\n\n private onMouseUp() {\n this.mapCanvas.style.cursor = this.lastCursorStyle;\n }\n\n private onMouseMove(ev: MapMouseEvent) {\n if (!this.isEnabled()) {\n // We ensure no unwanted hover handling while disabled or the map moves\n return;\n }\n\n this.hoveringFeatures = this.getRenderedFeatures(ev.point);\n deserializeFeatures(this.hoveringFeatures);\n const [hoveredTopFeature] = this.hoveringFeatures;\n\n // Check if the layer has any handlers registered.\n // Since hover is the \"lowest\" event type, having a handler for any event type justifies supporting hover state.\n // However, we'll only fire the hover events if there are handlers for hover specifically.\n if (hoveredTopFeature && !this.hasSourceID(hoveredTopFeature.source)) {\n return;\n }\n\n // hoverChangeDetected: whether a change happened, such as no-hover -> hover or vice versa:\n // mouseInMotionOverHoveredFeature: whether the mouse is moving along the hovered feature (not stopped on it):\n const { hoverChanged, mouseInMotionOverHoveredFeature } = detectHoverState(\n ev.point,\n hoveredTopFeature,\n this.hoveringPoint,\n this.hoveringFeature,\n );\n\n if (hoverChanged || mouseInMotionOverHoveredFeature) {\n this.hoveringLngLat = ev.lngLat;\n this.hoveringPoint = ev.point;\n const prevHoveredFeature = this.hoveringFeature;\n this.hoveringFeature = hoveredTopFeature;\n const prevHoveredSourceWithLayers = this.hoveringSourceWithLayers;\n\n // Hovering basic event states are still processed if any other handlers are registered for that source/layers.\n // We do so because basic hovering states indicate a feature is interactive.\n // (e.g. if there's a click handler, we'll still apply basic hover states, even if we don't fire hover events)\n const firstHandler = this.findHandlers(\n ['hover', 'long-hover', 'click', 'contextmenu'],\n hoveredTopFeature?.source,\n hoveredTopFeature?.layer.id,\n )?.[0];\n\n // NOTE: handlers overlapping in source and layer IDs won't be supported properly:\n this.hoveringSourceWithLayers = firstHandler?.sourceWithLayers;\n\n if (hoverChanged) {\n this.updateHoverCursor(firstHandler?.config);\n\n const eventState = updateEventState(\n 'hover',\n this.hoveringFeature,\n prevHoveredFeature,\n this.hoveringSourceWithLayers,\n prevHoveredSourceWithLayers,\n );\n\n const hoverHandlers = this.findHandlers(\n ['hover'],\n hoveredTopFeature?.source,\n hoveredTopFeature?.layer.id,\n );\n\n for (const handler of hoverHandlers) {\n handler.fn(eventState.feature, ev.lngLat, this.hoveringFeatures, this.hoveringSourceWithLayers);\n }\n }\n\n this.restartLongHoverTimeout();\n }\n }\n\n private updateHoverCursor(config: EventHandlerConfig | undefined) {\n if (this.hoveringFeature) {\n this.mapCanvas.style.cursor = config?.cursorOnHover ?? this.config.cursorOnHover;\n } else {\n this.mapCanvas.style.cursor = this.config.cursorOnMap;\n }\n }\n\n private onMapClick(clickType: ClickEventType, ev: MapMouseEvent) {\n if (!this.isEnabled()) {\n // We avoid any accidental click handling while disabled or the map moves\n return;\n }\n\n const clickedFeatures = this.getRenderedFeatures(ev.point);\n // Deserialize Features from maplibre queryRenderedFeatures response\n deserializeFeatures(clickedFeatures);\n\n const prevClickedFeature = this.lastClickedFeature;\n this.lastClickedFeature = clickedFeatures[0];\n const prevClickedSourceWithLayers = this.lastClickedSourceWithLayers;\n const clickHandlers = this.findHandlers(\n [clickType],\n this.lastClickedFeature?.source,\n this.lastClickedFeature?.layer.id,\n );\n\n // NOTE: handlers overlapping in source and layer IDs won't be supported properly:\n this.lastClickedSourceWithLayers = clickHandlers?.[0]?.sourceWithLayers;\n\n const eventState = updateEventState(\n clickType,\n this.lastClickedFeature,\n prevClickedFeature,\n this.lastClickedSourceWithLayers,\n prevClickedSourceWithLayers,\n );\n\n for (const handler of clickHandlers) {\n handler.fn(eventState.feature, ev.lngLat, clickedFeatures, this.lastClickedSourceWithLayers);\n }\n }\n}\n","/**\n * Key layer IDs from the vector map style for positioning custom layers.\n *\n * @remarks\n * This constant provides reference layer IDs from TomTom's vector map styles that are used\n * as anchors when positioning custom layers in the map's layer stack. By referencing these\n * layer IDs, SDK modules and custom implementations can control where their layers appear\n * in the rendering order (visual stacking).\n *\n * **Understanding Layer Order:**\n *\n * \"Lowest\" refers to position in the layer stack, not physical elevation. Layers are rendered\n * from bottom to top - layers lower in the stack are drawn first and appear underneath layers\n * higher in the stack. When you add a layer \"before\" a reference layer, it's inserted lower\n * in the stack and will be drawn underneath that reference layer.\n *\n * **How SDK Modules Use These IDs:**\n *\n * **RoutingModule** - Positions route visualizations below labels for readability:\n * ```typescript\n * // Routes appear below labels but above the base map\n * const routingModule = await RoutingModule.get(map);\n * // Uses mapStyleLayerIDs.lowestLabel by default\n * ```\n *\n * **GeometriesModule** - Configurable layer positioning for polygon areas:\n * ```typescript\n * // Default: below labels\n * const geometriesModule = await GeometriesModule.get(map);\n *\n * // Custom: below buildings to show at ground level\n * const geometriesModule = await GeometriesModule.get(map, {\n * beforeLayerConfig: 'lowestBuilding'\n * });\n *\n * // On top of everything\n * const geometriesModule = await GeometriesModule.get(map, {\n * beforeLayerConfig: 'top'\n * });\n * ```\n *\n * **Custom Layer Implementation:**\n * ```typescript\n * // Add a highlight layer below labels\n * map.addLayer({\n * id: 'search-results',\n * type: 'fill',\n * source: 'results-source',\n * paint: { 'fill-color': '#ffcc00', 'fill-opacity': 0.4 }\n * }, mapStyleLayerIDs.lowestLabel);\n * ```\n *\n * **Style Persistence:**\n *\n * These layer IDs remain consistent across TomTom map style changes (e.g., switching from\n * 'standardLight' to 'standardDark'). The SDK automatically repositions module layers using\n * the corresponding reference layers in the new style, maintaining the intended visual hierarchy.\n *\n * **Important Notes:**\n * - `lowestBuilding` is not available in the Satellite style\n * - If a reference layer doesn't exist, custom layers will be added on top of the style\n * - Both RoutingModule and GeometriesModule default to `lowestLabel` for optimal visibility\n *\n * @see {@link GeometryBeforeLayerConfig} for GeometriesModule layer positioning options\n * @see {@link RouteLayersConfig} for RoutingModule layer configuration\n *\n * @group Map Style\n */\nexport const mapStyleLayerIDs = {\n /**\n * Country name label layer.\n *\n * @remarks\n * Lower in the stack than most labels. Use to position elements below country\n * labels but above other map features.\n */\n country: 'Places - Country name',\n /**\n * The lowest layer for place labels.\n *\n * @remarks\n * Lower in the stack than city labels. Use to position content below all place\n * name labels while keeping it visible above geographic features.\n */\n lowestPlaceLabel: 'Places - Village / Hamlet',\n /**\n * Points of Interest layer.\n *\n * @remarks\n * Use to position custom content in the layer stack relative to POI icons and labels.\n */\n poi: 'POI',\n /**\n * The lowest labels layer in the stack.\n *\n * @remarks\n * **Most commonly used reference layer.** Positioning layers before this ensures\n * content appears below all text labels, maintaining map readability while keeping\n * visualizations prominent.\n *\n * **Default for SDK modules:**\n * - RoutingModule uses this for route lines and waypoints\n * - GeometriesModule uses this as the default for polygon fills and borders\n *\n * This provides optimal balance between visibility and not obscuring map labels.\n */\n lowestLabel: 'Borders - Treaty label',\n /**\n * The lowest road line layer in the stack.\n *\n * @remarks\n * Represents tunnel railway outlines. Use to position content below the road network,\n * useful for showing base layers or features that should appear beneath transportation\n * infrastructure.\n */\n lowestRoadLine: 'Tunnel - Railway outline',\n /**\n * The lowest building layer in the stack.\n *\n * @remarks\n * Use to position content below 3D building extrusions while keeping it above\n * flat map features like roads and terrain.\n *\n * **Note:** Not available in the Satellite style.\n */\n lowestBuilding: 'Buildings - Underground',\n} as const;\n","/**\n * Source identifier for POI (Point of Interest) vector tiles.\n *\n * @remarks\n * Used to reference the POI layer in the map style, which contains\n * business locations, landmarks, and other points of interest.\n *\n * @group POIs\n */\nexport const POI_SOURCE_ID = 'vectorTiles';\n\n/**\n * Source identifier for hillshade terrain visualization.\n *\n * @remarks\n * References the raster source that provides terrain shading to visualize\n * elevation and topography on the map.\n *\n * @group Hillshade\n */\nexport const HILLSHADE_SOURCE_ID = 'hillshade';\n\n/**\n * Source identifier for base map vector tiles.\n *\n * @remarks\n * References the primary vector tile source containing roads, buildings,\n * land use, water bodies, and other fundamental map features.\n *\n * @group Base Map\n */\nexport const BASE_MAP_SOURCE_ID = 'vectorTiles';\n\n/**\n * Source identifier for traffic incidents vector tiles.\n *\n * @remarks\n * References the vector tile source containing real-time traffic incident data\n * such as accidents, road closures, and construction.\n *\n * @group Traffic Incidents\n */\nexport const TRAFFIC_INCIDENTS_SOURCE_ID = 'vectorTilesIncidents';\n\n/**\n * Source identifier for traffic flow vector tiles.\n *\n * @remarks\n * References the vector tile source containing real-time traffic flow data\n * showing current traffic speeds and congestion levels.\n *\n * @group Traffic Flow\n */\nexport const TRAFFIC_FLOW_SOURCE_ID = 'vectorTilesFlow';\n","/**\n * Layer IDs for POIs on the map.\n * @ignore\n */\nexport const poiLayerIDs = ['POI', 'POI - Micro'];\n","import type { POICategory } from '@tomtom-org/maps-sdk/core';\n\n/**\n * POI category mappings that have a direct equivalent in Map Display POI categories.\n * @ignore\n */\nexport const mapDisplayPoiCategoryMappings: Partial<Record<POICategory, string>> = {\n ACCESS_GATEWAY: 'border_control',\n ADVENTURE_SPORTS_FACILITY: 'sport_facility',\n ADVENTURE_SPORTS_VENUE: 'sport_facility',\n AGRICULTURE: 'agriculture_business',\n AIRPORT: 'airport',\n AMUSEMENT_PARK: 'amusement_park',\n AQUATIC_ZOO: 'zoo_or_aquarium',\n ASHRAM: 'religious_site',\n ATM: 'atm',\n AUTOMOTIVE_DEALER: 'vehicle_dealer',\n BANK: 'bank',\n BEACH: 'beach',\n BUS_STOP: 'bus_station',\n BUSINESS_PARK: 'business',\n CAFE_PUB: 'cafe',\n CAMPING_GROUND: 'camping_ground',\n CAR_WASH: 'vehicle_wash',\n CASH_DISPENSER: 'atm',\n CASINO: 'casino_and_gambling',\n CHURCH: 'religious_site',\n CINEMA: 'cinema',\n CLOTHING_SHOP: 'clothing_shop',\n CLUB_ASSOCIATION: 'club_and_association',\n COLLEGE_UNIVERSITY: 'college_or_university',\n COMMERCIAL_BUILDING: 'business',\n COMMUNITY_CENTER: 'cultural_center',\n COMPANY: 'company_or_office',\n CONCERT_HALL: 'nightlife',\n COURTHOUSE: 'courthouse',\n CULTURAL_CENTER: 'cultural_center',\n DENTIST: 'dentist',\n DEPARTMENT_STORE: 'department_store',\n DOCTOR: 'doctor',\n ELECTRIC_VEHICLE_STATION: 'charging_location',\n EMBASSY: 'institution_office',\n EMERGENCY_MEDICAL_SERVICE: 'emergency',\n EMERGENCY_ROOM: 'emergency',\n ENTERTAINMENT: 'entertainment',\n EXCHANGE: 'stock_exchange',\n EXHIBITION_CONVENTION_CENTER: 'cultural_center',\n FERRY_TERMINAL: 'ferry_terminal',\n FIRE_STATION_BRIGADE: 'fire_station',\n FRONTIER_CROSSING: 'border_control',\n FUEL_FACILITIES: 'fuel_station',\n GAS_STATION: 'fuel_station',\n GEOGRAPHIC_FEATURE: 'geographic_feature',\n GOLD_EXCHANGE: 'gold_exchange',\n GOLF_COURSE: 'golf_course',\n GOVERNMENT_OFFICE: 'institution_office',\n GURUDWARA: 'religious_site',\n HEALTH_CARE_SERVICE: 'healthcare_service',\n HELIPAD_HELICOPTER_LANDING: 'heliport_or_helipad',\n HILL: 'peak_high',\n HOLIDAY_RENTAL: 'holiday_home',\n HOSPITAL: 'hospital',\n HOSPITAL_POLYCLINIC: 'hospital',\n HOTEL_MOTEL: 'hotel_or_motel',\n ICE_SKATING_RINK: 'winter_sports',\n IMPORTANT_TOURIST_ATTRACTION: 'tourist_attraction',\n INDUSTRIAL_BUILDING: 'industrial_facility',\n LEISURE_CENTER: 'leisure',\n LIBRARY: 'public_library',\n MANUFACTURING_FACILITY: 'manufacturing_facility',\n MARINA: 'marina',\n MARKET: 'marketplace',\n MEDIA_FACILITY: 'media_facility',\n MILITARY_INSTALLATION: 'military_facility',\n MOSQUE: 'religious_site',\n MOTORING_ORGANIZATION_OFFICE: 'traffic_office',\n MOUNTAIN_PASS: 'mountain_pass',\n MOUNTAIN_PEAK: 'peak',\n MOVIE_THEATER: 'cinema',\n MUSEUM: 'museum',\n NATIVE_RESERVATION: 'aboriginal_land',\n NIGHTLIFE: 'nightlife',\n NON_GOVERNMENTAL_ORGANIZATION: 'ngo_office',\n OPEN_PARKING_AREA: 'parking_facility',\n OPERA_HOUSE: 'theater',\n PAGODA: 'religious_site',\n PARK_RECREATION_AREA: 'park_and_recreation_area',\n PARKING_GARAGE: 'parking_facility',\n PETROL_STATION: 'fuel_station',\n PHARMACY: 'pharmacy',\n PLACE_OF_WORSHIP: 'religion',\n POLICE_STATION: 'police_station',\n PORT_WAREHOUSE_FACILITY: 'industrial_facility',\n POST_OFFICE: 'post_office',\n PRIMARY_RESOURCE_UTILITY: 'industrial_facility',\n PRISON_CORRECTIONAL_FACILITY: 'prison',\n PUBLIC_AMENITY: 'public_amenity',\n PUBLIC_TRANSPORT_STOP: 'public_transport_stop',\n RAILWAY_STATION: 'railway_station',\n RENT_A_CAR_FACILITY: 'car_rental',\n RENT_A_CAR_PARKING: 'rental_car_parking',\n REPAIR_FACILITY: 'vehicle_repair',\n RESEARCH_FACILITY: 'research_facility',\n RESIDENTIAL_ACCOMMODATION: 'business',\n REST_AREA: 'rest_area',\n RESTAURANT: 'restaurant',\n RESTAURANT_AREA: 'restaurant',\n SCENIC_PANORAMIC_VIEW: 'viewpoint',\n SCHOOL: 'education',\n SHOP: 'shop_or_store',\n SHOPPING_CENTER: 'shop_or_store',\n SPORTS_CENTER: 'sport_facility',\n STADIUM: 'stadium',\n SUPERMARKETS_HYPERMARKETS: 'supermarket',\n SWIMMING_POOL: 'swimming_pool',\n SYNAGOG: 'religious_site',\n TAXI_STAND: 'taxi_stand',\n TEMPLE: 'religious_site',\n TENNIS_COURT: 'sport_facility',\n THEATER: 'theater',\n TOLL_GATE: 'toll_gantry',\n TOURIST_INFORMATION_OFFICE: 'tourist_information',\n TRAFFIC_CONTROL_DEPARTMENT: 'traffic_office',\n TRAFFIC_SERVICE_CENTER: 'traffic_office',\n TRAIL_SYSTEM: 'trailhead',\n TRAILS: 'trailhead',\n TRANSPORT_AUTHORITY_VEHICLE_REGISTRATION: 'traffic_office',\n TRUCK_STOP: 'truck_stop',\n VACATION_RENTAL: 'holiday_home',\n VETERINARIAN: 'veterinary',\n WATER_SPORT: 'outdoor',\n WEIGH_STATION: 'weighbridge',\n WELFARE_ORGANIZATION: 'social_service',\n WINERY: 'manufacturing_facility',\n ZOOS_ARBORETA_BOTANICAL_GARDEN: 'zoo_or_aquarium',\n} as const;\n\n/**\n * Complete POI category mappings including all POI categories.\n * Extends the original mappings with additional categories mapped to semantically appropriate values.\n * @ignore\n */\nconst completeMapDisplayPoiCategoryMappings: Record<POICategory, string> = {\n ...(mapDisplayPoiCategoryMappings as Record<POICategory, string>),\n // Additional POI categories not in the original mapping\n SECURED_ENTRANCE: 'border_control',\n AGRICULTURAL_BUSINESS: 'agriculture_business',\n FARM: 'agriculture_business',\n HORTICULTURE: 'agriculture_business',\n PRIMARY_PRODUCER: 'agriculture_business',\n AIRFIELD: 'airport',\n AIRLINE_ACCESS: 'airport',\n MILITARY_AIRPORT: 'airport',\n PRIVATE_AIRPORT: 'airport',\n PUBLIC_AIRPORT: 'airport',\n ATV_DEALER: 'vehicle_dealer',\n BOAT_DEALER: 'boat_dealer',\n BUS_DEALER: 'vehicle_dealer',\n CAR_DEALER: 'vehicle_dealer',\n MOTORCYCLE_DEALER: 'vehicle_dealer',\n RECREATIONAL_VEHICLE_DEALER: 'vehicle_dealer',\n TRUCK_DEALER: 'vehicle_dealer',\n VAN_DEALER: 'vehicle_dealer',\n DIVERSIFIED_FINANCIALS: 'bank',\n SAVINGS_INSTITUTION: 'bank',\n BEACH_CLUB: 'beach',\n BAR: 'bar',\n CAFE: 'cafe',\n COCKTAIL_BAR: 'bar',\n COFFEE_SHOP: 'coffee_shop',\n INTERNET_CAFE: 'cafe',\n PUB: 'pub',\n TEA_HOUSE: 'tea_house',\n WINE_BAR: 'bar',\n CARAVAN_SITE: 'camping_ground',\n RECREATIONAL_CAMPING_GROUND: 'camping_ground',\n REST_CAMP: 'camping_ground',\n TRUCK_WASH: 'vehicle_wash',\n DRIVE_IN_MOVIES: 'cinema',\n CHILDRENS_CLOTHES: 'clothing_shop',\n MENS_CLOTHING: 'clothing_shop',\n SPECIALTY_CLOTHING_SHOP: 'clothing_shop',\n WOMENS_CLOTHING: 'clothing_shop',\n PRIVATE_CLUB: 'club_and_association',\n JUNIOR_COLLEGE_COMMUNITY_COLLEGE: 'college_or_university',\n BUILDING: 'business',\n ADVERTISING_COMPANY: 'company_or_office',\n AGRICULTURAL_TECHNOLOGY: 'company_or_office',\n AIRLINE_COMPANY: 'company_or_office',\n AUTOMOBILE_COMPANY: 'company_or_office',\n BUSINESS_SERVICES: 'company_or_office',\n BUS_CHARTER_COMPANY: 'company_or_office',\n CABLE_TELEPHONE_COMPANY: 'company_or_office',\n CLEANING_SERVICES: 'company_or_office',\n COMPUTER_DATA_SERVICES: 'company_or_office',\n CONSTRUCTION_COMPANY: 'company_or_office',\n DELIVERY_SERVICE: 'company_or_office',\n ELECTRONICS_COMPANY: 'company_or_office',\n EQUIPMENT_RENTAL: 'company_or_office',\n FUNERAL_SERVICE_MORTUARIES: 'company_or_office',\n IMPORT_EXPORT_AND_DISTRIBUTION: 'company_or_office',\n INSURANCE_COMPANY: 'company_or_office',\n INVESTMENT_ADVISOR: 'company_or_office',\n LEGAL_SERVICES: 'company_or_office',\n MINING_COMPANY: 'company_or_office',\n MOVING_STORAGE_COMPANY: 'company_or_office',\n OIL_NATURAL_GAS: 'company_or_office',\n PHARMACEUTICAL_COMPANY: 'company_or_office',\n PUBLIC_HEALTH_TECHNOLOGY_COMPANY: 'company_or_office',\n PUBLISHING_TECHNOLOGIES: 'company_or_office',\n REAL_ESTATE_AGENT: 'company_or_office',\n REAL_ESTATE_COMPANY: 'company_or_office',\n SERVICE_COMPANY: 'company_or_office',\n SOFTWARE_COMPANY: 'company_or_office',\n TAX_SERVICES: 'company_or_office',\n TELECOMMUNICATIONS: 'company_or_office',\n TRANSPORT_COMPANY: 'company_or_office',\n TRAVEL_AGENT: 'company_or_office',\n WEDDING_SERVICES: 'company_or_office',\n GENERAL_PRACTITIONER: 'doctor',\n SPECIALIST: 'doctor',\n RIDGE: 'peak',\n AMBULANCE_UNIT: 'emergency',\n ROAD_RESCUE: 'emergency',\n AMUSEMENT_ARCADE: 'entertainment',\n AMUSEMENT_PLACE: 'entertainment',\n BETTING_STATION: 'entertainment',\n FAIRGROUND: 'entertainment',\n MUSIC_CENTER: 'entertainment',\n CHECKPOINT: 'border_control',\n BAY: 'geographic_feature',\n BRIDGE: 'geographic_feature',\n BRIDGE_TUNNEL_OPERATIONS: 'geographic_feature',\n CAPE: 'geographic_feature',\n COVE: 'geographic_feature',\n DAM: 'geographic_feature',\n DUNE: 'geographic_feature',\n ISLAND: 'geographic_feature',\n LAGOON: 'geographic_feature',\n LAKESHORE: 'geographic_feature',\n LOCALE: 'geographic_feature',\n MARSH: 'geographic_feature',\n OASIS: 'geographic_feature',\n PAN: 'geographic_feature',\n PARKWAY: 'geographic_feature',\n PLAIN_FLAT: 'geographic_feature',\n PLATEAU: 'geographic_feature',\n RAPIDS: 'geographic_feature',\n REEF: 'geographic_feature',\n RESERVOIR: 'geographic_feature',\n RIVER_CROSSING: 'geographic_feature',\n RIVER_SCENIC_AREA: 'geographic_feature',\n ROCKS: 'geographic_feature',\n SEASHORE: 'geographic_feature',\n TUNNEL: 'geographic_feature',\n VALLEY: 'geographic_feature',\n WATER_HOLE: 'geographic_feature',\n WELL: 'geographic_feature',\n BUNGALOW_RENTAL: 'holiday_home',\n CABINS_LODGES: 'holiday_home',\n CHALET_RENTAL: 'holiday_home',\n COTTAGE_RENTAL: 'holiday_home',\n VILLA_RENTAL: 'holiday_home',\n BLOOD_BANK: 'hospital',\n HOSPITAL_FOR_WOMEN_AND_CHILDREN: 'hospital',\n HOSPITAL_OF_CHINESE_MEDICINE: 'hospital',\n SPECIAL_HOSPITAL: 'hospital',\n B_B_GUEST_HOUSE: 'hotel_or_motel',\n HOSTEL: 'hotel_or_motel',\n HOTEL: 'hotel_or_motel',\n MOTEL: 'hotel_or_motel',\n RESORT: 'hotel_or_motel',\n QUARRY: 'industrial_facility',\n AUTOMOBILE_MANUFACTURING: 'manufacturing_facility',\n CHEMICAL_COMPANY: 'manufacturing_facility',\n MANUFACTURING_COMPANY: 'manufacturing_facility',\n MECHANICAL_ENGINEERING: 'manufacturing_facility',\n MICROBREWERY: 'manufacturing_facility',\n OEM: 'manufacturing_facility',\n BOAT_LAUNCHING_RAMP: 'marina',\n HARBOR: 'marina',\n YACHT_BASIN: 'marina',\n FARMERS_MARKET: 'marketplace',\n FOOD_MARKET: 'marketplace',\n INFORMAL_MARKET: 'marketplace',\n PUBLIC_MARKET: 'marketplace',\n PLANETARIUM: 'planetarium',\n CABARET_THEATER: 'nightlife',\n COMEDY_CLUB: 'comedy_club',\n DISCO_CLUB: 'nightlife',\n JAZZ_CLUB: 'nightlife',\n KARAOKE_CLUB: 'nightlife',\n FISHING_HUNTING_AREA: 'park_and_recreation_area',\n FOREST_AREA: 'park_and_recreation_area',\n HISTORICAL_PARK: 'park_and_recreation_area',\n NATURAL_RECREATION_ATTRACTION: 'park_and_recreation_area',\n PARK: 'park_and_recreation_area',\n PICNIC_AREA: 'park_and_recreation_area',\n PRESERVE: 'park_and_recreation_area',\n RECREATION_AREA: 'park_and_recreation_area',\n WILDERNESS_AREA: 'park_and_recreation_area',\n OPEN_CAR_PARKING_AREA: 'parking_facility',\n DRUG_STORE: 'pharmacy',\n MARIJUANA_DISPENSARY: 'pharmacy',\n MEDICINAL_MARIJUANA_DISPENSARY: 'pharmacy',\n RECREATIONAL_MARIJUANA_DISPENSARY: 'pharmacy',\n COURIER_DROP_BOX: 'post_office',\n LOCAL_POST_OFFICE: 'post_office',\n PUBLIC_CALL_BOX: 'public_amenity',\n PUBLIC_TOILET: 'public_amenity',\n BUS_LINES: 'public_transport_stop',\n COACH_STOP: 'public_transport_stop',\n PASSENGER_TRANSPORT_TICKET_OFFICE: 'public_transport_stop',\n PEDESTRIAN_SUBWAY: 'public_transport_stop',\n STREETCAR_STOP: 'public_transport_stop',\n SUBWAY_STATION: 'public_transport_stop',\n INTERNATIONAL_RAILROAD_STATION: 'railway_station',\n NATIONAL_RAILROAD_STATION: 'railway_station',\n RAILROAD_SIDING: 'railway_station',\n STATION_ACCESS: 'railway_station',\n URBAN_STATION: 'railway_station',\n BODYSHOP: 'vehicle_repair',\n CAR_GLASS_REPLACEMENT_SHOP: 'vehicle_repair',\n CAR_REPAIR_AND_SERVICE: 'vehicle_repair',\n HOME_APPLIANCE_REPAIR: 'vehicle_repair',\n MOTORCYCLE_REPAIR: 'vehicle_repair',\n OTHER_REPAIR_SHOPS: 'vehicle_repair',\n REPAIR_SHOP: 'vehicle_repair',\n TIRE_SERVICE: 'vehicle_repair',\n TRUCK_REPAIR_AND_SERVICE: 'vehicle_repair',\n AFGHAN_RESTAURANT: 'restaurant',\n AFRICAN_RESTAURANT: 'restaurant',\n ALGERIAN_RESTAURANT: 'restaurant',\n AMERICAN_RESTAURANT: 'restaurant',\n ARABIAN_RESTAURANT: 'restaurant',\n ARGENTINIAN_RESTAURANT: 'restaurant',\n ARMENIAN_RESTAURANT: 'restaurant',\n ASIAN_RESTAURANT: 'restaurant',\n AUSTRALIAN_RESTAURANT: 'restaurant',\n AUSTRIAN_RESTAURANT: 'restaurant',\n BANQUET_ROOMS: 'restaurant',\n BARBECUE_RESTAURANT: 'restaurant',\n BASQUE_RESTAURANT: 'restaurant',\n BELGIAN_RESTAURANT: 'restaurant',\n BISTRO: 'restaurant',\n BOLIVIAN_RESTAURANT: 'restaurant',\n BOSNIAN_RESTAURANT: 'restaurant',\n BRAZILIAN_RESTAURANT: 'restaurant',\n BRITISH_RESTAURANT: 'restaurant',\n BUFFET_RESTAURANT: 'restaurant',\n BULGARIAN_RESTAURANT: 'restaurant',\n BURMESE_RESTAURANT: 'restaurant',\n CAFETERIA: 'restaurant',\n CALIFORNIAN_RESTAURANT: 'restaurant',\n CAMBODIAN_RESTAURANT: 'restaurant',\n CANADIAN_RESTAURANT: 'restaurant',\n CARIBBEAN_RESTAURANT: 'restaurant',\n CATERING_SERVICES: 'restaurant',\n CHICKEN_RESTAURANT: 'restaurant',\n CHILEAN_RESTAURANT: 'restaurant',\n CHINESE_RESTAURANT: 'restaurant',\n COLOMBIAN_RESTAURANT: 'restaurant',\n CORSICAN_RESTAURANT: 'restaurant',\n CREOLE_RESTAURANT: 'restaurant',\n CREPERIE: 'restaurant',\n CUBAN_RESTAURANT: 'restaurant',\n CYPRIOT_RESTAURANT: 'restaurant',\n CZECH_RESTAURANT: 'restaurant',\n DANISH_RESTAURANT: 'restaurant',\n DINNER_THEATER: 'restaurant',\n DOMINICAN_RESTAURANT: 'restaurant',\n DONGBEI_RESTAURANT: 'restaurant',\n DOUGHNUT_RESTAURANT: 'restaurant',\n DUTCH_RESTAURANT: 'restaurant',\n EGYPTIAN_RESTAURANT: 'restaurant',\n ENGLISH_RESTAURANT: 'restaurant',\n EROTIC_RESTAURANT: 'restaurant',\n ETHIOPIAN_RESTAURANT: 'restaurant',\n EXOTIC_RESTAURANT: 'restaurant',\n FAST_FOOD: 'restaurant',\n FINNISH_RESTAURANT: 'restaurant',\n FONDUE_RESTAURANT: 'restaurant',\n FRENCH_RESTAURANT: 'restaurant',\n FUSION_RESTAURANT: 'restaurant',\n GERMAN_RESTAURANT: 'restaurant',\n GREEK_RESTAURANT: 'restaurant',\n GRILL_RESTAURANT: 'restaurant',\n GUANGDONG_RESTAURANT: 'restaurant',\n HAMBURGER_RESTAURANT: 'restaurant',\n HAWAIIAN_RESTAURANT: 'restaurant',\n HOT_POT_RESTAURANT: 'restaurant',\n HUNAN_RESTAURANT: 'restaurant',\n HUNGARIAN_RESTAURANT: 'restaurant',\n ICE_CREAM_PARLOR: 'restaurant',\n INDIAN_RESTAURANT: 'restaurant',\n INDONESIAN_RESTAURANT: 'restaurant',\n INTERNATIONAL_RESTAURANT: 'restaurant',\n IRANIAN_RESTAURANT: 'restaurant',\n IRISH_RESTAURANT: 'restaurant',\n ISRAELI_RESTAURANT: 'restaurant',\n ITALIAN_RESTAURANT: 'restaurant',\n JAMAICAN_RESTAURANT: 'restaurant',\n JAPANESE_RESTAURANT: 'restaurant',\n JEWISH_RESTAURANT: 'restaurant',\n KOREAN_RESTAURANT: 'restaurant',\n KOSHER_RESTAURANT: 'restaurant',\n LATIN_AMERICAN_RESTAURANT: 'restaurant',\n LEBANESE_RESTAURANT: 'restaurant',\n LUXEMBOURGIAN_RESTAURANT: 'restaurant',\n MACROBIOTIC_RESTAURANT: 'restaurant',\n MAGHRIB_RESTAURANT: 'restaurant',\n MALTESE_RESTAURANT: 'restaurant',\n MAURITIAN_RESTAURANT: 'restaurant',\n MEDITERRANEAN_RESTAURANT: 'restaurant',\n MEXICAN_RESTAURANT: 'restaurant',\n MIDDLE_EASTERN_RESTAURANT: 'restaurant',\n MONGOLIAN_RESTAURANT: 'restaurant',\n MOROCCAN_RESTAURANT: 'restaurant',\n MUSSELS_RESTAURANT: 'restaurant',\n NEPALESE_RESTAURANT: 'restaurant',\n NORWEGIAN_RESTAURANT: 'restaurant',\n ORGANIC_FOOD_RESTAURANT: 'restaurant',\n ORIENTAL_RESTAURANT: 'restaurant',\n PAKISTANI_RESTAURANT: 'restaurant',\n PERUVIAN_RESTAURANT: 'restaurant',\n PHILIPPINE_RESTAURANT: 'restaurant',\n PIZZERIA: 'restaurant',\n POLISH_RESTAURANT: 'restaurant',\n POLYNESIAN_RESTAURANT: 'restaurant',\n PORTUGUESE_RESTAURANT: 'restaurant',\n PROVENCAL_RESTAURANT: 'restaurant',\n PUB_FOOD: 'restaurant',\n ROADSIDE_RESTAURANT: 'restaurant',\n ROMANIAN_RESTAURANT: 'restaurant',\n RUSSIAN_RESTAURANT: 'restaurant',\n SALAD_BAR: 'restaurant',\n SANDWICH_RESTAURANT: 'restaurant',\n SAVOY_RESTAURANT: 'restaurant',\n SCANDINAVIAN_RESTAURANT: 'restaurant',\n SCOTTISH_RESTAURANT: 'restaurant',\n SEAFOOD: 'restaurant',\n SHANDONG_RESTAURANT: 'restaurant',\n SHANGHAI_RESTAURANT: 'restaurant',\n SICHUAN_RESTAURANT: 'restaurant',\n SICILIAN_RESTAURANT: 'restaurant',\n SLAVIC_RESTAURANT: 'restaurant',\n SLOVAK_RESTAURANT: 'restaurant',\n SNACKS_RESTAURANT: 'restaurant',\n SOUL_FOOD: 'restaurant',\n SOUP_RESTAURANT: 'restaurant',\n SPANISH_RESTAURANT: 'restaurant',\n STEAK_HOUSE: 'restaurant',\n SUDANESE_RESTAURANT: 'restaurant',\n SURINAMESE_RESTAURANT: 'restaurant',\n SUSHI_RESTAURANT: 'restaurant',\n SWEDISH_RESTAURANT: 'restaurant',\n SWISS_RESTAURANT: 'restaurant',\n SYRIAN_RESTAURANT: 'restaurant',\n TAIWANESE_RESTAURANT: 'restaurant',\n TAKEOUT_FOOD: 'restaurant',\n TAPAS_RESTAURANT: 'restaurant',\n TEPPANYAKI_RESTAURANT: 'restaurant',\n THAI_RESTAURANT: 'restaurant',\n TIBETAN_RESTAURANT: 'restaurant',\n TUNISIAN_RESTAURANT: 'restaurant',\n TURKISH_RESTAURANT: 'restaurant',\n URUGUAYAN_RESTAURANT: 'restaurant',\n VEGETARIAN_RESTAURANT: 'restaurant',\n VENEZUELAN_RESTAURANT: 'restaurant',\n VIETNAMESE_RESTAURANT: 'restaurant',\n WELSH_RESTAURANT: 'restaurant',\n WESTERN_RESTAURANT: 'restaurant',\n YOGURT_JUICE_BAR: 'restaurant',\n ART_SCHOOL: 'education',\n CHILD_CARE_FACILITY: 'education',\n CULINARY_SCHOOL: 'education',\n DANCE_STUDIO_SCHOOL: 'education',\n DRIVING_SCHOOL: 'education',\n HIGH_SCHOOL: 'education',\n LANGUAGE_SCHOOL: 'education',\n MIDDLE_SCHOOL: 'education',\n PRE_SCHOOL: 'education',\n PRIMARY_SCHOOL: 'education',\n SENIOR_HIGH_SCHOOL: 'education',\n SPECIAL_SCHOOL: 'education',\n SPORT_SCHOOL: 'education',\n TECHNICAL_SCHOOL: 'education',\n VOCATIONAL_SCHOOL: 'education',\n AGRICULTURAL_SUPPLIES: 'shop_or_store',\n ANTIQUE_ART_SHOP: 'shop_or_store',\n BAGS_LEATHERWEAR: 'shop_or_store',\n BAKERY: 'shop_or_store',\n BEAUTY_SALON: 'shop_or_store',\n BEAUTY_SUPPLIES: 'shop_or_store',\n BOATING_EQUIPMENT_ACCESSORIES: 'shop_or_store',\n BOOK_SHOP: 'shop_or_store',\n BUTCHER: 'shop_or_store',\n CAMERAS_PHOTOGRAPHY: 'shop_or_store',\n CARPET_FLOOR_COVERINGS: 'shop_or_store',\n CAR_ACCESSORIES: 'shop_or_store',\n CHRISTMAS_HOLIDAY_SHOP: 'shop_or_store',\n COMPUTER_COMPUTER_SUPPLIES: 'shop_or_store',\n CONSTRUCTION_MATERIAL_EQUIPMENT: 'shop_or_store',\n CONSUMER_ELECTRONICS: 'shop_or_store',\n CONVENIENCE_STORE: 'shop_or_store',\n CURTAINS_TEXTILES: 'shop_or_store',\n C_DS_DVD_VIDEOS: 'shop_or_store',\n DELICATESSEN: 'shop_or_store',\n DO_IT_YOURSELF_CENTERS: 'shop_or_store',\n DRIVE_THROUGH_BOTTLE_SHOP: 'shop_or_store',\n DRY_CLEANER: 'shop_or_store',\n ELECTRICAL_APPLIANCES_SHOP: 'shop_or_store',\n FACTORY_OUTLET: 'shop_or_store',\n FISHMONGER: 'shop_or_store',\n FLORISTS: 'shop_or_store',\n FOOTWEAR_SHOE_REPAIRS: 'shop_or_store',\n FURNITURE_HOME_FURNISHINGS: 'shop_or_store',\n GARDEN_CENTERS_SERVICES: 'shop_or_store',\n GIFTS_CARDS_NOVELTIES_SOUVENIRS: 'shop_or_store',\n GLASSWARE_CERAMIC_SHOP: 'shop_or_store',\n GLASS_WINDOWS_STORE: 'shop_or_store',\n GREENGROCER: 'shop_or_store',\n GROCERY_STORE: 'shop_or_store',\n HAIRDRESSER: 'shop_or_store',\n HARDWARE_STORE: 'shop_or_store',\n HOBBY_SHOP: 'shop_or_store',\n HOUSE_GARDEN_FURNITURE_FITTINGS: 'shop_or_store',\n JEWELRY_CLOCKS_WATCHES: 'shop_or_store',\n KITCHENS_BATHROOMS: 'shop_or_store',\n LAUNDRY: 'shop_or_store',\n LIGHTING_SHOPS: 'shop_or_store',\n LOCAL_SPECIALITIES_SHOP: 'shop_or_store',\n LOTTERY_SHOP: 'shop_or_store',\n MARINE_ELECTRONIC_EQUIPMENT: 'shop_or_store',\n MEDICAL_SUPPLIES_EQUIPMENT: 'shop_or_store',\n MOBILE_PHONE_SHOP: 'shop_or_store',\n MUSIC_INSTRUMENTS_STORE: 'shop_or_store',\n NAIL_SALON: 'shop_or_store',\n NEWSAGENTS_TOBACCONISTS: 'shop_or_store',\n OFFICE_EQUIPMENT: 'shop_or_store',\n OPTICIAN: 'shop_or_store',\n OTHER_FOOD_SHOPS: 'shop_or_store',\n PAINTING_DECORATING: 'shop_or_store',\n PAWN_SHOP: 'shop_or_store',\n PERSONAL_CARE_FACILITY: 'shop_or_store',\n PERSONAL_SERVICE: 'shop_or_store',\n PET_SUPPLIES: 'shop_or_store',\n PHOTOCOPY_SHOP: 'shop_or_store',\n PHOTO_LAB_DEVELOPMENT: 'shop_or_store',\n RECYCLING_SHOP: 'shop_or_store',\n RETAIL_OUTLET: 'shop_or_store',\n SAUNA_SOLARIUM_MASSAGE: 'shop_or_store',\n SECURITY_PRODUCTS: 'shop_or_store',\n SHOPPING_SERVICE: 'shop_or_store',\n SPECIALTY_FOODS: 'shop_or_store',\n SPORTS_EQUIPMENT_CLOTHING: 'shop_or_store',\n STAMP_SHOP: 'shop_or_store',\n TAILOR_SHOP: 'shop_or_store',\n TOYS_GAMES_SHOP: 'shop_or_store',\n VARIETY_STORE: 'shop_or_store',\n VIDEO_RENTAL_SHOP: 'shop_or_store',\n WHOLESALE_CLUB: 'shop_or_store',\n WINE_SPIRITS: 'shop_or_store',\n ATHLETICS_TRACK: 'sport_facility',\n BASEBALL_PARK: 'sport_facility',\n BASKETBALL_ARENA: 'sport_facility',\n BOWLING_CENTER: 'sport_facility',\n CRICKET_GROUND: 'sport_facility',\n FITNESS_CLUB_CENTER: 'sport_facility',\n FLYING_CLUB: 'sport_facility',\n HOCKEY_CLUB: 'sport_facility',\n HORSE_RACING_TRACK: 'sport_facility',\n HORSE_RIDING_CENTER: 'sport_facility',\n ICE_HOCKEY_ARENA: 'sport_facility',\n OTHER_WINTER_SPORT: 'sport_facility',\n RACE_TRACK: 'sport_facility',\n RUGBY_GROUND: 'sport_facility',\n SKI_RESORT: 'sport_facility',\n SNOOKER_POOL_BILLIARD: 'sport_facility',\n THEMATIC_SPORT_CENTER: 'sport_facility',\n FOOTBALL_STADIUM: 'stadium',\n MOTOR_RACING_STADIUM: 'stadium',\n MULTI_PURPOSE_STADIUM: 'stadium',\n NETBALL_STADIUM: 'stadium',\n SOCCER_STADIUM: 'stadium',\n STOCK_EXCHANGE: 'stock_exchange',\n TAXI_LIMOUSINE_SHUTTLE_SERVICE: 'taxi_stand',\n AMPHITHEATER: 'theater',\n ARCH: 'tourist_attraction',\n BATTLEFIELD: 'tourist_attraction',\n CAVE: 'tourist_attraction',\n CEMETERY: 'tourist_attraction',\n HISTORIC_SITE: 'tourist_attraction',\n MAUSOLEUM_GRAVE: 'tourist_attraction',\n MEMORIAL: 'tourist_attraction',\n MINERAL_HOT_SPRINGS: 'tourist_attraction',\n MONUMENT: 'tourist_attraction',\n NATURAL_TOURIST_ATTRACTION: 'tourist_attraction',\n OBSERVATORY: 'tourist_attraction',\n STATUE: 'tourist_attraction',\n TOURIST_ATTRACTION: 'tourist_attraction',\n TOWER: 'tourist_attraction',\n ROAD_TRAFFIC_CONTROL_CENTER: 'traffic_office',\n ADVENTURE_VEHICLE_TRAIL: 'trailhead',\n HIKING_TRAIL: 'trailhead',\n HORSE_RIDING_TRAIL: 'trailhead',\n MOUNTAIN_BIKE_TRAIL: 'trailhead',\n ROCK_CLIMBING_TRAIL: 'trailhead',\n APARTMENT_RENTAL: 'business',\n CONDOMINIUM_COMPLEX: 'business',\n FLATS_APARTMENT_COMPLEX: 'business',\n RESIDENTIAL_ESTATE: 'business',\n RETIREMENT_COMMUNITY: 'business',\n TOWNHOUSE_COMPLEX: 'business',\n ANIMAL_SERVICES: 'veterinary',\n ANIMAL_SHELTER: 'animal_shelter',\n WEIGH_SCALES: 'weighbridge',\n WILDLIFE_PARK: 'zoo_or_aquarium',\n ZOO: 'zoo_or_aquarium',\n} as const;\n\n/**\n * Map style POI category type.\n *\n * @remarks\n * Represents all available POI (Point of Interest) categories used in the map style.\n * These categories correspond to Search API classification codes and are used for\n * filtering, styling, and displaying POI icons on the map.\n *\n * Each category maps to a specific icon sprite and can be used with custom icon configurations.\n *\n * @example\n * ```ts\n * const category: MapStylePOICategory = 'RESTAURANT';\n * ```\n *\n * @see {@link POICategoryGroup} - For grouped collections of related categories\n *\n * @group POIs\n */\nexport type MapStylePOICategory = keyof typeof mapDisplayPoiCategoryMappings;\n\n/**\n * @ignore\n */\nexport const toBaseMapPOICategory = (category: POICategory): string => completeMapDisplayPoiCategoryMappings[category];\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * Bold font face used in the TomTom map style.\n *\n * @remarks\n * This is the primary bold font used for prominent labels and headings in the map.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_BOLD_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_BOLD_FONT],\n * 'text-field': ['get', 'name']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_BOLD_FONT = 'Noto-Bold';\n\n/**\n * Regular font face used in the TomTom map style.\n *\n * @remarks\n * This is the standard font used for most text labels on the map.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_REGULAR_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_REGULAR_FONT],\n * 'text-field': ['get', 'description']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_REGULAR_FONT = 'Noto-Regular';\n\n/**\n * Medium weight font face used in the TomTom map style.\n *\n * @remarks\n * This font provides a middle ground between regular and bold weights.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_MEDIUM_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_MEDIUM_FONT],\n * 'text-field': ['get', 'title']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_MEDIUM_FONT = 'Noto-Medium';\n\n/**\n * Italic font face used in the TomTom map style.\n *\n * @remarks\n * This is the italic variant used for emphasized or secondary text labels.\n * Use this constant when creating custom layers to maintain visual consistency with the map style.\n *\n * @example\n * ```typescript\n * import { MAP_ITALIC_FONT } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [MAP_ITALIC_FONT],\n * 'text-field': ['get', 'subtitle']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const MAP_ITALIC_FONT = 'NotoSans-MediumItalic';\n\n/**\n * Default text size expression used in the TomTom map style.\n *\n * @remarks\n * This MapLibre expression defines zoom-dependent text sizing that scales from 12px at zoom 10\n * to 14px at zoom 16. Use this for consistent text sizing across zoom levels.\n *\n * @example\n * ```typescript\n * import { DEFAULT_TEXT_SIZE } from '@tomtom-international/maps-sdk-js/map';\n *\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-size': DEFAULT_TEXT_SIZE,\n * 'text-field': ['get', 'name']\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const DEFAULT_TEXT_SIZE: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 10, 14, 18, 16];\n\n/**\n * Array of all available font faces in the TomTom map style.\n *\n * @remarks\n * Contains all font variants available in the map style. Useful for font selection\n * or validation when creating custom layers.\n *\n * @example\n * ```typescript\n * import { mapFonts } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Check if a font is available\n * if (mapFonts.includes('Noto-Bold')) {\n * // Use the font\n * }\n *\n * // Use as fallback list\n * const textLayer = {\n * type: 'symbol',\n * layout: {\n * 'text-font': [...mapFonts]\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport const mapFonts = [MAP_REGULAR_FONT, MAP_ITALIC_FONT, MAP_BOLD_FONT, MAP_MEDIUM_FONT] as const;\n\n/**\n * Type representing valid font faces available in the TomTom map style.\n *\n * @remarks\n * Use this type to ensure type-safe font selection when working with text layers.\n * Restricts values to only the fonts available in the map style.\n *\n * @example\n * ```typescript\n * import type { MapFont } from '@tomtom-international/maps-sdk-js/map';\n *\n * function createTextLayer(font: MapFont) {\n * return {\n * type: 'symbol',\n * layout: {\n * 'text-font': [font],\n * 'text-field': ['get', 'name']\n * }\n * };\n * }\n *\n * // Type-safe: only accepts valid map fonts\n * const layer = createTextLayer('Noto-Bold');\n * ```\n *\n * @group Map Style\n */\nexport type MapFont = (typeof mapFonts)[number];\n\n/**\n * Default pin icon scale at max zoom level (zoom 22).\n * This is the icon-size scale factor - 1.0 would be the original icon size.\n * @ignore\n */\nexport const DEFAULT_MAX_PIN_SCALE = 0.8;\n\n/**\n * @ignore\n */\nexport const PIN_ICON_SIZE: ExpressionSpecification = [\n 'interpolate',\n ['linear'],\n ['zoom'],\n 8,\n 0.6,\n 22,\n DEFAULT_MAX_PIN_SCALE,\n];\n\n/**\n * @ignore\n */\nexport const SELECTED_PIN_ICON_SIZE: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 8, 0.8, 22, 1];\n","import { SymbolLayerSpecification } from 'maplibre-gl';\nimport { LayerSpecTemplate } from '../types';\nimport { DEFAULT_TEXT_SIZE, MAP_BOLD_FONT, PIN_ICON_SIZE } from './commonLayerProps';\n\n/**\n * @ignore\n */\nexport const TITLE = 'title';\n\n/**\n * @ignore\n */\nexport const ICON_ID = 'iconID';\n\n/**\n * Y-offset multiplier for text positioned below icons (top anchor).\n * In ems, relative to icon scale.\n * @ignore\n */\nexport const DEFAULT_TEXT_OFFSET_Y = 0.7;\n\n/**\n * X-offset multiplier for text positioned beside icons (left/right anchors).\n * In ems, relative to icon scale.\n * @ignore\n */\nexport const DEFAULT_TEXT_OFFSET_X = 1.4;\n\n/**\n * @ignore\n */\nexport const DEFAULT_PLACE_ICON_ID = 'default_place';\n\n/**\n * @ignore\n */\nexport const pinIconBaseLayout: SymbolLayerSpecification['layout'] = {\n 'icon-image': ['get', ICON_ID],\n 'icon-anchor': 'bottom',\n 'icon-size': PIN_ICON_SIZE,\n 'icon-allow-overlap': true,\n 'icon-padding': 0,\n};\n\n/**\n * @ignore\n */\nexport const pinIconBasePaint: SymbolLayerSpecification['paint'] = {\n 'icon-translate': [0, 5],\n 'icon-translate-anchor': 'viewport',\n};\n\n/**\n * @ignore\n */\nexport const pinTextBaseLayout: SymbolLayerSpecification['layout'] = {\n 'text-optional': true,\n 'text-font': [MAP_BOLD_FONT],\n 'text-field': ['get', TITLE],\n 'text-justify': 'auto',\n 'text-variable-anchor': ['top', 'left', 'right'],\n // NOTE: make sure to text against pins and waypoints, in a way that there's enough distance from the pin so the text doesn't disappear\n 'text-variable-anchor-offset': [\n 'top',\n [0, DEFAULT_TEXT_OFFSET_Y],\n 'left',\n [DEFAULT_TEXT_OFFSET_X, -DEFAULT_TEXT_OFFSET_X],\n 'right',\n [-DEFAULT_TEXT_OFFSET_X, -DEFAULT_TEXT_OFFSET_X],\n ],\n 'text-size': DEFAULT_TEXT_SIZE,\n 'text-padding': 5,\n};\n\n/**\n * @ignore\n */\nexport const pinTextBasePaint: SymbolLayerSpecification['paint'] = {\n 'text-color': '#333333',\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': ['interpolate', ['linear'], ['zoom'], 6, 1, 10, 1.5],\n 'text-translate-anchor': 'viewport',\n};\n\n/**\n * Pin places, base layer with mostly the icon portion.\n * @ignore\n */\nexport const pinLayerBaseSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n layout: { ...pinIconBaseLayout, ...pinTextBaseLayout },\n paint: { ...pinIconBasePaint, ...pinTextBasePaint },\n};\n","/**\n * Returns a text with a number suffixed after a hyphen.\n * @ignore\n */\nexport const suffixNumber = (text: string, numberToSuffix: number): string => `${text}-${numberToSuffix}`;\n","import { suffixNumber } from '../../shared/layers/utils';\nimport { parseSvg } from '../../shared/resources';\nimport type { PlacesModuleConfig, PlacesTheme } from '../types/placesModuleConfig';\n\n/**\n * Map of icon IDs to their text offset scale factors.\n * @ignore\n */\nexport type IconScalesMap = Map<string, { heightScale: number; widthScale: number }>;\n\n/**\n * Default pin dimensions (from base pin.svg)\n */\nconst DEFAULT_PIN_HEIGHT_PX = 140;\nconst DEFAULT_PIN_WIDTH_PX = 120;\n\n/**\n * Default base-map POI icon dimensions (from base-theme POI icons)\n */\nconst DEFAULT_MAP_POI_HEIGHT_PX = 54;\nconst DEFAULT_MAP_POI_WIDTH_PX = 54;\n\n/**\n * Extracts dimensions from an SVG string or HTMLImageElement.\n * For SVGs, parses the viewBox or width/height attributes.\n * For images, uses naturalWidth/naturalHeight.\n * @ignore\n */\nexport const extractImageDimensions = (image: string | HTMLImageElement): { width: number; height: number } | null => {\n try {\n if (typeof image === 'string') {\n if (image.includes('<svg')) {\n // Parse SVG to extract dimensions\n const svgElement = parseSvg(image);\n\n // Try viewBox first (format: \"minX minY width height\")\n const viewBox = svgElement.getAttribute('viewBox');\n if (viewBox) {\n const parts = viewBox.split(/\\s+/);\n if (parts.length === 4) {\n return {\n width: Number.parseFloat(parts[2]),\n height: Number.parseFloat(parts[3]),\n };\n }\n }\n\n // Fallback to width/height attributes\n const width = svgElement.getAttribute('width');\n const height = svgElement.getAttribute('height');\n if (width && height) {\n return {\n width: Number.parseFloat(width),\n height: Number.parseFloat(height),\n };\n }\n }\n // For URL strings, we can't extract dimensions synchronously\n return null;\n } else {\n // HTMLImageElement - check if loaded\n if (image.complete && image.naturalWidth > 0) {\n return {\n width: image.naturalWidth,\n height: image.naturalHeight,\n };\n }\n return null;\n }\n } catch (error) {\n console.warn('Failed to extract image dimensions:', error);\n return null;\n }\n};\n\n/**\n * Calculate the scale factors for a custom icon based on its dimensions relative to standard icon sizes.\n *\n * Calculates both height and width scales independently:\n * - Height scale is used for vertical text offset\n * - Width scale is used for horizontal text offset\n *\n *\n * @param image The image to extract dimensions from\n * @param theme The places theme ('base-map' for circles, 'pin' for pins)\n * @returns Object with heightScale and widthScale, or undefined if icon is standard-sized (within tolerance)\n * @ignore\n */\nexport const calculateIconScale = (\n image: string | HTMLImageElement | undefined,\n theme?: PlacesTheme,\n): { heightScale: number; widthScale: number } | undefined => {\n if (!image) {\n return undefined;\n }\n\n const dimensions = extractImageDimensions(image);\n if (!dimensions) {\n return undefined;\n }\n\n const isBaseMapTheme = theme === 'base-map';\n\n // For base-map theme, we need to scale relative to POI icons\n if (isBaseMapTheme) {\n const heightScale = dimensions.height / DEFAULT_MAP_POI_HEIGHT_PX;\n const widthScale = dimensions.width / DEFAULT_MAP_POI_WIDTH_PX;\n\n return { heightScale, widthScale };\n } else {\n // For pin theme, check if it's different from default pin\n const heightScale = dimensions.height / DEFAULT_PIN_HEIGHT_PX;\n const widthScale = dimensions.width / DEFAULT_PIN_WIDTH_PX;\n\n return { heightScale, widthScale };\n }\n};\n\n/**\n * Builds a map of icon IDs to their text offset scales for custom icons.\n * @ignore\n */\nexport const buildCustomIconScalesMap = (\n config: PlacesModuleConfig | undefined,\n instanceIndex: number,\n): IconScalesMap => {\n const iconTextOffsetScales = new Map<string, { heightScale: number; widthScale: number }>();\n const customIcons = config?.icon?.categoryIcons ?? [];\n\n for (const icon of customIcons) {\n if (icon.image) {\n const scales = calculateIconScale(icon.image, config?.theme);\n if (scales !== undefined) {\n // Base icon ID with instance suffix\n const suffixedIconId = suffixNumber(icon.id, instanceIndex);\n iconTextOffsetScales.set(suffixedIconId, scales);\n\n // If this icon has an availability level, also add the availability-suffixed version\n // (e.g., \"ELECTRIC_VEHICLE_STATION-available-0\")\n if (icon.availabilityLevel) {\n const availabilitySuffixedId = suffixNumber(`${icon.id}-${icon.availabilityLevel}`, instanceIndex);\n iconTextOffsetScales.set(availabilitySuffixedId, scales);\n }\n }\n }\n }\n\n return iconTextOffsetScales;\n};\n","import type { ChargingPark, ChargingParkWithAvailability, Place, POICategory } from '@tomtom-org/maps-sdk/core';\nimport type { ExpressionSpecification } from 'maplibre-gl';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport type { AvailabilityLevel } from '../../shared/types/image';\nimport type { EVAvailabilityConfig, PlacesModuleConfig, PlacesTheme } from '../types/placesModuleConfig';\n\n/**\n * Type guard to check if a charging park has availability data.\n * @ignore\n */\nexport const hasChargingAvailability = (\n chargingPark: ChargingPark | ChargingParkWithAvailability | undefined,\n): chargingPark is ChargingParkWithAvailability =>\n Boolean(chargingPark && 'availability' in chargingPark && chargingPark.availability);\n\n/**\n * Check if a place is an EV charging station with availability data.\n * @ignore\n */\nexport const isEVStationWithAvailability = (place: Place): boolean => {\n const category = place.properties.poi?.classifications?.[0]?.code;\n return category === 'ELECTRIC_VEHICLE_STATION' && hasChargingAvailability(place.properties.chargingPark);\n};\n\n/**\n * Calculate charging point availability information.\n * @ignore\n */\nexport const getChargingPointAvailability = (\n place: Place,\n): { availableCount: number; totalCount: number; ratio: number } | undefined => {\n const chargingPark = place.properties.chargingPark;\n if (hasChargingAvailability(chargingPark)) {\n const availability = chargingPark.availability.chargingPointAvailability;\n const available = availability.statusCounts.Available ?? 0;\n return {\n availableCount: available,\n totalCount: availability.count,\n ratio: available / availability.count,\n };\n }\n return undefined;\n};\n\n/**\n * Default threshold for EV availability - available vs occupied.\n * @ignore\n */\nexport const DEFAULT_EV_AVAILABILITY_THRESHOLD = 0;\n\n/**\n * Default formatter for EV availability text.\n * @ignore\n */\nexport const defaultFormatAvailabilityText = (available: number, total: number): string => `${available}/${total}`;\n\n/**\n * Build availability text for a place with EV availability data.\n * @ignore\n */\nexport const buildAvailabilityText = (place: Place, config?: EVAvailabilityConfig): string => {\n const availability = getChargingPointAvailability(place);\n if (!availability) {\n return '';\n }\n\n const formatFn = config?.formatText ?? defaultFormatAvailabilityText;\n return formatFn(availability.availableCount, availability.totalCount);\n};\n\n/**\n * Build availability ratio for a place with EV availability data.\n * @ignore\n */\nexport const getAvailabilityRatio = (place: Place): number => {\n const availability = getChargingPointAvailability(place);\n return availability?.ratio ?? 0;\n};\n\n/**\n * Get the color expression for EV availability based on ratio.\n * @ignore\n */\nexport const getAvailabilityColorExpression = (config?: EVAvailabilityConfig): ExpressionSpecification => {\n const threshold = config?.threshold ?? DEFAULT_EV_AVAILABILITY_THRESHOLD;\n\n return ['case', ['>=', ['get', 'evAvailabilityRatio'], threshold], 'green', 'red'] as ExpressionSpecification;\n};\n\n/**\n * Handles icon selection for EV stations with availability data.\n * Returns icon ID if availability-specific icon should be used, or undefined to fall through to regular selection.\n * @ignore\n */\nexport const getEVAvailabilityIconID = (\n place: Place,\n poiCategory: POICategory,\n instanceIndex: number,\n config: PlacesModuleConfig,\n iconTheme: PlacesTheme,\n): string | undefined => {\n if (!config.evAvailability?.enabled || !isEVStationWithAvailability(place)) {\n return undefined;\n }\n\n const ratio = getAvailabilityRatio(place);\n const threshold = config.evAvailability.threshold ?? 0.3;\n const requiredLevel: AvailabilityLevel = ratio >= threshold ? 'available' : 'occupied';\n const hasCustomIcons = config.icon?.categoryIcons && config.icon.categoryIcons.length > 0;\n\n const customIconWithAvailability = config.icon?.categoryIcons?.find(\n (customIcon) => customIcon.id === poiCategory && customIcon.availabilityLevel === requiredLevel,\n );\n\n // If a custom icon with the required availability level exists, use it\n if (customIconWithAvailability) {\n return suffixNumber(`${customIconWithAvailability.id}-${requiredLevel}`, instanceIndex);\n }\n\n // For pin theme: use CDN availability sprites when no custom icons are defined\n if (!hasCustomIcons && iconTheme === 'pin') {\n return `7309-${requiredLevel}`;\n }\n\n // Otherwise, fall through to regular icon selection\n return undefined;\n};\n","import type {\n DataDrivenPropertyValueSpecification,\n ExpressionSpecification,\n SymbolLayerSpecification,\n} from 'maplibre-gl';\nimport { DEFAULT_MAX_PIN_SCALE } from '../../shared/layers/commonLayerProps';\nimport { DEFAULT_TEXT_OFFSET_X, DEFAULT_TEXT_OFFSET_Y, ICON_ID } from '../../shared/layers/symbolLayers';\nimport type { PlacesTheme } from '../types/placesModuleConfig';\n\ntype VariableAnchorOffset = NonNullable<SymbolLayerSpecification['layout']>['text-variable-anchor-offset'];\n\n/**\n * Extracts the maximum icon scale factor from an icon-size expression.\n * For interpolate expressions, returns the last value (max zoom scale).\n * @ignore\n */\nconst extractMaxIconScale = (expression: DataDrivenPropertyValueSpecification<number> | undefined): number => {\n if (!expression) {\n return DEFAULT_MAX_PIN_SCALE;\n }\n\n if (typeof expression === 'number') {\n return expression;\n }\n\n if (Array.isArray(expression)) {\n const lastValue = expression.at(-1);\n if (typeof lastValue === 'number') {\n return lastValue;\n }\n }\n\n return DEFAULT_MAX_PIN_SCALE;\n};\n\n/**\n * Layout properties for text offset - can be spread directly into layer layout.\n */\ntype TextOffsetLayout = {\n 'text-offset'?: [number, number];\n 'text-variable-anchor-offset'?: VariableAnchorOffset;\n};\n\n/**\n * Builds anchor offsets for variable-anchor-offset property.\n * @ignore\n */\nconst buildAnchorOffsets = (\n topOffset: number,\n sideOffset: number,\n pinVerticalAdjustment: number,\n customTextOffset?: number,\n): { top: [number, number]; left: [number, number]; right: [number, number] } => {\n const hasCustomOffset = customTextOffset !== undefined;\n // For pin theme with custom offset, override only the primary direction for each anchor\n // top anchor → custom offset applies to vertical, left/right → custom offset applies to horizontal\n return {\n top: hasCustomOffset ? [0, customTextOffset] : [0, topOffset],\n left: hasCustomOffset ? [customTextOffset, pinVerticalAdjustment] : [sideOffset, pinVerticalAdjustment],\n right: hasCustomOffset ? [-customTextOffset, pinVerticalAdjustment] : [-sideOffset, pinVerticalAdjustment],\n };\n};\n\n/**\n * Calculates text offset for place labels\n *\n * @param iconSizeExpression The icon-size property from the layer specification\n * @param iconTextOffsetScales Map of icon IDs to their scale factors (heightScale for vertical, widthScale for horizontal)\n * @param theme The places theme ('base-map' for circles, 'pin' for pins)\n * @param customTextOffset Custom text offset multiplier (overrides default TEXT_OFFSET constants)\n * @returns Configuration object with the MapLibre property type and value to apply\n * @ignore\n */\nexport const getTextOffset = (\n iconSizeExpression: DataDrivenPropertyValueSpecification<number> | undefined,\n iconTextOffsetScales: Map<string, { heightScale: number; widthScale: number }>,\n theme?: PlacesTheme,\n customTextOffset?: number,\n): TextOffsetLayout => {\n const maxIconScale = extractMaxIconScale(iconSizeExpression);\n const iconScaleMultiplier = maxIconScale / DEFAULT_MAX_PIN_SCALE;\n const isBaseMapTheme = theme === 'base-map';\n const hasCustomOffset = customTextOffset !== undefined;\n\n // For base-map theme with custom offset, use simple text-offset (circles are centered)\n if (isBaseMapTheme && hasCustomOffset) {\n return {\n 'text-offset': [customTextOffset, customTextOffset],\n };\n }\n\n // Calculate fallback offsets (used when no custom icons or as default case)\n const fallbackTopOffset = DEFAULT_TEXT_OFFSET_Y * iconScaleMultiplier;\n const fallbackSideOffset = DEFAULT_TEXT_OFFSET_X * iconScaleMultiplier;\n const fallbackPinVerticalAdjustment = isBaseMapTheme ? 0 : -fallbackSideOffset;\n const fallbackOffsets = buildAnchorOffsets(\n fallbackTopOffset,\n fallbackSideOffset,\n fallbackPinVerticalAdjustment,\n customTextOffset,\n );\n const fallbackAnchorOffset = [\n 'top',\n fallbackOffsets.top,\n 'left',\n fallbackOffsets.left,\n 'right',\n fallbackOffsets.right,\n ];\n\n // No custom icons - return literal value directly (no case expression needed)\n if (iconTextOffsetScales.size === 0) {\n return {\n 'text-variable-anchor-offset': fallbackAnchorOffset as VariableAnchorOffset,\n };\n }\n\n // Build case expression for custom icons\n const offsetCaseExpression: (string | number | ExpressionSpecification)[] = ['case'];\n\n for (const [iconId, scales] of iconTextOffsetScales.entries()) {\n // Base-map POI layer uses larger vertical offsets than pin theme to match native map styling\n const baseTopOffset = isBaseMapTheme ? DEFAULT_TEXT_OFFSET_Y * 2 : DEFAULT_TEXT_OFFSET_Y;\n const topOffset = baseTopOffset * scales.heightScale;\n const sideOffset = DEFAULT_TEXT_OFFSET_X * scales.widthScale;\n\n // Base-map theme uses circles (centered) → no vertical adjustment for side anchors\n // Pin theme uses pins (bottom-anchored) → shift labels upward to align with visual center\n const pinVerticalAdjustment = isBaseMapTheme ? 0 : -sideOffset;\n\n const offsets = buildAnchorOffsets(topOffset, sideOffset, pinVerticalAdjustment, customTextOffset);\n offsetCaseExpression.push(\n ['==', ['get', ICON_ID], iconId],\n ['literal', ['top', offsets.top, 'left', offsets.left, 'right', offsets.right]],\n );\n }\n\n // Add fallback for icons not in the custom scales map\n offsetCaseExpression.push(['literal', fallbackAnchorOffset]);\n\n return {\n 'text-variable-anchor-offset': offsetCaseExpression as VariableAnchorOffset,\n };\n};\n","import type { DataDrivenPropertyValueSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { TITLE } from '../../shared/layers/symbolLayers';\nimport type { LightDark } from '../../shared/types/style';\nimport type { PlaceLayerName, PlacesModuleConfig } from '../types/placesModuleConfig';\nimport type { IconScalesMap } from './customIconScales';\nimport { getAvailabilityColorExpression } from './evAvailabilityHelpers';\nimport { getTextOffset } from './textOffsetCalculator';\nimport { getThemeAdaptiveTextColors } from './themeAdaptation';\n\n/**\n * Builds the text field expression for place labels\n * Supports EV availability text when enabled.\n * @ignore\n */\nexport const buildTextFieldExpression = (\n config: PlacesModuleConfig | undefined,\n evAvailabilityEnabled: boolean,\n): DataDrivenPropertyValueSpecification<string> => {\n if (!evAvailabilityEnabled) {\n return ['get', TITLE];\n }\n\n return [\n 'case',\n ['has', 'evAvailabilityText'],\n // If has EV availability, show two-line format with colored availability\n [\n 'format',\n ['get', TITLE],\n {},\n '\\n',\n {},\n ['get', 'evAvailabilityText'],\n {\n 'font-scale': 1.1,\n 'text-color': getAvailabilityColorExpression(config?.evAvailability),\n },\n ],\n // Otherwise, show normal title\n ['get', TITLE],\n ];\n};\n\n/**\n * Builds the layout configuration\n * @ignore\n */\nexport const buildLayoutConfig = (\n layerSpec: LayerSpecTemplate<SymbolLayerSpecification>,\n config: PlacesModuleConfig | undefined,\n layerName: PlaceLayerName,\n textField: DataDrivenPropertyValueSpecification<string>,\n iconTextOffsetScales?: IconScalesMap,\n): SymbolLayerSpecification['layout'] => {\n const textConfig = config?.text;\n const customLayer = config?.layers?.[layerName];\n const hasCustomIcons = iconTextOffsetScales && iconTextOffsetScales.size > 0;\n\n // Start with base layout\n const baseLayout = { ...layerSpec.layout };\n\n // Remove offset properties we'll replace\n if (hasCustomIcons || textConfig?.offset !== undefined) {\n delete baseLayout['text-offset'];\n delete baseLayout['text-variable-anchor-offset'];\n delete baseLayout['text-radial-offset'];\n }\n\n const layout = {\n ...baseLayout,\n ...customLayer?.layout,\n ...(textConfig?.size && { 'text-size': textConfig.size }),\n ...(textConfig?.font && { 'text-font': textConfig.font }),\n 'text-field': textField,\n };\n\n // Apply offset configuration\n if (hasCustomIcons || textConfig?.offset !== undefined) {\n // Dynamic offset calculation handles custom icons and/or custom offset\n // For pin theme, this ensures proper vertical adjustments for left/right anchors\n const iconSize = layerSpec.layout?.['icon-size'];\n const scales = iconTextOffsetScales ?? new Map();\n Object.assign(layout, getTextOffset(iconSize, scales, config?.theme, textConfig?.offset));\n }\n\n return layout;\n};\n\n/**\n * Builds the paint configuration with theme-adaptive colors.\n * @ignore\n */\nexport const buildPaintConfig = (\n layerSpec: LayerSpecTemplate<SymbolLayerSpecification>,\n config: PlacesModuleConfig | undefined,\n layerName: PlaceLayerName,\n lightDark: LightDark,\n): SymbolLayerSpecification['paint'] => {\n const textConfig = config?.text;\n const customLayer = config?.layers?.[layerName];\n const { textColor: baseTextColor, haloColor: baseHaloColor } = getThemeAdaptiveTextColors(lightDark);\n return {\n ...layerSpec.paint,\n // Apply theme-adaptive colors as defaults\n ...(!textConfig?.color && { 'text-color': baseTextColor }),\n ...(!textConfig?.haloColor && { 'text-halo-color': baseHaloColor }),\n // User config takes precedence\n ...(textConfig?.color && { 'text-color': textConfig.color }),\n ...(textConfig?.haloColor && { 'text-halo-color': textConfig.haloColor }),\n ...(textConfig?.haloWidth && { 'text-halo-width': textConfig.haloWidth }),\n ...customLayer?.paint,\n };\n};\n","import { LightDark } from '../../shared/types/style';\n/**\n * Calculates theme-adaptive text colors based on light/dark mode.\n * @param lightDark Whether the current theme is light or dark\n * @returns Object with text and halo colors appropriate for the theme\n * @ignore\n *\n * TODO: Should these colors adapt to the POI context colors,\n * or should they remain as fixed defaults?\n */\nexport const getThemeAdaptiveTextColors = (\n lightDark: LightDark,\n): {\n textColor: string;\n haloColor: string;\n} => {\n return {\n textColor: lightDark === 'dark' ? '#FFFFFF' : '#333333',\n haloColor: lightDark === 'dark' ? '#333333' : '#FFFFFF',\n };\n};\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * @ignore\n */\nexport const isClickEventState: ExpressionSpecification = [\n 'in',\n ['get', 'eventState'],\n ['literal', ['click', 'contextmenu']],\n];\n","import type { DataDrivenPropertyValueSpecification, Map as MapLibreMap, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { isClickEventState } from '../../shared/layers/eventState';\nimport { ICON_ID, TITLE } from '../../shared/layers/symbolLayers';\n\n/**\n * Replaces placeholders in text size spec with the actual title property.\n * @ignore\n */\nexport const getTextSizeSpec = (\n textSize?: DataDrivenPropertyValueSpecification<number>,\n): DataDrivenPropertyValueSpecification<number> => {\n return JSON.parse(JSON.stringify(textSize)?.replaceAll('name', TITLE));\n};\n\n/**\n * Builds a POI-like layer spec that matches the base map style.\n * @ignore\n */\nexport const buildPoiLikeLayerSpec = (map: MapLibreMap): LayerSpecTemplate<SymbolLayerSpecification> => {\n const poiLayer = (map.getStyle().layers.find((layer) => layer.id === 'POI') as SymbolLayerSpecification) || {};\n const textSize = poiLayer.layout?.['text-size'];\n return {\n filter: ['!', isClickEventState],\n type: 'symbol',\n paint: poiLayer.paint,\n layout: {\n ...poiLayer.layout,\n 'text-field': ['get', TITLE],\n 'icon-image': ['get', ICON_ID],\n ...(textSize && { 'text-size': getTextSizeSpec(textSize) }),\n },\n };\n};\n","import type { ExpressionSpecification, Map as MapLibreMap, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate, LightDark } from '../../shared';\nimport { SELECTED_PIN_ICON_SIZE } from '../../shared/layers/commonLayerProps';\nimport { pinLayerBaseSpec } from '../../shared/layers/symbolLayers';\nimport type { PlaceLayerName, PlaceLayersConfig, PlacesModuleConfig } from '../types/placesModuleConfig';\nimport { buildCustomIconScalesMap, type IconScalesMap } from '../utils/customIconScales';\nimport { buildLayoutConfig, buildPaintConfig, buildTextFieldExpression } from '../utils/layerConfiguration';\nimport { buildPoiLikeLayerSpec } from '../utils/layerSpecBuilders';\n\n/**\n * @ignore\n */\nexport const hasEventState: ExpressionSpecification = ['has', 'eventState'];\n\n/**\n * @ignore\n */\nexport const SELECTED_COLOR = '#3f9cd9';\n\n/**\n * @ignore\n */\nexport const pinLayerSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...pinLayerBaseSpec,\n filter: ['!', hasEventState],\n};\n\n/**\n * We use an extra layer for highlighted text since it's not easy to enforce z-ordering with icons and text\n * while text has different collision rules.\n * @ignore\n */\nexport const selectedPinLayerSpec: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...pinLayerBaseSpec,\n filter: hasEventState,\n layout: {\n ...pinLayerBaseSpec.layout,\n 'icon-size': SELECTED_PIN_ICON_SIZE,\n 'text-allow-overlap': true,\n },\n paint: {\n ...pinLayerBaseSpec.paint,\n 'text-color': SELECTED_COLOR,\n },\n};\n\n/**\n * Applies configuration to a layer specification template.\n * @ignore\n */\nconst withConfig = (\n layerSpec: LayerSpecTemplate<SymbolLayerSpecification>,\n config: PlacesModuleConfig | undefined,\n layerName: PlaceLayerName,\n lightDark: LightDark,\n iconTextOffsetScales?: IconScalesMap,\n): LayerSpecTemplate<SymbolLayerSpecification> => {\n const textConfig = config?.text;\n const customLayer = config?.layers?.[layerName];\n const evAvailabilityEnabled = config?.evAvailability?.enabled === true;\n\n const textFieldExpression = buildTextFieldExpression(config, evAvailabilityEnabled);\n const textField =\n textConfig?.title && typeof textConfig?.title !== 'function' ? textConfig.title : textFieldExpression;\n\n return {\n ...layerSpec,\n layout: buildLayoutConfig(layerSpec, config, layerName, textField, iconTextOffsetScales),\n paint: buildPaintConfig(layerSpec, config, layerName, lightDark),\n ...customLayer,\n };\n};\n\n/**\n * Builds layer specifications for places display.\n * @ignore\n */\nexport const buildPlacesLayerSpecs = (\n config: PlacesModuleConfig | undefined,\n mapLibreMap: MapLibreMap,\n styleLightDarkTheme: LightDark,\n instanceIndex: number,\n): PlaceLayersConfig => {\n const iconTextOffsetScales = buildCustomIconScalesMap(config, instanceIndex);\n\n let main: LayerSpecTemplate<SymbolLayerSpecification>;\n let selected: LayerSpecTemplate<SymbolLayerSpecification>;\n\n if (config?.theme === 'base-map') {\n const poiLikeLayerSpec = buildPoiLikeLayerSpec(mapLibreMap);\n main = poiLikeLayerSpec;\n selected = {\n ...poiLikeLayerSpec,\n filter: hasEventState,\n layout: {\n ...poiLikeLayerSpec.layout,\n 'text-allow-overlap': true,\n },\n paint: {\n ...poiLikeLayerSpec.paint,\n 'text-color': SELECTED_COLOR,\n },\n };\n } else {\n // pin / circle\n main = pinLayerSpec;\n selected = selectedPinLayerSpec;\n }\n\n return {\n main: withConfig(main, config, 'main', styleLightDarkTheme, iconTextOffsetScales),\n selected: withConfig(selected, config, 'selected', styleLightDarkTheme, iconTextOffsetScales),\n ...config?.layers?.additional,\n };\n};\n","import { SVGIconStyleOptions } from '../../shared';\nimport { isDOMImageSupported, svgToImg } from '../../shared/imageUtils';\nimport { pinSvg } from '../../shared/resources';\n\n/**\n * Default pin for selected images without a specific category on it.\n * @ignore\n */\nexport const defaultPin = (options?: SVGIconStyleOptions): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return svgToImg(pinSvg(options));\n};\n","// Supported sub-categories for map display pins\n// See: https://github.com/tomtom-internal/mdt-backend-mapbox-gl-js-styles/blob/orbis-preview/src/orbis/sprites/poi_light/config.json\n// For the rest we'll use the main categories (which are the first 4 digits of a category)\nconst supportedPinSubcategories: Set<number> = new Set([\n 7339002, 8099002, 7369004, 7321003, 7376006, 9362003, 9362004, 9160004, 9376007, 7315015, 9376006, 9376002, 7315078,\n 7315149, 9376005, 7372003, 9352045, 9352032, 9361048, 9902003, 9378005, 7383004, 9910004, 7320002, 9362016, 7320003,\n 9362025, 9942002, 9942003, 7380005, 9663003, 9361021, 9379009, 9379004, 7315147, 9376003, 9160002, 9160003, 9352008,\n 9361006, 7389004, 9910006,\n]);\n\n/**\n * @ignore\n */\nexport const toPinImageID = (categoryID: number | undefined): string | undefined => {\n if (!categoryID) {\n return undefined;\n }\n\n // Check if the category ID is in our supported subcategories:\n if (supportedPinSubcategories.has(categoryID)) {\n return categoryID.toString();\n }\n\n // If not, fall back to the main category (first 4 digits of the category ID):\n return categoryID.toString().substring(0, 4);\n};\n","import { generateId, Place, Places, POICategory, poiCategoriesToID } from '@tomtom-org/maps-sdk/core';\nimport { toBaseMapPOICategory } from '../../pois/poiCategoryMapping';\nimport { DEFAULT_PLACE_ICON_ID } from '../../shared/layers/symbolLayers';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport type { DisplayPlaceProps } from '../types/placeDisplayProps';\nimport type { PlacesModuleConfig, PlacesTheme } from '../types/placesModuleConfig';\nimport {\n buildAvailabilityText,\n getAvailabilityRatio,\n getEVAvailabilityIconID,\n isEVStationWithAvailability,\n} from './evAvailabilityHelpers';\nimport { toPinImageID } from './toPinImageID';\n\n/**\n * Builds the title of the place to display it on the map.\n * @param place The place to display.\n * @ignore\n */\nexport const buildPlaceTitle = (place: Place): string =>\n place.properties.poi?.name ?? place.properties.address.freeformAddress;\n\n/**\n * Resolves the image ID to use for the given POI category and icon theme.\n */\nconst toImageID = (poiCategory: POICategory, iconTheme: PlacesTheme, defaultPlaceIconID: string): string => {\n if (iconTheme === 'pin') {\n const imageID = toPinImageID(poiCategoriesToID[poiCategory]);\n return imageID ?? defaultPlaceIconID;\n } else {\n const imageID = toBaseMapPOICategory(poiCategory);\n return imageID ? `poi-${imageID}` : defaultPlaceIconID;\n }\n};\n\n/**\n * Gets the map style sprite image ID to display on the map for the give place.\n * @ignore\n */\nexport const getIconIDForPlace = (place: Place, instanceIndex: number, config: PlacesModuleConfig = {}): string => {\n const iconTheme = config.theme ?? 'pin';\n const defaultPlaceIconID = suffixNumber(DEFAULT_PLACE_ICON_ID, instanceIndex);\n\n const imageMapping = config.icon?.mapping;\n // First, try custom mapping if provided:\n if (imageMapping) {\n if (imageMapping.to === 'imageID') {\n // Direct image ID mapping\n return imageMapping.fn(place);\n } else {\n // POI category mapping - resolve category to icon ID\n return toImageID(imageMapping.fn(place), iconTheme, defaultPlaceIconID);\n }\n }\n\n // Next, try to match any custom icon:\n const poiCategory = place.properties.poi?.classifications?.[0]?.code as POICategory;\n\n // Check for EV availability-specific icon selection\n const evAvailabilityIconID = getEVAvailabilityIconID(place, poiCategory, instanceIndex, config, iconTheme);\n if (evAvailabilityIconID) {\n return evAvailabilityIconID;\n }\n\n // Regular custom icon matching (no availability)\n const matchingCustomIcon = config.icon?.categoryIcons?.find((customIcon) => customIcon.id === poiCategory);\n if (matchingCustomIcon) {\n return suffixNumber(matchingCustomIcon.id, instanceIndex);\n }\n\n // Else: if no custom icon matched, we map to the map style icons or default:\n const baseIconID = toImageID(poiCategory, iconTheme, defaultPlaceIconID);\n return baseIconID;\n};\n\n/**\n * Maps a Place category to the poi layer one, so the latter's style can apply it.\n * @ignore\n */\nexport const getPOILayerCategoryForPlace = (place: Place): string | undefined => {\n const category = place.properties.poi?.classifications?.[0]?.code;\n // if it's one of the different categories between search and poi layer, use poi layer category\n return category && toBaseMapPOICategory(category);\n};\n\n/**\n * Transforms the input of a \"show\" call to FeatureCollection \"Places\".\n * @ignore\n */\nexport const toPlaces = (places: Place | Place[] | Places): Places => {\n if (Array.isArray(places)) {\n return { type: 'FeatureCollection', features: places };\n }\n return places.type === 'Feature' ? { type: 'FeatureCollection', features: [places] } : places;\n};\n\n/**\n * Merges EV availability props into extraFeatureProps if enabled.\n * This makes EV stations use the same mechanism as any other custom properties.\n * @ignore\n */\nconst mergeEVAvailabilityProps = (\n extraFeatureProps: PlacesModuleConfig['extraFeatureProps'],\n evAvailabilityConfig: PlacesModuleConfig['evAvailability'],\n places: Places,\n): PlacesModuleConfig['extraFeatureProps'] => {\n if (evAvailabilityConfig?.enabled !== true) {\n return extraFeatureProps;\n }\n\n // Check if any EV stations exist but lack availability data\n let hasEVStations = false;\n let hasEVStationsWithAvailability = false;\n\n for (const place of places.features) {\n const isEVStation = place.properties.poi?.classifications?.[0]?.code === 'ELECTRIC_VEHICLE_STATION';\n if (isEVStation) {\n hasEVStations = true;\n if (isEVStationWithAvailability(place)) {\n hasEVStationsWithAvailability = true;\n break;\n }\n }\n }\n\n if (hasEVStations && !hasEVStationsWithAvailability) {\n console.warn(\n 'PlacesModule: evAvailability is enabled but no availability data found. ' +\n 'Did you call getPlacesWithEVAvailability()?',\n );\n }\n\n return {\n ...extraFeatureProps,\n evAvailabilityText: (place: Place) =>\n isEVStationWithAvailability(place) ? buildAvailabilityText(place, evAvailabilityConfig) : '',\n evAvailabilityRatio: (place: Place) => (isEVStationWithAvailability(place) ? getAvailabilityRatio(place) : 0),\n };\n};\n\n/**\n * prepare places features to be displayed on map by adding needed properties for title, icon and style\n * @ignore\n */\nexport const preparePlacesForDisplay = (\n placesInput: Place | Place[] | Places,\n instanceIndex: number,\n config: PlacesModuleConfig = {},\n): Places<DisplayPlaceProps> => {\n const places = toPlaces(placesInput);\n\n // Only merge EV availability props when explicitly enabled\n const mergedExtraFeatureProps =\n config.evAvailability?.enabled === true\n ? mergeEVAvailabilityProps(config.extraFeatureProps, config.evAvailability, places)\n : config.extraFeatureProps;\n\n return {\n ...places,\n features: places.features.map((place) => {\n const title =\n typeof config?.text?.title === 'function' ? config?.text?.title(place) : buildPlaceTitle(place);\n\n const extraFeatureProps = mergedExtraFeatureProps\n ? Object.fromEntries(\n Object.entries(mergedExtraFeatureProps).map(([prop, value]) => [\n prop,\n typeof value === 'function' ? value(place) : value,\n ]),\n )\n : {};\n\n const id = place.id ?? generateId();\n\n return {\n ...place,\n id,\n geometry: { ...place.geometry, bbox: place.bbox },\n properties: {\n ...place.properties,\n id, // we need id in properties due to promoteId feature\n title,\n iconID: getIconIDForPlace(place, instanceIndex, config),\n ...(config?.theme === 'base-map' && { category: getPOILayerCategoryForPlace(place) }),\n ...extraFeatureProps,\n },\n };\n }),\n };\n};\n","import type { Place, Places } from '@tomtom-org/maps-sdk/core';\nimport type {\n CleanEventStateOptions,\n CleanEventStatesOptions,\n PutEventStateOptions,\n SymbolLayerSpecWithoutSource,\n} from '../shared';\nimport { AbstractMapModule, EventsModule, GeoJSONSourceWithLayers } from '../shared';\nimport { DEFAULT_PLACE_ICON_ID } from '../shared/layers/symbolLayers';\nimport { suffixNumber } from '../shared/layers/utils';\nimport { addOrUpdateImage, changeLayersProps, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { buildPlacesLayerSpecs } from './layers/placesLayers';\nimport { defaultPin } from './resources';\nimport type { DisplayPlaceProps } from './types/placeDisplayProps';\nimport {\n PlaceIconConfig,\n PlaceLayerName,\n PlacesModuleConfig,\n PlacesTheme,\n PlaceTextConfig,\n} from './types/placesModuleConfig';\nimport { preparePlacesForDisplay } from './utils/preparePlacesForDisplay';\n\ntype PlacesSourcesAndLayers = {\n /**\n * Places source id with corresponding layers ids.\n */\n places: GeoJSONSourceWithLayers<Places<DisplayPlaceProps>>;\n};\n\n/**\n * Map module for displaying and managing place markers.\n *\n * The PlacesModule provides functionality to display location markers (pins) on the map\n * for points of interest, search results, or custom locations. It supports various marker\n * styles, custom icons, text labels, and interactive events.\n *\n * @remarks\n * **Features:**\n * - Multiple marker styles (pin, circle, POI-like)\n * - Custom icons per POI category\n * - Text labels with styling options\n * - Data-driven styling via MapLibre expressions\n * - Interactive events (click, hover, etc.)\n * - Support for custom feature properties\n * - EV charging station availability display (opt-in)\n *\n * **Marker Styles:**\n * - `pin`: Traditional teardrop-shaped map pins\n * - `circle`: Simple circular markers\n * - `base-map`: Mimics built-in POI layer styling\n *\n * **EV Charging Station Availability:**\n * When displaying EV charging stations with availability data from\n * {@link getPlacesWithEVAvailability}, the module can:\n * - Show available/total charging points (e.g., \"3/10\")\n * - Color-code availability (green = good, orange = limited, red = none/low)\n * - Display as formatted text within the station's label\n *\n * This feature is disabled by default. To enable it, set `evAvailability.enabled` to `true`\n * in the configuration.\n *\n * **Common Use Cases:**\n * - Search result visualization\n * - Custom location markers\n * - Store locators\n * - EV charging station maps with real-time availability\n * - Delivery/pickup points\n * - Saved locations display\n *\n * @example\n * ```typescript\n * // Create places module with pin markers\n * const placesModule = await PlacesModule.get(map, {\n * icon: {\n * categoryIcons: []\n * },\n * text: {\n * field: (place) => place.properties.poi?.name || 'Unknown'\n * },\n * theme: 'pin'\n * });\n *\n * // Display places from search\n * await placesModule.show(searchResults);\n *\n * // EV Charging Stations - Opt-in to availability display\n * const evStations = await PlacesModule.get(map, {\n * evAvailability: { enabled: true }\n * });\n * const results = await search({ poiCategories: ['ELECTRIC_VEHICLE_STATION'] });\n * evStations.show(await getPlacesWithEVAvailability(results)); // Shows availability\n *\n * // Granular control: Enable for searched stations only, background stations without\n * const bgStations = await PlacesModule.get(map); // EV availability disabled\n * const searched = await PlacesModule.get(map, {\n * evAvailability: { enabled: true }\n * });\n *\n * // Handle clicks\n * placesModule.events.on('click', (feature) => {\n * console.log('Clicked:', feature.properties);\n * });\n *\n * placesModule.events.on('hover', (feature) => {\n * showTooltip(feature.properties.poi?.name);\n * });\n * ```\n *\n * @see [Places Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/places)\n *\n * @group Places\n */\nexport class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, PlacesModuleConfig> {\n private static lastInstanceIndex = -1;\n private layerSpecs!: Record<PlaceLayerName, SymbolLayerSpecWithoutSource>;\n private sourceID!: string;\n private layerIDPrefix!: string;\n /**\n * The index of this instance, to generate unique source and layer IDs.\n * * Starts with 0 and each instance increments it by one.\n * @private\n */\n private instanceIndex!: number;\n private defaultPlaceIconID!: string;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n */\n static async get(tomtomMap: TomTomMap, config?: PlacesModuleConfig): Promise<PlacesModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new PlacesModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: PlacesModuleConfig) {\n super('geojson', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: PlacesModuleConfig, restore?: boolean): PlacesSourcesAndLayers {\n // Only increment the instance index for new instances, not for restore operations\n if (!restore) {\n PlacesModule.lastInstanceIndex++;\n this.instanceIndex = PlacesModule.lastInstanceIndex;\n this.sourceID = `places-${this.instanceIndex}`;\n this.layerIDPrefix = this.sourceID;\n this.defaultPlaceIconID = suffixNumber(DEFAULT_PLACE_ICON_ID, this.instanceIndex);\n }\n\n // Update each layer id with the instance-specific prefix\n this.layerSpecs = this.buildLayerSpecs(config);\n\n return {\n places: new GeoJSONSourceWithLayers(this.mapLibreMap, this.sourceID, [\n this.layerSpecs.main,\n this.layerSpecs.selected,\n ]),\n };\n }\n\n private buildLayerSpecs(config?: PlacesModuleConfig) {\n const layerSpecTemplates = buildPlacesLayerSpecs(\n config,\n this.tomtomMap.mapLibreMap,\n this.tomtomMap.styleLightDarkTheme,\n this.instanceIndex,\n );\n\n // Update each layer id with the instance-specific prefix\n return Object.fromEntries(\n Object.entries(layerSpecTemplates).map(([key, spec]) => [\n key,\n { ...spec, id: `${this.layerIDPrefix}-${key}` },\n ]),\n ) as Record<PlaceLayerName, SymbolLayerSpecWithoutSource>;\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: PlacesModuleConfig | undefined) {\n this.updateLayersAndData(config);\n return config;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previousShownFeatures = this.sourcesWithLayers.places.shownFeatures;\n this.initSourcesWithLayers(this.config, true);\n this.config && this._applyConfig(this.config);\n this.show(previousShownFeatures);\n }\n\n /**\n * Updates the visual theme for displayed places.\n *\n * @param theme - The theme style to apply to place markers.\n *\n * @remarks\n * **Available Themes:**\n * - `pin`: Traditional teardrop-shaped map pins\n * - `circle`: Simple circular markers\n * - `base-map`: Mimics the map's built-in POI layer style with category icons\n *\n * Changes apply immediately to all currently shown places. Other configuration\n * properties (icon config, text config) remain unchanged.\n *\n * @example\n * ```typescript\n * // Switch to pin markers\n * placesModule.applyTheme('pin');\n *\n * // Use simple circles\n * placesModule.applyTheme('circle');\n *\n * // Match map's POI style (ideal to blend in)\n * placesModule.applyTheme('base-map');\n * ```\n */\n applyTheme(theme: PlacesTheme): void {\n this.applyConfigPart({ theme });\n }\n\n /**\n * Updates the icon configuration for displayed places.\n *\n * @param iconConfig - New icon configuration settings.\n *\n * @remarks\n * - Changes apply immediately to currently shown places\n * - Custom icons are loaded if not already in style\n * - Other configuration properties remain unchanged\n *\n * @example\n * ```typescript\n * placesModule.applyIconConfig({\n * categoryIcons: [\n * { category: 'RESTAURANT', id: 'restaurant-icon', image: '/icons/food.png' }\n * ]\n * });\n * ```\n */\n applyIconConfig(iconConfig: PlaceIconConfig): void {\n this.applyConfigPart({ icon: iconConfig });\n }\n\n /**\n * Updates the text/label configuration for displayed places.\n *\n * @param textConfig - New text configuration settings.\n *\n * @remarks\n * Supports both functions and MapLibre expressions for dynamic text.\n *\n * @example\n * ```typescript\n * // Use function\n * placesModule.applyTextConfig({\n * field: (place) => place.properties.poi?.name || 'Unknown'\n * });\n *\n * // Use MapLibre expression\n * placesModule.applyTextConfig({\n * field: ['get', 'title'],\n * size: 14,\n * color: '#333'\n * });\n * ```\n */\n applyTextConfig(textConfig: PlaceTextConfig): void {\n this.applyConfigPart({ text: textConfig });\n }\n\n private applyConfigPart(partialConfig: Partial<PlacesModuleConfig>): void {\n const config = { ...this.config, ...partialConfig };\n this.updateLayersAndData(config);\n this.config = config;\n }\n\n /**\n * Applies additional feature properties to displayed places.\n *\n * @param extraFeatureProps - Object mapping property names to values or functions.\n *\n * @remarks\n * Useful for adding computed properties or metadata for styling/filtering.\n *\n * @example\n * ```typescript\n * placesModule.applyExtraFeatureProps({\n * category: (place) => place.properties.poi?.categories?.[0],\n * rating: (place) => place.properties.poi?.rating || 0,\n * isOpen: true\n * });\n * ```\n */\n applyExtraFeatureProps(extraFeatureProps: { [key: string]: any }): void {\n const config = { ...this.config, extraFeatureProps };\n this.updateData(config);\n this.config = config;\n }\n\n private updateLayersAndData(config: PlacesModuleConfig | undefined): void {\n this.setupImages(config);\n const newLayerSpecs = this.buildLayerSpecs(config);\n // Convert layerSpecs objects to arrays for changeLayersProps\n const newLayerSpecsArray = [newLayerSpecs.main, newLayerSpecs.selected];\n const oldLayerSpecsArray = [this.layerSpecs.main, this.layerSpecs.selected];\n changeLayersProps(newLayerSpecsArray, oldLayerSpecsArray, this.mapLibreMap);\n this.layerSpecs = newLayerSpecs;\n this.updateData(config);\n }\n\n private setupImages(config: PlacesModuleConfig | undefined): void {\n // Ensure default pin is added:\n if (config?.icon) {\n // If we have custom icons, ensure they're added to the map style:\n for (const customIcon of config.icon.categoryIcons ?? []) {\n // Create unique ID for each custom icon, including availability level if present\n const iconID = customIcon.availabilityLevel\n ? `${customIcon.id}-${customIcon.availabilityLevel}`\n : customIcon.id;\n\n addOrUpdateImage(\n 'if-not-in-sprite',\n suffixNumber(iconID, this.instanceIndex),\n customIcon.image as string | HTMLImageElement,\n this.mapLibreMap,\n {\n pixelRatio: customIcon.pixelRatio ?? 2,\n },\n );\n }\n\n if (config.icon.default) {\n if (config.icon.default.image) {\n addOrUpdateImage(\n 'if-not-in-sprite',\n this.defaultPlaceIconID,\n config.icon.default.image.image as string | HTMLImageElement,\n this.mapLibreMap,\n {\n pixelRatio: config.icon.default.image.pixelRatio ?? 2,\n },\n );\n }\n if (config.icon.default.style) {\n addOrUpdateImage(\n 'if-not-in-sprite',\n this.defaultPlaceIconID,\n defaultPin(config.icon.default.style),\n this.mapLibreMap,\n { pixelRatio: 2 },\n );\n }\n }\n } else {\n // Ensure default pin is added:\n addOrUpdateImage('if-not-in-sprite', this.defaultPlaceIconID, defaultPin(), this.mapLibreMap, {\n pixelRatio: 2,\n });\n }\n }\n\n private updateData(config: PlacesModuleConfig | undefined): void {\n this.sourcesWithLayers.places.source.runtimeSource?.setData(\n preparePlacesForDisplay(this.sourcesWithLayers.places.shownFeatures, this.instanceIndex, config),\n );\n }\n\n /**\n * Displays the given places on the map.\n *\n * @param places - Place data to display. Can be a single Place, array of Places,\n * or a Places FeatureCollection.\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown places\n * - Applies current module styling configuration\n * - Automatically generates labels if text config is set\n * - Waits for module to be ready before displaying\n *\n * **Data Sources:**\n * - TomTom Search API results\n * - Custom place objects matching the Place interface\n * - GeoJSON Point features\n *\n * @example\n * Display search results:\n * ```typescript\n * import { search } from '@tomtom-international/maps-sdk-js/services';\n *\n * const results = await search({ query: 'coffee' });\n * await placesModule.show(results);\n * ```\n *\n * @example\n * Display single place:\n * ```typescript\n * await placesModule.show({\n * type: 'Feature',\n * geometry: { type: 'Point', coordinates: [4.9041, 52.3676] },\n * properties: {\n * address: { freeformAddress: 'Amsterdam' },\n * poi: { name: 'Amsterdam Central' }\n * }\n * });\n * ```\n *\n * @example\n * Display multiple places:\n * ```typescript\n * await placesModule.show([place1, place2, place3]);\n * ```\n */\n async show(places: Place | Place[] | Places) {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.places.show(preparePlacesForDisplay(places, this.instanceIndex, this.config));\n }\n\n /**\n * Removes all places from the map.\n *\n * @remarks\n * - Clears all displayed places\n * - Does not reset styling configuration\n * - Module remains initialized and ready for new data\n *\n * @example\n * ```typescript\n * await placesModule.clear();\n * ```\n */\n async clear() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.places.clear();\n }\n\n /**\n * Programmatically sets an event state on a specific place.\n *\n * @param options - Configuration for the event state to apply.\n *\n * @remarks\n * Use this to make places appear clicked or hovered programmatically.\n *\n * @example\n * ```typescript\n * // Make first place appear clicked\n * placesModule.putEventState({\n * index: 0,\n * state: 'click',\n * mode: 'put'\n * });\n * ```\n */\n putEventState(options: PutEventStateOptions) {\n this.sourcesWithLayers.places.putEventState(options);\n }\n\n /**\n * Removes an event state from a specific place.\n *\n * @param options - Configuration for which event state to remove.\n *\n * @example\n * ```typescript\n * placesModule.cleanEventState({ index: 0 });\n * ```\n */\n cleanEventState(options: CleanEventStateOptions): void {\n this.sourcesWithLayers.places.cleanEventState(options);\n }\n\n /**\n * Removes event states from multiple places.\n *\n * @param options - Optional filter for which states to remove.\n *\n * @example\n * ```typescript\n * // Remove all event states\n * placesModule.cleanEventStates();\n *\n * // Remove only hover states\n * placesModule.cleanEventStates({ states: ['hover'] });\n * ```\n */\n cleanEventStates(options?: CleanEventStatesOptions) {\n this.sourcesWithLayers.places.cleanEventStates(options);\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule<Place<DisplayPlaceProps>>(\n this.eventsProxy,\n this.sourcesWithLayers.places,\n this.config?.events,\n );\n }\n}\n","import type { ExpressionFilterSpecification, FilterSpecification, LegacyFilterSpecification } from 'maplibre-gl';\nimport type { FilterShowMode, FilterSyntaxVersion, MultiSyntaxFilter, ValuesFilter } from './types';\n\n/**\n * @ignore\n */\nconst isExpressionFilter = (filter: FilterSpecification): filter is ExpressionFilterSpecification => {\n if (filter === true || filter === false) {\n return true;\n }\n\n if (!Array.isArray(filter) || filter.length === 0) {\n return false;\n }\n switch (filter[0]) {\n case 'has':\n return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';\n\n case 'in':\n return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2]));\n\n case '!in':\n case '!has':\n case 'none':\n return false;\n\n case '==':\n case '!=':\n case '>':\n case '>=':\n case '<':\n case '<=':\n return filter.length !== 3 || Array.isArray(filter[1]) || Array.isArray(filter[2]);\n\n case 'any':\n case 'all':\n for (const f of filter.slice(1)) {\n if (!isExpressionFilter(f as FilterSpecification) && typeof f !== 'boolean') {\n return false;\n }\n }\n return true;\n\n default:\n return true;\n }\n};\n\n/**\n * @ignore\n */\nexport const getSyntaxVersion = (expression: FilterSpecification): FilterSyntaxVersion =>\n isExpressionFilter(expression) ? 'expression' : 'legacy';\n\n/**\n * @ignore\n */\nexport const getMergedAnyFilter = (filters: MultiSyntaxFilter[]): MultiSyntaxFilter | null => {\n if (!filters?.length) {\n return null;\n }\n if (filters.length === 1) {\n return filters[0];\n }\n return {\n expression: ['any', ...filters.map((filter) => filter?.expression)],\n legacy: ['any', ...filters.map((filter) => filter?.legacy)],\n };\n};\n\n/**\n * @ignore\n */\nexport const getMergedAllFilter = (\n filterToAdd: MultiSyntaxFilter,\n originalFilter: FilterSpecification | undefined,\n): FilterSpecification => {\n if (originalFilter) {\n return ['all', filterToAdd[getSyntaxVersion(originalFilter)], originalFilter] as FilterSpecification;\n }\n return filterToAdd.expression;\n};\n\n/**\n * @ignore\n */\nexport const buildMappedValuesFilter = <T>(\n propName: string,\n showMode: FilterShowMode,\n values: T[],\n): MultiSyntaxFilter => {\n if (values.length === 1) {\n const comparator = showMode === 'only' ? '==' : '!=';\n return {\n expression: [comparator, ['get', propName], values[0]] as ExpressionFilterSpecification,\n legacy: [comparator, propName, values[0]] as LegacyFilterSpecification,\n };\n }\n const filterArrayNew = ['in', ['get', propName], ['literal', values]];\n if (showMode === 'only') {\n return {\n expression: filterArrayNew as ExpressionFilterSpecification,\n legacy: ['in', propName, ...values] as LegacyFilterSpecification,\n };\n }\n return {\n expression: ['!', filterArrayNew as ExpressionFilterSpecification],\n legacy: ['!in', propName, ...values] as LegacyFilterSpecification,\n };\n};\n\n/**\n * @ignore\n */\nexport const buildValuesFilter = <T>(\n propName: string,\n filter: ValuesFilter<T>,\n valuesMapping?: (value: T) => unknown,\n): MultiSyntaxFilter =>\n buildMappedValuesFilter(propName, filter.show, valuesMapping ? filter.values.map(valuesMapping) : filter.values);\n","import type { MapStylePOICategory } from '../places';\n\n/**\n * Predefined groups of related POI categories for convenient filtering.\n *\n * @remarks\n * This object maps group names to arrays of {@link MapStylePOICategory} values.\n * Each group contains POI categories that share a common theme or purpose,\n * making it easier to filter multiple related POI types with a single identifier.\n *\n * **Available Groups:**\n * - `FOOD_DRINKS_GROUP` - Dining and beverage establishments (restaurants, cafes, pubs, etc.)\n * - `SHOPPING_GROUP` - Retail stores and shopping centers (shops, markets, supermarkets, etc.)\n * - `TRANSPORTATION_GROUP` - Transportation hubs and stops (airports, stations, terminals, etc.)\n * - `HEALTH_GROUP` - Healthcare facilities and services (hospitals, clinics, pharmacies, etc.)\n * - `PARKING_GROUP` - Parking facilities (garages and open parking areas)\n * - `HOLIDAY_TOURISM_GROUP` - Tourist attractions and recreational sites (museums, parks, beaches, etc.)\n * - `EV_CHARGING_STATIONS_GROUP` - Electric vehicle charging locations\n * - `GAS_STATIONS_GROUP` - Fuel stations for traditional vehicles\n * - `ACCOMMODATION_GROUP` - Lodging facilities (hotels, motels, camping grounds, etc.)\n * - `ENTERTAINMENT_GROUP` - Entertainment venues (cinemas, theaters, nightlife, casinos, etc.)\n * - `SPORTS_LEISURE_GROUP` - Sports and leisure facilities (stadiums, gyms, pools, golf courses, etc.)\n * - `EDUCATION_GROUP` - Educational institutions (schools, universities, libraries, etc.)\n * - `GOVERNMENT_GROUP` - Government and public safety facilities (offices, courts, embassies, police, fire stations)\n *\n * @example\n * Filter to show only food-related POIs:\n * ```ts\n * import { poiCategoryGroups } from '@tomtom-international/maps-sdk-js/map';\n *\n * const foodCategories = poiCategoryGroups.FOOD_DRINKS_GROUP;\n * console.log(foodCategories);\n * // ['RESTAURANT', 'FAST_FOOD', 'CAFE_PUB', 'PUB', 'WINERY', ...]\n * ```\n *\n * @example\n * Use with POI module filtering:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'show',\n * values: ['FOOD_DRINKS_GROUP', 'ENTERTAINMENT_GROUP']\n * }\n * });\n * ```\n *\n * @see {@link POICategoryGroup} - Type representing all available group names\n * @see {@link MapStylePOICategory} - Individual POI category identifiers\n *\n * @group POIs\n */\nexport const poiCategoryGroups: Record<string, MapStylePOICategory[]> = {\n FOOD_DRINKS_GROUP: [\n 'RESTAURANT',\n 'FAST_FOOD',\n 'CAFE_PUB',\n 'PUB',\n 'WINERY',\n 'PUB_FOOD',\n 'SOUL_FOOD',\n 'DELICATESSEN',\n ],\n SHOPPING_GROUP: [\n 'SHOP',\n 'SHOPPING_CENTER',\n 'CLOTHING_SHOP',\n 'MARKET',\n 'FOOD_MARKET',\n 'SUPERMARKETS_HYPERMARKETS',\n 'DEPARTMENT_STORE',\n 'CONVENIENCE_STORE',\n 'GROCERY_STORE',\n 'HARDWARE_STORE',\n 'ELECTRICAL_APPLIANCES_SHOP',\n ],\n TRANSPORTATION_GROUP: [\n 'AIRPORT',\n 'FERRY_TERMINAL',\n 'HELIPAD_HELICOPTER_LANDING',\n 'PUBLIC_TRANSPORT_STOP',\n 'RAILWAY_STATION',\n 'BUS_STOP',\n 'TAXI_STAND',\n ],\n HEALTH_GROUP: [\n 'DOCTOR',\n 'EMERGENCY_MEDICAL_SERVICE',\n 'EMERGENCY_ROOM',\n 'HEALTH_CARE_SERVICE',\n 'HOSPITAL',\n 'HOSPITAL_POLYCLINIC',\n 'PHARMACY',\n 'DENTIST',\n 'WELFARE_ORGANIZATION',\n ],\n PARKING_GROUP: ['PARKING_GARAGE', 'OPEN_PARKING_AREA'],\n HOLIDAY_TOURISM_GROUP: [\n 'AMUSEMENT_PARK',\n 'BEACH',\n 'HOLIDAY_RENTAL',\n 'GEOGRAPHIC_FEATURE',\n 'IMPORTANT_TOURIST_ATTRACTION',\n 'LEISURE_CENTER',\n 'MOUNTAIN_PASS',\n 'MOUNTAIN_PEAK',\n 'MUSEUM',\n 'SCENIC_PANORAMIC_VIEW',\n 'TOURIST_INFORMATION_OFFICE',\n ],\n EV_CHARGING_STATIONS_GROUP: ['ELECTRIC_VEHICLE_STATION'],\n GAS_STATIONS_GROUP: ['GAS_STATION', 'PETROL_STATION'],\n ACCOMMODATION_GROUP: ['CAMPING_GROUND', 'HOTEL_MOTEL', 'HOLIDAY_RENTAL'],\n ENTERTAINMENT_GROUP: [\n 'CINEMA',\n 'THEATER',\n 'MOVIE_THEATER',\n 'NIGHTLIFE',\n 'CONCERT_HALL',\n 'ENTERTAINMENT',\n 'CLUB_ASSOCIATION',\n 'CASINO',\n ],\n SPORTS_LEISURE_GROUP: [\n 'SPORTS_CENTER',\n 'WATER_SPORT',\n 'SWIMMING_POOL',\n 'GOLF_COURSE',\n 'STADIUM',\n 'BEACH',\n 'ICE_SKATING_RINK',\n 'LEISURE_CENTER',\n 'MOUNTAIN_PASS',\n 'MOUNTAIN_PEAK',\n ],\n EDUCATION_GROUP: ['SCHOOL', 'COLLEGE_UNIVERSITY', 'LIBRARY', 'CULTURAL_CENTER'],\n GOVERNMENT_GROUP: ['GOVERNMENT_OFFICE', 'COURTHOUSE', 'EMBASSY', 'FIRE_STATION_BRIGADE', 'POLICE_STATION'],\n};\n\n/**\n * POI category group type.\n *\n * @remarks\n * Represents predefined groups of related POI categories for convenient filtering.\n * Each group contains multiple {@link MapStylePOICategory} values that share a common theme.\n *\n * Using category groups simplifies filtering by allowing you to show or hide\n * multiple related POI types with a single filter value.\n *\n * **Available groups:**\n * - `FOOD_DRINKS_GROUP` - Restaurants, cafes, fast food, wineries, etc.\n * - `SHOPPING_GROUP` - Stores, malls, markets, supermarkets, etc.\n * - `TRANSPORTATION_GROUP` - Airports, train stations, bus stops, ferry terminals, etc.\n * - `HEALTH_GROUP` - Hospitals, clinics, pharmacies, doctors, dentists, etc.\n * - `PARKING_GROUP` - Parking garages and open parking areas\n * - `HOLIDAY_TOURISM_GROUP` - Tourist attractions, museums, beaches, scenic views, etc.\n * - `EV_CHARGING_STATIONS_GROUP` - Electric vehicle charging stations\n * - `GAS_STATIONS_GROUP` - Gas and petrol stations\n * - `ACCOMMODATION_GROUP` - Hotels, motels, camping grounds, etc.\n * - `ENTERTAINMENT_GROUP` - Cinemas, theaters, nightlife, casinos, etc.\n * - `SPORTS_LEISURE_GROUP` - Stadiums, sports centers, swimming pools, golf courses, etc.\n * - `EDUCATION_GROUP` - Schools, universities, libraries, cultural centers\n * - `GOVERNMENT_GROUP` - Government offices, courthouses, embassies, police, fire stations\n *\n * @example\n * Filter to show only food-related POIs:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'show',\n * values: ['FOOD_DRINKS_GROUP']\n * }\n * });\n * ```\n *\n * @example\n * Hide parking and gas stations:\n * ```ts\n * poisModule.configure({\n * categoryFilter: {\n * mode: 'hide',\n * values: ['PARKING_GROUP', 'GAS_STATIONS_GROUP']\n * }\n * });\n * ```\n *\n * @example\n * Combine multiple groups for tourism use case:\n * ```ts\n * const tourismFilter = {\n * mode: 'show',\n * values: [\n * 'HOLIDAY_TOURISM_GROUP',\n * 'ACCOMMODATION_GROUP',\n * 'FOOD_DRINKS_GROUP',\n * 'ENTERTAINMENT_GROUP'\n * ]\n * };\n * ```\n *\n * @see {@link poiCategoryGroups} - The object containing all group definitions\n * @see {@link MapStylePOICategory} - For individual POI categories\n *\n * @group POIs\n */\nexport type POICategoryGroup = keyof typeof poiCategoryGroups;\n","import { POICategory } from '@tomtom-org/maps-sdk/core';\nimport { isNil } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport { toBaseMapPOICategory } from '../places';\nimport type { ValuesFilter } from '../shared';\nimport { AbstractMapModule, EventsModule, POI_SOURCE_ID, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { buildMappedValuesFilter, getMergedAllFilter } from '../shared/mapLibreFilterUtils';\nimport { waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { poiLayerIDs } from './layers/poisLayers';\nimport { poiCategoryGroups } from './poiCategoryGroups';\nimport type { FilterablePOICategory, POIsModuleConfig, POIsModuleFeature } from './types/poisModuleConfig';\n\n/**\n * Gets the specified filtered categories icon IDs to be used in map filtering.\n * @param categories list of filtered categories.\n * @ignore\n */\nexport const getStyleCategories = (categories: FilterablePOICategory[]): string[] => {\n const categoryIds: string[] = [];\n categories.forEach((category: FilterablePOICategory) => {\n if (category in poiCategoryGroups) {\n categoryIds.push(...poiCategoryGroups[category].map(toBaseMapPOICategory));\n } else {\n categoryIds.push(toBaseMapPOICategory(category as POICategory));\n }\n });\n return [...new Set(categoryIds)];\n};\n\n/**\n * IDs of sources and layers for places of interest module.\n */\ntype PoIsSourcesAndLayers = {\n /**\n * Places of interest with corresponding layer ids.\n * TODO: technically source ID is vectorTiles if POIs stay included in base map for Orbis\n */\n poi: StyleSourceWithLayers;\n};\n\n/**\n * POIs Module for controlling Points of Interest displayed in the map style.\n *\n * This module manages the built-in POI layer from the vector map, allowing you to\n * show/hide POIs and filter them by category. POIs are already part of the map style\n * and include businesses, landmarks, and other points of interest.\n *\n * @remarks\n * **Features:**\n * - Toggle POI visibility on/off\n * - Filter by POI categories or category groups\n * - Event handling for POI interactions\n * - Based on vector tile data in the map style\n *\n * **POI Categories:**\n * - Individual categories (e.g., RESTAURANT, HOTEL_MOTEL, PARKING_GARAGE)\n * - Category groups (e.g., FOOD_DRINKS_GROUP, SHOPPING_GROUP, TRANSPORTATION_GROUP)\n *\n * **Difference from PlacesModule:**\n * - POIsModule: Controls existing POIs in the map style\n * - PlacesModule: Displays custom place data from Search API or other sources\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { POIsModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module\n * const poisModule = await POIsModule.get(map);\n *\n * // Toggle visibility\n * poisModule.setVisible(false);\n * poisModule.setVisible(true);\n * ```\n *\n * @example\n * Filter specific categories:\n * ```typescript\n * // Show only restaurants and hotels\n * poisModule.filterCategories({\n * show: 'only',\n * values: ['RESTAURANT', 'HOTEL_MOTEL']\n * });\n *\n * // Hide parking garages\n * poisModule.filterCategories({\n * show: 'all_except',\n * values: ['PARKING_GARAGE', 'OPEN_PARKING_AREA']\n * });\n * ```\n *\n * @example\n * Filter using category groups:\n * ```typescript\n * // Show only food and shopping POIs\n * poisModule.filterCategories({\n * show: 'only',\n * values: ['FOOD_DRINKS_GROUP', 'SHOPPING_GROUP']\n * });\n *\n * // Hide transportation POIs\n * pois.filterCategories({\n * show: 'all_except',\n * values: ['TRANSPORTATION_GROUP']\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('Clicked POI:', feature.properties.name);\n * console.log('Category:', feature.properties.category);\n * });\n * ```\n *\n * @see [POIs Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/pois)\n *\n * @group POIs\n */\nexport class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers, POIsModuleConfig> {\n private categoriesFilter?: ValuesFilter<FilterablePOICategory> | null;\n private originalFilter?: FilterSpecification;\n\n /**\n * Retrieves a POIsModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional initial configuration for visibility and filters.\n *\n * @returns A promise that resolves to the initialized POIsModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `filters.categories`: Category filter to apply on initialization\n *\n * @throws Error if the POI source is not found in the map style\n *\n * @example\n * Default initialization:\n * ```typescript\n * const poisModule = await POIsModule.get(map);\n * ```\n *\n * @example\n * With initial filter:\n * ```typescript\n * const poisModule = await POIsModule.get(map, {\n * visible: true,\n * filters: {\n * categories: {\n * show: 'only',\n * values: ['RESTAURANT', 'CAFE_PUB']\n * }\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: POIsModuleConfig): Promise<POIsModule> {\n await waitUntilMapIsReady(map);\n return new POIsModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: POIsModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const poiRuntimeSource = this.mapLibreMap.getSource(POI_SOURCE_ID);\n if (!poiRuntimeSource) {\n throw notInTheStyle(`init ${POIsModule.name} with source ID ${POI_SOURCE_ID}`);\n }\n const poi = new StyleSourceWithLayers(this.mapLibreMap, poiRuntimeSource, (layer) =>\n poiLayerIDs.includes(layer.id),\n );\n // TODO: check if the layers are present in the style, and if not, throw exception?\n const mainLayer = poi.sourceAndLayerIDs.layerIDs[0];\n if (this.mapLibreMap.getLayer(mainLayer)) {\n this.originalFilter = this.mapLibreMap.getFilter(mainLayer) as FilterSpecification;\n }\n return { poi };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: POIsModuleConfig | undefined) {\n if (config && !isNil(config.visible)) {\n this.setVisible(config.visible);\n } else if (!this._initializing && !this.isVisible()) {\n // applying default:\n this.setVisible(true);\n }\n\n this.filterCategories(config?.filters?.categories);\n return config;\n }\n\n /**\n * Checks if POI layers are currently visible.\n *\n * @returns `true` if at least one POI layer is visible, `false` if all are hidden.\n *\n * @example\n * ```typescript\n * if (pois.isVisible()) {\n * console.log('POIs are displayed');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.poi.isAnyLayerVisible();\n }\n\n /**\n * Sets the visibility of POI layers.\n *\n * @param visible - `true` to show POIs, `false` to hide them.\n *\n * @remarks\n * Changes are applied immediately if the map is ready.\n *\n * @example\n * ```typescript\n * pois.setVisible(false); // Hide all POIs\n * pois.setVisible(true); // Show all POIs\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = {\n ...this.config,\n visible,\n };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.poi.setLayersVisible(visible);\n }\n }\n\n /**\n * Filters POIs by category or category group.\n *\n * @param categoriesFilter - Filter configuration specifying which categories to show/hide.\n * Pass `undefined` to reset to default (show all).\n *\n * @remarks\n * **Filter Modes:**\n * - `only`: Show only the specified categories, hide all others\n * - `all_except`: Show all categories except the specified ones\n *\n * **Category Types:**\n * - Individual categories (e.g., 'RESTAURANT', 'HOTEL_MOTEL')\n * - Category groups (e.g., 'FOOD_DRINKS_GROUP', 'SHOPPING_GROUP')\n *\n * **Available Category Groups:**\n * - FOOD_DRINKS_GROUP\n * - SHOPPING_GROUP\n * - TRANSPORTATION_GROUP\n * - HEALTH_GROUP\n * - PARKING_GROUP\n * - HOLIDAY_TOURISM_GROUP\n * - EV_CHARGING_STATIONS_GROUP\n * - GAS_STATIONS_GROUP\n * - ACCOMMODATION_GROUP\n * - ENTERTAINMENT_GROUP\n * - SPORTS_LEISURE_GROUP\n * - EDUCATION_GROUP\n * - GOVERNMENT_GROUP\n *\n * @example\n * Show only restaurants:\n * ```typescript\n * pois.filterCategories({\n * show: 'only',\n * values: ['RESTAURANT']\n * });\n * ```\n *\n * @example\n * Hide parking:\n * ```typescript\n * pois.filterCategories({\n * show: 'all_except',\n * values: ['PARKING_GROUP']\n * });\n * ```\n *\n * @example\n * Reset filter (show all):\n * ```typescript\n * pois.filterCategories(undefined);\n * ```\n */\n filterCategories(categoriesFilter?: ValuesFilter<FilterablePOICategory> | undefined): void {\n if (categoriesFilter) {\n if (this.tomtomMap.mapReady) {\n const poiFilter = buildMappedValuesFilter(\n 'category',\n categoriesFilter.show,\n getStyleCategories(categoriesFilter.values),\n );\n\n this.mapLibreMap.setFilter('POI', getMergedAllFilter(poiFilter, this.originalFilter));\n }\n this.config = {\n ...this.config,\n filters: {\n categories: categoriesFilter,\n },\n };\n } else if (this.categoriesFilter) {\n // reset categories config to default\n this.config = {\n ...this.config,\n filters: {\n categories: {\n show: 'all_except',\n values: [],\n },\n },\n };\n if (this.tomtomMap.mapReady) {\n // Applies default:\n this.mapLibreMap.setFilter('POI', this.originalFilter);\n }\n }\n\n this.categoriesFilter = categoriesFilter;\n }\n\n /**\n * Gets the events interface for handling user interactions with POIs.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a POI\n * - `contextmenu`: User right-clicks on a POI\n * - `hover`: Mouse enters a POI\n * - `long-hover`: Mouse hovers over POI for extended time\n *\n * **Event Feature Properties:**\n * - `id`: Unique POI identifier\n * - `name`: POI name in native language\n * - `category`: POI category\n * - `iconID`: Icon sprite ID\n * - `group`: Category group\n * - `priority`: Importance level (lower = more important)\n *\n * @example\n * ```typescript\n * pois.events.on('click', (feature, lngLat) => {\n * console.log('POI:', feature.properties.name);\n * console.log('Category:', feature.properties.category);\n * console.log('ID:', feature.properties.id);\n * });\n *\n * pois.events.on('hover', (feature) => {\n * showTooltip(feature.properties.name);\n * });\n * ```\n */\n get events() {\n return new EventsModule<POIsModuleFeature>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.poi,\n this.config?.events,\n );\n }\n}\n","import type { LayerSpecification } from 'maplibre-gl';\nimport { poiLayerIDs } from '../pois';\nimport type { LayerSpecFilter } from '../shared';\nimport type { BaseMapLayerGroupName, BaseMapLayerGroups } from './types/baseMapModuleConfig';\n\ntype LayerGroupMapping = {\n layerIDMatches: string[];\n layerTypes: LayerSpecification['type'][];\n};\n\nconst layerGroupMappings: Record<BaseMapLayerGroupName, LayerGroupMapping> = {\n land: {\n layerIDMatches: ['lulc'],\n layerTypes: ['fill'],\n },\n borders: {\n layerIDMatches: ['borders'],\n layerTypes: ['line'],\n },\n water: {\n layerIDMatches: ['water'],\n layerTypes: ['fill', 'line'],\n },\n buildings2D: {\n layerIDMatches: ['building'],\n layerTypes: ['fill', 'line'],\n },\n buildings3D: {\n layerIDMatches: ['building'],\n layerTypes: ['fill-extrusion'],\n },\n houseNumbers: {\n layerIDMatches: ['house number'],\n layerTypes: ['symbol'],\n },\n roadLines: {\n layerIDMatches: ['road', 'tunnel', 'bridge', 'surface'],\n layerTypes: ['fill', 'line'],\n },\n roadLabels: {\n layerIDMatches: ['road', 'tunnel', 'bridge', 'surface'],\n layerTypes: ['symbol'],\n },\n roadShields: {\n layerIDMatches: ['shield'],\n layerTypes: ['symbol'],\n },\n placeLabels: {\n layerIDMatches: ['places'],\n layerTypes: ['symbol'],\n },\n smallerTownLabels: {\n layerIDMatches: ['town', 'village', 'neighbourhood'],\n layerTypes: ['symbol'],\n },\n cityLabels: {\n layerIDMatches: ['city', 'capital'],\n layerTypes: ['symbol'],\n },\n capitalLabels: {\n layerIDMatches: ['capital'],\n layerTypes: ['symbol'],\n },\n stateLabels: {\n layerIDMatches: ['state'],\n layerTypes: ['symbol'],\n },\n countryLabels: {\n layerIDMatches: ['places - country'],\n layerTypes: ['symbol'],\n },\n};\n\nconst isMatching = (group: BaseMapLayerGroupName, layer: LayerSpecification) => {\n const mapping = layerGroupMappings[group];\n return (\n mapping.layerIDMatches.some((part) => layer.id.toLowerCase().includes(part)) &&\n mapping.layerTypes.includes(layer.type)\n );\n};\n\n/**\n * @ignore\n */\nexport const buildLayerGroupFilter = (layerGroups: BaseMapLayerGroups): LayerSpecFilter => {\n const mode = layerGroups.mode;\n const groups = layerGroups.names;\n if (mode === 'include') {\n return (layer) => groups.some((group) => isMatching(group, layer));\n }\n if (mode === 'exclude') {\n return (layer) => !groups.some((group) => isMatching(group, layer));\n }\n // No filtering if we don't recognize the mode:\n console.error('Unrecognized layer group mode:', mode);\n return () => true;\n};\n\n/**\n * @ignore\n */\nexport const filterLayerByGroups = (layer: LayerSpecification, layerGroups?: BaseMapLayerGroups): boolean => {\n const mode = layerGroups?.mode;\n const groups = layerGroups?.names;\n if (mode && groups?.length) {\n if (mode === 'include') {\n return groups.some((group) => isMatching(group, layer));\n }\n if (mode === 'exclude') {\n return !groups.some((group) => isMatching(group, layer));\n }\n }\n return true;\n};\n\n/**\n * @ignore\n */\nexport const buildBaseMapLayerGroupFilter =\n (layerGroupsFilter?: BaseMapLayerGroups): LayerSpecFilter =>\n (layer: LayerSpecification): boolean =>\n (!layerGroupsFilter || filterLayerByGroups(layer, layerGroupsFilter)) && !poiLayerIDs.includes(layer.id);\n","import { isNil } from 'lodash-es';\n\nimport { AbstractMapModule, BASE_MAP_SOURCE_ID, EventsModule, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { waitUntilMapIsReady } from '../shared/mapUtils';\nimport { TomTomMap } from '../TomTomMap';\nimport { buildBaseMapLayerGroupFilter, buildLayerGroupFilter } from './layerGroups';\nimport type { BaseMapLayerGroups, BaseMapModuleConfig, BaseMapModuleInitConfig } from './types/baseMapModuleConfig';\n\ntype BaseSourceAndLayers = {\n vectorTiles: StyleSourceWithLayers;\n};\n\n/**\n * Base Map Module for controlling standard map layers and their visibility.\n *\n * This module manages the fundamental map layers including background, water, land, roads,\n * buildings, labels, and other vector tile layers from the base map style.\n *\n * @remarks\n * **Managed Layers:**\n * - Background and terrain\n * - Water bodies and coastlines\n * - Country and administrative borders\n * - Buildings (2D and 3D)\n * - Road lines, labels, and shields\n * - Place labels at various zoom levels\n * - House numbers\n *\n * **Does NOT Include:**\n * - Traffic flow/incidents (use {@link TrafficFlowModule} or {@link TrafficIncidentsModule})\n * - Points of Interest/POIs (use {@link POIsModule})\n * - Hillshade/terrain shading (use {@link HillshadeModule})\n *\n * **Use Cases:**\n * - Toggle base map visibility on/off\n * - Show only specific layer groups (e.g., roads only)\n * - Create custom map appearances by hiding certain elements\n * - Build overlay maps with selective base layers\n *\n * @example\n * Basic usage:\n * ```typescript\n * // Get module with default configuration\n * const baseMap = await BaseMapModule.get(map);\n *\n * // Toggle visibility\n * baseMap.setVisible(false); // Hide all base layers\n * baseMap.setVisible(true); // Show all base layers\n *\n * // Check current state\n * if (baseMap.isVisible()) {\n * console.log('Base map is visible');\n * }\n * ```\n *\n * @example\n * Working with layer groups:\n * ```typescript\n * // Show only roads and borders\n * const baseMap = await BaseMapModule.get(map, {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'borders']\n * }\n * });\n *\n * // Hide buildings and labels\n * baseMap.setVisible(false, {\n * layerGroups: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D', 'placeLabels']\n * }\n * });\n *\n * // Show only water and land\n * baseMap.setVisible(true, {\n * layerGroups: {\n * mode: 'include',\n * names: ['water', 'land']\n * }\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map);\n *\n * // Listen for clicks on base map features\n * baseMap.events.on('click', (feature, lngLat) => {\n * console.log('Clicked base map feature:', feature);\n * });\n *\n * // Remove event listeners\n * baseMap.events.off('click');\n * ```\n *\n * @see [Base Map Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/base-map)\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n *\n * @group Base Map\n */\nexport class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseMapModuleConfig> {\n /**\n * Asynchronously retrieves a BaseMapModule instance for the given map.\n *\n * This is the recommended way to create a BaseMapModule. It ensures the map\n * is fully loaded before initializing the module.\n *\n * @param tomtomMap - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for module initialization.\n *\n * @returns A promise that resolves to the initialized BaseMapModule.\n *\n * @remarks\n * **Initialization:**\n * - Waits for map to be ready before creating module\n * - Validates that required sources exist in the map style\n * - Applies initial configuration if provided\n *\n * **Configuration Options:**\n * - `visible`: Initial visibility state\n * - `layerGroupsFilter`: Which layer groups to include/exclude\n * - `layerGroupsVisibility`: Fine-grained visibility per group\n *\n * @throws Error if the base map source is not found in the style\n *\n * @example\n * Default initialization:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map);\n * ```\n *\n * @example\n * With configuration:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map, {\n * visible: true,\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings3D', 'houseNumbers']\n * }\n * });\n * ```\n *\n * @example\n * Show only specific groups:\n * ```typescript\n * const baseMap = await BaseMapModule.get(map, {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land', 'borders']\n * },\n * visible: true\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: BaseMapModuleInitConfig): Promise<BaseMapModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new BaseMapModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: BaseMapModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config: BaseMapModuleInitConfig | undefined) {\n const source = this.mapLibreMap.getSource(BASE_MAP_SOURCE_ID);\n if (!source) {\n throw notInTheStyle(`init ${BaseMapModule.name} with source ID ${BASE_MAP_SOURCE_ID}`);\n }\n\n return {\n vectorTiles: new StyleSourceWithLayers(\n this.mapLibreMap,\n source,\n buildBaseMapLayerGroupFilter(config?.layerGroupsFilter),\n ),\n };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: BaseMapModuleConfig | undefined) {\n if (config && !isNil(config.visible)) {\n this.setVisible(config.visible);\n } else if (!this._initializing && !this.isVisible()) {\n // applying default:\n this.setVisible(true);\n }\n\n if (config?.layerGroupsVisibility) {\n this.setVisible(config.layerGroupsVisibility.visible, { layerGroups: config.layerGroupsVisibility });\n }\n\n // We merge the given config with the previous one to ensure init config parameters are kept:\n // (the init config can have more parameters than the runtime one)\n return this.config || config ? { ...this.config, ...config } : undefined;\n }\n\n /**\n * Checks if any base map layers are currently visible.\n *\n * @returns `true` if at least one base map layer is visible, `false` if all are hidden.\n *\n * @remarks\n * This checks the actual visibility state of layers in the map, not just the\n * module's configuration setting.\n *\n * @example\n * ```typescript\n * if (baseMap.isVisible()) {\n * console.log('Base map is rendered');\n * } else {\n * console.log('Base map is hidden');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.vectorTiles.isAnyLayerVisible();\n }\n\n /**\n * Sets the visibility of base map layers.\n *\n * @param visible - `true` to show layers, `false` to hide them.\n * @param options - Optional settings for fine-grained control.\n * @param options.layerGroups - Target specific layer groups instead of all layers.\n *\n * @remarks\n * **Behavior:**\n * - Without `options.layerGroups`: Affects all base map layers\n * - With `options.layerGroups`: Affects only specified layer groups\n * - Changes are applied immediately if map is ready\n *\n * **Layer Groups:**\n * Available groups: `land`, `water`, `borders`, `buildings2D`, `buildings3D`,\n * `houseNumbers`, `roadLines`, `roadLabels`, `roadShields`, `placeLabels`,\n * `smallerTownLabels`, `cityLabels`, `capitalLabels`, `stateLabels`, `countryLabels`\n *\n * @example\n * Show/hide all layers:\n * ```typescript\n * baseMap.setVisible(false); // Hide everything\n * baseMap.setVisible(true); // Show everything\n * ```\n *\n * @example\n * Control specific groups:\n * ```typescript\n * // Hide only buildings\n * baseMap.setVisible(false, {\n * layerGroups: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D']\n * }\n * });\n *\n * // Show everything except labels\n * baseMap.setVisible(true, {\n * layerGroups: {\n * mode: 'exclude',\n * names: ['placeLabels', 'cityLabels', 'countryLabels']\n * }\n * });\n * ```\n *\n * @example\n * Toggle visibility:\n * ```typescript\n * const isVisible = baseMap.isVisible();\n * baseMap.setVisible(!isVisible); // Toggle\n * ```\n */\n setVisible(visible: boolean, options?: { layerGroups?: BaseMapLayerGroups }): void {\n if (!options?.layerGroups) {\n // We remove the layer groups visibility from the config if it was there:\n delete this.config?.layerGroupsVisibility;\n this.config = { ...this.config, visible };\n } else {\n this.config = { ...this.config, layerGroupsVisibility: { ...options.layerGroups, visible } };\n }\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.vectorTiles.setLayersVisible(\n visible,\n options?.layerGroups && buildLayerGroupFilter(options.layerGroups),\n );\n }\n }\n\n /**\n * Gets the events interface for this module to handle user interactions.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a base map feature\n * - `contextmenu`: User right-clicks on a feature\n * - `hover`: Mouse enters a feature\n * - `long-hover`: Mouse hovers over a feature for extended time\n *\n * **Event Handler Signature:**\n * ```typescript\n * (feature: MapGeoJSONFeature, lngLat: LngLat, allFeatures: MapGeoJSONFeature[]) => void\n * ```\n *\n * @example\n * Register click handler:\n * ```typescript\n * baseMap.events.on('click', (feature, lngLat) => {\n * console.log('Clicked on:', feature.properties);\n * console.log('At coordinates:', lngLat);\n * });\n * ```\n *\n * @example\n * Multiple event types:\n * ```typescript\n * // Show tooltip on hover\n * baseMap.events.on('hover', (feature) => {\n * showTooltip(feature.properties.name);\n * });\n *\n * // Handle clicks\n * baseMap.events.on('click', (feature) => {\n * selectFeature(feature.id);\n * });\n *\n * // Clean up\n * baseMap.events.off('hover');\n * baseMap.events.off('click');\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.vectorTiles, this.config?.events);\n }\n}\n","import type { MapModuleCommonConfig } from '../../shared';\n\n/**\n * Available base map layer group identifiers.\n *\n * @remarks\n * Use these names with {@link BaseMapModule} to control layer visibility.\n *\n * @see {@link BaseMapLayerGroupName}\n * @see {@link BaseMapModuleInitConfig.layerGroupsFilter}\n *\n * @group Base Map\n */\nexport const baseMapLayerGroupNames = [\n 'land',\n 'water',\n 'borders',\n 'buildings2D',\n 'buildings3D',\n 'houseNumbers',\n 'roadLines',\n 'roadLabels',\n 'roadShields',\n 'placeLabels',\n 'smallerTownLabels',\n 'cityLabels',\n 'capitalLabels',\n 'stateLabels',\n 'countryLabels',\n] as const;\n\n/**\n * Name of a base map layer group.\n *\n * Identifies specific categories of base map layers that can be controlled together.\n *\n * @remarks\n * **Available Layer Groups:**\n * - `land` - Land areas and terrain\n * - `water` - Water bodies (oceans, lakes, rivers)\n * - `borders` - Country and administrative boundaries\n * - `buildings2D` - 2D building footprints\n * - `buildings3D` - 3D building models\n * - `houseNumbers` - House number labels\n * - `roadLines` - Road line geometries\n * - `roadLabels` - Street name labels\n * - `roadShields` - Highway shields (e.g., I-95, A1)\n * - `placeLabels` - General place labels\n * - `smallerTownLabels` - Small town/village labels\n * - `cityLabels` - City labels\n * - `capitalLabels` - Capital city labels\n * - `stateLabels` - State/province labels\n * - `countryLabels` - Country name labels\n *\n * @example\n * ```typescript\n * const group: BaseMapLayerGroupName = 'roadLines';\n * const labels: BaseMapLayerGroupName[] = ['cityLabels', 'countryLabels'];\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroupName = (typeof baseMapLayerGroupNames)[number];\n\n/**\n * Layer group visibility configuration with explicit visible state.\n *\n * Extends {@link BaseMapLayerGroups} to include a visibility flag, allowing\n * you to show or hide specific groups of base map layers.\n *\n * @example\n * ```typescript\n * // Hide all buildings\n * const config: BaseMapLayerGroupsVisibility = {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * };\n *\n * // Show only roads\n * const roadsOnly: BaseMapLayerGroupsVisibility = {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels'],\n * visible: true\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroupsVisibility = BaseMapLayerGroups & { visible: boolean };\n\n/**\n * Layer group filter for selective base map display.\n *\n * Defines which layer groups to include or exclude from the base map module.\n * Can be expressed as explicit inclusions (show only these) or exclusions\n * (show all except these).\n *\n * @remarks\n * **Filter Modes:**\n * - `include`: Only the specified groups are shown, all others are hidden\n * - `exclude`: All groups are shown except the specified ones\n *\n * **Common Use Cases:**\n * - Show only roads and labels (minimal map)\n * - Hide buildings for cleaner appearance\n * - Show only water and land (base terrain)\n * - Remove labels for overlay maps\n *\n * @example\n * ```typescript\n * // Show only roads and borders\n * const roadsOnly: BaseMapLayerGroups = {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'borders']\n * };\n *\n * // Show everything except buildings\n * const noBuildings: BaseMapLayerGroups = {\n * mode: 'exclude',\n * names: ['buildings2D', 'buildings3D']\n * };\n *\n * // Show only terrain (no labels, no roads)\n * const terrainOnly: BaseMapLayerGroups = {\n * mode: 'include',\n * names: ['land', 'water']\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapLayerGroups = {\n /**\n * Filter mode determining whether groups are included or excluded.\n *\n * @remarks\n * - `include`: Only the specified groups are considered, all others are ignored\n * - `exclude`: All base map groups except the specified ones are considered\n *\n * @example\n * ```typescript\n * mode: 'include' // Whitelist approach\n * mode: 'exclude' // Blacklist approach\n * ```\n */\n mode: 'include' | 'exclude';\n\n /**\n * Names of the layer groups to include or exclude.\n *\n * @remarks\n * The meaning depends on the `mode`:\n * - In `include` mode: Only these groups will be shown\n * - In `exclude` mode: These groups will be hidden, all others shown\n *\n * @example\n * ```typescript\n * // Show only these\n * names: ['roadLines', 'roadLabels', 'water']\n *\n * // Hide these\n * names: ['buildings2D', 'buildings3D', 'houseNumbers']\n * ```\n */\n names: BaseMapLayerGroupName[];\n};\n\n/**\n * Configuration for the BaseMapModule (initialization or runtime).\n *\n * Controls visibility and behavior of base map layer groups. Can be used both\n * during module initialization and for runtime updates.\n *\n * @remarks\n * This configuration allows fine-grained control over which base map elements\n * are displayed, enabling you to create custom map appearances for different\n * use cases.\n *\n * @example\n * ```typescript\n * // Hide specific layer groups\n * const config: BaseMapModuleConfig = {\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * }\n * };\n *\n * // Show only certain groups\n * const minimalConfig: BaseMapModuleConfig = {\n * visible: true,\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['roadLines', 'water', 'land'],\n * visible: true\n * }\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapModuleConfig = MapModuleCommonConfig & {\n /**\n * Controls the visibility of all layers associated with this module.\n *\n * @default true\n */\n visible?: boolean;\n\n /**\n * Optional visibility configuration for specific layer groups.\n *\n * @remarks\n * **Important:** The layer groups specified here must be included in the\n * module (not excluded by `layerGroupsFilter` during initialization).\n *\n * Use this to control visibility of layer groups at runtime without\n * reinitializing the module.\n *\n * @example\n * ```typescript\n * // Hide all building layers\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['buildings2D', 'buildings3D'],\n * visible: false\n * }\n *\n * // Show only labels\n * layerGroupsVisibility: {\n * mode: 'include',\n * names: ['placeLabels', 'cityLabels', 'countryLabels'],\n * visible: true\n * }\n * ```\n */\n layerGroupsVisibility?: BaseMapLayerGroupsVisibility;\n};\n\n/**\n * Initialization configuration for the BaseMapModule.\n *\n * Extends {@link BaseMapModuleConfig} with additional options available only\n * during module initialization.\n *\n * @remarks\n * **Initialization vs Runtime:**\n * - `layerGroupsFilter`: Only available at init - determines which groups to load\n * - `layerGroupsVisibility`: Available at init and runtime - controls visibility\n *\n * **Use Cases:**\n * - Create minimal maps with only essential layers\n * - Build custom map styles by excluding certain features\n * - Optimize performance by not loading unnecessary layers\n *\n * @example\n * ```typescript\n * // Initialize with only roads and water\n * const initConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['roadLines', 'roadLabels', 'water', 'land']\n * },\n * visible: true\n * };\n *\n * // Exclude buildings from initialization\n * const noBuildingsConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings2D', 'buildings3D', 'houseNumbers']\n * }\n * };\n *\n * // Minimal map for data overlay\n * const overlayBaseConfig: BaseMapModuleInitConfig = {\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land', 'borders']\n * },\n * visible: true\n * };\n * ```\n *\n * @group Base Map\n */\nexport type BaseMapModuleInitConfig = BaseMapModuleConfig & {\n /**\n * Layer groups to include/exclude during module initialization.\n *\n * @remarks\n * **One-time configuration:** This can only be set during initialization.\n * Once the module is created, you cannot change which groups are loaded,\n * only their visibility via `layerGroupsVisibility`.\n *\n * @example\n * ```typescript\n * // Load only essential layers\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['land', 'water', 'roadLines', 'borders']\n * }\n *\n * // Load everything except 3D buildings\n * layerGroupsFilter: {\n * mode: 'exclude',\n * names: ['buildings3D']\n * }\n *\n * // Minimal overlay map\n * layerGroupsFilter: {\n * mode: 'include',\n * names: ['water', 'land']\n * }\n * ```\n */\n layerGroupsFilter?: BaseMapLayerGroups;\n};\n","import type { Anything, CommonPlaceProps } from '@tomtom-org/maps-sdk/core';\nimport type { SupportsEvents } from '../../shared';\n\n/**\n * Extra properties to display color and title for a geometry on the map.\n *\n * Provides customization options for rendering polygon geometries, including\n * visual styling and labeling.\n *\n * @remarks\n * **Use Cases:**\n * - Search result boundaries (e.g., city limits, postal codes)\n * - Reachable range polygons\n * - Delivery zones\n * - Custom area highlights\n *\n * These properties override default styling and allow per-feature customization.\n *\n * @example\n * ```typescript\n * const geometryProps: ExtraGeometryDisplayProps = {\n * title: 'Amsterdam City Center',\n * color: '#FF5733',\n * eventState: 'click'\n * };\n *\n * // With custom properties\n * const customProps: ExtraGeometryDisplayProps = {\n * title: 'Delivery Zone A',\n * color: '#00FF00',\n * zoneId: 'zone-a',\n * capacity: 100\n * };\n * ```\n *\n * @group Geometries\n */\nexport type ExtraGeometryDisplayProps = {\n /**\n * Display title for the geometry.\n *\n * @remarks\n * Optional text label displayed at the center of the polygon.\n * If not provided, no label will be shown.\n *\n * **Common Uses:**\n * - Area names (e.g., \"Downtown\", \"Zone A\")\n * - Statistics (e.g., \"30 min reachable\")\n * - Custom labels\n *\n * @example\n * ```typescript\n * title: 'Amsterdam City Center'\n * title: 'Zone A'\n * title: '30 min driving range'\n * title: undefined // No label\n * ```\n */\n title?: string;\n\n /**\n * Fill color for the geometry.\n *\n * @remarks\n * Overrides the default fill color from the module configuration.\n * Accepts any valid CSS color value.\n *\n * **Color Formats:**\n * - Hex: '#FF5733'\n * - RGB: 'rgb(255, 87, 51)'\n * - RGBA: 'rgba(255, 87, 51, 0.5)'\n * - Named: 'red', 'blue', 'green'\n *\n * @example\n * ```typescript\n * color: '#FF5733'\n * color: 'rgb(0, 128, 255)'\n * color: 'rgba(255, 0, 0, 0.5)'\n * color: 'red'\n * ```\n */\n color?: string;\n} & SupportsEvents &\n Anything;\n\n/**\n * Geometry base and display properties.\n *\n * Combines complete place information with geometry-specific display properties\n * for rendering polygon features on the map.\n *\n * @remarks\n * Used by the GeometriesModule for rendering:\n * - Search API geometry results\n * - Reachable range polygons\n * - Custom polygon overlays\n * - Administrative boundaries\n *\n * Includes both geographic/metadata and visual styling properties.\n *\n * @example\n * ```typescript\n * const geometry: DisplayGeometryProps = {\n * type: 'Polygon',\n * id: 'geom-123',\n * title: 'Amsterdam',\n * color: '#0080FF',\n * address: {\n * municipalitySubdivision: 'Amsterdam',\n * countryCode: 'NL'\n * }\n * };\n * ```\n *\n * @group Geometries\n */\nexport type DisplayGeometryProps = CommonPlaceProps & ExtraGeometryDisplayProps;\n\n/**\n * @ignore\n */\nexport const GEOMETRY_TITLE_PROP = 'title';\n\n/**\n * @ignore\n */\nexport const GEOMETRY_COLOR_PROP = 'color';\n","import type { FillLayerSpecification, LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { GEOMETRY_COLOR_PROP } from '../types/geometryDisplayProps';\n\nexport const colorPalettes = {\n warm: [\n '#793F0D',\n '#AC703D',\n '#C38E63',\n '#E49969',\n '#E5AE86',\n '#EEC5A9',\n '#6E7649',\n '#9D9754',\n '#C7C397',\n '#B4A851',\n '#DFD27C',\n '#E7E3B5',\n '#846D74',\n '#B7A6AD',\n '#D3C9CE',\n ],\n browns: [\n '#edc4b3',\n '#e6b8a2',\n '#deab90',\n '#d69f7e',\n '#cd9777',\n '#c38e70',\n '#b07d62',\n '#9d6b53',\n '#8a5a44',\n '#774936',\n ],\n cold: ['#344464', '#548ca4', '#549cac', '#2c445c', '#a4ccd4', '#acbccc', '#b4c4d4', '#acd4cc', '#5c8ca4'],\n fadedBlues: [\n '#152033',\n '#1d2d44',\n '#2e455d',\n '#3e5c76',\n '#4c6884',\n '#597491',\n '#67809e',\n '#6e86a5',\n '#7b91ad',\n '#879bb4',\n ],\n blues: ['#03045e', '#023e8a', '#0077b6', '#0096c7', '#00b4d8', '#48cae4', '#90e0ef', '#ade8f4', '#caf0f8'],\n greens: ['#004b23', '#006400', '#007200', '#008000', '#38b000', '#70e000', '#9ef01a', '#ccff33'],\n fadedGreenToBlue: [\n '#d9ed92',\n '#b5e48c',\n '#99d98c',\n '#76c893',\n '#52b69a',\n '#34a0a4',\n '#168aad',\n '#1a759f',\n '#1e6091',\n '#184e77',\n ],\n blueToRed: [\n '#033270',\n '#1368aa',\n '#4091c9',\n '#9dcee2',\n '#fedfd4',\n '#f29479',\n '#f26a4f',\n '#ef3c2d',\n '#cb1b16',\n '#65010c',\n ],\n greenToYellow: [\n '#007f5f',\n '#2b9348',\n '#55a630',\n '#80b918',\n '#aacc00',\n '#bfd200',\n '#d4d700',\n '#dddf00',\n '#eeef20',\n '#ffff3f',\n ],\n pastel: [\n '#fec5bb',\n '#fcd5ce',\n '#fae1dd',\n '#f8edeb',\n '#e8e8e4',\n '#d8e2dc',\n '#ece4db',\n '#ffe5d9',\n '#ffd7ba',\n '#fec89a',\n ],\n retro: [\n '#f94144',\n '#f3722c',\n '#f8961e',\n '#f9844a',\n '#f9c74f',\n '#90be6d',\n '#43aa8b',\n '#4d908e',\n '#577590',\n '#277da1',\n ],\n contrastRetro: [\n '#001219',\n '#005f73',\n '#0a9396',\n '#94d2bd',\n '#e9d8a6',\n '#ee9b00',\n '#ca6702',\n '#bb3e03',\n '#ae2012',\n '#9b2226',\n ],\n fadedRainbow: ['#ffadad', '#ffd6a5', '#fdffb6', '#caffbf', '#9bf6ff', '#a0c4ff', '#bdb2ff', '#ffc6ff', '#fffffc'],\n pastelRainbow: [\n '#54478c',\n '#2c699a',\n '#048ba8',\n '#0db39e',\n '#16db93',\n '#83e377',\n '#b9e769',\n '#efea5a',\n '#f1c453',\n '#f29e4c',\n ],\n};\n\nexport type ColorPaletteOptions = keyof typeof colorPalettes;\n\nconst defaultColor = '#0A3653';\n\n/**\n * @ignore\n */\nexport const geometryFillSpec: LayerSpecTemplate<FillLayerSpecification> = {\n type: 'fill',\n paint: {\n 'fill-color': ['coalesce', ['get', GEOMETRY_COLOR_PROP], defaultColor],\n 'fill-opacity': 0.15,\n 'fill-antialias': false,\n },\n};\n\n/**\n * @ignore\n */\nexport const geometryOutlineSpec: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n paint: {\n 'line-color': defaultColor,\n 'line-opacity': 0.45,\n 'line-width': 2,\n },\n};\n","import { bboxCenter, bboxFromCoordsArray, generateId, PolygonFeatures } from '@tomtom-org/maps-sdk/core';\nimport type { Feature, FeatureCollection, GeoJsonProperties, MultiPolygon, Point, Polygon, Position } from 'geojson';\nimport { isNil } from 'lodash-es';\nimport type { DataDrivenPropertyValueSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { SymbolLayerSpecWithoutSource } from '../shared';\nimport { MAP_BOLD_FONT } from '../shared/layers/commonLayerProps';\nimport type { ColorPaletteOptions } from './layers/geometryLayers';\nimport { colorPalettes, geometryFillSpec, geometryOutlineSpec } from './layers/geometryLayers';\nimport type { GeometriesModuleConfig } from './types/geometriesModuleConfig';\nimport type { DisplayGeometryProps, ExtraGeometryDisplayProps } from './types/geometryDisplayProps';\nimport { GEOMETRY_TITLE_PROP } from './types/geometryDisplayProps';\n\n/**\n * Builds Geometry layer specifications for fill and outline layers.\n * @ignore\n */\nexport const buildGeometryLayerSpecs = (\n fillLayerId: string,\n outlineLayerId: string,\n config?: GeometriesModuleConfig,\n): [SymbolLayerSpecWithoutSource, SymbolLayerSpecWithoutSource] => {\n const colorConfig = config?.colorConfig;\n const lineConfig = config?.lineConfig;\n\n const fillLayerSpec = {\n ...geometryFillSpec,\n id: fillLayerId,\n paint: {\n ...geometryFillSpec.paint,\n ...(!isNil(colorConfig?.fillOpacity) && { 'fill-opacity': colorConfig?.fillOpacity }),\n ...(colorConfig?.fillColor && { 'fill-color': ['get', 'color'] }),\n },\n } as unknown as SymbolLayerSpecWithoutSource;\n\n const outlineLayerSpec = {\n ...geometryOutlineSpec,\n id: outlineLayerId,\n paint: {\n ...geometryOutlineSpec.paint,\n ...(!isNil(lineConfig?.lineColor) && { 'line-color': lineConfig?.lineColor }),\n ...(!isNil(lineConfig?.lineWidth) && { 'line-width': lineConfig?.lineWidth }),\n ...(!isNil(lineConfig?.lineOpacity) && { 'line-opacity': lineConfig?.lineOpacity }),\n },\n } as unknown as SymbolLayerSpecWithoutSource;\n\n return [fillLayerSpec, outlineLayerSpec];\n};\n\n/**\n * Build geometry Title. The type can be a string or a Maplibre expression.\n * @param feature - Geometry\n * @param config - Geometry module configuration\n * @returns\n */\nconst buildTitle = (\n feature: Feature<Polygon | MultiPolygon, DisplayGeometryProps | GeoJsonProperties>,\n config: GeometriesModuleConfig,\n): DataDrivenPropertyValueSpecification<string> | string | undefined => {\n if (config.textConfig?.textField) {\n return config.textConfig.textField;\n }\n\n return feature.properties?.address?.freeformAddress;\n};\n\n/**\n * Builds a geometry color string or MapLibre expression.\n * @param config - Geometry module configuration\n * @param index - Number to use as index to pick color from palette option\n */\nconst buildColor = (\n config: GeometriesModuleConfig,\n index: number,\n): DataDrivenPropertyValueSpecification<string> | string | undefined => {\n const color = config?.colorConfig?.fillColor;\n\n if (typeof color === 'string' && colorPalettes[color as ColorPaletteOptions]) {\n const palette = colorPalettes[color as ColorPaletteOptions];\n return palette[index % palette.length];\n }\n\n return color;\n};\n\n/**\n * Build geometry layer specification for title\n * @param layerID\n * @param config\n * @returns\n * @ignore\n */\nexport const buildGeometryTitleLayerSpec = (\n layerId: string,\n config?: GeometriesModuleConfig,\n): Omit<SymbolLayerSpecification, 'source'> => {\n const textConfig = config?.textConfig;\n\n return {\n type: 'symbol',\n id: layerId,\n layout: {\n 'text-field': ['get', GEOMETRY_TITLE_PROP],\n ...(textConfig?.textField && { 'text-field': textConfig.textField }),\n 'text-padding': 5,\n 'text-size': 12,\n 'text-font': [MAP_BOLD_FONT],\n 'symbol-placement': 'point',\n },\n paint: {\n 'text-color': '#333333',\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': ['interpolate', ['linear'], ['zoom'], 6, 1, 10, 1.5],\n 'text-translate-anchor': 'viewport',\n },\n };\n};\n\n/**\n * Prepare geometry for display.\n * If colorConfig is set, it will apply the property \"color\" to \"properties\" in each feature.\n * @param geometry\n * @param config\n * @returns\n * @ignore\n */\nexport const prepareGeometryForDisplay = (\n geometry: PolygonFeatures<GeoJsonProperties | DisplayGeometryProps>,\n config: GeometriesModuleConfig = {},\n): PolygonFeatures<ExtraGeometryDisplayProps> => ({\n ...geometry,\n features: geometry.features.map((feature, index) => {\n const title = feature.properties?.title ?? buildTitle(feature, config);\n const color = feature.properties?.color ?? buildColor(config, index);\n return {\n ...feature,\n properties: {\n ...feature.properties,\n ...(title && { title }),\n ...(color && { color }),\n id: feature.properties?.id ?? generateId(),\n },\n };\n }),\n});\n\n/**\n * Find the biggest array length inside an array.\n * Used to find the biggest array in a Multi-Polygon feature.\n * @param coordinates\n * @returns\n */\nconst getLongestArray = (coordinates: Position[][][]) =>\n coordinates.flat().reduce((result, coord) => (coord.length > result.length ? coord : result), []);\n\n/**\n * Create a Feature<Point> with coordinates where title will be placed.\n * If feature properties contains a coordinates value, it will use it.\n * In case there is not coordinates value, it will get the biggest Polygon inside a feature and calculate\n * the bounding box for those coordinates and finally calculate the bounding box center to place the title.\n * @param geometries\n * @returns\n * @ignore\n */\nexport const prepareTitleForDisplay = (geometries: PolygonFeatures): FeatureCollection<Point> => {\n const features = geometries.features.map((feature) => {\n let coordinates: Position[] | Position | null;\n\n if (feature.properties?.placeCoordinates) {\n coordinates = feature.properties?.placeCoordinates;\n } else if (feature.geometry.type === 'MultiPolygon') {\n const biggestPolygon = getLongestArray(feature.geometry.coordinates);\n const bbox = bboxFromCoordsArray(biggestPolygon);\n coordinates = (bbox && bboxCenter(bbox)) || null;\n } else {\n coordinates = feature.geometry.coordinates.flat();\n }\n\n const id = feature.id ?? feature.properties?.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: { type: 'Point', coordinates },\n properties: {\n ...feature.properties,\n id, // we need id in properties due to promoteId feature\n },\n } as Feature<Point>;\n });\n\n return { type: 'FeatureCollection', bbox: geometries.bbox, features };\n};\n","import type { PolygonFeatures } from '@tomtom-org/maps-sdk/core';\nimport type { FeatureCollection, Point } from 'geojson';\nimport type { SymbolLayerSpecification } from 'maplibre-gl';\nimport type { SymbolLayerSpecWithoutSource, ToBeAddedLayerSpec } from '../shared';\nimport { AbstractMapModule, EventsModule, GeoJSONSourceWithLayers, mapStyleLayerIDs } from '../shared';\nimport { changeLayerProps, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport {\n buildGeometryLayerSpecs,\n buildGeometryTitleLayerSpec,\n prepareGeometryForDisplay,\n prepareTitleForDisplay,\n} from './prepareGeometryForDisplay';\nimport type {\n GeometriesModuleConfig,\n GeometryBeforeLayerConfig,\n GeometryTextConfig,\n} from './types/geometriesModuleConfig';\n\n/**\n * IDs of sources and layers from a geometry module.\n */\ntype GeometrySourcesWithLayers = {\n geometry: GeoJSONSourceWithLayers<PolygonFeatures>;\n geometryLabel: GeoJSONSourceWithLayers<FeatureCollection<Point>>;\n};\n\n/**\n * Geometries Module for displaying polygon areas with custom styling on the map.\n *\n * This module enables visualization of geographic areas (polygons) with customizable\n * colors, borders, and labels. Ideal for displaying search results, administrative\n * boundaries, service areas, or any polygon-based geographic data.\n *\n * @remarks\n * **Features:**\n * - Display single or multiple polygon geometries\n * - Customizable fill colors and opacity\n * - Configurable borders (color, width, opacity)\n * - Optional text labels for geometries\n * - Support for data-driven styling via MapLibre expressions\n * - Layer ordering control\n * - Event handling for user interactions\n *\n * **Data Format:**\n * - Accepts GeoJSON Polygon and MultiPolygon features\n * - Supports FeatureCollection for multiple geometries\n * - Compatible with TomTom Search API geometry results\n *\n * **Styling:**\n * - Use predefined color palettes or custom colors\n * - Apply MapLibre expressions for dynamic styling\n * - Per-feature styling via feature properties\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { GeometriesModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Initialize module\n * const geometriesModule = await GeometriesModule.get(map);\n *\n * // Display a polygon\n * await geometriesModule.show({\n * type: 'Feature',\n * geometry: {\n * type: 'Polygon',\n * coordinates: [[[4.88, 52.37], [4.89, 52.37], [4.89, 52.38], [4.88, 52.38], [4.88, 52.37]]]\n * },\n * properties: {\n * title: 'Area of Interest'\n * }\n * });\n * ```\n *\n * @example\n * Custom styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * fillColor: '#FF5733',\n * fillOpacity: 0.3\n * },\n * lineConfig: {\n * lineColor: '#C70039',\n * lineWidth: 3\n * },\n * textConfig: {\n * textField: ['get', 'name']\n * }\n * });\n *\n * await geometriesModule.show(polygonFeatures);\n * ```\n *\n * @example\n * Multiple geometries with different colors:\n * ```typescript\n * await geometriesModule.show({\n * type: 'FeatureCollection',\n * features: [\n * {\n * type: 'Feature',\n * geometry: { type: 'Polygon', coordinates: [...] },\n * properties: { color: '#FF0000', title: 'Red Zone' }\n * },\n * {\n * type: 'Feature',\n * geometry: { type: 'Polygon', coordinates: [...] },\n * properties: { color: '#00FF00', title: 'Green Zone' }\n * }\n * ]\n * });\n * ```\n *\n * @example\n * Event handling:\n * ```typescript\n * geometriesModule.events.on('click', (feature, lngLat) => {\n * console.log('Clicked geometry:', feature.properties.title);\n * console.log('At coordinates:', lngLat);\n * });\n *\n * geometriesModule.events.on('hover', (feature) => {\n * showTooltip(feature.properties.title);\n * });\n * ```\n *\n * @see [Geometries Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/geometries)\n *\n * @group Geometries\n */\nexport class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLayers, GeometriesModuleConfig> {\n private static lastInstanceIndex = -1;\n\n private titleLayerSpecs!: SymbolLayerSpecWithoutSource;\n private geometryFillLayerSpecs!: SymbolLayerSpecWithoutSource;\n private geometryOutlineLayerSpecs!: SymbolLayerSpecWithoutSource;\n\n private sourceID!: string;\n private fillLayerID!: string;\n private outlineLayerID!: string;\n\n private titleSourceID!: string;\n private titleLayerID!: string;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n *\n * @remarks\n * **Configuration Options:**\n * - `colorConfig`: Fill color and opacity settings\n * - `lineConfig`: Border/outline styling\n * - `textConfig`: Label display configuration\n * - `beforeLayerConfig`: Layer ordering (place above/below other layers)\n *\n * **Multiple Instances:**\n * You can create multiple GeometriesModule instances on the same map,\n * each managing different sets of geometries with different styles.\n *\n * @example\n * Default initialization:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map);\n * ```\n *\n * @example\n * With custom styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * fillColor: 'blue',\n * fillOpacity: 0.25\n * },\n * lineConfig: {\n * lineColor: 'darkblue',\n * lineWidth: 2,\n * lineOpacity: 0.8\n * },\n * textConfig: {\n * textField: ['get', 'title']\n * },\n * beforeLayerConfig: 'top'\n * });\n * ```\n *\n * @example\n * Data-driven styling:\n * ```typescript\n * const geometriesModule = await GeometriesModule.get(map, {\n * colorConfig: {\n * // Color based on feature properties\n * fillColor: [\n * 'match',\n * ['get', 'type'],\n * 'residential', '#FFEB3B',\n * 'commercial', '#2196F3',\n * 'industrial', '#9E9E9E',\n * '#E0E0E0' // default\n * ],\n * fillOpacity: 0.4\n * }\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: GeometriesModuleConfig): Promise<GeometriesModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new GeometriesModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: GeometriesModuleConfig) {\n super('geojson', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: GeometriesModuleConfig, restore?: boolean): GeometrySourcesWithLayers {\n if (!restore) {\n GeometriesModule.lastInstanceIndex++;\n this.sourceID = `geometry-${GeometriesModule.lastInstanceIndex}`;\n this.titleSourceID = `geometryTitle-${GeometriesModule.lastInstanceIndex}`;\n const layerIdPrefix = `geometry-${GeometriesModule.lastInstanceIndex}`;\n this.fillLayerID = `${layerIdPrefix}_Fill`;\n this.outlineLayerID = `${layerIdPrefix}_Outline`;\n this.titleLayerID = `${layerIdPrefix}_Title`;\n }\n\n const [geometryFillSpec, geometryOutlineSpec] = buildGeometryLayerSpecs(\n this.fillLayerID,\n this.outlineLayerID,\n config,\n );\n const titleLayerSpec = buildGeometryTitleLayerSpec(this.titleLayerID, config);\n this.titleLayerSpecs = titleLayerSpec;\n this.geometryFillLayerSpecs = geometryFillSpec;\n this.geometryOutlineLayerSpecs = geometryOutlineSpec;\n\n return {\n geometry: new GeoJSONSourceWithLayers(this.mapLibreMap, this.sourceID, [\n { ...geometryFillSpec },\n { ...geometryOutlineSpec },\n ]),\n geometryLabel: new GeoJSONSourceWithLayers(this.mapLibreMap, this.titleSourceID, [\n titleLayerSpec as ToBeAddedLayerSpec<SymbolLayerSpecification>,\n ]),\n };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: GeometriesModuleConfig | undefined) {\n if (config?.textConfig || config?.colorConfig || config?.lineConfig) {\n this.updateLayerAndData(config);\n }\n if (config?.beforeLayerConfig) {\n this.moveBeforeLayer(config.beforeLayerConfig);\n }\n return config;\n }\n\n private moveBeforeLayerID(beforeLayerId?: string) {\n for (const layer of this.sourcesWithLayers.geometry.sourceAndLayerIDs.layerIDs) {\n this.mapLibreMap.moveLayer(layer, beforeLayerId);\n }\n }\n\n /**\n * Positions the geometry layers relative to other map layers.\n *\n * @param layerConfig - Layer positioning configuration.\n * Can be `'top'` to place above all layers, or a specific layer ID.\n *\n * @remarks\n * **Use Cases:**\n * - Place geometries above base map but below labels\n * - Ensure geometries appear above/below specific features\n * - Control visual hierarchy of multiple data layers\n *\n * **Available Layer IDs:**\n * Use predefined layer IDs from `mapStyleLayerIDs` or custom layer IDs.\n *\n * @example\n * ```typescript\n * import { mapStyleLayerIDs } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Place below labels\n * geometries.moveBeforeLayer(mapStyleLayerIDs.lowestLabel);\n *\n * // Place on top\n * geometries.moveBeforeLayer('top');\n * ```\n */\n moveBeforeLayer(layerConfig: GeometryBeforeLayerConfig) {\n this.config = { ...this.config, beforeLayerConfig: layerConfig };\n this.moveBeforeLayerID(layerConfig === 'top' ? this.titleLayerID : mapStyleLayerIDs[layerConfig]);\n }\n\n /**\n * Updates the text/label configuration for displayed geometries.\n *\n * @param textConfig - New text configuration settings.\n *\n * @remarks\n * **Configuration:**\n * - `textField`: MapLibre expression for label text content\n * - Supports dynamic text based on feature properties\n * - Changes apply to currently shown and future geometries\n *\n * @example\n * ```typescript\n * // Show feature property as label\n * geometries.applyTextConfig({\n * textField: ['get', 'name']\n * });\n *\n * // Conditional labels\n * geometries.applyTextConfig({\n * textField: [\n * 'case',\n * ['has', 'label'],\n * ['get', 'label'],\n * ['get', 'title']\n * ]\n * });\n * ```\n */\n applyTextConfig(textConfig: GeometryTextConfig) {\n const config = { ...this.config, textConfig };\n this.updateLayerAndData(config);\n // TODO: is this consistent with _applyConfig?\n this.sourcesWithLayers.geometryLabel.show(\n prepareTitleForDisplay(this.sourcesWithLayers.geometry.shownFeatures),\n );\n this.config = config;\n }\n\n private updateLayerAndData(config: GeometriesModuleConfig) {\n const [geometryFillSpec, geometryOutlineSpec] = buildGeometryLayerSpecs(\n this.fillLayerID,\n this.outlineLayerID,\n config,\n );\n const newTitleLayerSpecs = buildGeometryTitleLayerSpec(this.titleLayerID, config);\n\n changeLayerProps(geometryFillSpec, this.geometryFillLayerSpecs, this.mapLibreMap);\n changeLayerProps(geometryOutlineSpec, this.geometryOutlineLayerSpecs, this.mapLibreMap);\n changeLayerProps(newTitleLayerSpecs, this.titleLayerSpecs, this.mapLibreMap);\n\n this.geometryFillLayerSpecs = geometryFillSpec;\n this.geometryOutlineLayerSpecs = geometryOutlineSpec;\n this.titleLayerSpecs = newTitleLayerSpecs;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previousShownFeatures = this.sourcesWithLayers.geometry.shownFeatures;\n this.initSourcesWithLayers(this.config, true);\n this.config && this._applyConfig(this.config);\n this.show(previousShownFeatures);\n }\n\n /**\n * Displays the given polygon geometries on the map.\n *\n * @param geometries - Polygon features to display. Can be a single Feature,\n * array of Features, or a FeatureCollection.\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown geometries\n * - Applies current module styling configuration\n * - Waits for module to be ready before displaying\n * - Automatically handles both Polygon and MultiPolygon types\n *\n * **Feature Properties:**\n * - `title`: Used for labels if text config is set\n * - `color`: Override fill color per feature\n * - Custom properties accessible in styling expressions\n *\n * @example\n * Single polygon:\n * ```typescript\n * await geometries.show({\n * type: 'Feature',\n * geometry: {\n * type: 'Polygon',\n * coordinates: [[[4.88, 52.37], [4.89, 52.37], [4.89, 52.38], [4.88, 52.37]]]\n * },\n * properties: {\n * title: 'Amsterdam Center',\n * color: '#FF5733'\n * }\n * });\n * ```\n *\n * @example\n * Multiple polygons:\n * ```typescript\n * await geometries.show({\n * type: 'FeatureCollection',\n * features: [\n * { type: 'Feature', geometry: {...}, properties: {...} },\n * { type: 'Feature', geometry: {...}, properties: {...} }\n * ]\n * });\n * ```\n *\n * @example\n * From search API response:\n * ```typescript\n * import { search } from '@tomtom-international/maps-sdk-js/services';\n *\n * const result = await search.geometrySearch({\n * query: 'Amsterdam',\n * geometryList: [{ type: 'CIRCLE', position: [52.37, 4.89], radius: 5000 }]\n * });\n *\n * if (result.results[0].dataSources?.geometry) {\n * await geometries.show(result.results[0].dataSources.geometry);\n * }\n * ```\n */\n async show(geometries: PolygonFeatures) {\n await this.waitUntilModuleReady();\n const geometry = this.sourcesWithLayers.geometry;\n geometry.show(prepareGeometryForDisplay(geometries, this.config));\n this.sourcesWithLayers.geometryLabel.show(prepareTitleForDisplay(geometry.shownFeatures));\n }\n\n /**\n * Removes all geometries from the map.\n *\n * @remarks\n * - Clears both geometry layers and labels\n * - Does not reset styling configuration\n * - Module remains initialized and ready for new data\n *\n * @example\n * ```typescript\n * // Clear displayed geometries\n * await geometries.clear();\n *\n * // Show new geometries\n * await geometries.show(newGeometries);\n * ```\n */\n async clear() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.geometry.clear();\n }\n\n /**\n * Gets the events interface for handling user interactions with geometries.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on a geometry\n * - `contextmenu`: User right-clicks on a geometry\n * - `hover`: Mouse enters a geometry\n * - `long-hover`: Mouse hovers over geometry for extended time\n *\n * **Event Features:**\n * - Receive the original feature data passed to `show()`\n * - Access feature properties and geometry\n * - Get click/hover coordinates\n *\n * @example\n * Basic event handling:\n * ```typescript\n * geometries.events.on('click', (feature, lngLat) => {\n * console.log('Clicked:', feature.properties);\n * console.log('Location:', lngLat);\n * });\n * ```\n *\n * @example\n * Multiple handlers:\n * ```typescript\n * // Highlight on hover\n * geometries.events.on('hover', (feature) => {\n * highlightGeometry(feature.id);\n * });\n *\n * // Show details on click\n * geometries.events.on('click', (feature) => {\n * showDetailPanel(feature.properties);\n * });\n *\n * // Context menu\n * geometries.events.on('contextmenu', (feature, lngLat) => {\n * showContextMenu(lngLat, feature);\n * });\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.geometry, this.config?.events);\n }\n}\n","import { AbstractMapModule, EventsModule, HILLSHADE_SOURCE_ID, StyleSourceWithLayers } from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport type { HillshadeModuleConfig } from '.';\n\n/**\n * IDs of sources and layers for hillshade module.\n */\ntype HillshadeSourcesWithLayers = {\n hillshade: StyleSourceWithLayers;\n};\n\n/**\n * Map module for displaying terrain shading (hillshade).\n *\n * The HillshadeModule adds realistic terrain depth perception to the map by rendering\n * shadow and highlight effects based on elevation data. This enhances the 3D appearance\n * of mountainous and hilly terrain.\n *\n * @remarks\n * **Features:**\n * - Realistic terrain shading\n * - Uses vector tile elevation data\n * - Lightweight performance impact\n * - Seamlessly integrates with other map layers\n * - Toggle visibility on/off\n *\n * **Common Use Cases:**\n * - Outdoor recreation maps (hiking, skiing)\n * - Geographic/topographic applications\n * - Environmental visualization\n * - Landscape planning tools\n *\n * @example\n * ```typescript\n * // Create the module with hillshade visible\n * const hillshade = await HillshadeModule.getInstance(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * hillshade.setVisible(false);\n *\n * // Listen to events\n * hillshade.events.on('click', (feature, lngLat) => {\n * console.log('Clicked hillshade at:', lngLat);\n * });\n * ```\n *\n * @see [Hillshade Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/hillshade)\n *\n * @group Hillshade\n */\nexport class HillshadeModule extends AbstractMapModule<HillshadeSourcesWithLayers, HillshadeModuleConfig> {\n /**\n * Retrieves a HillshadeModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization and visibility.\n *\n * @returns A promise that resolves to the initialized HillshadeModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `ensureAddedToStyle`: Auto-add hillshade to style if missing\n *\n * **Style Requirement:**\n * - Hillshade must be included in the map style or added via `ensureAddedToStyle`\n * - Some styles may not support hillshade (e.g., satellite)\n *\n * @throws Error if hillshade source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map);\n * ```\n *\n * @example\n * Auto-add to style if missing:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map, {\n * visible: true\n * });\n * ```\n *\n * @example\n * Start hidden:\n * ```typescript\n * const hillshadeModule = await HillshadeModule.get(map, {\n * visible: false\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: HillshadeModuleConfig): Promise<HillshadeModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, HILLSHADE_SOURCE_ID, 'hillshade');\n return new HillshadeModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: HillshadeModuleConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const hillshadeSource = this.mapLibreMap.getSource(HILLSHADE_SOURCE_ID);\n if (!hillshadeSource) {\n throw notInTheStyle(`init ${HillshadeModule.name} with source ID ${HILLSHADE_SOURCE_ID}`);\n }\n return { hillshade: new StyleSourceWithLayers(this.mapLibreMap, hillshadeSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: HillshadeModuleConfig | undefined) {\n this.setVisible(config?.visible ?? false);\n return config;\n }\n\n /**\n * Sets the visibility of the hillshade layer.\n *\n * @param visible - `true` to show hillshade, `false` to hide it.\n *\n * @remarks\n * Changes are applied immediately if the map is ready.\n *\n * @example\n * ```typescript\n * hillshade.setVisible(true); // Show terrain shading\n * hillshade.setVisible(false); // Hide terrain shading\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = {\n ...this.config,\n visible,\n };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.hillshade.setLayersVisible(visible);\n }\n }\n\n /**\n * Checks if the hillshade layer is currently visible.\n *\n * @returns `true` if visible, `false` if hidden.\n *\n * @example\n * ```typescript\n * if (hillshade.isVisible()) {\n * console.log('Terrain shading is active');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.hillshade.isAnyLayerVisible();\n }\n\n /**\n * Gets the events interface for handling user interactions with hillshade.\n *\n * @returns An EventsModule instance for registering event handlers.\n *\n * @remarks\n * **Supported Events:**\n * - `click`: User clicks on the hillshade layer\n * - `contextmenu`: User right-clicks\n * - `hover`: Mouse enters hillshade area\n * - `long-hover`: Extended hover\n *\n * @example\n * ```typescript\n * hillshade.events.on('click', (feature, lngLat) => {\n * console.log('Clicked terrain at:', lngLat);\n * });\n * ```\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.hillshade, this.config?.events);\n }\n}\n","import type { GlobalConfig } from '@tomtom-org/maps-sdk/core';\nimport type { MapOptions, StyleSpecification } from 'maplibre-gl';\nimport type { MapEventsConfig } from './mapEventsConfig';\n\n/**\n * Array of all available standard style identifiers.\n *\n * This constant provides the complete list of TomTom-hosted standard map styles\n * that can be used when initializing a map. It serves as the source of truth for\n * valid style IDs and is used to derive the {@link StandardStyleID} type.\n *\n * @remarks\n * Use this array when you need to:\n * - Iterate over all available styles (e.g., building a style picker UI)\n * - Validate if a style ID is a standard style\n * - Display available options to users\n *\n * The array is defined as `const` with `as const` assertion to ensure type safety\n * and prevent modifications at runtime.\n *\n * @example\n * ```typescript\n * import { standardStyleIDs } from '@tomtom-org/maps-sdk/map';\n *\n * // Build a dropdown menu with all standard styles\n * const styleSelector = document.getElementById('style-selector');\n * standardStyleIDs.forEach((styleId) => {\n * const option = new Option(styleId);\n * styleSelector.add(option);\n * });\n *\n * // Check if a style ID is valid\n * const isValidStyle = (id: string): boolean => {\n * return standardStyleIDs.includes(id as any);\n * };\n * ```\n *\n * @see {@link StandardStyleID} - The type derived from this array\n *\n * @group Map Style\n */\nexport const standardStyleIDs = [\n 'standardLight',\n 'standardDark',\n // TODO: driving styles not supported in Orbis for now\n 'drivingLight',\n 'drivingDark',\n 'monoLight',\n 'monoDark',\n 'satellite',\n] as const;\n\n/**\n * Identifier for a TomTom-hosted standard map style.\n *\n * Standard styles are officially maintained by TomTom and provide consistent,\n * professionally designed map appearances.\n *\n * @remarks\n * Available styles:\n * - `standardLight`: Default light theme with full detail\n * - `standardDark`: Dark theme for low-light environments\n * - `drivingLight`: Optimized for in-car navigation (light)\n * - `drivingDark`: Optimized for in-car navigation (dark)\n * - `monoLight`: Minimalist monochrome light theme\n * - `monoDark`: Minimalist monochrome dark theme\n * - `satellite`: Satellite imagery basemap\n *\n * @example\n * ```typescript\n * const styleId: StandardStyleID = 'standardLight';\n * ```\n *\n * @group Map Style\n */\nexport type StandardStyleID = (typeof standardStyleIDs)[number];\n\n/**\n * Configuration for a TomTom standard map style.\n *\n * Provides options to customize which modules are included and which style version to use.\n *\n * @example\n * ```typescript\n * // Standard style with all default modules\n * const style: StandardStyle = {\n * id: 'standardLight'\n * };\n *\n * // Exclude traffic modules\n * const styleNoTraffic: StandardStyle = {\n * id: 'standardLight',\n * include: ['hillshade'] // Only include hillshade, exclude traffic\n * };\n *\n * // Use specific style version\n * const versionedStyle: StandardStyle = {\n * id: 'standardDark',\n * version: '1.0.0'\n * };\n * ```\n *\n * @group Map Style\n */\nexport type StandardStyle = {\n /**\n * Standard style identifier.\n *\n * Determines the visual appearance of the map.\n */\n id?: StandardStyleID;\n /**\n * Modules to include when loading the style.\n * * Use this to selectively enable only needed modules for better performance.\n *\n * If not specified, all available modules are included by default.\n * If an empty array is provided, no optional modules will be included.\n *\n * @default All available modules\n *\n * @remarks\n * Available modules:\n * - `trafficIncidents`: Real-time traffic incidents (accidents, closures)\n * - `trafficFlow`: Real-time traffic flow visualization\n * - `hillshade`: Terrain elevation shading\n *\n * @example\n * ```typescript\n * // Include only traffic modules\n * include: ['trafficIncidents', 'trafficFlow']\n *\n * // Include only hillshade\n * include: ['hillshade']\n *\n * // Include no optional modules\n * include: []\n * ```\n */\n include?: StyleModule[];\n /**\n * Style version to load.\n *\n * Allows pinning to a specific style version for consistency.\n * If not specified, uses the latest SDK-supported version.\n *\n * @default Latest SDK-supported version\n *\n * @example\n * ```typescript\n * version: '1.0.0'\n * ```\n */\n version?: string;\n};\n\n/**\n * Configuration for a custom map style.\n *\n * Allows using your own map style either via URL or direct JSON specification.\n *\n * @remarks\n * Use custom styles for:\n * - Branded map appearances\n * - Specialized use cases (indoor maps, thematic maps)\n * - Integration with custom tile servers\n *\n * @example\n * ```typescript\n * // Load from URL\n * const urlStyle: CustomStyle = {\n * url: 'https://example.com/my-custom-style.json'\n * };\n *\n * // Direct JSON specification\n * const jsonStyle: CustomStyle = {\n * json: {\n * version: 8,\n * sources: { ... },\n * layers: [ ... ]\n * }\n * };\n * ```\n *\n * @group Map Style\n */\nexport type CustomStyle = {\n /**\n * URL to a MapLibre/Mapbox style JSON.\n *\n * The URL should not include the API key - it will be automatically added.\n * Mutually exclusive with the `json` property.\n *\n * @example\n * ```typescript\n * url: 'https://api.tomtom.com/style/1/style/my-custom-style'\n * ```\n */\n url?: string;\n /**\n * Direct style specification as JSON.\n *\n * Provide the complete MapLibre Style Specification object.\n * Mutually exclusive with the `url` property.\n *\n * @see [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/)\n *\n * @example\n * ```typescript\n * json: {\n * version: 8,\n * sources: {\n * 'my-source': { type: 'vector', url: '...' }\n * },\n * layers: [\n * { id: 'background', type: 'background', paint: { 'background-color': '#f0f0f0' } }\n * ]\n * }\n * ```\n */\n json?: StyleSpecification;\n};\n\n/**\n * Array of all available style modules.\n *\n * @group Map Style\n */\nexport const styleModules = ['trafficIncidents', 'trafficFlow', 'hillshade'] as const;\n\n/**\n * Optional map modules that can be included with a style.\n *\n * @remarks\n * - `trafficIncidents`: Shows real-time traffic incidents on the map\n * - `trafficFlow`: Shows real-time traffic flow with color-coded speeds\n * - `hillshade`: Adds terrain elevation shading for topographic context\n *\n * @group Map Style\n */\nexport type StyleModule = (typeof styleModules)[number];\n\n/**\n * Map style specification for initialization.\n *\n * Defines which map style to load and how it should be configured.\n * Supports standard TomTom styles or custom styles.\n *\n * @remarks\n * Three input formats:\n * 1. **Simple ID**: Just pass a standard style ID string\n * 2. **Standard style object**: Use a TomTom style with custom configuration\n * 3. **Custom style object**: Load your own style from URL or JSON\n *\n * @example\n * ```typescript\n * // 1. Simple standard style\n * style: 'standardLight'\n *\n * // 2. Standard style with configuration\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * }\n *\n * // 3. Custom style from URL\n * style: {\n * type: 'custom',\n * url: 'https://example.com/style.json'\n * }\n *\n * // 4. Custom style from JSON\n * style: {\n * type: 'custom',\n * json: { version: 8, sources: {...}, layers: [...] }\n * }\n * ```\n *\n * @group Map Style\n */\nexport type StyleInput = StandardStyleID | (StandardStyle & { type: 'standard' }) | (CustomStyle & { type: 'custom' });\n\n/**\n * MapLibre-specific options for advanced map configuration.\n *\n * Extends MapLibre GL JS MapOptions, excluding style and attribution control\n * which are handled by the TomTom SDK.\n *\n * @remarks\n * Includes options for:\n * - Initial viewport (center, zoom, bearing, pitch)\n * - Interaction controls (zoom, rotation, drag)\n * - Rendering options (antialiasing, terrain)\n * - Localization and accessibility\n *\n * @see [MapLibre MapOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/)\n *\n * @group Map\n */\nexport type MapLibreOptions = Omit<MapOptions, 'style' | 'attributionControl'>;\n\n/**\n * Parameters for initializing a TomTom map instance.\n *\n * Combines global SDK configuration with map-specific settings like style, events, and MapLibre options.\n * All GlobalConfig properties (key, baseURL, etc.) are optional and will be merged from global configuration.\n * Only mapLibre.container is strictly required.\n *\n * @example\n * ```typescript\n * const mapParams: TomTomMapParams = {\n * key: 'your-api-key',\n * style: 'standardLight',\n * events: {\n * onClick: (event) => console.log('Map clicked', event)\n * },\n * mapLibre: {\n * container: 'map-container',\n * center: [4.9041, 52.3676],\n * zoom: 12\n * }\n * };\n * ```\n *\n * @group Map\n */\nexport type TomTomMapParams = Partial<GlobalConfig> & {\n /**\n * Map style to load.\n *\n * If not specified, defaults to 'standardLight'.\n *\n * @default 'standardLight'\n *\n * @example\n * ```typescript\n * // Use dark theme\n * style: 'standardDark'\n *\n * // Custom configuration\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow']\n * }\n * ```\n */\n style?: StyleInput;\n\n /**\n * Event handler configuration for map interactions.\n *\n * Define callbacks for various map events like clicks, hovers, and movements.\n *\n * @example\n * ```typescript\n * events: {\n * onClick: (event) => {\n * console.log('Clicked at', event.lngLat);\n * },\n * onMoveEnd: () => {\n * console.log('Map moved to', map.getCenter());\n * }\n * }\n * ```\n */\n events?: MapEventsConfig;\n\n /**\n * MapLibre-specific options for map configuration.\n *\n * Includes options for viewport settings, interaction controls, rendering options, and more.\n *\n * @example\n * ```typescript\n * mapLibre: {\n * container: 'map',\n * center: [4.9041, 52.3676],\n * zoom: 12,\n * pitch: 45,\n * bearing: -17.6,\n * antialias: true,\n * maxZoom: 18,\n * minZoom: 8\n * }\n * ```\n */\n mapLibre: MapLibreOptions;\n};\n\n/**\n * Complete TomTom map parameters after merging with global configuration.\n * This type represents the fully resolved configuration used internally by the SDK.\n *\n * @ignore\n */\nexport type InternalTomTomMapParams = GlobalConfig & TomTomMapParams;\n","import type { ExpressionSpecification } from 'maplibre-gl';\n\n/**\n * Main route line foreground color.\n * @ignore\n */\nexport const ROUTE_LINE_FOREGROUND_COLOR = '#36A8F0';\n\n/**\n * Main route outline color.\n * @ignore\n */\nexport const ROUTE_LINE_OUTLINE_COLOR = '#105287';\n\n/**\n * Deselected route line foreground color.\n * @ignore\n */\nexport const DESELECTED_FOREGROUND_COLOR = '#ABAFB3';\n\n/**\n * Deselected route line outline color.\n * @ignore\n */\nexport const DESELECTED_OUTLINE_COLOR = '#3C4956';\n\n/**\n * @ignore\n */\nexport const DESELECTED_SECONDARY_COLOR = '#727C85';\n\n/**\n * Main route line width based on zoom level.\n * @ignore\n */\nexport const ROUTE_LINE_FOREGROUND_WIDTH: ExpressionSpecification = [\n 'interpolate',\n ['linear'],\n ['zoom'],\n 1,\n 3,\n 5,\n 4,\n 10,\n 7,\n 18,\n 10,\n];\n\n/**\n * Used for showing/hiding layer depending on layer being part of selected route or not.\n *\n * @remarks\n * Add this to layers that depend on whether they are part of the selected route or not.\n *\n * @example:\n * filter: SELECTED_ROUTE_FILTER\n\n * @group Routing\n */\nexport const SELECTED_ROUTE_FILTER: ExpressionSpecification = ['==', ['get', 'routeState'], 'selected'];\n\n/**\n * Used for showing/hiding layer depending on layer being part of deselected route or not.\n *\n * @remarks\n * Add this to layers that depend on whether they are part of the deselected route or not.\n *\n * @example:\n * filter: DESELECTED_ROUTE_FILTER\n\n * @group Routing\n */\nexport const DESELECTED_ROUTE_FILTER: ExpressionSpecification = ['==', ['get', 'routeState'], 'deselected'];\n\n/**\n * @ignore\n */\nexport const MAJOR_DELAY_COLOR = '#AD0000';\n/**\n * @ignore\n */\nexport const MODERATE_DELAY_COLOR = '#FB2D09';\n/**\n * @ignore\n */\nexport const MINOR_DELAY_LABEL_COLOR = '#f58240';\n/**\n * @ignore\n */\nexport const UNKNOWN_DELAY_COLOR = '#000000';\n","import type {\n DataDrivenPropertyValueSpecification,\n FormattedSpecification,\n SymbolLayerSpecification,\n} from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { pinLayerBaseSpec } from '../../shared/layers/symbolLayers';\nimport { ChargingStopsConfig, ChargingStopTextConfig } from '../types/routeModuleConfig';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\nconst chargingStopTextField = (\n config: ChargingStopTextConfig | undefined,\n): DataDrivenPropertyValueSpecification<FormattedSpecification> => {\n if (config?.visible === false) {\n return '';\n }\n\n return (\n config?.title ?? [\n 'format',\n ['get', 'title'],\n '\\n',\n ['get', 'chargingPower'],\n ' • ',\n ['get', 'chargingDuration'],\n ]\n );\n};\n\n/**\n * @ignore\n * @see toDisplayChargingStops\n */\nexport const chargingStopSymbol = (\n config: ChargingStopsConfig | undefined,\n): LayerSpecTemplate<SymbolLayerSpecification> => {\n return {\n ...pinLayerBaseSpec,\n filter: SELECTED_ROUTE_FILTER,\n minzoom: 4,\n layout: {\n ...pinLayerBaseSpec.layout,\n 'text-field': chargingStopTextField(config?.text),\n },\n paint: {\n ...pinLayerBaseSpec.paint,\n },\n };\n};\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\nconst commonProps = {\n filter: SELECTED_ROUTE_FILTER,\n minzoom: 16,\n};\n\nconst commonLineProps: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonProps,\n type: 'line',\n layout: { 'line-cap': 'round' },\n};\n\n/**\n * @ignore\n */\nexport const instructionOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonLineProps,\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 16, 14, 22, 20],\n 'line-color': 'grey',\n },\n};\n\n/**\n * @ignore\n */\nexport const instructionLine: LayerSpecTemplate<LineLayerSpecification> = {\n ...commonLineProps,\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 16, 12, 22, 17],\n 'line-color': 'white',\n },\n};\n\n/**\n * @ignore\n */\nexport const INSTRUCTION_ARROW_IMAGE_ID = 'instruction-arrow';\n\n/**\n * @ignore\n */\nexport const instructionArrow: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...commonProps,\n type: 'symbol',\n layout: {\n 'icon-allow-overlap': true,\n 'icon-image': INSTRUCTION_ARROW_IMAGE_ID, // Will be updated with instance suffix in config\n 'icon-rotation-alignment': 'map',\n 'icon-rotate': ['get', 'lastPointBearingDegrees'],\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 16, 1, 22, 2],\n },\n};\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { ROUTE_LINE_FOREGROUND_WIDTH, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeFerriesLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n 'line-color': '#6dc4ed',\n },\n};\n\n/**\n * @ignore\n */\nexport const routeFerriesSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 6,\n // zoom where the map POI naturally appears:\n maxzoom: 16.5,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-image': 'poi-ferry_terminal',\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 6, 0.8, 16.5, 1],\n // helps smooth the transition from along-route to map-poi, which also has a label in it:\n 'icon-ignore-placement': true,\n },\n};\n","import type { ExpressionSpecification, LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport {\n DESELECTED_FOREGROUND_COLOR,\n DESELECTED_OUTLINE_COLOR,\n DESELECTED_ROUTE_FILTER,\n ROUTE_LINE_FOREGROUND_COLOR,\n ROUTE_LINE_FOREGROUND_WIDTH,\n ROUTE_LINE_OUTLINE_COLOR,\n SELECTED_ROUTE_FILTER,\n} from './shared';\n\n/**\n * @ignore\n */\nexport const routeLineBaseTemplate: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n 'line-sort-key': ['get', 'index'],\n },\n};\n\nconst outlineLineWidth: ExpressionSpecification = ['interpolate', ['linear'], ['zoom'], 1, 5, 5, 6, 10, 10, 18, 14];\n\n/**\n * @ignore\n */\nexport const routeDeselectedOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: DESELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': DESELECTED_OUTLINE_COLOR,\n 'line-width': outlineLineWidth,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeDeselectedLine: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: DESELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': DESELECTED_FOREGROUND_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeOutline: LayerSpecTemplate<LineLayerSpecification> = {\n ...routeLineBaseTemplate,\n filter: SELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': ROUTE_LINE_OUTLINE_COLOR,\n 'line-width': outlineLineWidth,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeMainLine = (props?: { color?: string }): LayerSpecTemplate<LineLayerSpecification> => ({\n ...routeLineBaseTemplate,\n filter: SELECTED_ROUTE_FILTER,\n paint: {\n 'line-color': props?.color ?? ROUTE_LINE_FOREGROUND_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n});\n\n/**\n * @ignore\n */\nexport const routeLineArrows: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n layout: {\n 'symbol-placement': 'line',\n 'icon-image': 'roads-arrow-white',\n // The current arrow icon seems to point backwards otherwise. Check with caution!\n 'icon-rotate': 180,\n },\n};\n\n/**\n * @ignore\n */\nexport const SELECTED_SUMMARY_POPUP_IMAGE_ID = 'selected-route-summary-popup';\n/**\n * @ignore\n */\nexport const DESELECTED_SUMMARY_POPUP_IMAGE_ID = 'deselected-route-summary-popup';\n","import type { LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeTollRoadsOutline: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-width': ['interpolate', ['linear'], ['zoom'], 1, 9, 5, 11, 10, 15, 18, 20],\n 'line-color': '#BEBFFA',\n },\n};\n\n/**\n * @ignore\n */\nexport const routeTollRoadsSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 4,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-image': 'poi-toll_plaza',\n 'icon-size': ['interpolate', ['linear'], ['zoom'], 4, 0.8, 16.5, 1],\n },\n};\n","import type { ExpressionSpecification, LineLayerSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT } from '../../shared/layers/commonLayerProps';\nimport {\n MAJOR_DELAY_COLOR,\n MINOR_DELAY_LABEL_COLOR,\n MODERATE_DELAY_COLOR,\n SELECTED_ROUTE_FILTER,\n UNKNOWN_DELAY_COLOR,\n} from './shared';\n\nconst EXTRA_FOREGROUND_LINE_WIDTH: ExpressionSpecification = [\n 'interpolate',\n ['linear'],\n ['zoom'],\n 1,\n 2,\n 5,\n 3,\n 10,\n 4,\n 18,\n 6,\n];\n\n/**\n * @ignore\n */\nexport const routeIncidentsBGLine: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n layout: { 'line-cap': 'round' },\n paint: {\n 'line-width': EXTRA_FOREGROUND_LINE_WIDTH,\n 'line-color': [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'minor',\n '#FFC105',\n 'moderate',\n MODERATE_DELAY_COLOR,\n 'major',\n MAJOR_DELAY_COLOR,\n // other\n '#C7D2D8',\n ],\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsDashedLine: LayerSpecTemplate<LineLayerSpecification> = {\n type: 'line',\n filter: ['in', ['get', 'magnitudeOfDelay'], ['literal', ['unknown', 'indefinite']]],\n layout: { 'line-join': 'round' },\n paint: {\n 'line-width': EXTRA_FOREGROUND_LINE_WIDTH,\n 'line-color': [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'unknown',\n 'rgba(190, 39, 27, 1)',\n // other (undefined):\n 'rgba(137, 150, 168, 1)',\n ],\n 'line-dasharray': [1.5, 1],\n },\n};\n\n/**\n * @ignore\n */\nexport const magnitudeOfDelayTextColor: ExpressionSpecification = [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'minor',\n MINOR_DELAY_LABEL_COLOR,\n 'moderate',\n MODERATE_DELAY_COLOR,\n 'major',\n MAJOR_DELAY_COLOR,\n 'indefinite',\n '#666666',\n // other\n UNKNOWN_DELAY_COLOR,\n];\n\nconst routeIncidentsSymbolBase: LayerSpecTemplate<SymbolLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'symbol',\n minzoom: 6,\n layout: {\n 'symbol-placement': 'point',\n 'symbol-avoid-edges': true,\n 'icon-ignore-placement': true,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsJamSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...routeIncidentsSymbolBase,\n filter: ['all', ['has', 'jamIconID'], routeIncidentsSymbolBase.filter as ExpressionSpecification],\n layout: {\n ...routeIncidentsSymbolBase.layout,\n 'icon-image': ['get', 'jamIconID'],\n 'icon-anchor': 'bottom-left',\n 'text-anchor': 'bottom-left',\n // Jam symbols have delay labels in them:\n 'text-field': ['get', 'title'],\n 'text-font': [MAP_BOLD_FONT],\n 'text-offset': [3.9, -1.4],\n 'text-size': 13,\n },\n paint: {\n ...routeIncidentsSymbolBase.paint,\n 'text-color': magnitudeOfDelayTextColor,\n 'text-halo-color': '#FFFFFF',\n 'text-halo-width': 1,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeIncidentsCauseSymbol: LayerSpecTemplate<SymbolLayerSpecification> = {\n ...routeIncidentsSymbolBase,\n filter: ['all', ['has', 'causeIconID'], routeIncidentsSymbolBase.filter as ExpressionSpecification],\n layout: {\n ...routeIncidentsSymbolBase.layout,\n 'icon-image': ['get', 'causeIconID'],\n 'icon-anchor': 'bottom-right',\n // Cause symbols have no label in them.\n },\n paint: { ...routeIncidentsSymbolBase.paint },\n};\n","import type { LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { ROUTE_LINE_FOREGROUND_WIDTH, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const routeTunnelsLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n 'line-color': '#000000',\n 'line-opacity': 0.3,\n },\n};\n","import type { LineLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport {\n ROUTE_LINE_FOREGROUND_COLOR,\n ROUTE_LINE_FOREGROUND_WIDTH,\n ROUTE_LINE_OUTLINE_COLOR,\n SELECTED_ROUTE_FILTER,\n} from './shared';\n\n/**\n * @ignore\n */\nexport const routeVehicleRestrictedBackgroundLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n },\n paint: {\n 'line-color': ROUTE_LINE_OUTLINE_COLOR,\n 'line-width': ROUTE_LINE_FOREGROUND_WIDTH,\n },\n};\n\n/**\n * @ignore\n */\nexport const routeVehicleRestrictedDottedLine: LayerSpecTemplate<LineLayerSpecification> = {\n filter: SELECTED_ROUTE_FILTER,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-color': ROUTE_LINE_FOREGROUND_COLOR,\n 'line-width': ['interpolate', ['linear'], ['zoom'], 1, 2, 5, 3, 10, 5, 18, 7],\n 'line-dasharray': [0, 1.5],\n },\n};\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT, MAP_MEDIUM_FONT } from '../../shared/layers/commonLayerProps';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport { DESELECTED_SUMMARY_POPUP_IMAGE_ID, SELECTED_SUMMARY_POPUP_IMAGE_ID } from './routeMainLineLayers';\nimport { magnitudeOfDelayTextColor } from './routeTrafficSectionLayers';\nimport { DESELECTED_SECONDARY_COLOR, SELECTED_ROUTE_FILTER } from './shared';\n\n/**\n * @ignore\n */\nexport const TRAFFIC_CLEAR_IMAGE_ID = 'traffic-clear';\n/**\n * @ignore\n */\nexport const TRAFFIC_MAJOR_IMAGE_ID = 'traffic-major';\n/**\n * @ignore\n */\nexport const TRAFFIC_MODERATE_IMAGE_ID = 'traffic-moderate';\n/**\n * @ignore\n */\nexport const TRAFFIC_MINOR_IMAGE_ID = 'traffic-minor';\n\nconst hasFormattedTraffic: ExpressionSpecification = ['has', 'formattedTraffic'];\n\n/**\n * Builds the summary bubble symbol layer specification with instance-specific image IDs.\n * @param instanceIndex - Optional instance index for supporting multiple RoutingModule instances\n * @ignore\n */\nexport const buildSummaryBubbleSymbolPoint = (instanceIndex?: number): LayerSpecTemplate<SymbolLayerSpecification> => {\n const selectedImageID =\n instanceIndex !== undefined\n ? suffixNumber(SELECTED_SUMMARY_POPUP_IMAGE_ID, instanceIndex)\n : SELECTED_SUMMARY_POPUP_IMAGE_ID;\n const deselectedImageID =\n instanceIndex !== undefined\n ? suffixNumber(DESELECTED_SUMMARY_POPUP_IMAGE_ID, instanceIndex)\n : DESELECTED_SUMMARY_POPUP_IMAGE_ID;\n const trafficClearID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_CLEAR_IMAGE_ID, instanceIndex) : TRAFFIC_CLEAR_IMAGE_ID;\n const trafficMajorID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_MAJOR_IMAGE_ID, instanceIndex) : TRAFFIC_MAJOR_IMAGE_ID;\n const trafficModerateID =\n instanceIndex !== undefined\n ? suffixNumber(TRAFFIC_MODERATE_IMAGE_ID, instanceIndex)\n : TRAFFIC_MODERATE_IMAGE_ID;\n const trafficMinorID =\n instanceIndex !== undefined ? suffixNumber(TRAFFIC_MINOR_IMAGE_ID, instanceIndex) : TRAFFIC_MINOR_IMAGE_ID;\n\n return {\n type: 'symbol',\n layout: {\n 'icon-image': ['case', SELECTED_ROUTE_FILTER, selectedImageID, deselectedImageID],\n 'symbol-placement': 'point',\n 'icon-rotation-alignment': 'viewport',\n 'text-rotation-alignment': 'viewport',\n 'symbol-sort-key': ['case', SELECTED_ROUTE_FILTER, 0, 1],\n 'icon-text-fit': 'both',\n 'icon-text-fit-padding': [10, 5, 5, 10],\n 'text-font': [MAP_MEDIUM_FONT],\n 'text-size': 13,\n 'icon-padding': 0,\n 'text-justify': 'left',\n 'text-line-height': 1.5,\n 'text-field': [\n 'format',\n ['get', 'formattedDuration'],\n {\n 'text-font': ['literal', [MAP_BOLD_FONT]],\n 'text-color': ['case', SELECTED_ROUTE_FILTER, 'black', DESELECTED_SECONDARY_COLOR],\n },\n ['concat', '\\t\\t', ['get', 'formattedDistance']],\n { 'text-color': DESELECTED_SECONDARY_COLOR },\n ['case', hasFormattedTraffic, '\\n', ''],\n {},\n [\n 'image',\n [\n 'case',\n hasFormattedTraffic,\n [\n 'match',\n ['get', 'magnitudeOfDelay'],\n 'major',\n trafficMajorID,\n 'moderate',\n trafficModerateID,\n 'minor',\n trafficMinorID,\n trafficClearID,\n ],\n '',\n ],\n ],\n {},\n ['case', hasFormattedTraffic, ['concat', ' ', ['get', 'formattedTraffic']], ''],\n {\n 'text-font': ['literal', [MAP_BOLD_FONT]],\n 'text-color': magnitudeOfDelayTextColor,\n },\n ],\n },\n paint: {\n 'icon-translate': [0, -35],\n 'text-translate': [0, -35],\n },\n };\n};\n\n/**\n * Default summary bubble symbol layer (without instance suffix)\n * @ignore\n */\nexport const summaryBubbleSymbolPoint: LayerSpecTemplate<SymbolLayerSpecification> = buildSummaryBubbleSymbolPoint();\n","import type { PlaceDisplayProps } from '../../places';\n\n/**\n * @group Routing\n */\nexport const START_INDEX = 'start';\n/**\n * @group Routing\n */\nexport const MIDDLE_INDEX = 'middle';\n/**\n * @group Routing\n */\nexport const FINISH_INDEX = 'finish';\n/**\n * @group Routing\n */\nexport type WaypointIndexType = typeof START_INDEX | typeof MIDDLE_INDEX | typeof FINISH_INDEX;\n\n/**\n * Display properties for a waypoint marker on the map.\n *\n * Extends location display properties with waypoint-specific information\n * including position in the route and stop numbering.\n *\n * @remarks\n * Waypoints are displayed differently based on their position:\n * - **Start**: Origin marker (often \"A\" or green pin)\n * - **Middle**: Numbered stop markers (1, 2, 3, etc.)\n * - **Finish**: Destination marker (often \"B\" or red pin)\n *\n * @example\n * ```typescript\n * // Start waypoint\n * const start: WaypointDisplayProps = {\n * id: 'waypoint-0',\n * iconID: 'waypoint-start',\n * index: 0,\n * indexType: 'start',\n * title: 'Amsterdam Central Station'\n * };\n *\n * // Intermediate stop\n * const stop: WaypointDisplayProps = {\n * id: 'waypoint-1',\n * iconID: 'waypoint-stop',\n * index: 1,\n * indexType: 'middle',\n * stopDisplayIndex: 1,\n * title: 'Schiphol Airport'\n * };\n *\n * // Destination\n * const finish: WaypointDisplayProps = {\n * id: 'waypoint-2',\n * iconID: 'waypoint-finish',\n * index: 2,\n * indexType: 'finish',\n * title: 'Rotterdam Central Station'\n * };\n * ```\n *\n * @group Routing\n */\nexport type WaypointDisplayProps = PlaceDisplayProps & {\n /**\n * The index of the waypoint in relation to the other waypoints.\n *\n * @remarks\n * Zero-based index of this waypoint in the complete waypoints array,\n * including start, all stops, and finish.\n *\n * @example\n * ```typescript\n * index: 0 // First waypoint (start)\n * index: 1 // Second waypoint (first stop or finish)\n * index: 2 // Third waypoint\n * ```\n */\n index: number;\n\n /**\n * The type associated to the index, describing how the waypoint sits in the list of waypoints.\n *\n * @remarks\n * Determines the waypoint's role and visual representation:\n * - `start`: Origin point\n * - `middle`: Intermediate stop\n * - `finish`: Final destination\n *\n * This affects icon selection and labeling behavior.\n */\n indexType: WaypointIndexType;\n\n /**\n * The stop index to be displayed.\n *\n * @remarks\n * Stops are the non-soft waypoints added between origin and destination,\n * numbered starting from 1. Only present for middle waypoints.\n *\n * **Display Behavior:**\n * - Start waypoint: undefined\n * - First stop: 1\n * - Second stop: 2\n * - Finish waypoint: undefined\n *\n * Used for displaying stop numbers (e.g., \"Stop 1\", \"Stop 2\") in the UI.\n *\n * @example\n * ```typescript\n * stopDisplayIndex: 1 // First intermediate stop\n * stopDisplayIndex: 2 // Second intermediate stop\n * stopDisplayIndex: undefined // Start or finish waypoint\n * ```\n */\n stopDisplayIndex?: number;\n};\n\n/**\n * @ignore\n */\nexport const INDEX_TYPE = 'indexType';\n\n/**\n * @ignore\n */\nexport const STOP_DISPLAY_INDEX = 'stopDisplayIndex';\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\nimport type { LayerSpecTemplate } from '../../shared';\nimport { MAP_BOLD_FONT } from '../../shared/layers/commonLayerProps';\nimport {\n ICON_ID,\n pinIconBaseLayout,\n pinIconBasePaint,\n pinTextBaseLayout,\n pinTextBasePaint,\n} from '../../shared/layers/symbolLayers';\nimport { INDEX_TYPE, MIDDLE_INDEX, STOP_DISPLAY_INDEX } from '../types/waypointDisplayProps';\n\n/**\n * Waypoint start image ID.\n * @group Routing\n */\nexport const WAYPOINT_START_IMAGE_ID = 'waypointStart';\n/**\n * Waypoint stop image ID.\n *\n * @remarks\n * Used for intermediate waypoints in a route.\n *\n * @group Routing.\n */\nexport const WAYPOINT_STOP_IMAGE_ID = 'waypointStop';\n/**\n * Soft waypoint image ID.\n *\n * @remarks\n * This is currently unsupported in Orbis maps.\n *\n * @group Routing\n */\nexport const WAYPOINT_SOFT_IMAGE_ID = 'waypointSoft';\n/**\n * Waypoint finish image ID.\n *\n * @group Routing\n */\nexport const WAYPOINT_FINISH_IMAGE_ID = 'waypointFinish';\n\nconst isSoftWaypoint: ExpressionSpecification = [\n 'all',\n ['==', ['get', INDEX_TYPE], MIDDLE_INDEX],\n ['!', ['has', STOP_DISPLAY_INDEX]],\n];\n\nconst pinIndexLabelPaint: SymbolLayerSpecification['paint'] = {\n 'text-color': '#ffffff',\n};\n\nconst pinIndexLabelLayout: SymbolLayerSpecification['layout'] = {\n // optional centered text to indicate stop numbers (1, 2 ...):\n 'text-field': ['get', STOP_DISPLAY_INDEX],\n 'text-font': [MAP_BOLD_FONT],\n 'text-size': ['interpolate', ['linear'], ['zoom'], 13, 14, 18, 16],\n 'text-offset': [0, -1.6],\n // pin vs circle:\n 'icon-anchor': [\n 'case',\n isSoftWaypoint,\n 'center',\n // else\n 'bottom',\n ],\n 'text-allow-overlap': true,\n};\n\n// TODO: reusable display of pins with indexes, not just waypoints\n/**\n * @ignore\n */\nexport const waypointSymbols: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n paint: {\n ...pinIconBasePaint,\n ...pinIndexLabelPaint,\n },\n layout: {\n ...pinIconBaseLayout,\n ...pinIndexLabelLayout,\n 'symbol-sort-key': [\n 'case',\n ['==', ['get', ICON_ID], WAYPOINT_SOFT_IMAGE_ID],\n 0,\n ['abs', ['-', ['get', 'index'], 1000]],\n ],\n },\n};\n\n/**\n * @ignore\n */\nexport const waypointLabels: LayerSpecTemplate<SymbolLayerSpecification> = {\n type: 'symbol',\n paint: {\n ...pinTextBasePaint,\n 'text-color': 'black',\n 'text-halo-width': 1.5,\n 'text-halo-color': '#ffffff',\n },\n layout: {\n ...pinTextBaseLayout,\n 'text-anchor': 'top',\n 'text-offset': [0, 0.4],\n },\n};\n","import { mapStyleLayerIDs } from '../../shared';\nimport type { RouteLayersConfig, RoutingModuleConfig } from '../types/routeModuleConfig';\nimport { chargingStopSymbol } from './chargingStopLayers';\nimport { instructionArrow, instructionLine, instructionOutline } from './guidanceLayers';\nimport { routeFerriesLine, routeFerriesSymbol } from './routeFerrySectionLayers';\nimport {\n routeDeselectedLine,\n routeDeselectedOutline,\n routeLineArrows,\n routeMainLine,\n routeOutline,\n} from './routeMainLineLayers';\nimport { routeTollRoadsOutline, routeTollRoadsSymbol } from './routeTollRoadLayers';\nimport {\n routeIncidentsBGLine,\n routeIncidentsCauseSymbol,\n routeIncidentsDashedLine,\n routeIncidentsJamSymbol,\n} from './routeTrafficSectionLayers';\nimport { routeTunnelsLine } from './routeTunnelSectionLayers';\nimport { routeVehicleRestrictedBackgroundLine, routeVehicleRestrictedDottedLine } from './routeVehicleRestrictedLayers';\nimport { buildSummaryBubbleSymbolPoint, summaryBubbleSymbolPoint } from './summaryBubbleLayers';\nimport { waypointLabels, waypointSymbols } from './waypointLayers';\n\n/**\n * Helper function to add layer ID prefix to beforeID references, but only for internal routing layer IDs\n * @ignore\n */\nconst prefixBeforeID = (beforeID: string | undefined, layerIDPrefix: string | undefined): string | undefined => {\n if (!beforeID || !layerIDPrefix) {\n return beforeID;\n }\n // Don't prefix map style layer IDs (they start with capital letters or contain specific prefixes)\n if (beforeID.startsWith('route') || beforeID.startsWith('waypoint')) {\n return `${layerIDPrefix}-${beforeID}`;\n }\n return beforeID;\n};\n\n/**\n * Helper function to process additional layers and prefix their beforeID fields\n * @ignore\n */\nconst prefixBeforeIDs = (\n additional: Record<string, any> | undefined,\n layerIDPrefix: string | undefined,\n): Record<string, any> | undefined => {\n if (!additional || !layerIDPrefix) {\n return additional;\n }\n\n return Object.fromEntries(\n Object.entries(additional).map(([key, layer]) => [\n key,\n layer?.beforeID ? { ...layer, beforeID: prefixBeforeID(layer.beforeID, layerIDPrefix) } : layer,\n ]),\n );\n};\n\n/**\n * Helper function to add instance suffix to image IDs for supporting multiple RoutingModule instances\n * @ignore\n */\nconst suffixImageID = (imageID: string | undefined, instanceIndex: number | undefined): string | undefined => {\n if (!imageID || instanceIndex === undefined) {\n return imageID;\n }\n return `${imageID}-${instanceIndex}`;\n};\n\n/**\n * Generates the routing layers configuration for route visualization on the map.\n * @param config - Optional routing module configuration to customize layer properties.\n * @param layerIDPrefix - Optional prefix to add to layer IDs for supporting multiple instances.\n * @param instanceIndex - Optional instance index for image ID suffixes.\n * @ignore\n */\nexport const buildRoutingLayers = (\n config: RoutingModuleConfig = {},\n layerIDPrefix?: string,\n instanceIndex?: number,\n): Required<RouteLayersConfig> => {\n const configLayers = config.layers;\n const configSectionLayers = configLayers?.sections;\n const mainColor = config.theme?.mainColor;\n\n return {\n mainLines: {\n routeLineArrows: {\n ...routeLineArrows,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configLayers?.mainLines?.routeLineArrows,\n },\n routeLine: {\n ...routeMainLine({ color: mainColor }),\n beforeID: prefixBeforeID('routeIncidentBackgroundLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeLine,\n },\n routeOutline: {\n ...routeOutline,\n beforeID: prefixBeforeID('routeLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeOutline,\n },\n routeDeselectedLine: {\n ...routeDeselectedLine,\n beforeID: prefixBeforeID('routeOutline', layerIDPrefix),\n ...configLayers?.mainLines?.routeDeselectedLine,\n },\n routeDeselectedOutline: {\n ...routeDeselectedOutline,\n beforeID: prefixBeforeID('routeDeselectedLine', layerIDPrefix),\n ...configLayers?.mainLines?.routeDeselectedOutline,\n },\n ...prefixBeforeIDs(configLayers?.mainLines?.additional, layerIDPrefix),\n },\n waypoints: {\n routeWaypointSymbol: {\n ...waypointSymbols,\n beforeID: prefixBeforeID('routeSummaryBubbleSymbol', layerIDPrefix),\n ...configLayers?.waypoints?.routeWaypointSymbol,\n },\n routeWaypointLabel: {\n ...waypointLabels,\n beforeID: prefixBeforeID('routeWaypointSymbol', layerIDPrefix),\n ...configLayers?.waypoints?.routeWaypointLabel,\n },\n ...prefixBeforeIDs(configLayers?.waypoints?.additional, layerIDPrefix),\n },\n chargingStops: {\n routeChargingStopSymbol: {\n ...chargingStopSymbol(config.chargingStops),\n beforeID: prefixBeforeID('routeWaypointSymbol', layerIDPrefix),\n ...configLayers?.chargingStops?.routeChargingStopSymbol,\n },\n ...prefixBeforeIDs(configLayers?.chargingStops?.additional, layerIDPrefix),\n },\n sections: {\n incident: {\n routeIncidentJamSymbol: {\n ...routeIncidentsJamSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentJamSymbol,\n },\n routeIncidentCauseSymbol: {\n ...routeIncidentsCauseSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentCauseSymbol,\n },\n routeIncidentBackgroundLine: {\n ...routeIncidentsBGLine,\n beforeID: prefixBeforeID('routeIncidentDashedLine', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentBackgroundLine,\n },\n routeIncidentDashedLine: {\n ...routeIncidentsDashedLine,\n beforeID: prefixBeforeID('routeTunnelLine', layerIDPrefix),\n ...configSectionLayers?.incident?.routeIncidentDashedLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.incident?.additional, layerIDPrefix),\n },\n ferry: {\n routeFerryLine: {\n ...routeFerriesLine,\n beforeID: prefixBeforeID('routeLineArrows', layerIDPrefix),\n ...configSectionLayers?.ferry?.routeFerryLine,\n },\n routeFerrySymbol: {\n ...routeFerriesSymbol,\n beforeID: prefixBeforeID('routeIncidentJamSymbol', layerIDPrefix),\n ...configSectionLayers?.ferry?.routeFerrySymbol,\n },\n ...prefixBeforeIDs(configSectionLayers?.ferry?.additional, layerIDPrefix),\n },\n tollRoad: {\n routeTollRoadOutline: {\n ...routeTollRoadsOutline,\n beforeID: prefixBeforeID('routeDeselectedOutline', layerIDPrefix),\n ...configSectionLayers?.tollRoad?.routeTollRoadOutline,\n },\n routeTollRoadSymbol: {\n ...routeTollRoadsSymbol,\n beforeID: prefixBeforeID('routeChargingStopSymbol', layerIDPrefix),\n ...configSectionLayers?.tollRoad?.routeTollRoadSymbol,\n },\n ...prefixBeforeIDs(configSectionLayers?.tollRoad?.additional, layerIDPrefix),\n },\n tunnel: {\n routeTunnelLine: {\n ...routeTunnelsLine,\n beforeID: prefixBeforeID('routeLineArrows', layerIDPrefix),\n ...configSectionLayers?.tunnel?.routeTunnelLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.tunnel?.additional, layerIDPrefix),\n },\n vehicleRestricted: {\n routeVehicleRestrictedBackgroundLine: {\n ...routeVehicleRestrictedBackgroundLine,\n beforeID: prefixBeforeID('routeVehicleRestrictedForegroundLine', layerIDPrefix),\n ...configSectionLayers?.vehicleRestricted?.routeVehicleRestrictedBackgroundLine,\n },\n routeVehicleRestrictedForegroundLine: {\n ...routeVehicleRestrictedDottedLine,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configSectionLayers?.vehicleRestricted?.routeVehicleRestrictedForegroundLine,\n },\n ...prefixBeforeIDs(configSectionLayers?.vehicleRestricted?.additional, layerIDPrefix),\n },\n },\n instructionLines: {\n routeInstructionLine: {\n ...instructionLine,\n beforeID: mapStyleLayerIDs.lowestLabel,\n ...configLayers?.instructionLines?.routeInstructionLine,\n },\n routeInstructionOutline: {\n ...instructionOutline,\n beforeID: prefixBeforeID('routeInstructionLine', layerIDPrefix),\n ...configLayers?.instructionLines?.routeInstructionOutline,\n },\n ...prefixBeforeIDs(configLayers?.instructionLines?.additional, layerIDPrefix),\n },\n instructionArrows: {\n routeInstructionArrowSymbol: {\n ...instructionArrow,\n beforeID: prefixBeforeID('routeInstructionLine', layerIDPrefix),\n ...(instanceIndex !== undefined && {\n layout: {\n ...instructionArrow.layout,\n 'icon-image': suffixImageID(instructionArrow.layout?.['icon-image'] as string, instanceIndex),\n },\n }),\n ...configLayers?.instructionArrows?.routeInstructionArrowSymbol,\n },\n ...prefixBeforeIDs(configLayers?.instructionArrows?.additional, layerIDPrefix),\n },\n summaryBubbles: {\n routeSummaryBubbleSymbol: {\n ...(instanceIndex !== undefined\n ? buildSummaryBubbleSymbolPoint(instanceIndex)\n : summaryBubbleSymbolPoint),\n ...configLayers?.summaryBubbles?.routeSummaryBubbleSymbol,\n },\n ...prefixBeforeIDs(configLayers?.summaryBubbles?.additional, layerIDPrefix),\n },\n };\n};\n\n/**\n * Default routing layers configuration. Calls routingLayers with no parameters.\n *\n * @remarks\n * This configuration defines the complete visual styling for all route-related map layers,\n * including main route lines, waypoints, special road sections (ferries, tunnels, toll roads, etc.),\n * turn-by-turn guidance instructions, and route summary information.\n *\n * **Usage:**\n * - Automatically applied when initializing {@link RoutingModule} without custom layer configuration\n * - Can be used as a reference or starting point for creating custom layer configurations\n * - Individual properties can be selectively overridden while keeping defaults for others\n *\n * @see {@link buildRoutingLayers} for details.\n *\n * @see {@link RouteLayersConfig} for the configuration type definition\n * @see {@link RoutingModule.get} for initialization options\n * @see {@link RoutingModule.applyConfig} for runtime configuration updates\n *\n * @group Routing\n */\nexport const defaultRoutingLayers: Required<RouteLayersConfig> = buildRoutingLayers();\n","import type { StyleImageMetadata } from 'maplibre-gl';\nimport { SVGIconStyleOptions } from '../../shared';\nimport { isDOMImageSupported, svgToImg } from '../../shared/imageUtils';\nimport { parseSvg, pinSvg } from '../../shared/resources';\nimport circleSvgRaw from './circle.svg?raw';\nimport finishSvgRaw from './finish.svg?raw';\nimport instructionArrowSvgRaw from './instruction-line-arrow.svg?raw';\nimport startSvgRaw from './start.svg?raw';\nimport summaryMapBubbleSvgRaw from './summary-map-bubble.svg?raw';\nimport trafficSvgRaw from './traffic.svg?raw';\n\nlet instructionArrowIconImg: HTMLImageElement;\n\n// defensive check for SSR\nif (isDOMImageSupported()) {\n instructionArrowIconImg = svgToImg(parseSvg(instructionArrowSvgRaw));\n}\n\n/**\n * @ignore\n */\nexport { instructionArrowIconImg };\n\n/**\n * @ignore\n */\nexport const summaryMapBubbleImg = (color: string): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg: SVGElement = parseSvg(summaryMapBubbleSvgRaw);\n svg.querySelector('#bubble')?.setAttribute('fill', color);\n svg.querySelector('#pin')?.setAttribute('fill', color);\n return svgToImg(svg);\n};\n\n/**\n * Options to effectively stretch the summary bubble image to fit its text.\n * * They are tightly coupled with the SVG original dimensions.\n * @ignore\n */\nexport const summaryBubbleImageOptions: Partial<StyleImageMetadata> = {\n pixelRatio: 2,\n stretchX: [\n [20, 45],\n [100, 130],\n ],\n stretchY: [[20, 35]],\n content: [10, 10, 130, 45],\n};\n\n/**\n * @ignore\n * @param color\n */\nexport const trafficImg = (color: string): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg: SVGElement = parseSvg(trafficSvgRaw);\n const main = svg.querySelector('#main') as Element;\n main.setAttribute('transform', 'scale(2)');\n main.setAttribute('fill', color);\n return svgToImg(svg);\n};\n\n/**\n * @ignore\n */\nexport const waypointIcon = (\n foregroundSvg: SVGElement | undefined,\n svgOptions: SVGIconStyleOptions | undefined,\n): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n const svg = pinSvg(svgOptions);\n if (foregroundSvg) {\n svg.appendChild(foregroundSvg);\n }\n return svgToImg(svg);\n};\n\n/**\n * @ignore\n */\nexport const waypointStartIcon = (svgOptions: SVGIconStyleOptions | undefined): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return waypointIcon(parseSvg(startSvgRaw), svgOptions);\n};\n\n/**\n * @ignore\n */\nexport const waypointFinishIcon = (svgOptions: SVGIconStyleOptions | undefined): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return waypointIcon(parseSvg(finishSvgRaw), svgOptions);\n};\n\n/**\n * @ignore\n */\nexport const softWaypointIcon = (): HTMLImageElement => {\n // defensive check for SSR and node-test environments:\n if (!isDOMImageSupported()) {\n return undefined as never as HTMLImageElement;\n }\n return svgToImg(parseSvg(circleSvgRaw));\n};\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"50\\\" height=\\\"50\\\">\\n <path d=\\\"M1.562 40.569L25 1.562l23.438 39.007L25 27.566 1.562 40.569z\\\" fill=\\\"#fff\\\"/>\\n <path d=\\\"M25.369.107c.782.429.506.167.917.682l23.438 39.007c.79 1.316-.671 2.829-2.014 2.085L25 29.281l-22.71 12.6c-1.343.744-2.804-.769-2.014-2.085L23.714.789c.461-.694.9-.682 1.656-.682zM25 1.562L1.562 40.569 25 27.566l23.438 13.003L25 1.562z\\\"\\n fill=\\\"gray\\\"/>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"160\\\" height=\\\"65\\\">\\n <g filter=\\\"url(#A)\\\">\\n <rect id=\\\"pin\\\" x=\\\"81.899\\\" y=\\\"47\\\" width=\\\"10\\\" height=\\\"10\\\" rx=\\\"2\\\" transform=\\\"rotate(45 81.899 47)\\\"/>\\n <rect id=\\\"bubble\\\" x=\\\"10\\\" y=\\\"10\\\" width=\\\"140\\\" height=\\\"45\\\" rx=\\\"12\\\"/>\\n </g>\\n <defs>\\n <filter id=\\\"A\\\">\\n <feDropShadow dx=\\\"0\\\" dy=\\\"2\\\" stdDeviation=\\\"4\\\" flood-opacity=\\\".3\\\"/>\\n </filter>\\n </defs>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"32\\\" height=\\\"32\\\">\\n <g id=\\\"main\\\">\\n <path fill-rule=\\\"evenodd\\\"\\n d=\\\"M11.389 4H9.025a.86.86 0 0 0-.517.173l-.001-.001a.5.5 0 0 1-.464.059l-.028-.011a.5.5 0 0 1-.129-.83A1.86 1.86 0 0 1 9.025 3h2.364a2 2 0 0 1 1.789 1.106l1.02 2.04c.471.176.802.63.802 1.156v.803c0 .543 0 .815-.071 1.038a1.5 1.5 0 0 1-.914.953c-.219.08-.491.092-1.034.114l-1.481.062v-.166-.803a2.23 2.23 0 0 0-1.055-1.897l-.74-1.479 2.326.033h.955l-.703-1.406A1 1 0 0 0 11.389 4zM12 8.4a1 1 0 1 1 2 0 .5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\\\"/>\\n <path d=\\\"M11.833 11.115c0-.109.089-.198.198-.198h1.979c.109 0 .198.089.198.198 0 .328-.266.594-.594.594h-1.187c-.328 0-.594-.266-.594-.594z\\\"/>\\n <path fill-rule=\\\"evenodd\\\"\\n d=\\\"M1.802 8.146C1.331 8.321 1 8.776 1 9.302v.803c0 .543 0 .815.071 1.038a1.5 1.5 0 0 0 .914.953c.219.08.491.092 1.034.114l2.731.114 2.731-.114c.543-.023.814-.034 1.034-.114a1.5 1.5 0 0 0 .914-.953c.071-.223.071-.494.071-1.038v-.803c0-.526-.331-.98-.802-1.156l-1.02-2.04A2 2 0 0 0 6.889 5H4.611a2 2 0 0 0-1.789 1.106l-1.02 2.04zM6.889 6H4.611a1 1 0 0 0-.894.553l-.703 1.406h.955 3.563.955l-.703-1.406A1 1 0 0 0 6.889 6zM2 10.4a1 1 0 1 1 2 0 .5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm6.5-1a1 1 0 0 0-1 1 .5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5 1 1 0 0 0-1-1z\\\"/>\\n <path d=\\\"M1.792 13.115c0-.109.089-.198.198-.198h1.979c.109 0 .198.089.198.198 0 .328-.266.594-.594.594H2.385c-.328 0-.594-.266-.594-.594zm5.739-.198c-.109 0-.198.089-.198.198 0 .328.266.594.594.594h1.188c.328 0 .594-.266.594-.594 0-.109-.089-.198-.198-.198h-1.98z\\\"/>\\n </g>\\n</svg>\\n\"","import { TomTomConfig } from '@tomtom-org/maps-sdk/core';\nimport type { ToBeAddedLayerSpecTemplate, ToBeAddedLayerSpecWithoutSource } from '../../shared';\nimport { buildRoutingLayers } from '../layers/routingLayers';\nimport type { RouteLayersConfig, RoutingModuleConfig } from '../types/routeModuleConfig';\nimport type { RoutingLayersSpecs } from '../types/routingSourcesAndLayers';\n\n/**\n * @ignore\n */\nconst mapLayerSpecs = (\n layerSpecs: Record<string, Partial<ToBeAddedLayerSpecTemplate>> = {},\n layerIDPrefix?: string,\n): ToBeAddedLayerSpecWithoutSource[] =>\n // The key of the entry is the layer ID:\n Object.entries(layerSpecs).map(\n ([id, spec]) =>\n ({\n ...spec,\n id: layerIDPrefix ? `${layerIDPrefix}-${id}` : id,\n }) as ToBeAddedLayerSpecWithoutSource,\n );\n\n/**\n * @ignore\n */\nexport const createLayersSpecs = (\n layerConfigs: RouteLayersConfig = {},\n layerIDPrefix?: string,\n): RoutingLayersSpecs => ({\n mainLines: mapLayerSpecs(layerConfigs.mainLines, layerIDPrefix),\n waypoints: mapLayerSpecs(layerConfigs.waypoints, layerIDPrefix),\n chargingStops: mapLayerSpecs(layerConfigs?.chargingStops, layerIDPrefix),\n ferries: mapLayerSpecs(layerConfigs.sections?.ferry, layerIDPrefix),\n incidents: mapLayerSpecs(layerConfigs.sections?.incident, layerIDPrefix),\n tollRoads: mapLayerSpecs(layerConfigs.sections?.tollRoad, layerIDPrefix),\n tunnels: mapLayerSpecs(layerConfigs.sections?.tunnel, layerIDPrefix),\n vehicleRestricted: mapLayerSpecs(layerConfigs.sections?.vehicleRestricted, layerIDPrefix),\n instructionLines: mapLayerSpecs(layerConfigs.instructionLines, layerIDPrefix),\n instructionArrows: mapLayerSpecs(layerConfigs.instructionArrows, layerIDPrefix),\n summaryBubbles: mapLayerSpecs(layerConfigs.summaryBubbles, layerIDPrefix),\n});\n\n/**\n * @ignore\n */\nexport const routeModuleConfigWithDefaults = (\n config: RoutingModuleConfig | undefined,\n layerIDPrefix: string,\n instanceIndex: number,\n): RoutingModuleConfig => {\n const globalDisplayUnits = TomTomConfig.instance.get().displayUnits;\n const displayUnits = config?.displayUnits;\n return {\n // First apply the provided configuration not to lose any properties:\n ...config,\n ...(displayUnits ? {} : { displayUnits: globalDisplayUnits }),\n layers: buildRoutingLayers(config, layerIDPrefix, instanceIndex),\n };\n};\n","import {\n ChargingStop,\n ChargingStopProps,\n formatDuration,\n generateId,\n type Place,\n type Routes,\n} from '@tomtom-org/maps-sdk/core';\nimport { FeatureCollection, Point } from 'geojson';\nimport { PlaceDisplayProps } from '../../places';\nimport type { DisplayRouteProps, RouteStateProps } from '../types/displayRoutes';\nimport { RoutingModuleConfig } from '../types/routeModuleConfig';\n\nconst getIconID = (chargingStop: ChargingStop, config: RoutingModuleConfig | undefined): string => {\n const iconConfig = config?.chargingStops?.icon;\n if (iconConfig?.mapping) {\n const mapping = iconConfig.mapping;\n switch (mapping.basedOn) {\n case 'chargingSpeed':\n if (chargingStop.properties.chargingConnectionInfo?.chargingSpeed) {\n return mapping.value[chargingStop.properties.chargingConnectionInfo?.chargingSpeed];\n }\n break;\n case 'custom':\n return mapping.fn(chargingStop);\n }\n }\n\n // default: (genesis-like) categorySet ID for \"EV Charging Station\" based on search\n return '7309';\n};\n\nconst formatTitle = (chargingStop: ChargingStop): string => {\n const properties = chargingStop.properties;\n return properties.chargingParkName ?? (properties.chargingParkOperatorName as string);\n};\n\ntype DisplayChargingStopProps = PlaceDisplayProps &\n ChargingStopProps &\n RouteStateProps & {\n chargingDuration: string;\n chargingPower: string;\n };\n\ntype DisplayChargingStops = FeatureCollection<Point, DisplayChargingStopProps>;\n\n/**\n * Generates display-ready charging stations for the given planning context ones.\n * @param routes The routes return for ldEV.\n * @param config The charging stops display configuration.\n * @see chargingStopLayers\n * @ignore\n */\nexport const toDisplayChargingStops = (\n routes: Routes<DisplayRouteProps>,\n config: RoutingModuleConfig | undefined,\n): DisplayChargingStops => {\n const displayChargingStops: Place<DisplayChargingStopProps>[] = [];\n\n if (config?.chargingStops?.visible !== false) {\n for (const route of routes.features) {\n for (const leg of route.properties.sections.leg) {\n const chargingStop = leg.summary.chargingInformationAtEndOfLeg;\n\n if (chargingStop) {\n const properties = chargingStop.properties;\n displayChargingStops.push({\n ...chargingStop,\n properties: {\n ...chargingStop.properties,\n id: chargingStop.properties.chargingParkId ?? generateId(),\n iconID: getIconID(chargingStop, config),\n title: formatTitle(chargingStop),\n chargingPower: `${properties.chargingConnectionInfo?.chargingPowerInkW} kW`,\n chargingDuration: formatDuration(\n properties.chargingTimeInSeconds,\n config?.displayUnits?.time,\n ) as string,\n routeState: route.properties.routeState,\n },\n });\n }\n }\n }\n }\n return { type: 'FeatureCollection', features: displayChargingStops };\n};\n","import { formatDuration, type TrafficSectionProps } from '@tomtom-org/maps-sdk/core';\nimport type { DisplayTrafficSectionProps } from '../types/routeSections';\n\nconst hasJam = (sectionProps: TrafficSectionProps): boolean => sectionProps.categories.includes('jam');\n\nconst buildTitle = (sectionProps: TrafficSectionProps): string | undefined => {\n if (hasJam(sectionProps)) {\n return formatDuration(sectionProps.delayInSeconds);\n }\n return undefined;\n};\n\nconst toTrafficJamIconSuffix = (title: string | undefined): 'collapsed' | 'small' | 'medium' | 'large' => {\n if (!title?.length) {\n return 'collapsed';\n }\n if (title.length < 6) {\n // 1 digit minutes\n return 'small';\n }\n if (title.length < 8) {\n // 2 digit minutes\n return 'medium';\n }\n // hours + minutes\n return 'large';\n};\n\nconst toJamIconID = (sectionProps: TrafficSectionProps, title: string | undefined): string | null => {\n if (!hasJam(sectionProps)) {\n return null;\n }\n const magnitude = sectionProps.magnitudeOfDelay ?? 'unknown';\n return `traffic-jam-${magnitude}-${toTrafficJamIconSuffix(title)}`;\n};\n\nconst toCauseIconID = (sectionProps: TrafficSectionProps): string | null => {\n const firstNonJamCategory = sectionProps.categories.find((category) => category !== 'jam');\n switch (firstNonJamCategory) {\n case 'accident':\n return 'traffic-incidents-accident';\n case 'roadworks':\n return 'traffic-incidents-roadworks';\n case 'road-closed':\n return 'traffic-incidents-road_closed';\n case 'danger':\n case 'animals-on-road':\n return 'traffic-incidents-danger';\n case 'broken-down-vehicle':\n return 'traffic-incidents-broken_down_vehicle';\n case 'lane-closed':\n case 'narrow-lanes':\n return 'traffic-incidents-lane_closed';\n case 'wind':\n return 'traffic-incidents-wind';\n case 'fog':\n return 'traffic-incidents-fog';\n case 'rain':\n return 'traffic-incidents-rain';\n case 'frost':\n return 'traffic-incidents-frost';\n case 'flooding':\n return 'traffic-incidents-flooding';\n default:\n return null;\n }\n};\n\n/**\n * @ignore\n */\nexport const toDisplayTrafficSectionProps = (\n sectionProps: TrafficSectionProps,\n): Omit<DisplayTrafficSectionProps, 'routeState' | 'routeIndex'> => {\n const title = buildTitle(sectionProps);\n const jamIconID = toJamIconID(sectionProps, title);\n const causeIconID = toCauseIconID(sectionProps);\n return {\n ...sectionProps,\n ...(jamIconID && { jamIconID }),\n ...(causeIconID && { causeIconID }),\n ...(title && { title }),\n };\n};\n","import type { CommonPlaceProps, Waypoint, WaypointLike, Waypoints } from '@tomtom-org/maps-sdk/core';\nimport { generateId, getPosition } from '@tomtom-org/maps-sdk/core';\nimport type { Point, Position } from 'geojson';\nimport { suffixNumber } from '../../shared/layers/utils';\nimport {\n WAYPOINT_FINISH_IMAGE_ID,\n WAYPOINT_SOFT_IMAGE_ID,\n WAYPOINT_START_IMAGE_ID,\n WAYPOINT_STOP_IMAGE_ID,\n} from '../layers/waypointLayers';\nimport type { PlanningWaypoint } from '../types/planningWaypoint';\nimport type { WaypointsConfig } from '../types/routeModuleConfig';\nimport type { WaypointDisplayProps, WaypointIndexType } from '../types/waypointDisplayProps';\nimport { FINISH_INDEX, MIDDLE_INDEX, START_INDEX } from '../types/waypointDisplayProps';\n\nconst indexTypeFor = (index: number, arrayLength: number): WaypointIndexType =>\n index === 0 ? START_INDEX : index < arrayLength - 1 ? MIDDLE_INDEX : FINISH_INDEX;\n\n/**\n * Builds the title of the given waypoint.\n * @param waypoint The waypoint for which to build the title.\n */\nexport const buildWaypointTitle = (waypoint: Waypoint): string | undefined => {\n const placeProperties = waypoint?.properties as CommonPlaceProps;\n return placeProperties?.poi?.name ?? placeProperties?.address?.freeformAddress ?? undefined;\n};\n\nexport const getImageIDForWaypoint = (\n waypoint: Waypoint,\n indexType: WaypointIndexType,\n instanceIndex?: number,\n): string => {\n if (waypoint.properties.radiusMeters) {\n return instanceIndex !== undefined\n ? suffixNumber(WAYPOINT_SOFT_IMAGE_ID, instanceIndex)\n : WAYPOINT_SOFT_IMAGE_ID;\n }\n let baseImageID: string;\n switch (indexType) {\n case 'start':\n baseImageID = WAYPOINT_START_IMAGE_ID;\n break;\n case 'finish':\n baseImageID = WAYPOINT_FINISH_IMAGE_ID;\n break;\n default:\n baseImageID = WAYPOINT_STOP_IMAGE_ID;\n break;\n }\n return instanceIndex !== undefined ? suffixNumber(baseImageID, instanceIndex) : baseImageID;\n};\n\nconst toWaypointFromPosition = (position: Position): Waypoint => ({\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: position,\n },\n properties: {},\n});\n\nconst toWaypointFromPoint = (point: Point): Waypoint => ({\n type: 'Feature',\n geometry: point,\n properties: {},\n ...(point.bbox && { bbox: point.bbox }),\n});\n\nconst asWaypoint = (waypointInput: WaypointLike): Waypoint => {\n if (Array.isArray(waypointInput)) {\n return toWaypointFromPosition(waypointInput);\n }\n if (waypointInput.type === 'Point') {\n return toWaypointFromPoint(waypointInput);\n }\n return waypointInput as Waypoint;\n};\n\n/**\n * Determines whether the given waypoint is a regular start/stop/destination with guidance attached,\n * as opposed to a circle (soft) waypoint.\n * @param waypoint The waypoint to verify.\n */\nexport const isHardWaypoint = (waypoint: Waypoint): boolean => !waypoint.properties.radiusMeters;\n\n/**\n * Generates display-ready waypoints for the given planning context ones.\n * @param waypoints The planning context waypoints.\n * @param options\n * @param instanceIndex Optional instance index for supporting multiple RoutingModule instances\n */\nexport const toDisplayWaypoints = (\n waypoints: PlanningWaypoint[],\n options: WaypointsConfig | undefined,\n instanceIndex?: number,\n): Waypoints<WaypointDisplayProps> => {\n // Since waypoints are of mixed types (hard and soft), we need to calculate the hard-only indexes\n // in case we have stops with numbered icons:\n let hardWaypointIndex = -1;\n return {\n type: 'FeatureCollection',\n features: waypoints\n .map((waypointInput, index) => {\n if (!waypointInput) {\n // (we consider placeholder waypoints to be \"hard\", since they typically occupy a position in a planner panel)\n hardWaypointIndex++;\n // (will be filtered out below - we don't pre-filter it to keep the original input index)\n return null as unknown as Waypoint<WaypointDisplayProps>;\n }\n const waypoint: Waypoint = asWaypoint(waypointInput);\n const indexType = indexTypeFor(index, waypoints.length);\n const hardWaypoint = isHardWaypoint(waypoint);\n if (hardWaypoint) {\n hardWaypointIndex++;\n }\n const title = buildWaypointTitle(waypoint);\n const id = (waypoint.id as string) ?? generateId();\n return {\n ...waypoint,\n ...(options?.entryPoints === 'main-when-available' && {\n geometry: {\n type: 'Point',\n // We replace the waypoint coordinates with their main entry point ones:\n coordinates: getPosition(waypoint, { useEntryPoint: 'main-when-available' }),\n } as Point,\n }),\n id,\n properties: {\n ...waypoint.properties,\n id,\n index,\n indexType,\n ...(title && { title }),\n iconID: getImageIDForWaypoint(waypoint, indexType, instanceIndex),\n ...(hardWaypoint && indexType === MIDDLE_INDEX && { stopDisplayIndex: hardWaypointIndex }),\n },\n };\n })\n .filter((feature) => feature),\n };\n};\n","// index.ts\nvar earthRadius = 63710088e-1;\nvar factors = {\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n degrees: 360 / (2 * Math.PI),\n feet: earthRadius * 3.28084,\n inches: earthRadius * 39.37,\n kilometers: earthRadius / 1e3,\n kilometres: earthRadius / 1e3,\n meters: earthRadius,\n metres: earthRadius,\n miles: earthRadius / 1609.344,\n millimeters: earthRadius * 1e3,\n millimetres: earthRadius * 1e3,\n nauticalmiles: earthRadius / 1852,\n radians: 1,\n yards: earthRadius * 1.0936\n};\nvar areaFactors = {\n acres: 247105e-9,\n centimeters: 1e4,\n centimetres: 1e4,\n feet: 10.763910417,\n hectares: 1e-4,\n inches: 1550.003100006,\n kilometers: 1e-6,\n kilometres: 1e-6,\n meters: 1,\n metres: 1,\n miles: 386e-9,\n nauticalmiles: 29155334959812285e-23,\n millimeters: 1e6,\n millimetres: 1e6,\n yards: 1.195990046\n};\nfunction feature(geom, properties, options = {}) {\n const feat = { type: \"Feature\" };\n if (options.id === 0 || options.id) {\n feat.id = options.id;\n }\n if (options.bbox) {\n feat.bbox = options.bbox;\n }\n feat.properties = properties || {};\n feat.geometry = geom;\n return feat;\n}\nfunction geometry(type, coordinates, _options = {}) {\n switch (type) {\n case \"Point\":\n return point(coordinates).geometry;\n case \"LineString\":\n return lineString(coordinates).geometry;\n case \"Polygon\":\n return polygon(coordinates).geometry;\n case \"MultiPoint\":\n return multiPoint(coordinates).geometry;\n case \"MultiLineString\":\n return multiLineString(coordinates).geometry;\n case \"MultiPolygon\":\n return multiPolygon(coordinates).geometry;\n default:\n throw new Error(type + \" is invalid\");\n }\n}\nfunction point(coordinates, properties, options = {}) {\n if (!coordinates) {\n throw new Error(\"coordinates is required\");\n }\n if (!Array.isArray(coordinates)) {\n throw new Error(\"coordinates must be an Array\");\n }\n if (coordinates.length < 2) {\n throw new Error(\"coordinates must be at least 2 numbers long\");\n }\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {\n throw new Error(\"coordinates must contain numbers\");\n }\n const geom = {\n type: \"Point\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction points(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return point(coords, properties);\n }),\n options\n );\n}\nfunction polygon(coordinates, properties, options = {}) {\n for (const ring of coordinates) {\n if (ring.length < 4) {\n throw new Error(\n \"Each LinearRing of a Polygon must have 4 or more Positions.\"\n );\n }\n if (ring[ring.length - 1].length !== ring[0].length) {\n throw new Error(\"First and last Position are not equivalent.\");\n }\n for (let j = 0; j < ring[ring.length - 1].length; j++) {\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error(\"First and last Position are not equivalent.\");\n }\n }\n }\n const geom = {\n type: \"Polygon\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction polygons(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return polygon(coords, properties);\n }),\n options\n );\n}\nfunction lineString(coordinates, properties, options = {}) {\n if (coordinates.length < 2) {\n throw new Error(\"coordinates must be an array of two or more positions\");\n }\n const geom = {\n type: \"LineString\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction lineStrings(coordinates, properties, options = {}) {\n return featureCollection(\n coordinates.map((coords) => {\n return lineString(coords, properties);\n }),\n options\n );\n}\nfunction featureCollection(features, options = {}) {\n const fc = { type: \"FeatureCollection\" };\n if (options.id) {\n fc.id = options.id;\n }\n if (options.bbox) {\n fc.bbox = options.bbox;\n }\n fc.features = features;\n return fc;\n}\nfunction multiLineString(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiLineString\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction multiPoint(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiPoint\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction multiPolygon(coordinates, properties, options = {}) {\n const geom = {\n type: \"MultiPolygon\",\n coordinates\n };\n return feature(geom, properties, options);\n}\nfunction geometryCollection(geometries, properties, options = {}) {\n const geom = {\n type: \"GeometryCollection\",\n geometries\n };\n return feature(geom, properties, options);\n}\nfunction round(num, precision = 0) {\n if (precision && !(precision >= 0)) {\n throw new Error(\"precision must be a positive number\");\n }\n const multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\nfunction radiansToLength(radians, units = \"kilometers\") {\n const factor = factors[units];\n if (!factor) {\n throw new Error(units + \" units is invalid\");\n }\n return radians * factor;\n}\nfunction lengthToRadians(distance, units = \"kilometers\") {\n const factor = factors[units];\n if (!factor) {\n throw new Error(units + \" units is invalid\");\n }\n return distance / factor;\n}\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\nfunction bearingToAzimuth(bearing) {\n let angle = bearing % 360;\n if (angle < 0) {\n angle += 360;\n }\n return angle;\n}\nfunction azimuthToBearing(angle) {\n angle = angle % 360;\n if (angle > 180) {\n return angle - 360;\n } else if (angle < -180) {\n return angle + 360;\n }\n return angle;\n}\nfunction radiansToDegrees(radians) {\n const normalisedRadians = radians % (2 * Math.PI);\n return normalisedRadians * 180 / Math.PI;\n}\nfunction degreesToRadians(degrees) {\n const normalisedDegrees = degrees % 360;\n return normalisedDegrees * Math.PI / 180;\n}\nfunction convertLength(length, originalUnit = \"kilometers\", finalUnit = \"kilometers\") {\n if (!(length >= 0)) {\n throw new Error(\"length must be a positive number\");\n }\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);\n}\nfunction convertArea(area, originalUnit = \"meters\", finalUnit = \"kilometers\") {\n if (!(area >= 0)) {\n throw new Error(\"area must be a positive number\");\n }\n const startFactor = areaFactors[originalUnit];\n if (!startFactor) {\n throw new Error(\"invalid original units\");\n }\n const finalFactor = areaFactors[finalUnit];\n if (!finalFactor) {\n throw new Error(\"invalid final units\");\n }\n return area / startFactor * finalFactor;\n}\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\nfunction isObject(input) {\n return input !== null && typeof input === \"object\" && !Array.isArray(input);\n}\nfunction validateBBox(bbox) {\n if (!bbox) {\n throw new Error(\"bbox is required\");\n }\n if (!Array.isArray(bbox)) {\n throw new Error(\"bbox must be an Array\");\n }\n if (bbox.length !== 4 && bbox.length !== 6) {\n throw new Error(\"bbox must be an Array of 4 or 6 numbers\");\n }\n bbox.forEach((num) => {\n if (!isNumber(num)) {\n throw new Error(\"bbox must only contain numbers\");\n }\n });\n}\nfunction validateId(id) {\n if (!id) {\n throw new Error(\"id is required\");\n }\n if ([\"string\", \"number\"].indexOf(typeof id) === -1) {\n throw new Error(\"id must be a number or a string\");\n }\n}\nexport {\n areaFactors,\n azimuthToBearing,\n bearingToAzimuth,\n convertArea,\n convertLength,\n degreesToRadians,\n earthRadius,\n factors,\n feature,\n featureCollection,\n geometry,\n geometryCollection,\n isNumber,\n isObject,\n lengthToDegrees,\n lengthToRadians,\n lineString,\n lineStrings,\n multiLineString,\n multiPoint,\n multiPolygon,\n point,\n points,\n polygon,\n polygons,\n radiansToDegrees,\n radiansToLength,\n round,\n validateBBox,\n validateId\n};\n//# sourceMappingURL=index.js.map","// index.ts\nimport { isNumber } from \"@turf/helpers\";\nfunction getCoord(coord) {\n if (!coord) {\n throw new Error(\"coord is required\");\n }\n if (!Array.isArray(coord)) {\n if (coord.type === \"Feature\" && coord.geometry !== null && coord.geometry.type === \"Point\") {\n return [...coord.geometry.coordinates];\n }\n if (coord.type === \"Point\") {\n return [...coord.coordinates];\n }\n }\n if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {\n return [...coord];\n }\n throw new Error(\"coord must be GeoJSON Point or an Array of numbers\");\n}\nfunction getCoords(coords) {\n if (Array.isArray(coords)) {\n return coords;\n }\n if (coords.type === \"Feature\") {\n if (coords.geometry !== null) {\n return coords.geometry.coordinates;\n }\n } else {\n if (coords.coordinates) {\n return coords.coordinates;\n }\n }\n throw new Error(\n \"coords must be GeoJSON Feature, Geometry Object or an Array\"\n );\n}\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {\n return true;\n }\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error(\"coordinates must only contain numbers\");\n}\nfunction geojsonType(value, type, name) {\n if (!type || !name) {\n throw new Error(\"type and name required\");\n }\n if (!value || value.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + value.type\n );\n }\n}\nfunction featureOf(feature, type, name) {\n if (!feature) {\n throw new Error(\"No feature passed\");\n }\n if (!name) {\n throw new Error(\".featureOf() requires a name\");\n }\n if (!feature || feature.type !== \"Feature\" || !feature.geometry) {\n throw new Error(\n \"Invalid input to \" + name + \", Feature with geometry required\"\n );\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + feature.geometry.type\n );\n }\n}\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) {\n throw new Error(\"No featureCollection passed\");\n }\n if (!name) {\n throw new Error(\".collectionOf() requires a name\");\n }\n if (!featureCollection || featureCollection.type !== \"FeatureCollection\") {\n throw new Error(\n \"Invalid input to \" + name + \", FeatureCollection required\"\n );\n }\n for (const feature of featureCollection.features) {\n if (!feature || feature.type !== \"Feature\" || !feature.geometry) {\n throw new Error(\n \"Invalid input to \" + name + \", Feature with geometry required\"\n );\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error(\n \"Invalid input to \" + name + \": must be a \" + type + \", given \" + feature.geometry.type\n );\n }\n }\n}\nfunction getGeom(geojson) {\n if (geojson.type === \"Feature\") {\n return geojson.geometry;\n }\n return geojson;\n}\nfunction getType(geojson, _name) {\n if (geojson.type === \"FeatureCollection\") {\n return \"FeatureCollection\";\n }\n if (geojson.type === \"GeometryCollection\") {\n return \"GeometryCollection\";\n }\n if (geojson.type === \"Feature\" && geojson.geometry !== null) {\n return geojson.geometry.type;\n }\n return geojson.type;\n}\nexport {\n collectionOf,\n containsNumber,\n featureOf,\n geojsonType,\n getCoord,\n getCoords,\n getGeom,\n getType\n};\n//# sourceMappingURL=index.js.map","// index.ts\nimport { degreesToRadians, radiansToDegrees } from \"@turf/helpers\";\nimport { getCoord } from \"@turf/invariant\";\nfunction bearing(start, end, options = {}) {\n if (options.final === true) {\n return calculateFinalBearing(start, end);\n }\n const coordinates1 = getCoord(start);\n const coordinates2 = getCoord(end);\n const lon1 = degreesToRadians(coordinates1[0]);\n const lon2 = degreesToRadians(coordinates2[0]);\n const lat1 = degreesToRadians(coordinates1[1]);\n const lat2 = degreesToRadians(coordinates2[1]);\n const a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n const b = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n return radiansToDegrees(Math.atan2(a, b));\n}\nfunction calculateFinalBearing(start, end) {\n let bear = bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\nvar index_default = bearing;\nexport {\n bearing,\n index_default as default\n};\n//# sourceMappingURL=index.js.map","import { generateId, Routes } from '@tomtom-org/maps-sdk/core';\nimport calcBearing from '@turf/bearing';\nimport type { DisplayRouteProps } from '../types/displayRoutes';\nimport type {\n DisplayInstruction,\n DisplayInstructionArrow,\n DisplayInstructionArrows,\n DisplayInstructions,\n} from '../types/guidance';\n\n/**\n * @ignore\n */\nexport const toDisplayInstructions = (routes: Routes<DisplayRouteProps>): DisplayInstructions => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap(\n (route, routeIndex) =>\n route.properties.guidance?.instructions\n ?.filter((instruction) => instruction.routePath?.length)\n .map(\n (instruction): DisplayInstruction => ({\n type: 'Feature',\n geometry: {\n type: 'LineString',\n coordinates: instruction.routePath.map((pathPoint) => pathPoint.point),\n },\n properties: {\n ...instruction,\n id: generateId(),\n routeIndex,\n routeState: route.properties.routeState,\n },\n }),\n ) || [],\n ),\n});\n\n/**\n * @ignore\n */\nexport const toDisplayInstructionArrows = (routes: Routes<DisplayRouteProps>): DisplayInstructionArrows => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap(\n (route, routeIndex) =>\n route.properties.guidance?.instructions\n ?.filter((instruction) => instruction.routePath?.length && instruction.routePath.length > 1)\n .map((instruction): DisplayInstructionArrow => {\n const instructionLastSegment = [\n instruction.routePath[instruction.routePath.length - 2]?.point,\n instruction.routePath[instruction.routePath.length - 1]?.point,\n ];\n\n return {\n type: 'Feature',\n geometry: { type: 'Point', coordinates: instructionLastSegment[1] },\n properties: {\n ...instruction,\n id: generateId(),\n routeIndex,\n routeState: route.properties.routeState,\n lastPointBearingDegrees: calcBearing(instructionLastSegment[0], instructionLastSegment[1]),\n },\n };\n }) || [],\n ),\n});\n","import { generateId, Route, Routes, SectionProps, SectionType } from '@tomtom-org/maps-sdk/core';\nimport type { DisplayRouteProps } from '../types/displayRoutes';\nimport type { DisplaySectionProps, RouteSection, RouteSections } from '../types/routeSections';\n\nconst buildRouteSectionsFromRoute = <\n S extends SectionProps = SectionProps,\n D extends DisplaySectionProps = DisplaySectionProps,\n>(\n route: Route<DisplayRouteProps>,\n sectionType: SectionType,\n displaySectionPropsBuilder?: (\n sectionProps: S,\n routeProps?: DisplayRouteProps,\n ) => Omit<D, 'routeState' | 'routeIndex'>,\n): RouteSection<D>[] =>\n (route.properties.sections[sectionType] as S[])?.map((sectionProps) => {\n const id = sectionProps.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: {\n type: 'LineString',\n coordinates: route.geometry.coordinates.slice(\n sectionProps.startPointIndex,\n sectionProps.endPointIndex + 1,\n ),\n },\n properties: {\n ...(displaySectionPropsBuilder\n ? displaySectionPropsBuilder(sectionProps, route.properties)\n : sectionProps),\n routeState: route.properties.routeState,\n routeIndex: route.properties.index,\n id, // we need id in properties due to promoteId feature\n } as D,\n };\n }) || [];\n\n/**\n * Builds display-ready LineString features to render the sections of a given type, from the given route.\n * @param routes The routes from which to extract the section props.\n * @param sectionType The type of the sections to extract.\n * @param displaySectionPropsBuilder An optional function which will convert each section props into an extended display-ready version.\n * @ignore\n */\nexport const toDisplayRouteSections = <\n S extends SectionProps = SectionProps,\n D extends DisplaySectionProps = DisplaySectionProps,\n>(\n routes: Routes<DisplayRouteProps>,\n sectionType: SectionType,\n displaySectionPropsBuilder?: (\n sectionProps: S,\n routeProps?: DisplayRouteProps,\n ) => Omit<D, 'routeState' | 'routeIndex'>,\n): RouteSections<D> => ({\n type: 'FeatureCollection',\n features: routes.features.flatMap((route) =>\n buildRouteSectionsFromRoute<S, D>(route, sectionType, displaySectionPropsBuilder),\n ),\n});\n","import type { Routes } from '@tomtom-org/maps-sdk/core';\nimport type { FeatureCollection, Geometry } from 'geojson';\nimport type { GeoJSONSourceWithLayers } from '../../shared';\nimport type { DisplayRouteProps, DisplayRouteRelatedProps } from '../types/displayRoutes';\n\n/**\n * Rebuilds route-related display features such as sections or instructions, with the updated route selection based on the given routes.\n * @ignore\n */\nexport const rebuildFeaturesWithRouteSelection = <T extends FeatureCollection<Geometry, DisplayRouteRelatedProps>>(\n routes: Routes<DisplayRouteProps>,\n featureCollection: T,\n): T => ({\n ...featureCollection,\n features: featureCollection.features.map((features) => ({\n ...features,\n properties: {\n ...features.properties,\n routeState: routes.features[features.properties.routeIndex || 0].properties.routeState,\n },\n })),\n});\n\n/**\n * @ignore\n */\nexport const showFeaturesWithRouteSelection = <T extends FeatureCollection<Geometry, DisplayRouteRelatedProps>>(\n routesWithSelection: Routes<DisplayRouteProps>,\n sourceWithLayers: GeoJSONSourceWithLayers<T>,\n): void =>\n sourceWithLayers.show(rebuildFeaturesWithRouteSelection(routesWithSelection, sourceWithLayers.shownFeatures));\n","import {\n DelayMagnitude,\n DisplayUnits,\n formatDistance,\n formatDuration,\n generateId,\n Route,\n Routes,\n TrafficSectionProps,\n} from '@tomtom-org/maps-sdk/core';\nimport type { DisplayRouteProps, DisplayRouteSummaries } from '../types/displayRoutes';\n\n/**\n * Builds map display-ready routes, applying default style props.\n * @ignore\n */\nexport const toDisplayRoutes = (routes: Route | Routes, selectedIndex = 0): Routes<DisplayRouteProps> => {\n const routesCollection: Routes = 'features' in routes ? routes : { type: 'FeatureCollection', features: [routes] };\n return {\n ...routesCollection,\n features: routesCollection.features.map((route, index) => {\n const id = route.id ?? generateId();\n return {\n ...route,\n id,\n properties: {\n ...route.properties,\n id, // we need id in properties due to promoteId feature\n routeState: index === selectedIndex ? 'selected' : 'deselected',\n },\n };\n }),\n };\n};\n\nconst hasMagnitude = (sections: TrafficSectionProps[], magnitude: DelayMagnitude): boolean =>\n sections.some((section) => section.magnitudeOfDelay === magnitude);\n\nconst summaryDelayMagnitude = (route: Route): DelayMagnitude | undefined => {\n const trafficSections = route.properties.sections.traffic;\n if (!trafficSections?.length) {\n return undefined;\n }\n if (hasMagnitude(trafficSections, 'major')) {\n return 'major';\n }\n if (hasMagnitude(trafficSections, 'moderate')) {\n return 'moderate';\n }\n if (hasMagnitude(trafficSections, 'minor')) {\n return 'minor';\n }\n return undefined;\n};\n/**\n * Builds map display-ready route summaries based on display routes.\n * @ignore\n */\nexport const toDisplayRouteSummaries = (\n routes: Routes<DisplayRouteProps>,\n displayUnits?: DisplayUnits,\n): DisplayRouteSummaries => ({\n type: 'FeatureCollection',\n features: routes.features.map((route) => {\n const summary = route.properties.summary;\n const routeCoordinates = route.geometry.coordinates;\n const formattedTraffic = formatDuration(summary.trafficDelayInSeconds, displayUnits?.time);\n const magnitudeOfDelay = summaryDelayMagnitude(route);\n const id = route.id ?? generateId();\n return {\n type: 'Feature',\n id,\n geometry: {\n type: 'Point',\n coordinates: routeCoordinates[Math.round(routeCoordinates.length / 2)],\n },\n properties: {\n id, // we need id in properties due to promoteId feature\n routeIndex: route.properties.index,\n routeState: route.properties.routeState,\n formattedDistance: formatDistance(summary.lengthInMeters, displayUnits?.distance),\n ...(magnitudeOfDelay && { magnitudeOfDelay }),\n ...(formattedTraffic && { formattedTraffic }),\n formattedDuration: formatDuration(summary.travelTimeInSeconds, displayUnits?.time),\n },\n };\n }),\n});\n","import type { Route, Routes, Waypoint, Waypoints } from '@tomtom-org/maps-sdk/core';\nimport { isEqual } from 'lodash-es';\nimport type { StyleImageMetadata } from 'maplibre-gl';\nimport {\n AbstractMapModule,\n EventsModule,\n GeoJSONSourceWithLayers,\n mapStyleLayerIDs,\n SVGIconStyleOptions,\n} from '../shared';\nimport { suffixNumber } from '../shared/layers/utils';\nimport { addLayers, addOrUpdateImage, updateLayersAndSource, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { INSTRUCTION_ARROW_IMAGE_ID } from './layers/guidanceLayers';\nimport { DESELECTED_SUMMARY_POPUP_IMAGE_ID, SELECTED_SUMMARY_POPUP_IMAGE_ID } from './layers/routeMainLineLayers';\nimport { MAJOR_DELAY_COLOR, MINOR_DELAY_LABEL_COLOR, MODERATE_DELAY_COLOR, UNKNOWN_DELAY_COLOR } from './layers/shared';\nimport {\n TRAFFIC_CLEAR_IMAGE_ID,\n TRAFFIC_MAJOR_IMAGE_ID,\n TRAFFIC_MINOR_IMAGE_ID,\n TRAFFIC_MODERATE_IMAGE_ID,\n} from './layers/summaryBubbleLayers';\nimport {\n WAYPOINT_FINISH_IMAGE_ID,\n WAYPOINT_SOFT_IMAGE_ID,\n WAYPOINT_START_IMAGE_ID,\n WAYPOINT_STOP_IMAGE_ID,\n} from './layers/waypointLayers';\nimport {\n instructionArrowIconImg,\n softWaypointIcon,\n summaryBubbleImageOptions,\n summaryMapBubbleImg,\n trafficImg,\n waypointFinishIcon,\n waypointIcon,\n waypointStartIcon,\n} from './resources';\nimport type { DisplayRouteProps, DisplayRouteSummary } from './types/displayRoutes';\nimport type { DisplayInstruction } from './types/guidance';\nimport type { PlanningWaypoint } from './types/planningWaypoint';\nimport type { RoutingModuleConfig } from './types/routeModuleConfig';\nimport type { DisplayTrafficSectionProps, RouteSection, RouteSections } from './types/routeSections';\nimport type { RoutingLayersSpecs, RoutingSourcesWithLayers } from './types/routingSourcesAndLayers';\nimport type { ShowRoutesOptions } from './types/showOptions';\nimport type { WaypointDisplayProps } from './types/waypointDisplayProps';\nimport { createLayersSpecs, routeModuleConfigWithDefaults } from './util/config';\nimport { toDisplayChargingStops } from './util/displayChargingStops';\nimport { toDisplayTrafficSectionProps } from './util/displayTrafficSectionProps';\nimport { toDisplayWaypoints } from './util/displayWaypoints';\nimport { toDisplayInstructionArrows, toDisplayInstructions } from './util/guidance';\nimport { toDisplayRouteSections } from './util/routeSections';\nimport { showFeaturesWithRouteSelection } from './util/routeSelection';\nimport { toDisplayRouteSummaries, toDisplayRoutes } from './util/routes';\n\n/**\n * Map module for displaying and managing route visualizations.\n *\n * The RoutingModule provides comprehensive functionality for displaying routes on the map,\n * including route lines, alternative routes, turn-by-turn guidance, and interactive waypoints.\n * It integrates seamlessly with the TomTom Routing API.\n *\n * @remarks\n * **Features:**\n * - Display route lines with customizable styling\n * - Show alternative routes with different styling\n * - Interactive waypoint markers (drag, add, remove)\n * - Turn-by-turn guidance instructions\n * - Route section highlighting\n * - Distance and duration information\n * - Support for multiple routes simultaneously\n *\n * **Common Use Cases:**\n * - Turn-by-turn navigation displays\n * - Route planning and comparison\n * - Multi-stop route optimization\n * - Interactive route editing\n * - Fleet management route visualization\n *\n * @example\n * ```typescript\n * // Create the module\n * const routingModule = await RoutingModule.getInstance(map, {\n * displayUnits: {\n * distance: { type: 'metric' }\n * }\n * });\n *\n * // Calculate and display a route\n * const result = await calculateRoute({\n * key: 'your-api-key',\n * locations: [\n * [4.9041, 52.3676], // Amsterdam\n * [4.4777, 51.9244] // Rotterdam\n * ],\n * routeOptions: {\n * travelMode: 'car',\n * routeType: 'fastest'\n * }\n * });\n *\n * await routingModule.showRoutes(result);\n * ```\n *\n * @see [Routing Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/routing)\n *\n * @group Routing\n */\nexport class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers, RoutingModuleConfig> {\n private static lastInstanceIndex = -1;\n private layersSpecs!: RoutingLayersSpecs;\n private layerIDPrefix!: string;\n /**\n * The index of this instance, to generate unique source and layer IDs.\n * * Starts with 0 and each instance increments it by one.\n * @private\n */\n private instanceIndex!: number;\n\n /**\n * Make sure the map is ready before create an instance of the module and any other interaction with the map\n * @param tomtomMap The TomTomMap instance.\n * @param config The module optional configuration\n * @returns {Promise} Returns a promise with a new instance of this module\n *\n * @remarks\n * **Configuration Options:**\n * - `displayUnits`: Distance units (metric/imperial)\n * - `waypointsSource`: Waypoint entry point options\n * - `layers`: Complete layer styling configuration\n *\n * **Default Styling:**\n * If no custom layers are provided, uses {@link defaultRoutingLayers}.\n *\n * @example\n * Default initialization:\n * ```typescript\n * const routingModule = await RoutingModule.get(map);\n * ```\n *\n * @example\n * With custom configuration:\n * ```typescript\n * const routingModule = await RoutingModule.get(map, {\n * displayUnits: 'imperial',\n * waypointsSource: {\n * entryPoints: 'main-when-available'\n * }\n * });\n * ```\n */\n static async get(tomtomMap: TomTomMap, config?: RoutingModuleConfig): Promise<RoutingModule> {\n await waitUntilMapIsReady(tomtomMap);\n return new RoutingModule(tomtomMap, config);\n }\n\n private constructor(map: TomTomMap, config?: RoutingModuleConfig) {\n super('geojson', map, config);\n }\n\n private createSourcesWithLayers(layersSpecs: RoutingLayersSpecs): RoutingSourcesWithLayers {\n const sourcePrefix = suffixNumber('routes', this.instanceIndex);\n return {\n mainLines: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-mainLines`,\n layersSpecs.mainLines,\n false,\n ),\n waypoints: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-waypoints`,\n layersSpecs.waypoints,\n false,\n ),\n incidents: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-incidents`,\n layersSpecs.incidents,\n false,\n ),\n ferries: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-ferries`,\n layersSpecs.ferries,\n false,\n ),\n chargingStops: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-chargingStops`,\n layersSpecs.chargingStops,\n false,\n ),\n tollRoads: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-tollRoads`,\n layersSpecs.tollRoads,\n false,\n ),\n tunnels: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-tunnels`,\n layersSpecs.tunnels,\n false,\n ),\n vehicleRestricted: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-vehicleRestricted`,\n layersSpecs.vehicleRestricted,\n false,\n ),\n instructionLines: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-instructionLines`,\n layersSpecs.instructionLines,\n false,\n ),\n instructionArrows: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-instructionArrows`,\n layersSpecs.instructionArrows,\n false,\n ),\n summaryBubbles: new GeoJSONSourceWithLayers(\n this.mapLibreMap,\n `${sourcePrefix}-summaryBubbles`,\n layersSpecs.summaryBubbles,\n false,\n ),\n };\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers(config?: RoutingModuleConfig, restore?: boolean): RoutingSourcesWithLayers {\n // Only increment the instance index for new instances, not for restore operations\n if (!restore) {\n RoutingModule.lastInstanceIndex++;\n this.instanceIndex = RoutingModule.lastInstanceIndex;\n this.layerIDPrefix = suffixNumber('routes', this.instanceIndex);\n }\n\n this.layersSpecs = createLayersSpecs(\n routeModuleConfigWithDefaults(config, this.layerIDPrefix, this.instanceIndex).layers,\n this.layerIDPrefix,\n );\n const routingSourcesWithLayers: RoutingSourcesWithLayers = this.createSourcesWithLayers(this.layersSpecs);\n addLayers(\n Object.values(routingSourcesWithLayers).flatMap((source) => source._layerSpecs),\n this.mapLibreMap,\n );\n\n const svgIconOptions: SVGIconStyleOptions = {\n // first comes the main theme fill color, if any:\n fillColor: config?.theme?.mainColor,\n // then come any icon style configs for the waypoint icons, if any:\n ...config?.waypoints?.icon?.style,\n };\n const options: Partial<StyleImageMetadata> = { pixelRatio: 2 };\n\n // Generate instance-specific image IDs to support multiple RoutingModule instances\n const waypointStartImageId = suffixNumber(WAYPOINT_START_IMAGE_ID, this.instanceIndex);\n const waypointStopImageId = suffixNumber(WAYPOINT_STOP_IMAGE_ID, this.instanceIndex);\n const waypointSoftImageId = suffixNumber(WAYPOINT_SOFT_IMAGE_ID, this.instanceIndex);\n const waypointFinishImageId = suffixNumber(WAYPOINT_FINISH_IMAGE_ID, this.instanceIndex);\n const instructionArrowImageId = suffixNumber(INSTRUCTION_ARROW_IMAGE_ID, this.instanceIndex);\n const selectedSummaryPopupImageId = suffixNumber(SELECTED_SUMMARY_POPUP_IMAGE_ID, this.instanceIndex);\n const deselectedSummaryPopupImageId = suffixNumber(DESELECTED_SUMMARY_POPUP_IMAGE_ID, this.instanceIndex);\n const trafficClearImageId = suffixNumber(TRAFFIC_CLEAR_IMAGE_ID, this.instanceIndex);\n const trafficMajorImageId = suffixNumber(TRAFFIC_MAJOR_IMAGE_ID, this.instanceIndex);\n const trafficModerateImageId = suffixNumber(TRAFFIC_MODERATE_IMAGE_ID, this.instanceIndex);\n const trafficMinorImageId = suffixNumber(TRAFFIC_MINOR_IMAGE_ID, this.instanceIndex);\n\n // loading of extra assets if not present in the map style:\n this.addImageIfNotExisting(waypointStartImageId, waypointStartIcon(svgIconOptions), options);\n this.addImageIfNotExisting(waypointStopImageId, waypointIcon(undefined, svgIconOptions), options);\n this.addImageIfNotExisting(waypointSoftImageId, softWaypointIcon(), options);\n this.addImageIfNotExisting(waypointFinishImageId, waypointFinishIcon(svgIconOptions), options);\n this.addImageIfNotExisting(instructionArrowImageId, instructionArrowIconImg, options);\n this.addImageIfNotExisting(\n selectedSummaryPopupImageId,\n summaryMapBubbleImg('white'),\n summaryBubbleImageOptions,\n );\n this.addImageIfNotExisting(\n deselectedSummaryPopupImageId,\n summaryMapBubbleImg('#EEEEEE'),\n summaryBubbleImageOptions,\n );\n this.addImageIfNotExisting(trafficClearImageId, trafficImg(UNKNOWN_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficMajorImageId, trafficImg(MAJOR_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficModerateImageId, trafficImg(MODERATE_DELAY_COLOR), options);\n this.addImageIfNotExisting(trafficMinorImageId, trafficImg(MINOR_DELAY_LABEL_COLOR), options);\n\n // If we have custom icons, ensure they're added to the map style:\n for (const customChargingStopIcon of config?.chargingStops?.icon?.customIcons ?? []) {\n this.addImageIfNotExisting(customChargingStopIcon.id, customChargingStopIcon.image as string, {\n pixelRatio: customChargingStopIcon.pixelRatio ?? 2,\n });\n }\n\n return routingSourcesWithLayers;\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config?: RoutingModuleConfig) {\n const mergedConfig = routeModuleConfigWithDefaults(config, this.layerIDPrefix, this.instanceIndex);\n\n // If there was already some config set, we must update the changes:\n if (this.config) {\n // replace existing configuration with new one\n const newLayersSpecs = createLayersSpecs(mergedConfig.layers, this.layerIDPrefix);\n\n // here we assume that keys for layer specs and sources are the same, please keep it that way to simplify the logic\n Object.keys(newLayersSpecs).forEach((layersSpecID) => {\n const id = layersSpecID as keyof RoutingSourcesWithLayers;\n updateLayersAndSource(\n newLayersSpecs[id],\n this.layersSpecs[id],\n this.sourcesWithLayers[id],\n this.mapLibreMap,\n );\n });\n // we need to add layers correctly\n const listOfSources = Object.values(this.sourcesWithLayers) as GeoJSONSourceWithLayers[];\n addLayers(\n listOfSources.flatMap((source) => source._layerSpecs),\n this.mapLibreMap,\n );\n // set the correct visibility if there are new layers\n listOfSources.forEach((source) => source.setLayersVisible(!!source.shownFeatures.features.length));\n this.layersSpecs = newLayersSpecs;\n }\n\n // Summary bubbles have dedicated sources and contain distance-units dependent text ...\n // ... so we need to re-show them if that config part changed:\n if (\n !isEqual(this.config?.displayUnits, mergedConfig.displayUnits) &&\n this.sourcesWithLayers.summaryBubbles.shownFeatures.features.length\n ) {\n this.sourcesWithLayers.summaryBubbles.show(\n toDisplayRouteSummaries(this.sourcesWithLayers.mainLines.shownFeatures, mergedConfig.displayUnits),\n );\n }\n\n return mergedConfig;\n }\n\n /**\n * @ignore\n */\n protected restoreDataAndConfigImpl() {\n const previouslyShown = Object.entries(this.sourcesWithLayers)\n .map((entry) => ({\n [entry[0]]: entry[1].shownFeatures,\n }))\n .reduce((acc, item) => ({ ...acc, ...item }), {}) as Record<keyof RoutingSourcesWithLayers, any>;\n\n this.initSourcesWithLayers(this.config, true);\n this._applyConfig(this.config);\n\n for (const key of Object.keys(previouslyShown) as (keyof RoutingSourcesWithLayers)[]) {\n this.sourcesWithLayers[key].show(previouslyShown[key]);\n }\n }\n\n private addImageIfNotExisting(\n imageId: string,\n image: string | HTMLImageElement,\n options: Partial<StyleImageMetadata> | undefined,\n ) {\n addOrUpdateImage('if-not-in-sprite', imageId, image, this.mapLibreMap, options);\n }\n\n /**\n * Displays the given routes on the map.\n *\n * @param routes - Route data from Routing API or custom routes.\n * @param options - Optional configuration for route selection and display.\n * @param options.selectedIndex - Index of the route to display as selected (default: 0).\n *\n * @remarks\n * **Behavior:**\n * - Replaces any previously shown routes\n * - Shows all route-related features: lines, sections, summaries, guidance\n * - First route is selected by default (appears more prominent)\n * - Waypoints are NOT shown automatically (use {@link showWaypoints})\n *\n * **Route Features:**\n * - Main route lines (selected and deselected styles)\n * - Traffic sections with delays\n * - Ferry, tunnel, and toll sections\n * - EV charging stations (for EV routes)\n * - Turn-by-turn instruction lines and arrows\n * - Summary bubbles with distance/time/traffic info\n *\n * @example\n * Show single route:\n * ```typescript\n * await routing.showRoutes(response.routes);\n * ```\n *\n * @example\n * Show multiple routes with specific selection:\n * ```typescript\n * await routing.showRoutes(response.routes, { selectedIndex: 1 });\n * ```\n *\n * @example\n * Complete routing workflow:\n * ```typescript\n * import { routing as routingAPI } from '@tomtom-international/maps-sdk-js/services';\n *\n * // Calculate route\n * const response = await routingAPI.calculateRoute({\n * locations: [[4.9, 52.4], [4.5, 51.9]],\n * traffic: true,\n * travelMode: 'car'\n * });\n *\n * // Display on map\n * const routing = await RoutingModule.get(map);\n * await routing.showRoutes(response.routes);\n * await routing.showWaypoints(response.routes[0].legs[0].points);\n * ```\n */\n async showRoutes(routes: Route | Routes, options?: ShowRoutesOptions) {\n const displayRoutes = toDisplayRoutes(routes, options?.selectedIndex);\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.mainLines.show(displayRoutes);\n this.sourcesWithLayers.vehicleRestricted.show(toDisplayRouteSections(displayRoutes, 'vehicleRestricted'));\n this.sourcesWithLayers.incidents.show(\n toDisplayRouteSections(displayRoutes, 'traffic', toDisplayTrafficSectionProps),\n );\n this.sourcesWithLayers.chargingStops.show(toDisplayChargingStops(displayRoutes, this.config));\n this.sourcesWithLayers.ferries.show(toDisplayRouteSections(displayRoutes, 'ferry'));\n this.sourcesWithLayers.tunnels.show(toDisplayRouteSections(displayRoutes, 'tunnel'));\n this.sourcesWithLayers.tollRoads.show(toDisplayRouteSections(displayRoutes, 'toll'));\n this.sourcesWithLayers.instructionLines.show(toDisplayInstructions(displayRoutes));\n this.sourcesWithLayers.instructionArrows.show(toDisplayInstructionArrows(displayRoutes));\n this.sourcesWithLayers.summaryBubbles.show(toDisplayRouteSummaries(displayRoutes, this.config?.displayUnits));\n }\n\n /**\n * Clears any previously shown routes from the map.\n *\n * @remarks\n * - Clears all route-related layers (lines, sections, guidance, summaries)\n * - Does NOT clear waypoints (use {@link clearWaypoints})\n * - Module remains initialized and ready for new routes\n *\n * @example\n * ```typescript\n * await routing.clearRoutes();\n * ```\n */\n async clearRoutes() {\n await this.waitUntilModuleReady();\n for (const key of Object.keys(this.sourcesWithLayers) as (keyof RoutingSourcesWithLayers)[]) {\n if (key !== 'waypoints') {\n this.sourcesWithLayers[key as keyof RoutingSourcesWithLayers].clear();\n }\n }\n }\n\n /**\n * Changes which route appears as selected.\n *\n * @param index - Zero-based index of the route to select.\n *\n * @remarks\n * **Visual Changes:**\n * - Selected route appears more prominent (thicker, brighter)\n * - Previously selected route becomes deselected style\n * - Updates all route-related features (sections, guidance)\n *\n * **Requirements:**\n * - Route must already be displayed via {@link showRoutes}\n * - Index must be within range of displayed routes\n *\n * @example\n * ```typescript\n * // Show multiple routes\n * await routingModule.showRoutes(routes);\n *\n * // User clicks alternative route\n * await routingModule.selectRoute(1);\n *\n * // Switch back to first route\n * await routingModule.selectRoute(0);\n * ```\n */\n async selectRoute(index: number) {\n const updatedRoutes = toDisplayRoutes(this.sourcesWithLayers.mainLines.shownFeatures, index);\n\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.mainLines.show(updatedRoutes);\n // TODO: simply update route style instead of regenerating EV stations again\n this.sourcesWithLayers.chargingStops.show(toDisplayChargingStops(updatedRoutes, this.config));\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.vehicleRestricted);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.incidents);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.ferries);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.tollRoads);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.tunnels);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.instructionLines);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.instructionArrows);\n showFeaturesWithRouteSelection(updatedRoutes, this.sourcesWithLayers.summaryBubbles);\n }\n\n /**\n * Shows the given waypoints on the map.\n * @param waypoints The waypoint-like inputs to show.\n */\n async showWaypoints(waypoints: PlanningWaypoint[] | Waypoints) {\n const displayWaypoints = Array.isArray(waypoints)\n ? toDisplayWaypoints(waypoints, this.config?.waypoints, this.instanceIndex)\n : // FeatureCollection expected:\n toDisplayWaypoints(waypoints.features as PlanningWaypoint[], this.config?.waypoints, this.instanceIndex);\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.waypoints.show(displayWaypoints);\n }\n\n /**\n * Clears any previously shown waypoints from the map.\n * * If nothing was shown before, nothing happens.\n */\n async clearWaypoints() {\n await this.waitUntilModuleReady();\n this.sourcesWithLayers.waypoints.clear();\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return {\n mainLines: new EventsModule<Route<DisplayRouteProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.mainLines,\n this.config?.events,\n ),\n waypoints: new EventsModule<Waypoint<WaypointDisplayProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.waypoints,\n this.config?.events,\n ),\n chargingStops: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.chargingStops,\n this.config?.events,\n ),\n summaryBubbles: new EventsModule<DisplayRouteSummary>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.summaryBubbles,\n this.config?.events,\n ),\n incidents: new EventsModule<RouteSections<DisplayTrafficSectionProps>>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.incidents,\n this.config?.events,\n ),\n vehicleRestricted: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.vehicleRestricted,\n this.config?.events,\n ),\n ferries: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.ferries,\n this.config?.events,\n ),\n tollRoads: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.tollRoads,\n this.config?.events,\n ),\n tunnels: new EventsModule<RouteSection>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.tunnels,\n this.config?.events,\n ),\n instructionLines: new EventsModule<DisplayInstruction>(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.instructionLines,\n this.config?.events,\n ),\n };\n }\n\n /**\n * Returns the map style layer under which route lines are rendered.\n * * Useful if you want to render extra layers just above the route ones but not on top of everything else.\n * * It might differ depending on the loaded style/version.\n */\n getLayerToRenderLinesUnder(): string {\n return mapStyleLayerIDs.lowestLabel;\n }\n}\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path d=\\\"M63.734 86.383c-1.404.026-2.78-.393-3.93-1.197s-2.01-1.949-2.46-3.271l-3.15-9.339c-1.093-3.403-3.748-6.089-7.154-7.238L37.5 62.21c-2.742-.902-4.567-3.477-4.5-6.345-.058-2.874 1.761-5.457 4.5-6.388l36-11.886c2.461-.88 5.213-.27 7.062 1.567s2.466 4.571 1.578 7.015L70.17 81.918c-.938 2.719-3.54 4.526-6.436 4.469h0z\\\"\\n fill=\\\"#f4f5f6\\\"/>\\n</svg>\\n\"","export default \"<svg width=\\\"32\\\" height=\\\"32\\\" viewBox=\\\"0 0 32 32\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\">\\n <circle id=\\\"circle\\\" cx=\\\"16\\\" cy=\\\"16\\\" r=\\\"12\\\" fill=\\\"white\\\" stroke=\\\"#105287\\\" stroke-width=\\\"4\\\"/>\\n</svg>\\n\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"120\\\" height=\\\"140\\\">\\n <path d=\\\"M33 83.404a2.99 2.99 0 0 1-3-2.978V44.681a2.99 2.99 0 1 1 6 0v35.745a2.99 2.99 0 0 1-3 2.978zm48-38.723H39v17.872h42V44.681zm3.878 37.851a3.02 3.02 0 0 0 4.244 0c.561-.559.878-1.317.878-2.106V44.681a2.99 2.99 0 1 0-6 0v35.745c0 .789.317 1.547.878 2.106z\\\"\\n fill=\\\"#f4f5f6\\\"/>\\n</svg>\\n\"","import type { StyleSpecification } from 'maplibre-gl';\nimport type { InternalTomTomMapParams, StandardStyle, StandardStyleID, StyleInput, StyleModule } from './types/mapInit';\nimport { styleModules } from './types/mapInit';\n\nexport const DEFAULT_STANDARD_STYLE_ID: StandardStyleID = 'standardLight';\nconst URL_PREFIX = '${baseURL}/maps/orbis/assets/styles/${version}/style.json?&apiVersion=1&key=${apiKey}';\n\nconst standardStyleModulesValues: Record<StandardStyleID, Record<StyleModule, string>> = {\n standardLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_light',\n },\n standardDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_dark',\n },\n drivingLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_light',\n },\n drivingDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_dark',\n },\n monoLight: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_mono-light',\n },\n monoDark: {\n trafficIncidents: 'incidents_dark',\n trafficFlow: 'flow_relative-dark',\n hillshade: 'hillshade_mono-dark',\n },\n satellite: {\n trafficIncidents: 'incidents_light',\n trafficFlow: 'flow_relative-light',\n hillshade: 'hillshade_satellite',\n },\n};\n\nconst baseMapStyleUrlTemplate = (suffix: string): string => `${URL_PREFIX}&map=${suffix}`;\n\nconst baseMapStyleUrlTemplates: Record<StandardStyleID, string> = {\n standardLight: baseMapStyleUrlTemplate('basic_street-light'),\n standardDark: baseMapStyleUrlTemplate('basic_street-dark'),\n drivingLight: baseMapStyleUrlTemplate('basic_street-light-driving'),\n drivingDark: baseMapStyleUrlTemplate('basic_street-dark-driving'),\n monoLight: baseMapStyleUrlTemplate('basic_mono-light'),\n monoDark: baseMapStyleUrlTemplate('basic_mono-dark'),\n satellite: baseMapStyleUrlTemplate('basic_street-satellite'),\n};\n\nconst buildStandardStyleUrl = (standardStyle: StandardStyle, baseUrl: string, apiKey: string): string => {\n const standardStyleID = standardStyle.id ?? DEFAULT_STANDARD_STYLE_ID;\n\n const styleURL = new URL(\n baseMapStyleUrlTemplates[standardStyleID]\n .replace('${baseURL}', baseUrl)\n .replace('${version}', standardStyle.version ?? '0.6.0-0')\n .replace('${apiKey}', apiKey),\n );\n\n for (const module of standardStyle.include ?? styleModules) {\n styleURL.searchParams.append(module, standardStyleModulesValues[standardStyleID][module]);\n }\n\n return styleURL.toString();\n};\n\nconst withApiKey = (givenUrl: string, apiKey: string): string => {\n const url = new URL(givenUrl);\n if (!url.searchParams.has('key')) {\n url.searchParams.set('key', apiKey);\n } else {\n console.warn(\n 'The style URL is coming with an API key parameter which takes priority. ' +\n 'If you want to use the SDK configured API key, remove the key param from the style URL',\n );\n }\n return url.toString();\n};\n\n/**\n * @ignore\n * @param mapParams The SDK parameters to convert to input renderer style.\n * @return The map style to load into the renderer.\n */\nexport const buildStyleInput = (mapParams: InternalTomTomMapParams): StyleSpecification | string => {\n const style = mapParams.style;\n const baseUrl = mapParams.commonBaseURL;\n const apiKey = mapParams.apiKey;\n\n if (typeof style === 'string') {\n return buildStandardStyleUrl({ id: style }, baseUrl, apiKey);\n } else if (style?.type === 'standard') {\n return buildStandardStyleUrl(style, baseUrl, apiKey);\n } else if (style?.type === 'custom' && style?.url) {\n return withApiKey(style.url, apiKey);\n } else if (style?.type === 'custom' && style?.json) {\n return style.json;\n }\n\n // no style defined, use default\n return buildStandardStyleUrl({ id: DEFAULT_STANDARD_STYLE_ID }, baseUrl, apiKey);\n};\n\n/**\n * Includes the previous standard style parts into the given standard style if the new one didn't define any.\n * * Both new and previous styles must be of \"standard\" type.\n * @ignore\n */\nexport const withPreviousStyleParts = (style: StyleInput, previousStyle?: StyleInput): StyleInput => {\n if (\n previousStyle &&\n typeof previousStyle === 'object' &&\n previousStyle.type === 'standard' &&\n previousStyle.include\n ) {\n if (typeof style === 'string' || (style.type === 'standard' && !style.include)) {\n return {\n type: 'standard',\n id: typeof style === 'string' ? style : style.id,\n include: (previousStyle as StandardStyle).include,\n };\n }\n }\n return style;\n};\n","import { type BBox, type Language, mergeFromGlobal } from '@tomtom-org/maps-sdk/core';\nimport { isEqual } from 'lodash-es';\nimport { getRTLTextPluginStatus, Map, setRTLTextPlugin } from 'maplibre-gl';\nimport { version as maplibreVersion } from 'maplibre-gl/package.json';\nimport type { InternalTomTomMapParams, MapLibreOptions, StyleInput, TomTomMapParams } from './init';\nimport { buildMapOptions } from './init/buildMapOptions';\nimport { buildStyleInput, DEFAULT_STANDARD_STYLE_ID, withPreviousStyleParts } from './init/styleInputBuilder';\nimport {\n EventsProxy,\n filterLayersBySources,\n HILLSHADE_SOURCE_ID,\n LightDark,\n TRAFFIC_FLOW_SOURCE_ID,\n TRAFFIC_INCIDENTS_SOURCE_ID,\n} from './shared';\nimport { isLayerLocalizable } from './shared/localization';\nimport { addPinCategoriesSpriteToStyle, getStyleLightDarkTheme } from './shared/mapUtils';\n\n/**\n * Handler interface for responding to map style changes.\n *\n * @remarks\n * This interface defines callbacks that are invoked when the map style changes via {@link TomTomMap.setStyle}.\n * Use this to perform cleanup or reinitialization of custom map features when styles are switched.\n *\n * **Lifecycle:**\n * 1. `onStyleAboutToChange` - Called before the new style is applied\n * 2. Style change occurs\n * 3. `onStyleChanged` - Called after the new style has been fully loaded\n *\n * **Common Use Cases:**\n * - Saving and restoring custom layers or sources\n * - Reinitializing map modules after style changes\n * - Updating UI components based on the new style\n * - Cleaning up resources tied to the previous style\n *\n * @example\n * ```typescript\n * const styleHandler: StyleChangeHandler = {\n * onStyleAboutToChange: () => {\n * console.log('Style changing - saving state...');\n * // Save custom layer data\n * },\n * onStyleChanged: () => {\n * console.log('Style changed - restoring state...');\n * // Restore custom layers\n * }\n * };\n *\n * map.addStyleChangeHandler(styleHandler);\n * ```\n *\n * @see {@link TomTomMap.addStyleChangeHandler}\n * @see {@link TomTomMap.setStyle}\n *\n * @group Map Style\n */\nexport type StyleChangeHandler = {\n /**\n * Callback invoked immediately before a style change begins.\n *\n * @remarks\n * Use this to perform cleanup or save state before the current style is removed.\n * This method can be synchronous or asynchronous.\n *\n * @returns void or a Promise that resolves when preparation is complete\n */\n onStyleAboutToChange?: () => void | Promise<void>;\n /**\n * Callback invoked after a new style has been fully loaded.\n *\n * @remarks\n * Use this to restore state, reinitialize layers, or perform other setup\n * that depends on the new style being ready. This method can be synchronous or asynchronous.\n *\n * @returns void or a Promise that resolves when reinitialization is complete\n */\n onStyleChanged?: () => void | Promise<void>;\n};\n\n/**\n * Main TomTom Map class for displaying interactive maps in web applications.\n *\n * This is the entry point for rendering TomTom maps. It wraps MapLibre GL JS and provides\n * a simplified, enhanced API for common mapping tasks.\n *\n * @remarks\n * **Key Features:**\n * - Built on MapLibre GL JS for high-performance rendering\n * - Seamless style switching without map reload\n * - Integrated event handling system\n * - Multi-language support with dynamic switching\n * - Compatible with TomTom map modules (traffic, POIs, routing, etc.)\n *\n * **Architecture:**\n * - Exposes the underlying MapLibre Map instance via {@link mapLibreMap}\n * - Manages map lifecycle and style transitions\n * - Coordinates with map modules for data visualization\n *\n * @example\n * Basic map initialization:\n * ```typescript\n * import { TomTomMap } from '@tomtom-international/maps-sdk-js/map';\n *\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: 'standardLight',\n * mapLibre: {\n * container: 'map',\n * center: [4.9041, 52.3676],\n * zoom: 10\n * }\n * });\n * ```\n *\n * @example\n * With modules and configuration:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: {\n * type: 'standard',\n * id: 'standardDark',\n * include: ['trafficFlow', 'trafficIncidents']\n * },\n * language: 'en-US',\n * events: {\n * precisionMode: 'point-then-box',\n * cursorOnHover: 'pointer'\n * },\n * mapLibre: {\n * container: 'map',\n * center: [-74.006, 40.7128],\n * zoom: 12\n * }\n * });\n *\n * // Access MapLibre functionality directly\n * map.mapLibreMap.on('load', () => {\n * console.log('Map loaded');\n * });\n * ```\n *\n * @group Map\n */\nexport class TomTomMap {\n /**\n * Indicates whether the map style has been fully loaded and is ready for interaction.\n *\n * @remarks\n * - `true` when the style is loaded and modules can be safely initialized\n * - `false` during map construction or style changes\n * - Check this before performing style-dependent operations\n *\n * @example\n * ```typescript\n * if (map.mapReady) {\n * // Safe to initialize modules\n * const trafficFlowModule = await TrafficFlowModule.get(map);\n * }\n * ```\n */\n mapReady = false;\n\n /**\n * The underlying MapLibre GL JS Map instance.\n *\n * @remarks\n * **When to Use:**\n * - Access advanced MapLibre functionality not exposed by TomTomMap\n * - Add custom layers, sources, or controls\n * - Listen to MapLibre-specific events\n * - Integrate third-party MapLibre plugins\n *\n * **Important:**\n * - Available immediately after TomTomMap construction\n * - Direct modifications may affect SDK module behavior\n * - Coordinate with SDK modules to avoid conflicts\n *\n * @example\n * Add custom layer:\n * ```typescript\n * map.mapLibreMap.addLayer({\n * id: 'custom-layer',\n * type: 'circle',\n * source: 'my-data',\n * paint: {\n * 'circle-radius': 6,\n * 'circle-color': '#ff0000'\n * }\n * });\n * ```\n *\n * @example\n * Listen to events:\n * ```typescript\n * map.mapLibreMap.on('moveend', () => {\n * console.log('Camera position:', map.mapLibreMap.getCenter());\n * });\n * ```\n *\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Documentation}\n */\n readonly mapLibreMap: Map;\n /**\n * @ignore\n */\n readonly _eventsProxy: EventsProxy;\n /**\n * @ignore\n */\n _params: InternalTomTomMapParams;\n\n styleLightDarkTheme: LightDark;\n\n private readonly styleChangeHandlers: StyleChangeHandler[] = [];\n\n /**\n * Constructs a new TomTom Map instance and attaches it to a DOM element.\n *\n * @param mapParams - Combined TomTom and MapLibre parameters for map initialization.\n * Includes API key, style, events, and MapLibre options like container, center, zoom, etc.\n * See {@link TomTomMapParams} for all available parameters.\n *\n * @remarks\n * **Initialization Process:**\n * 1. Merges `mapParams` with global configuration\n * 2. Creates underlying MapLibre map instance\n * 3. Loads specified style asynchronously\n * 4. Sets `mapReady` to `true` when complete\n *\n * **Configuration Priority:**\n * - Parameters passed here override global configuration\n * - Allows per-map customization while sharing common settings\n *\n * @example\n * Minimal initialization:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * mapLibre: {\n * container: 'map',\n * center: [0, 0],\n * zoom: 2\n * }\n * });\n * ```\n *\n * @example\n * Full configuration:\n * ```typescript\n * const map = new TomTomMap({\n * key: 'YOUR_API_KEY',\n * style: {\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * },\n * language: 'en-US',\n * events: {\n * precisionMode: 'point-then-box',\n * paddingBoxPx: 10\n * },\n * mapLibre: {\n * container: 'map',\n * center: [-122.4194, 37.7749],\n * zoom: 13,\n * pitch: 45,\n * bearing: -17.6,\n * antialias: true,\n * maxZoom: 18,\n * minZoom: 8\n * }\n * });\n * ```\n *\n * @throws Will log errors if RTL text plugin fails to load (non-blocking)\n *\n * @see {@link MapLibreOptions}\n * @see {@link TomTomMapParams}\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Parameters}\n * @see [Map Quickstart Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/quickstart)\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n * @see [User Interaction Events Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/user-events)\n */\n constructor(mapParams: TomTomMapParams) {\n this._params = mergeFromGlobal(mapParams);\n if (this._params.style === undefined) {\n this._params = { ...this._params, style: DEFAULT_STANDARD_STYLE_ID };\n }\n this.styleLightDarkTheme = getStyleLightDarkTheme(this._params.style);\n this.ensureMapLibreCSSLoaded();\n\n this.mapLibreMap = new Map(buildMapOptions(this._params));\n this.mapLibreMap.once('styledata', () => {\n this.handleStyleData(false);\n });\n this._eventsProxy = new EventsProxy(this.mapLibreMap, this._params?.events);\n\n this.loadRTLTextPlugin();\n }\n\n private loadRTLTextPlugin(): void {\n // deferred (just in case), lazy loading of the RTL plugin:\n setTimeout(() => {\n if (!['deferred', 'loaded'].includes(getRTLTextPluginStatus())) {\n setRTLTextPlugin(\n 'https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.3.0/dist/mapbox-gl-rtl-text.js',\n true,\n ).catch((error) => console.error('Something went wrong when setting RTL plugin', error));\n }\n });\n }\n\n /**\n * Dynamically loads the MapLibre CSS stylesheet from CDN.\n */\n private ensureMapLibreCSSLoaded(): void {\n if (typeof document === 'undefined') {\n return;\n }\n // Check if the CSS is already loaded to avoid duplicates:\n const existingLink = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"], style')).some((element) =>\n element.textContent?.includes('.maplibregl-map'),\n );\n if (existingLink) {\n return;\n }\n\n // Create and inject a link tag to load CSS from unpkg CDN\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = `https://unpkg.com/maplibre-gl@${maplibreVersion}/dist/maplibre-gl.css`;\n document.head.appendChild(link);\n }\n\n /**\n * Changes the map style dynamically without reloading the entire map.\n *\n * @param style - The new style to apply. Can be a string ID or a detailed style configuration.\n * @param options - Configuration options for the style change behavior.\n * @param options.keepState - Whether to preserve SDK-rendered items and configurations when changing styles.\n * When `true` (default), maintains traffic layers, routes, markers, and other SDK features.\n * When `false`, performs a clean style switch without preserving previous state.\n *\n * @remarks\n * **Behavior:**\n * - Temporarily sets {@link mapReady} to `false` during the transition\n * - Triggers all registered {@link StyleChangeHandler} callbacks\n * - Resets {@link mapReady} to `true` when the new style is fully loaded\n *\n * **State Preservation (keepState: true):**\n * - Merges style parts from the previous style with the new one\n * - Maintains SDK module layers (traffic, routes, POIs, etc.)\n * - Preserves language settings\n *\n * **Clean Switch (keepState: false):**\n * - Applies the new style without merging previous configuration\n * - Removes all SDK module layers\n * - Useful for complete style resets\n *\n * @example\n * Simple style change:\n * ```typescript\n * // Switch to dark mode\n * map.setStyle('standardDark');\n * ```\n *\n * @example\n * Style change with detailed configuration:\n * ```typescript\n * map.setStyle({\n * type: 'standard',\n * id: 'standardLight',\n * include: ['trafficFlow', 'hillshade']\n * });\n * ```\n *\n * @example\n * Clean style switch without state preservation:\n * ```typescript\n * // Complete reset - removes all SDK layers and modules\n * map.setStyle('standardDark', { keepState: false });\n * ```\n *\n * @example\n * With style change handlers:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * console.log('Preparing for style change...');\n * },\n * onStyleChanged: () => {\n * console.log('New style applied!');\n * }\n * });\n *\n * map.setStyle('standardDark');\n * ```\n *\n * @see {@link TomTomMapParams.style} - For setting style during initialization\n * @see {@link StyleChangeHandler} - For handling style change events\n * @see {@link getStyle} - For retrieving the current style\n * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)\n */\n setStyle = (style: StyleInput, options: { keepState?: boolean } = { keepState: true }): void => {\n this.mapReady = false;\n for (const handler of this.styleChangeHandlers) {\n try {\n handler.onStyleAboutToChange?.();\n } catch (e) {\n console.error(e);\n }\n }\n const effectiveStyle = options.keepState ? withPreviousStyleParts(style, this._params.style) : style;\n this._params = { ...this._params, style: effectiveStyle };\n this.styleLightDarkTheme = getStyleLightDarkTheme(effectiveStyle);\n this.mapLibreMap.once('styledata', () => {\n // We only handle the style data change if the applied style is still the same as the one we set,\n // to prevent race conditions when handling stale styles applied quickly in succession.\n // (If the current style parameters are different, there's likely a new style being set, which will trigger the handler soon after)\n if (!this.mapReady && isEqual(effectiveStyle, this._params.style)) {\n this.handleStyleData(options.keepState || true);\n }\n });\n this.mapLibreMap.setStyle(buildStyleInput(this._params), { validate: false });\n };\n\n /**\n * Retrieves the current style configuration of the map.\n *\n * @returns The current {@link StyleInput} configuration, or `undefined` if no style is set.\n *\n * @remarks\n * Returns the style configuration as it was set, not the fully resolved MapLibre style object.\n * Use this to inspect or store the current style configuration for later restoration.\n *\n * **Return Value:**\n * - String ID (e.g., `'standardLight'`) for simple style configurations\n * - Style object with `type`, `id`, and optional `include` properties for detailed configurations\n * - `undefined` if no style has been explicitly set\n *\n * @example\n * ```typescript\n * const currentStyle = map.getStyle();\n * console.log('Current style:', currentStyle);\n *\n * // Save style for later\n * const savedStyle = map.getStyle();\n *\n * // Later, restore it\n * if (savedStyle) {\n * map.setStyle(savedStyle);\n * }\n * ```\n *\n * @example\n * Conditional logic based on current style:\n * ```typescript\n * const style = map.getStyle();\n * if (typeof style === 'string' && style.includes('Dark')) {\n * console.log('Dark mode is active');\n * }\n * ```\n *\n * @see {@link setStyle} - For changing the map style\n * @see {@link StyleInput} - For available style configuration options\n */\n getStyle = (): StyleInput | undefined => {\n return this._params.style;\n };\n\n private _setLanguage(language: Language) {\n this._params = { ...this._params, language };\n const mapLanguage = language?.includes('-') ? language.split('-')[0] : language;\n this.mapLibreMap.getStyle().layers.forEach((layer) => {\n if (layer.type === 'symbol' && isLayerLocalizable(layer)) {\n const textFieldValue = mapLanguage\n ? ['coalesce', ['get', `name_${mapLanguage}`], ['get', 'name']]\n : ['get', 'name'];\n this.mapLibreMap.setLayoutProperty(layer.id, 'text-field', textFieldValue, { validate: false });\n }\n });\n }\n\n /**\n * Changes the language of the map.\n * * You can use this method to change the language at runtime.\n * * To set the language upon initialization, you can better do it via {@link core!TomTomConfig global config}\n * or {@link TomTomMapParams}.\n * @param language The language to be used in map translations.\n *\n * @remarks\n * **Behavior:**\n * - Updates all localizable map labels to the specified language\n * - Falls back to the default label name if the requested language is unavailable\n * - Can be called before or after the map is fully loaded\n * - If called before map is ready, will apply once the style loads\n *\n * **Language Format:**\n * - Simple language codes: `'en'`, `'fr'`, `'de'`, `'ja'`, `'zh'`\n * - Locale-specific codes: `'en-US'`, `'en-GB'`, `'zh-CN'`, `'pt-BR'`\n * - When using locale codes (with `-`), only the language portion is used for labels\n *\n * **Persistence:**\n * - Language setting persists across style changes (when `keepState: true`)\n * - Set during initialization via {@link TomTomMapParams.language} for immediate application\n *\n * @example\n * Change language at runtime:\n * ```typescript\n * // Switch to French\n * map.setLanguage('fr');\n * ```\n *\n * @example\n * Use locale-specific codes:\n * ```typescript\n * // Use Simplified Chinese\n * map.setLanguage('zh-CN');\n *\n * // Use Brazilian Portuguese\n * map.setLanguage('pt-BR');\n * ```\n *\n * @example\n * Language switcher UI:\n * ```typescript\n * const languageSelector = document.getElementById('lang-select');\n * languageSelector.addEventListener('change', (e) => {\n * map.setLanguage(e.target.value);\n * });\n * ```\n *\n * @see {@link TomTomMapParams.language} - For setting language during initialization\n * @see {@link https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes | ISO 639-1 Language Codes}\n */\n setLanguage(language: Language) {\n if (this.mapReady) {\n this._setLanguage(language);\n } else {\n this.mapLibreMap.once('styledata', () => this.setLanguage(language));\n }\n }\n\n /**\n * Retrieves the current visible map area as a GeoJSON bounding box.\n *\n * @returns A {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox} array\n * in the format `[west, south, east, north]` representing the map's current viewport bounds.\n *\n * @remarks\n * **Return Format:**\n * - Array of four numbers: `[minLongitude, minLatitude, maxLongitude, maxLatitude]`\n * - Coordinates are in WGS84 decimal degrees\n * - West/East values range from -180 to 180\n * - South/North values range from -90 to 90\n *\n * @example\n * Get current bounds:\n * ```typescript\n * const bbox = map.getBBox();\n * console.log('Bounds:', bbox);\n * // Output: [-122.5, 37.7, -122.3, 37.8]\n * // [west, south, east, north]\n * ```\n *\n * @example\n * Use bounds for spatial query:\n * ```typescript\n * const bbox = map.getBBox();\n * const results = await searchAPI.searchInBoundingBox({\n * bbox: bbox,\n * query: 'restaurants'\n * });\n * ```\n *\n * @example\n * Save and restore map view:\n * ```typescript\n * // Save current view\n * const savedBounds = map.getBBox();\n * const savedZoom = map.mapLibreMap.getZoom();\n *\n * // Later, restore the view\n * const [west, south, east, north] = savedBounds;\n * map.mapLibreMap.fitBounds([[west, south], [east, north]]);\n * ```\n *\n * @see {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox Specification}\n * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/geography/#lnglatbounds | MapLibre LngLatBounds}\n */\n getBBox(): BBox {\n return this.mapLibreMap.getBounds().toArray().flat() as BBox;\n }\n\n private handleStyleData(keepState: boolean) {\n // We ensure to make traffic and hillshade hidden by default (even if right after the modules bring it back to visible state)\n // This way we ensure such layers are invisible even of their related SDK modules are not used.\n for (const layer of filterLayersBySources(this.mapLibreMap, [\n TRAFFIC_INCIDENTS_SOURCE_ID,\n TRAFFIC_FLOW_SOURCE_ID,\n HILLSHADE_SOURCE_ID,\n ])) {\n this.mapLibreMap.setLayoutProperty(layer.id, 'visibility', 'none', { validate: false });\n }\n\n // For most use cases we'll need to have pins available (places, routing...) so we add them by default:\n // (subsequent loads for the same sprite should be cached)\n addPinCategoriesSpriteToStyle(this._params, this.mapLibreMap);\n // We restore the language if it was set before:\n this._params.language && this._setLanguage(this._params.language);\n\n this.mapReady = true;\n if (keepState) {\n for (const handler of this.styleChangeHandlers) {\n try {\n handler.onStyleChanged?.();\n } catch (e) {\n console.error(e);\n }\n }\n }\n }\n\n /**\n * Registers a handler to be notified when the map style changes.\n *\n * @param handler - A {@link StyleChangeHandler} object with callbacks for style change events.\n *\n * @remarks\n * **When to Use:**\n * - You have custom layers or sources that need to be recreated after style changes\n * - Your application needs to respond to style switches (e.g., light/dark mode transitions)\n * - You need to save and restore state during style changes\n * - Map modules need to reinitialize when styles change\n *\n * **Handler Lifecycle:**\n * 1. `onStyleAboutToChange()` - Called before the style change begins\n * 2. Style change occurs\n * 3. `onStyleChanged()` - Called after the new style has been fully loaded\n *\n * **Multiple Handlers:**\n * - Multiple handlers can be registered and will all be called in registration order\n * - Each handler's errors are caught independently and logged to the console\n * - One failing handler won't prevent others from executing\n *\n * **Important Notes:**\n * - Handlers are only triggered by {@link setStyle} calls, not initial map construction\n * - Only called when `keepState: true` in {@link setStyle} options\n * - Handlers persist for the lifetime of the TomTomMap instance\n *\n * @example\n * Basic usage:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * console.log('Style is changing...');\n * },\n * onStyleChanged: () => {\n * console.log('Style changed successfully!');\n * }\n * });\n *\n * // Later trigger the handlers\n * map.setStyle('standardDark');\n * ```\n *\n * @example\n * Preserve custom layers across style changes:\n * ```typescript\n * let customLayerData = null;\n *\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * // Save custom layer data before style changes\n * if (map.mapLibreMap.getLayer('my-custom-layer')) {\n * customLayerData = map.mapLibreMap.getSource('my-data')._data;\n * map.mapLibreMap.removeLayer('my-custom-layer');\n * map.mapLibreMap.removeSource('my-data');\n * }\n * },\n * onStyleChanged: () => {\n * // Restore custom layer after new style is loaded\n * if (customLayerData) {\n * map.mapLibreMap.addSource('my-data', {\n * type: 'geojson',\n * data: customLayerData\n * });\n * map.mapLibreMap.addLayer({\n * id: 'my-custom-layer',\n * type: 'circle',\n * source: 'my-data',\n * paint: { 'circle-radius': 6, 'circle-color': '#007cbf' }\n * });\n * }\n * }\n * });\n * ```\n *\n * @example\n * Async handler for external API calls:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: async () => {\n * await saveStateToAPI(map.getStyle());\n * },\n * onStyleChanged: async () => {\n * await loadStateFromAPI();\n * }\n * });\n * ```\n *\n * @example\n * Update UI based on style:\n * ```typescript\n * map.addStyleChangeHandler({\n * onStyleAboutToChange: () => {\n * document.body.classList.add('style-changing');\n * },\n * onStyleChanged: () => {\n * document.body.classList.remove('style-changing');\n * const style = map.getStyle();\n * if (typeof style === 'string' && style.includes('Dark')) {\n * document.body.classList.add('dark-mode');\n * } else {\n * document.body.classList.remove('dark-mode');\n * }\n * }\n * });\n * ```\n *\n * @see {@link StyleChangeHandler} - Handler interface definition\n * @see {@link setStyle} - Method that triggers the handlers\n */\n addStyleChangeHandler(handler: StyleChangeHandler): void {\n this.styleChangeHandlers.push(handler);\n }\n}\n","import type { MapOptions } from 'maplibre-gl';\nimport { injectTomTomHeaders } from '../shared/mapUtils';\nimport { buildStyleInput } from './styleInputBuilder';\nimport type { InternalTomTomMapParams } from './types/mapInit';\n\n/**\n * @ignore\n * @param tomtomMapParams\n */\nexport const buildMapOptions = (tomtomMapParams: InternalTomTomMapParams): MapOptions => {\n return {\n // defaults (can be overwritten by given options)\n validateStyle: false,\n maxTileCacheZoomLevels: 22,\n cancelPendingTileRequestsWhileZooming: false,\n // given options:\n ...tomtomMapParams.mapLibre,\n // SDK overrides (won't have any effect via given options):\n style: buildStyleInput(tomtomMapParams),\n attributionControl: { compact: false },\n transformRequest: injectTomTomHeaders(tomtomMapParams),\n };\n};\n","import type { ExpressionSpecification, SymbolLayerSpecification } from 'maplibre-gl';\n\n/**\n * @ignore\n */\nexport const isLayerLocalizable = (layer: SymbolLayerSpecification): boolean => {\n const textField = (layer.layout?.['text-field'] ?? '') as string | ExpressionSpecification;\n return textField\n ? // tries to detect layers which have a \"text-field\" that can be localized\n // ex. \"text-field\": \"{name}\" or \"text-field\": [\"get\", \"name\"]\n textField === '{name}' ||\n (textField.length === 2 && textField[1] === 'name') ||\n // tries to detect layers which have \"text-field\" that was localized already\n // ex. \"text-field\": [\"coalesce\", [\"get\", \"name_en\"], [\"get\", \"name\"]]\n (textField.length === 3 &&\n Array.isArray(textField[1]) &&\n typeof textField[1][1] === 'string' &&\n textField[1][1].includes('name_') &&\n Array.isArray(textField[2]) &&\n textField[2].includes('name'))\n : false;\n};\n","import type { DelayMagnitude } from '@tomtom-org/maps-sdk/core';\nimport type { FilterShowMode, MapModuleCommonConfig, ValuesFilter } from '../../shared';\n\n/**\n * Available traffic incident category identifiers.\n *\n * @remarks\n * These categories classify different types of traffic incidents that can be displayed on the map.\n *\n * @group Traffic Incidents\n */\nexport const incidentCategories = [\n 'unknown',\n 'accident',\n 'fog',\n 'dangerous_conditions',\n 'rain',\n 'ice',\n 'jam',\n 'lane_closed',\n 'road_closed',\n 'road_works',\n 'wind',\n 'flooding',\n 'broken_down_vehicle',\n] as const;\n\n/**\n * Traffic incident category type.\n *\n * @remarks\n * Represents the type of traffic incident affecting road conditions.\n * Used for filtering and categorizing incidents displayed on the map.\n *\n * Available categories:\n * - `unknown` - Unclassified incident\n * - `accident` - Vehicle collision or crash\n * - `fog` - Low visibility due to fog\n * - `dangerous_conditions` - Hazardous road conditions\n * - `rain` - Heavy rain affecting traffic\n * - `ice` - Icy road conditions\n * - `jam` - Traffic congestion or standstill\n * - `lane_closed` - One or more lanes unavailable\n * - `road_closed` - Complete road closure\n * - `road_works` - Construction or maintenance\n * - `wind` - Strong winds affecting traffic\n * - `flooding` - Water on roadway\n * - `broken_down_vehicle` - Disabled vehicle blocking traffic\n *\n * @group Traffic Incidents\n */\nexport type IncidentCategory = (typeof incidentCategories)[number];\n\n/**\n * @ignore\n */\nexport const incidentCategoriesMapping: Record<IncidentCategory, number> = {\n unknown: 0,\n accident: 1,\n fog: 2,\n dangerous_conditions: 3,\n rain: 4,\n ice: 5,\n jam: 6,\n lane_closed: 7,\n road_closed: 8,\n road_works: 9,\n wind: 10,\n flooding: 11,\n broken_down_vehicle: 14,\n} as const;\n\n/**\n * Available road hierarchy category identifiers.\n *\n * @remarks\n * These categories represent different levels in the road network hierarchy,\n * from major highways to local streets.\n *\n * @group Traffic\n */\nexport const roadCategories = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary', 'street'] as const;\n\n/**\n * Road hierarchy category type.\n *\n * @remarks\n * Classifies roads by their importance and capacity in the transportation network.\n * Used for filtering traffic data display based on road significance.\n *\n * Road hierarchy (from highest to lowest):\n * - `motorway` - High-capacity highways with restricted access\n * - `trunk` - Major inter-city roads\n * - `primary` - Primary through routes\n * - `secondary` - Secondary through routes\n * - `tertiary` - Connecting roads (see {@link TertiaryRoadCategory})\n * - `street` - Local streets (see {@link StreetRoadCategory})\n *\n * @group Traffic\n */\nexport type RoadCategory = (typeof roadCategories)[number];\n\n/**\n * Available tertiary road sub-category identifiers.\n *\n * @remarks\n * Provides finer granularity for classifying tertiary roads.\n *\n * @group Traffic\n */\nexport const tertiaryRoadCategories = ['connecting', 'major_local'] as const;\n\n/**\n * Tertiary road sub-category type.\n *\n * @remarks\n * Further classifies tertiary roads into specific sub-types for more granular filtering.\n *\n * Sub-categories:\n * - `connecting` - Roads connecting different areas\n * - `major_local` - Major roads within local areas\n *\n * @group Traffic\n */\nexport type TertiaryRoadCategory = (typeof tertiaryRoadCategories)[number];\n\n/**\n * Available street road sub-category identifiers.\n *\n * @remarks\n * Provides finer granularity for classifying local streets.\n *\n * @group Traffic\n */\nexport const streetRoadCategories = ['local', 'minor_local'] as const;\n\n/**\n * Street road sub-category type.\n *\n * @remarks\n * Further classifies local streets into specific sub-types for more granular filtering.\n *\n * Sub-categories:\n * - `local` - Standard local streets\n * - `minor_local` - Minor residential streets\n *\n * @group Traffic\n */\nexport type StreetRoadCategory = (typeof streetRoadCategories)[number];\n\n/**\n * Configuration for filtering traffic incidents by delay duration.\n *\n * @remarks\n * Allows filtering incidents based on whether they cause delays and the severity of those delays.\n * Useful for focusing on incidents with the most significant traffic impact.\n *\n * @group Traffic\n */\nexport type DelayFilter = {\n /**\n * Requires incidents to have an associated delay.\n *\n * @remarks\n * When `true`, incidents without delay information will be hidden from the map.\n * When `false` or omitted, incidents are shown regardless of delay data availability.\n *\n * @defaultValue `false`\n */\n mustHaveDelay?: boolean;\n\n /**\n * Minimum delay threshold in minutes.\n *\n * @remarks\n * Only incidents causing delays of at least this duration will be shown.\n *\n * **Behavior:**\n * - If `mustHaveDelay` is `false` or not set, this filter only applies to incidents that have delay data\n * - Incidents without delay data are still shown (unless `mustHaveDelay` is `true`)\n *\n * @example\n * ```ts\n * // Show only incidents with delays of 5 minutes or more\n * delays: { minDelayMinutes: 5 }\n * ```\n */\n minDelayMinutes?: number;\n};\n\n/**\n * Common filter configuration shared between traffic incidents and flow visualization.\n *\n * @remarks\n * Provides road category filtering capabilities used by both incident and flow modules.\n *\n * @group Traffic\n */\nexport type TrafficCommonFilter = {\n /**\n * Filters traffic data by road hierarchy categories.\n *\n * @remarks\n * Controls which road types display traffic information.\n * Use the `mode` field to specify whether to show or hide the selected categories.\n *\n * @example\n * ```ts\n * // Show only motorways and trunk roads\n * roadCategories: { mode: 'show', values: ['motorway', 'trunk'] }\n * ```\n */\n roadCategories?: ValuesFilter<RoadCategory>;\n\n /**\n * Filters traffic data by road sub-categories.\n *\n * @remarks\n * Provides finer-grained control for tertiary roads and streets.\n * Applies to sub-categories of {@link TertiaryRoadCategory} and {@link StreetRoadCategory}.\n *\n * @example\n * ```ts\n * // Hide minor local streets\n * roadSubCategories: { mode: 'hide', values: ['minor_local'] }\n * ```\n */\n roadSubCategories?: ValuesFilter<TertiaryRoadCategory | StreetRoadCategory>;\n};\n\n/**\n * Filter configuration for traffic incidents visualization.\n *\n * @remarks\n * Extends common traffic filters with incident-specific filtering options\n * including category, severity, and delay-based filtering.\n *\n * @group Traffic Incidents\n */\nexport type TrafficIncidentsFilter = TrafficCommonFilter & {\n /**\n * Filters incidents by category type.\n *\n * @remarks\n * Controls which types of incidents are displayed on the map.\n *\n * @example\n * ```ts\n * // Show only accidents and road closures\n * incidentCategories: { mode: 'show', values: ['accident', 'road_closed'] }\n * ```\n */\n incidentCategories?: ValuesFilter<IncidentCategory>;\n\n /**\n * Filters incidents by delay severity magnitude.\n *\n * @remarks\n * Controls display based on the severity of traffic delays caused by incidents.\n *\n * Magnitude levels:\n * - `0` - Unknown\n * - `1` - Minor\n * - `2` - Moderate\n * - `3` - Major\n * - `4` - Undefined\n *\n * @example\n * ```ts\n * // Show only major incidents\n * magnitudes: { mode: 'show', values: [3] }\n * ```\n */\n magnitudes?: ValuesFilter<DelayMagnitude>;\n\n /**\n * Filters incidents by delay duration.\n *\n * @remarks\n * Allows filtering based on whether incidents have delays and minimum delay thresholds.\n */\n delays?: DelayFilter;\n};\n\n/**\n * Collection of traffic incident filters with OR logic.\n *\n * @remarks\n * Combines multiple incident filter configurations where an incident is shown\n * if it matches **any** of the provided filter criteria (logical OR).\n *\n * This allows for complex filtering scenarios where incidents from different\n * categories or with different characteristics can all be displayed.\n *\n * @example\n * ```ts\n * // Show major incidents OR road closures\n * filters: {\n * any: [\n * { magnitudes: { mode: 'show', values: [3] } },\n * { incidentCategories: { mode: 'show', values: ['road_closed'] } }\n * ]\n * }\n * ```\n *\n * @group Traffic Incidents\n */\nexport type TrafficIncidentsFilters = {\n /**\n * Array of incident filters combined with OR logic.\n *\n * @remarks\n * An incident is displayed if it satisfies at least one of the filter configurations.\n */\n any: TrafficIncidentsFilter[];\n};\n\n/**\n * Filter configuration for traffic flow visualization.\n *\n * @remarks\n * Extends common traffic filters with flow-specific options,\n * particularly for highlighting road closures in the flow layer.\n *\n * @group Traffic Flow\n */\nexport type TrafficFlowFilter = TrafficCommonFilter & {\n /**\n * Controls road closure display in the traffic flow layer.\n *\n * @remarks\n * Determines whether to exclusively show road closures or exclude them from display.\n *\n * - `'show'` - Display only road closures\n * - `'hide'` - Display everything except road closures\n *\n * @example\n * ```ts\n * // Highlight only road closures\n * showRoadClosures: 'show'\n * ```\n */\n showRoadClosures?: FilterShowMode;\n};\n\n/**\n * Collection of traffic flow filters with OR logic.\n *\n * @remarks\n * Combines multiple flow filter configurations where traffic flow data is shown\n * if it matches **any** of the provided filter criteria (logical OR).\n *\n * @example\n * ```ts\n * // Show flow on motorways OR show road closures on any road\n * filters: {\n * any: [\n * { roadCategories: { mode: 'show', values: ['motorway'] } },\n * { showRoadClosures: 'show' }\n * ]\n * }\n * ```\n *\n * @group Traffic Flow\n */\nexport type TrafficFlowFilters = {\n /**\n * Array of flow filters combined with OR logic.\n *\n * @remarks\n * Traffic flow data is displayed if it satisfies at least one of the filter configurations.\n */\n any: TrafficFlowFilter[];\n};\n\n/**\n * Common configuration for traffic incident visualization components.\n *\n * @remarks\n * Provides shared styling and filtering options used by both incident lines and icons.\n * Extends base style module configuration with traffic incident-specific filters.\n *\n * @group Traffic Incidents\n */\nexport type IncidentsCommonConfig = {\n /**\n * Controls the visibility of the traffic incident layers.\n *\n * @default false\n */\n visible?: boolean;\n\n /**\n * Filter configuration for traffic incidents.\n *\n * @remarks\n * Controls which incidents are displayed based on category, severity, delay, and road type.\n */\n filters?: TrafficIncidentsFilters;\n};\n\n/**\n * Configuration for traffic incidents module.\n *\n * @remarks\n * Provides complete configuration for displaying traffic incidents on the map,\n * including separate styling for incident lines and icons.\n *\n * @group Traffic Incidents\n */\nexport type IncidentsConfig = MapModuleCommonConfig &\n IncidentsCommonConfig & {\n /**\n * Configuration specific to incident icon display.\n *\n * @remarks\n * Allows separate styling and filtering for incident marker icons,\n * independent of the incident line styling.\n */\n icons?: IncidentsCommonConfig;\n };\n\n/**\n * Configuration for traffic flow visualization module.\n *\n * @remarks\n * Controls the display of real-time traffic flow data on road segments,\n * including styling and filtering options.\n *\n * @group Traffic Flow\n */\nexport type FlowConfig = MapModuleCommonConfig & {\n /**\n * Controls the visibility of the traffic flow layers.\n *\n * @default false\n */\n visible?: boolean;\n\n /**\n * Filter configuration for traffic flow data.\n *\n * @remarks\n * Controls which road segments display traffic flow information\n * based on road category and closure status.\n */\n filters?: TrafficFlowFilters;\n};\n","import { indexedMagnitudes } from '@tomtom-org/maps-sdk/core';\nimport { isNil } from 'lodash-es';\nimport type {\n ExpressionFilterSpecification,\n FilterSpecification,\n LayerSpecification,\n LegacyFilterSpecification,\n Map,\n} from 'maplibre-gl';\nimport type { MultiSyntaxFilter, ValuesFilter } from '../../shared';\nimport { buildValuesFilter, getMergedAllFilter, getMergedAnyFilter } from '../../shared/mapLibreFilterUtils';\nimport type {\n DelayFilter,\n TrafficCommonFilter,\n TrafficFlowFilter,\n TrafficFlowFilters,\n TrafficIncidentsFilter,\n TrafficIncidentsFilters,\n} from '../types/trafficModuleConfig';\nimport { incidentCategoriesMapping } from '../types/trafficModuleConfig';\n\nconst toMultiSyntaxAllFilter = (\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n): MultiSyntaxFilter | null => {\n if (!newSyntaxExpressions.length) {\n return null;\n }\n if (newSyntaxExpressions.length === 1) {\n return {\n expression: newSyntaxExpressions[0] as ExpressionFilterSpecification,\n legacy: legacySyntaxExpressions[0] as LegacyFilterSpecification,\n };\n }\n return {\n expression: ['all', ...newSyntaxExpressions] as ExpressionFilterSpecification,\n legacy: ['all', ...legacySyntaxExpressions] as LegacyFilterSpecification,\n };\n};\n\nconst delayFilterToMapLibre = (delayFilter: DelayFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions = [];\n const legacySyntaxExpressions = [];\n if (delayFilter.mustHaveDelay && delayFilter.minDelayMinutes) {\n // there must be a delay and with the min specified value:\n const delaySeconds = delayFilter.minDelayMinutes * 60;\n newSyntaxExpressions.push(['>=', ['get', 'delay'], delaySeconds]);\n legacySyntaxExpressions.push(['>=', 'delay', delaySeconds]);\n } else if (delayFilter.mustHaveDelay) {\n // just expects a delay of any kind\n newSyntaxExpressions.push(['>', ['get', 'delay'], 0]);\n legacySyntaxExpressions.push(['>', 'delay', 0]);\n } else if (delayFilter.minDelayMinutes) {\n // Min delay expected, but also allows for non-existing delays:\n const delaySeconds = delayFilter.minDelayMinutes * 60;\n newSyntaxExpressions.push([\n 'any',\n ['!', ['has', 'delay']],\n ['==', ['get', 'delay'], 0],\n ['>=', ['get', 'delay'], delaySeconds],\n ]);\n legacySyntaxExpressions.push(['any', ['!has', 'delay'], ['==', 'delay', 0], ['>=', 'delay', delaySeconds]]);\n }\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\nconst addFilter = (\n filter: MultiSyntaxFilter | undefined | null,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n) => {\n if (filter) {\n newSyntaxExpressions.push(filter.expression);\n legacySyntaxExpressions.push(filter.legacy);\n }\n};\n\nconst addValuesFilter = (\n valuesFilter: ValuesFilter<string> | undefined,\n propName: string,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n) => {\n if (valuesFilter) {\n addFilter(buildValuesFilter(propName, valuesFilter), newSyntaxExpressions, legacySyntaxExpressions);\n }\n};\n\nconst addCommonFilterExpressions = (\n sdkFilter: TrafficCommonFilter,\n newSyntaxExpressions: unknown[],\n legacySyntaxExpressions: unknown[],\n): void => {\n addValuesFilter(sdkFilter.roadCategories, 'road_category', newSyntaxExpressions, legacySyntaxExpressions);\n addValuesFilter(sdkFilter.roadSubCategories, 'road_subcategory', newSyntaxExpressions, legacySyntaxExpressions);\n};\n\nconst buildMapLibreIncidentsFilter = (sdkFilter: TrafficIncidentsFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions: unknown[] = [];\n const legacySyntaxExpressions: unknown[] = [];\n\n addCommonFilterExpressions(sdkFilter, newSyntaxExpressions, legacySyntaxExpressions);\n\n if (sdkFilter.incidentCategories) {\n const incidentCategoryFilter = buildValuesFilter(\n 'icon_category_0',\n sdkFilter.incidentCategories,\n (value) => incidentCategoriesMapping[value],\n );\n addFilter(incidentCategoryFilter, newSyntaxExpressions, legacySyntaxExpressions);\n }\n if (sdkFilter.magnitudes) {\n const magnitudesFilter = buildValuesFilter('magnitude', sdkFilter.magnitudes, (magnitude) =>\n indexedMagnitudes.indexOf(magnitude),\n );\n addFilter(magnitudesFilter, newSyntaxExpressions, legacySyntaxExpressions);\n }\n if (sdkFilter.delays) {\n addFilter(delayFilterToMapLibre(sdkFilter.delays), newSyntaxExpressions, legacySyntaxExpressions);\n }\n\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\n/**\n * @ignore\n */\nexport const buildMapLibreIncidentFilters = (incidentFilters: TrafficIncidentsFilters): MultiSyntaxFilter | null => {\n if (!incidentFilters?.any?.length) {\n return null;\n }\n const mapLibreFilters = incidentFilters.any\n .map(buildMapLibreIncidentsFilter)\n .filter((mapLibreFilter) => !isNil(mapLibreFilter));\n return getMergedAnyFilter(mapLibreFilters);\n};\n\nconst buildMapLibreFlowFilter = (sdkFilter: TrafficFlowFilter): MultiSyntaxFilter | null => {\n const newSyntaxExpressions: unknown[] = [];\n const legacySyntaxExpressions: unknown[] = [];\n\n addCommonFilterExpressions(sdkFilter, newSyntaxExpressions, legacySyntaxExpressions);\n if (sdkFilter.showRoadClosures) {\n const operator = sdkFilter.showRoadClosures === 'only' ? '==' : '!=';\n newSyntaxExpressions.push([operator, ['get', 'road_closure'], true]);\n legacySyntaxExpressions.push([operator, 'road_closure', true]);\n }\n\n return toMultiSyntaxAllFilter(newSyntaxExpressions, legacySyntaxExpressions);\n};\n\n/**\n * @ignore\n */\nexport const buildMapLibreFlowFilters = (flowFilters: TrafficFlowFilters): MultiSyntaxFilter | null => {\n if (!flowFilters?.any?.length) {\n return null;\n }\n const mapLibreFilters = flowFilters.any\n .map(buildMapLibreFlowFilter)\n .filter((mapLibreFilter) => !isNil(mapLibreFilter));\n return getMergedAnyFilter(mapLibreFilters);\n};\n\n/**\n * @ignore\n * @param filter\n * @param layers\n * @param mapLibreMap\n * @param originalFilters\n */\nexport const applyFilter = (\n filter: MultiSyntaxFilter | undefined,\n layers: LayerSpecification[],\n mapLibreMap: Map,\n originalFilters: Record<string, FilterSpecification | undefined>,\n) => {\n for (const layer of layers) {\n mapLibreMap.setFilter(\n layer.id,\n filter ? getMergedAllFilter(filter, originalFilters[layer.id]) : originalFilters[layer.id],\n );\n }\n};\n","import { isNil, omitBy } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport type { LayerSpecWithSource } from '../shared';\nimport {\n AbstractMapModule,\n EventsModule,\n filterLayersBySources,\n StyleSourceWithLayers,\n TRAFFIC_FLOW_SOURCE_ID,\n} from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { applyFilter, buildMapLibreFlowFilters } from './filters/trafficFilters';\nimport type { FlowConfig, TrafficFlowFilters } from './types/trafficModuleConfig';\n\n/**\n * IDs of sources and layers for traffic flow module.\n */\ntype TrafficFlowSourcesWithLayers = {\n trafficFlow: StyleSourceWithLayers;\n};\n\n/**\n * Traffic Flow Module for displaying and configuring real-time traffic flow information on the map.\n *\n * This module controls the vector tile traffic flow layers that visualize current\n * traffic speed conditions using color-coded road segments.\n *\n * @remarks\n * **Features:**\n * - Toggle traffic flow visibility on/off\n * - Filter by road categories and types\n * - Color-coded speed visualization (green = free flow, red = congestion)\n * - Real-time traffic data from vector tiles\n * - Filter road closures\n *\n * **Visual Representation:**\n * - Green: Free-flowing traffic\n * - Yellow/Orange: Slow traffic\n * - Red: Heavy congestion\n * - Dark gray: Road closures\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { TrafficFlowModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module (auto-add to style if needed)\n * const trafficFlow = await TrafficFlowModule.get(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * trafficFlow.setVisible(false);\n * trafficFlow.setVisible(true);\n * ```\n *\n * @example\n * Filter by road type:\n * ```typescript\n * // Show only highway traffic\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk']\n * }\n * }]\n * });\n *\n * // Hide local streets\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'all_except',\n * values: ['street']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Show only road closures:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * showRoadClosures: 'only'\n * }]\n * });\n * ```\n *\n * @see [Traffic Flow Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-flow)\n * @see [Traffic Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic)\n *\n * @group Traffic Flow\n */\nexport class TrafficFlowModule extends AbstractMapModule<TrafficFlowSourcesWithLayers, FlowConfig> {\n private originalFilters!: Record<string, FilterSpecification | undefined>;\n\n /**\n * Retrieves a TrafficFlowModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization, visibility, and filters.\n *\n * @returns A promise that resolves to the initialized TrafficFlowModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state\n * - `ensureAddedToStyle`: Auto-add traffic flow to style if missing\n * - `filters`: Road category and type filters\n *\n * **Style Requirement:**\n * Traffic flow must be included in the map style or added via `ensureAddedToStyle`.\n *\n * @throws Error if traffic flow source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const trafficFlowModule = await TrafficFlowModule.get(map);\n * ```\n *\n * @example\n * Auto-add to style:\n * ```typescript\n * const trafficFlowModule = await TrafficFlowModule.get(map, {\n * visible: true,\n * filters: {\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk', 'primary']\n * }\n * }]\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: FlowConfig): Promise<TrafficFlowModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, TRAFFIC_FLOW_SOURCE_ID, 'trafficFlow');\n return new TrafficFlowModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: FlowConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const flowSource = this.mapLibreMap.getSource(TRAFFIC_FLOW_SOURCE_ID);\n if (!flowSource) {\n throw notInTheStyle(`init ${TrafficFlowModule.name} with source ID ${TRAFFIC_FLOW_SOURCE_ID}`);\n }\n this.originalFilters = {};\n for (const layer of this.getLayers()) {\n this.originalFilters[layer.id] = layer.filter;\n }\n return { trafficFlow: new StyleSourceWithLayers(this.mapLibreMap, flowSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: FlowConfig | undefined) {\n this.setVisible(config?.visible ?? false);\n this._filter(config?.filters, false);\n return config;\n }\n\n private getLayers(): LayerSpecWithSource[] {\n return filterLayersBySources(this.tomtomMap.mapLibreMap, [TRAFFIC_FLOW_SOURCE_ID]);\n }\n\n /**\n * Applies filters to traffic flow display.\n *\n * @param filters - Filter configuration for road types, categories, and closures.\n * Pass `undefined` to reset to defaults (show all).\n *\n * @remarks\n * **Filter Options:**\n * - `roadCategories`: Filter by road importance (motorway, trunk, primary, etc.)\n * - `roadSubCategories`: Filter by specific street types\n * - `showRoadClosures`: Show only closures or exclude them\n *\n * **Available Road Categories:**\n * - `motorway`: Major highways\n * - `trunk`: Major roads\n * - `primary`: Primary roads\n * - `secondary`: Secondary roads\n * - `tertiary`: Tertiary roads\n * - `street`: Local streets\n *\n * **Filter Logic:**\n * Uses \"any\" (OR) logic - traffic matching any filter is shown.\n *\n * @example\n * Show only major roads:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'only',\n * values: ['motorway', 'trunk', 'primary']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Hide street-level traffic:\n * ```typescript\n * trafficFlow.filter({\n * any: [{\n * roadCategories: {\n * show: 'all_except',\n * values: ['street']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Multiple filter criteria:\n * ```typescript\n * trafficFlow.filter({\n * any: [\n * {\n * roadCategories: { show: 'only', values: ['motorway'] }\n * },\n * {\n * showRoadClosures: 'only'\n * }\n * ]\n * });\n * ```\n *\n * @example\n * Reset filters:\n * ```typescript\n * trafficFlow.filter(undefined);\n * ```\n */\n filter(filters?: TrafficFlowFilters) {\n this._filter(filters);\n }\n\n private _filter(filters: TrafficFlowFilters | undefined, updateConfig = true) {\n if (this.tomtomMap.mapReady) {\n if (filters?.any?.length) {\n const filterExpression = buildMapLibreFlowFilters(filters);\n if (filterExpression) {\n applyFilter(filterExpression, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n } else if (this.config?.filters?.any?.length) {\n applyFilter(undefined, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n }\n\n if (updateConfig) {\n this.config = omitBy({ ...this.config, filters }, isNil);\n }\n }\n\n /**\n * Sets the visibility of traffic flow layers.\n *\n * @param visible - `true` to show traffic flow, `false` to hide it.\n *\n * @example\n * ```typescript\n * trafficFlow.setVisible(true); // Show traffic\n * trafficFlow.setVisible(false); // Hide traffic\n * ```\n */\n setVisible(visible: boolean): void {\n this.config = { ...this.config, visible };\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficFlow.setLayersVisible(visible);\n }\n }\n\n /**\n * Returns if any layer for traffic flow is visible or not.\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.trafficFlow.isAnyLayerVisible();\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule(this.tomtomMap._eventsProxy, this.sourcesWithLayers.trafficFlow, this.config?.events);\n }\n}\n","import { isEmpty, isNil, omitBy } from 'lodash-es';\nimport type { FilterSpecification } from 'maplibre-gl';\nimport type { LayerSpecWithSource } from '../shared';\nimport {\n AbstractMapModule,\n EventsModule,\n filterLayersBySources,\n StyleSourceWithLayers,\n TRAFFIC_INCIDENTS_SOURCE_ID,\n} from '../shared';\nimport { notInTheStyle } from '../shared/errorMessages';\nimport { ensureAddedToStyle, waitUntilMapIsReady } from '../shared/mapUtils';\nimport type { TomTomMap } from '../TomTomMap';\nimport { applyFilter, buildMapLibreIncidentFilters } from './filters/trafficFilters';\nimport type { IncidentsConfig, TrafficIncidentsFilters } from './types/trafficModuleConfig';\n\n/**\n * IDs of sources and layers for traffic incidents module.\n */\ntype TrafficIncidentsSourcesWithLayers = {\n trafficIncidents: StyleSourceWithLayers;\n};\n\n/**\n * Traffic Incidents Module for displaying and configuring real-time traffic incidents on the map.\n *\n * This module controls the vector tile traffic incidents layers that show traffic\n * events like accidents, road closures, construction, and hazards.\n *\n * @remarks\n * **Features:**\n * - Toggle incidents visibility on/off\n * - Separate control for incident icons\n * - Filter by incident type (accident, construction, etc.)\n * - Filter by severity/delay magnitude\n * - Filter by road categories\n * - Icon and line/polygon visualization\n *\n * **Incident Types:**\n * - Accidents\n * - Road closures\n * - Construction/road works\n * - Weather conditions (fog, ice, rain, etc.)\n * - Lane closures\n * - Traffic jams\n * - Broken down vehicles\n *\n * @example\n * Basic usage:\n * ```typescript\n * import { TrafficIncidentsModule } from '@tomtom-international/maps-sdk-js/map';\n *\n * // Get module (auto-add to style if needed)\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map, {\n * visible: true\n * });\n *\n * // Toggle visibility\n * trafficIncidentsModule.setVisible(false);\n * trafficIncidentsModule.setVisible(true);\n *\n * // Control icons separately\n * trafficIncidentsModule.setIconsVisible(false);\n * ```\n *\n * @example\n * Filter by incident type:\n * ```typescript\n * // Show only accidents and road closures\n * trafficIncidentsModule.filter({\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed']\n * }\n * }]\n * });\n *\n * // Hide construction\n * trafficIncidentsModule.filter({\n * any: [{\n * incidentCategories: {\n * show: 'all_except',\n * values: ['road_works']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter by severity:\n * ```typescript\n * // Show only major delays\n * incidents.filter({\n * any: [{\n * magnitudes: {\n * show: 'only',\n * values: ['major']\n * }\n * }]\n * });\n *\n * // Show incidents with at least 10 minutes delay\n * incidents.filter({\n * any: [{\n * delays: {\n * mustHaveDelay: true,\n * minDelayMinutes: 10\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter icons separately from incident areas:\n * ```typescript\n * // Show all incidents but only major icons\n * incidents.filter(\n * {\n * any: [{}] // Show all incidents\n * },\n * {\n * any: [{\n * magnitudes: { show: 'only', values: ['major'] }\n * }]\n * }\n * );\n * ```\n *\n * @see [Traffic Incidents Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-incidents)\n * @see [Traffic Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic)\n *\n * @group Traffic Incidents\n */\nexport class TrafficIncidentsModule extends AbstractMapModule<TrafficIncidentsSourcesWithLayers, IncidentsConfig> {\n private originalFilters!: Record<string, FilterSpecification | undefined>;\n\n /**\n * Retrieves a TrafficIncidentsModule instance for the given map.\n *\n * @param map - The TomTomMap instance to attach this module to.\n * @param config - Optional configuration for initialization, visibility, and filters.\n *\n * @returns A promise that resolves to the initialized TrafficIncidentsModule.\n *\n * @remarks\n * **Configuration:**\n * - `visible`: Initial visibility state for all incidents\n * - `icons.visible`: Initial visibility for incident icons\n * - `ensureAddedToStyle`: Auto-add traffic incidents to style if missing\n * - `filters`: Incident type, severity, and delay filters\n * - `icons.filters`: Separate filters for icons\n *\n * @throws Error if traffic incidents source is not in style and `ensureAddedToStyle` is false\n *\n * @example\n * Default initialization:\n * ```typescript\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map);\n * ```\n *\n * @example\n * With configuration:\n * ```typescript\n * const trafficIncidentsModule = await TrafficIncidentsModule.get(map, {\n * visible: true,\n * icons: { visible: true },\n * filters: {\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed', 'jam']\n * }\n * }]\n * }\n * });\n * ```\n */\n static async get(map: TomTomMap, config?: IncidentsConfig): Promise<TrafficIncidentsModule> {\n await waitUntilMapIsReady(map);\n await ensureAddedToStyle(map, TRAFFIC_INCIDENTS_SOURCE_ID, 'trafficIncidents');\n return new TrafficIncidentsModule(map, config);\n }\n\n private constructor(map: TomTomMap, config?: IncidentsConfig) {\n super('style', map, config);\n }\n\n /**\n * @ignore\n */\n protected _initSourcesWithLayers() {\n const incidentsSource = this.mapLibreMap.getSource(TRAFFIC_INCIDENTS_SOURCE_ID);\n if (!incidentsSource) {\n throw notInTheStyle(`init ${TrafficIncidentsModule.name} with source ID ${TRAFFIC_INCIDENTS_SOURCE_ID}`);\n }\n this.originalFilters = {};\n for (const layer of this.getLayers()) {\n this.originalFilters[layer.id] = layer.filter;\n }\n return { trafficIncidents: new StyleSourceWithLayers(this.mapLibreMap, incidentsSource) };\n }\n\n /**\n * @ignore\n */\n protected _applyConfig(config: IncidentsConfig | undefined) {\n // We do not update config in setVisible since it could override icons visibility setting:\n this._setVisible(config?.visible ?? false, { updateConfig: false });\n if (!isNil(config?.icons?.visible)) {\n this.setIconsVisible(config.icons.visible);\n }\n this._filter(config?.filters, config?.icons?.filters, false);\n return config;\n }\n\n /**\n * Applies filters to traffic incidents display.\n *\n * @param incidentFilters - Filter for incident areas/lines. Pass `undefined` to reset.\n * @param iconFilters - Optional separate filter for incident icons. Pass `undefined` to reset.\n *\n * @remarks\n * **Filter Options:**\n * - `incidentCategories`: Filter by incident type\n * - `magnitudes`: Filter by delay severity (minor/moderate/major/unknown)\n * - `delays`: Filter by delay duration\n * - `roadCategories`: Filter by road importance\n * - `roadSubCategories`: Filter by specific road types\n *\n * **Available Incident Categories:**\n * - `accident`, `road_closed`, `lane_closed`\n * - `road_works` (construction)\n * - `jam` (traffic jam)\n * - `fog`, `rain`, `ice`, `wind`, `flooding`\n * - `dangerous_conditions`\n * - `broken_down_vehicle`\n * - `unknown`\n *\n * **Delay Magnitudes:**\n * - `minor`: Small delays\n * - `moderate`: Moderate delays\n * - `major`: Significant delays\n * - `unknown`: Unknown or no delay info\n *\n * @example\n * Filter by type:\n * ```typescript\n * incidents.filter({\n * any: [{\n * incidentCategories: {\n * show: 'only',\n * values: ['accident', 'road_closed']\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Filter by severity and delay:\n * ```typescript\n * incidents.filter({\n * any: [{\n * magnitudes: { show: 'only', values: ['major', 'moderate'] },\n * delays: {\n * mustHaveDelay: true,\n * minDelayMinutes: 5\n * }\n * }]\n * });\n * ```\n *\n * @example\n * Different filters for icons and areas:\n * ```typescript\n * // Show all incidents on roads\n * const incidentFilter = {\n * any: [{\n * roadCategories: { show: 'only', values: ['motorway', 'trunk'] }\n * }]\n * };\n *\n * // But only show icons for major incidents\n * const iconFilter = {\n * any: [{\n * magnitudes: { show: 'only', values: ['major'] }\n * }]\n * };\n *\n * incidents.filter(incidentFilter, iconFilter);\n * ```\n */\n filter(incidentFilters?: TrafficIncidentsFilters, iconFilters?: TrafficIncidentsFilters) {\n this._filter(incidentFilters, iconFilters);\n }\n\n private _filter(\n incidentFilters: TrafficIncidentsFilters | undefined,\n iconFilters: TrafficIncidentsFilters | undefined,\n updateConfig = true,\n ) {\n if (this.tomtomMap.mapReady) {\n if (incidentFilters?.any?.length) {\n const incidentFilterExpression = buildMapLibreIncidentFilters(incidentFilters);\n if (incidentFilterExpression) {\n const layers = iconFilters ? this.getNonSymbolLayers() : this.getLayers();\n applyFilter(incidentFilterExpression, layers, this.mapLibreMap, this.originalFilters);\n }\n } else if (this.config?.filters?.any?.length) {\n applyFilter(undefined, this.getLayers(), this.mapLibreMap, this.originalFilters);\n }\n if (iconFilters?.any?.length) {\n const iconFilterExpression = buildMapLibreIncidentFilters(iconFilters);\n if (iconFilterExpression) {\n applyFilter(iconFilterExpression, this.getSymbolLayers(), this.mapLibreMap, this.originalFilters);\n }\n }\n }\n\n // else: default incidents visibility has been set already if necessary\n if (updateConfig) {\n this.config = omitBy(\n {\n ...this.config,\n filters: incidentFilters,\n icons: { ...this.config?.icons, filters: iconFilters },\n },\n isNil,\n );\n }\n }\n\n private getLayers(): LayerSpecWithSource[] {\n return filterLayersBySources(this.tomtomMap.mapLibreMap, [TRAFFIC_INCIDENTS_SOURCE_ID]);\n }\n\n private getSymbolLayers(): LayerSpecWithSource[] {\n return this.getLayers().filter((layer) => layer.type === 'symbol');\n }\n\n private getNonSymbolLayers(): LayerSpecWithSource[] {\n return this.getLayers().filter((layer) => layer.type != 'symbol');\n }\n\n /**\n * Sets the visibility of incident icon layers.\n *\n * @param visible - `true` to show icons, `false` to hide them.\n *\n * @remarks\n * This controls only the icon/symbol layers, not the incident area polygons or lines.\n *\n * @example\n * ```typescript\n * // Hide icons but keep incident areas visible\n * incidents.setIconsVisible(false);\n *\n * // Show icons\n * incidents.setIconsVisible(true);\n * ```\n */\n setIconsVisible(visible: boolean): void {\n // We adjust the config for this change (but it might be overwritten if it's part of an \"applyConfig\" call)\n this.config = { ...this.config, icons: { ...this.config?.icons, visible } };\n\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficIncidents.setLayersVisible(\n visible,\n (layerSpec) => layerSpec.type === 'symbol',\n );\n }\n }\n\n /**\n * Sets the visibility of all traffic incident layers.\n *\n * @param visible - `true` to show incidents, `false` to hide them.\n *\n * @remarks\n * This controls all incident layers including icons, lines, and polygons.\n *\n * @example\n * ```typescript\n * incidents.setVisible(false); // Hide all incidents\n * incidents.setVisible(true); // Show all incidents\n * ```\n */\n setVisible(visible: boolean): void {\n this._setVisible(visible);\n }\n\n private _setVisible(visible: boolean, options?: { updateConfig: boolean }): void {\n const updateConfig = options?.updateConfig ?? true;\n if (updateConfig) {\n // setting all traffic visible also nullifies the icons visible setting\n delete this.config?.icons?.visible;\n // we remove empty values from config to avoid confusion (in case icons part is just empty after deleting visible)\n this.config = { ...omitBy({ ...this.config }, isEmpty), visible };\n }\n if (this.tomtomMap.mapReady) {\n this.sourcesWithLayers.trafficIncidents.setLayersVisible(visible);\n }\n }\n\n /**\n * Checks if any traffic incident layers are currently visible.\n *\n * @returns `true` if any incident layer is visible, `false` if all are hidden.\n *\n * @example\n * ```typescript\n * if (incidents.isVisible()) {\n * console.log('Incidents are displayed');\n * }\n * ```\n */\n isVisible(): boolean {\n return this.sourcesWithLayers.trafficIncidents.isAnyLayerVisible();\n }\n\n /**\n * Checks if any incident icon layers are currently visible.\n *\n * @returns `true` if any icon layer is visible, `false` if all icons are hidden.\n *\n * @example\n * ```typescript\n * if (incidents.anyIconLayersVisible()) {\n * console.log('Incident icons are shown');\n * }\n * ```\n */\n anyIconLayersVisible(): boolean {\n return !!this.sourcesWithLayers.trafficIncidents?.isAnyLayerVisible((layerSpec) => layerSpec.type === 'symbol');\n }\n\n /**\n * Create the events on/off for this module\n * @returns An instance of EventsModule\n */\n get events() {\n return new EventsModule(\n this.tomtomMap._eventsProxy,\n this.sourcesWithLayers.trafficIncidents,\n this.config?.events,\n );\n }\n}\n","import type { BBox } from '@tomtom-org/maps-sdk/core';\nimport type { Position } from 'geojson';\nimport type { Map } from 'maplibre-gl';\nimport type { TomTomMap } from '../TomTomMap';\nimport type {\n CalculateFittingBBoxOptions,\n CalculateMapBoundsOptions,\n CalculateMapCenterOptions,\n} from './types/paddedBounds';\n\n// (Originally mostly AI-generated)\n\ntype BoundsPX = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n};\n\nconst getRelativeElementBounds = (elementRect: DOMRect, containerRect: DOMRect): BoundsPX => ({\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n right: elementRect.right - containerRect.left,\n bottom: elementRect.bottom - containerRect.top,\n});\n\nconst isElementOutsideContainer = (bounds: BoundsPX, containerWidth: number, containerHeight: number): boolean =>\n bounds.right <= 0 || bounds.left >= containerWidth || bounds.bottom <= 0 || bounds.top >= containerHeight;\n\n// Adjusts the current visible bounds to account for a horizontal bar element (that spans the whole width)\nconst adjustForHorizontalBar = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerHeight: number,\n padding: number,\n): void => {\n const distanceFromTop = bounds.top;\n const distanceFromBottom = containerHeight - bounds.bottom;\n if (distanceFromTop <= distanceFromBottom) {\n currentVisible.top = Math.max(currentVisible.top, bounds.bottom + padding);\n } else {\n currentVisible.bottom = Math.min(currentVisible.bottom, bounds.top - padding);\n }\n};\n\n// Adjusts the current visible bounds to account for a vertical bar element (that spans the whole height)\nconst adjustForVerticalBar = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerWidth: number,\n padding: number,\n): void => {\n const distanceFromLeft = bounds.left;\n const distanceFromRight = containerWidth - bounds.right;\n if (distanceFromLeft <= distanceFromRight) {\n currentVisible.left = Math.max(currentVisible.left, bounds.right + padding);\n } else {\n currentVisible.right = Math.min(currentVisible.right, bounds.left - padding);\n }\n};\n\n// Adjusts the current visible bounds to account for a floating element (that does not span full width or height)\nconst adjustForFloatingElement = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n containerWidth: number,\n containerHeight: number,\n padding: number,\n): void => {\n const distanceFromLeft = bounds.left;\n const distanceFromRight = containerWidth - bounds.right;\n const distanceFromTop = bounds.top;\n const distanceFromBottom = containerHeight - bounds.bottom;\n const minDistance = Math.min(distanceFromLeft, distanceFromRight, distanceFromTop, distanceFromBottom);\n\n if (minDistance === distanceFromLeft) {\n currentVisible.left = Math.max(currentVisible.left, bounds.right + padding);\n } else if (minDistance === distanceFromRight) {\n currentVisible.right = Math.min(currentVisible.right, bounds.left - padding);\n } else if (minDistance === distanceFromTop) {\n currentVisible.top = Math.max(currentVisible.top, bounds.bottom + padding);\n } else {\n currentVisible.bottom = Math.min(currentVisible.bottom, bounds.top - padding);\n }\n};\n\n/**\n * Clamps the element bounds to the container boundaries.\n * This handles cases where UI elements extend beyond the visible container\n * (e.g., a sidebar that goes past the screen edge).\n */\nconst clampBoundsToContainer = (bounds: BoundsPX, containerWidth: number, containerHeight: number): BoundsPX => ({\n left: Math.max(0, bounds.left),\n top: Math.max(0, bounds.top),\n right: Math.min(containerWidth, bounds.right),\n bottom: Math.min(containerHeight, bounds.bottom),\n});\n\nconst adjustVisibleBoundsForElement = (\n bounds: BoundsPX,\n currentVisible: BoundsPX, // will be mutated\n mapWidthPX: number,\n mapHeightPX: number,\n padding: number,\n): void => {\n // Clamp bounds to container to handle elements that extend beyond the screen\n const clampedBounds = clampBoundsToContainer(bounds, mapWidthPX, mapHeightPX);\n\n // Determine if the element touches or extends beyond the full width or height of the container\n // An element \"spans full width\" if it touches both left and right edges (or extends beyond)\n const spansFullWidth = bounds.left <= 0 && bounds.right >= mapWidthPX;\n const spansFullHeight = bounds.top <= 0 && bounds.bottom >= mapHeightPX;\n\n // For elements spanning full width (horizontal bars), only consider vertical adjustment\n if (spansFullWidth && !spansFullHeight) {\n adjustForHorizontalBar(clampedBounds, currentVisible, mapHeightPX, padding);\n return;\n }\n\n // For elements spanning full height (vertical bars), only consider horizontal adjustment\n if (spansFullHeight && !spansFullWidth) {\n adjustForVerticalBar(clampedBounds, currentVisible, mapWidthPX, padding);\n return;\n }\n\n // Check if element touches/extends beyond an edge (makes it act like a bar on that side)\n const touchesLeft = bounds.left <= 0;\n const touchesRight = bounds.right >= mapWidthPX;\n const touchesTop = bounds.top <= 0;\n const touchesBottom = bounds.bottom >= mapHeightPX;\n\n // If element touches opposite edges in one dimension but not the other,\n // treat it as a bar in that dimension\n if ((touchesLeft || touchesRight) && !touchesTop && !touchesBottom) {\n // Element extends horizontally but not vertically - treat as horizontal bar\n adjustForHorizontalBar(clampedBounds, currentVisible, mapHeightPX, padding);\n return;\n }\n if ((touchesTop || touchesBottom) && !touchesLeft && !touchesRight) {\n // Element extends vertically but not horizontally - treat as vertical bar\n adjustForVerticalBar(clampedBounds, currentVisible, mapWidthPX, padding);\n return;\n }\n\n // For corner elements (touching edges in both dimensions) or floating elements\n // determine the best adjustment based on which edge the element is closest to\n adjustForFloatingElement(clampedBounds, currentVisible, mapWidthPX, mapHeightPX, padding);\n};\n\n/**\n * Resolves a surrounding element reference to an HTMLElement.\n * If the reference is a string, it's treated as a DOM selector.\n * @param ref - Either an HTMLElement or a DOM selector string\n * @returns The resolved HTMLElement, or null if not found\n */\nconst toElement = (ref: HTMLElement | string): HTMLElement | null => {\n if (typeof ref === 'string') {\n return document.querySelector(ref);\n }\n return ref;\n};\n\n/**\n * Resolves a map reference to a MapLibre Map instance.\n * If the reference is a TomTomMap, it extracts the underlying mapLibreMap.\n * @param map - Either a TomTomMap or a MapLibre Map instance\n * @returns The MapLibre Map instance\n */\nconst getMapLibreMap = (map: TomTomMap | Map): Map => {\n if ('mapLibreMap' in map) {\n return map.mapLibreMap;\n }\n return map;\n};\n\ntype VisibleAreaResult = {\n visibleAreaBounds: BoundsPX;\n mapWidthPX: number;\n mapHeightPX: number;\n} | null;\n\n/**\n * Calculates the visible area bounds in pixel coordinates after accounting for\n * surrounding UI elements and padding.\n */\nconst calculateVisibleAreaBounds = (\n map: TomTomMap | Map,\n surroundingElements: (HTMLElement | string)[],\n paddingPX: number,\n): VisibleAreaResult => {\n const containerRect = getMapLibreMap(map).getContainer().getBoundingClientRect();\n const { width: mapWidthPX, height: mapHeightPX } = containerRect;\n\n // Initialize visible bounds with padding applied to all edges (will be mutated)\n const visibleAreaBounds: BoundsPX = {\n left: paddingPX,\n top: paddingPX,\n right: mapWidthPX - paddingPX,\n bottom: mapHeightPX - paddingPX,\n };\n\n for (const elementRef of surroundingElements) {\n const element = toElement(elementRef);\n if (!element) {\n continue;\n }\n const elementRect = element.getBoundingClientRect();\n const elementBounds = getRelativeElementBounds(elementRect, containerRect);\n\n if (isElementOutsideContainer(elementBounds, mapWidthPX, mapHeightPX)) {\n continue;\n }\n\n adjustVisibleBoundsForElement(elementBounds, visibleAreaBounds, mapWidthPX, mapHeightPX, paddingPX);\n }\n\n if (visibleAreaBounds.left >= visibleAreaBounds.right || visibleAreaBounds.top >= visibleAreaBounds.bottom) {\n return null;\n }\n\n return { visibleAreaBounds, mapWidthPX, mapHeightPX };\n};\n\n/**\n * Calculates the bounding box in lng-lat coordinates of the visible map area\n * that does not overlap with the given UI HTML elements.\n *\n * @remarks\n * This is useful for determining the area of the map that is not obscured by UI components.\n *\n * @param options - The options for calculating map bounds\n * @returns The padded bounding box as [west, south, east, north], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculatePaddedBBox = (options: CalculateMapBoundsOptions): BBox | null => {\n const { map, surroundingElements, paddingPX = 0 } = options;\n\n const result = calculateVisibleAreaBounds(map, surroundingElements, paddingPX);\n if (!result) {\n return null;\n }\n\n const { visibleAreaBounds } = result;\n const mapLibreMap = getMapLibreMap(map);\n const sw = mapLibreMap.unproject([visibleAreaBounds.left, visibleAreaBounds.bottom]);\n const ne = mapLibreMap.unproject([visibleAreaBounds.right, visibleAreaBounds.top]);\n\n return [sw.lng, sw.lat, ne.lng, ne.lat];\n};\n\n/**\n * Calculates the center point in lng-lat coordinates of the visible map area\n * that does not overlap with the given UI HTML elements.\n *\n * @remarks\n * * This is useful to offset the map center in a way that it looks harmonious with surrounding UI components.\n * * It's equivalent to the center of calculatePaddedBBox.\n *\n * @param options - The options for calculating map center\n * @returns The center as [lng, lat], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculatePaddedCenter = (options: CalculateMapCenterOptions): Position | null => {\n const { map, surroundingElements } = options;\n const bbox = calculatePaddedBBox({ map, surroundingElements });\n if (!bbox) {\n return null;\n }\n const [west, south, east, north] = bbox;\n return [(west + east) / 2, (south + north) / 2];\n};\n\n/**\n * Calculates an expanded bounding box that, when the map is zoomed to it, ensures that the given to-be-contained bounding box\n * is visible within the area not obscured by surrounding UI elements, including optional padding.\n * * In other words, calculates a bounding box that ensure the to-be-contained bbox fits within the visible area of the map.\n *\n * @remarks\n * This is useful when you have a specific geographic area (containedBBox) that you want to be fully visible\n * in the unobscured portion of the map (the area not covered by UI components).\n * The function returns a larger bounding box that accounts for the space taken by UI elements.\n *\n * @param options - The options for calculating expanded bounds\n * @returns The expanded bounding box as [west, south, east, north], or null if the visible area is too small\n *\n * @group Utils\n */\nexport const calculateFittingBBox = (options: CalculateFittingBBoxOptions): BBox | null => {\n const { map, toBeContainedBBox, surroundingElements, paddingPX = 0 } = options;\n\n const result = calculateVisibleAreaBounds(map, surroundingElements, paddingPX);\n if (!result) {\n return null;\n }\n\n const { visibleAreaBounds, mapWidthPX, mapHeightPX } = result;\n\n // Calculate the ratios of how much the visible area is offset from the full container\n // These represent what fraction of the full map the visible area occupies\n const leftRatio = visibleAreaBounds.left / mapWidthPX;\n const rightRatio = visibleAreaBounds.right / mapWidthPX;\n const topRatio = visibleAreaBounds.top / mapHeightPX;\n const bottomRatio = visibleAreaBounds.bottom / mapHeightPX;\n\n // Calculate the width and height ratios of the visible area\n const widthRatio = rightRatio - leftRatio;\n const heightRatio = bottomRatio - topRatio;\n\n // Target bbox coordinates\n const [west, south, east, north] = toBeContainedBBox;\n const targetWidth = east - west;\n const targetHeight = north - south;\n\n // Calculate the full map extent needed so that when cropped by the visible area,\n // the target bbox fits exactly\n const fullWidth = targetWidth / widthRatio;\n const fullHeight = targetHeight / heightRatio;\n\n // Calculate the fitting expanded bounds\n // The visible area starts at leftRatio of the full width, so we need to extend west\n const expandedWest = west - leftRatio * fullWidth;\n const expandedEast = expandedWest + fullWidth;\n\n // For latitude, remember that in pixel coordinates, top is smaller Y but higher latitude\n // topRatio represents the fraction from top, which corresponds to north\n const expandedNorth = north + topRatio * fullHeight;\n const expandedSouth = expandedNorth - fullHeight;\n\n return [expandedWest, expandedSouth, expandedEast, expandedNorth];\n};\n"],"names":["freeGlobal","global","Object","freeSelf","self","root","Function","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","baseGetTag","value","isOwn","call","tag","unmasked","e","result","getRawTag","objectToString","isObjectLike","isSymbol","arrayMap","array","iteratee","index","length","Array","isArray","symbolProto","symbolToString","baseToString","isObject","type","identity","isFunction","uid","coreJsData","maskSrcKey","exec","keys","IE_PROTO","funcToString","toSource","func","reIsHostCtor","funcProto","reIsNative","RegExp","replace","baseIsNative","test","getNative","object","key","getValue","WeakMap","nativeNow","Date","now","count","lastCalled","defineProperty","baseSetToString","string","configurable","enumerable","writable","setToString","stamp","remaining","arguments","apply","reIsUint","isIndex","baseAssignValue","eq","other","assignValue","objValue","nativeMax","Math","max","isLength","isArrayLike","isPrototype","Ctor","constructor","baseIsArguments","propertyIsEnumerable","isArguments","freeExports","exports","nodeType","freeModule","module","Buffer","isBuffer","typedArrayTags","baseUnary","freeProcess","process","nodeUtil","types","require","binding","nodeIsTypedArray","isTypedArray","arrayLikeKeys","inherited","isArr","isArg","isBuff","isType","skipIndexes","n","baseTimes","String","push","overArg","transform","arg","nativeKeys","baseKeys","baseKeysIn","nativeKeysIn","isProto","keysIn","reIsDeepProp","reIsPlainProp","isKey","nativeCreate","Hash","entries","this","clear","entry","set","assocIndexOf","__data__","size","has","get","data","splice","ListCache","pop","Map","getMapData","map","MapCache","hash","memoize","resolver","TypeError","memoized","args","cache","Cache","rePropName","reEscapeChar","stringToPath","memoizeCapped","charCodeAt","match","number","quote","subString","castPath","toKey","baseGet","path","arrayPush","values","offset","spreadableSymbol","isConcatSpreadable","isFlattenable","flatten","depth","predicate","isStrict","baseFlatten","getPrototype","getPrototypeOf","objectCtorString","Stack","pairs","LARGE_ARRAY_SIZE","stubArray","allocUnsafe","nativeGetSymbols","getOwnPropertySymbols","getSymbols","resIndex","arrayFilter","symbol","getSymbolsIn","baseGetAllKeys","keysFunc","symbolsFunc","getAllKeys","getAllKeysIn","DataView","Promise","Set","mapTag","promiseTag","setTag","weakMapTag","dataViewTag","dataViewCtorString","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","getTag","ArrayBuffer","resolve","ctorString","Uint8Array","cloneArrayBuffer","arrayBuffer","byteLength","reFlags","symbolValueOf","valueOf","initCloneByTag","isDeep","regexp","dataView","buffer","byteOffset","typedArray","cloneTypedArray","source","lastIndex","nodeIsMap","isMap","nodeIsSet","isSet","argsTag","funcTag","objectTag","cloneableTags","baseClone","bitmask","customizer","stack","input","initCloneArray","isFunc","slice","stacked","forEach","subValue","add","props","arrayEach","SetCache","arraySome","equalArrays","equalFunc","isPartial","arrLength","othLength","arrStacked","othStacked","seen","arrValue","othValue","compared","othIndex","mapToArray","setToArray","arrayTag","baseIsEqualDeep","objIsArr","othIsArr","objTag","othTag","objIsObj","othIsObj","isSameTag","name","message","convert","equalByTag","objIsWrapped","othIsWrapped","objUnwrapped","othUnwrapped","objProps","objLength","objStacked","skipCtor","objCtor","othCtor","equalObjects","baseIsEqual","isStrictComparable","matchesStrictComparable","srcValue","baseMatches","matchData","getMatchData","COMPARE_PARTIAL_FLAG","baseIsMatch","baseHasIn","hasIn","hasFunc","hasPath","baseMatchesProperty","defaultValue","property","basePropertyDeep","baseIteratee","parent","start","end","baseSlice","isEmpty","isEqual","isNil","baseUnset","isRootPrimitive","obj","last","customOmitClone","proto","isPlainObject","omit","otherArgs","thisArg","overRest","flatRest","paths","isNew","newValue","copyObject","CLONE_DEEP_FLAG","baseSet","nested","pickBy","prop","basePickBy","omitBy","negate","remove","indexes","previous","basePullAt","notInTheStyle","actionText","Error","isDOMImageSupported","document","DOMParser","btoa","svgToImg","svgDomElement","img","createElement","src","XMLSerializer","serializeToString","parseSvg","svgString","parseFromString","documentElement","pinSvg","options","element","fillColor","querySelector","setAttribute","outlineColor","outlineOpacity","asDefined","assertDefined","TomTomMapSource","id","spec","runtimeSource","ensureAddedToMap","getSource","addSource","AbstractSourceWithLayers","layerSpecs","_layerSpecs","_updateSourceAndLayerIDs","isAnyLayerVisible","filter","getLayerSpecs","some","layer","isLayerVisible","areAllLayersVisible","every","_sourceAndLayerIDs","sourceID","layerIDs","getLayoutProperty","setLayersVisible","visible","layerSpec","setLayoutProperty","validate","sourceAndLayerIDs","equalSourceAndLayerIDs","filterLayersBySources","loadedMap","sourceIDs","getStyle","layers","includes","StyleSourceWithLayers","super","sources","AddedSourceWithLayers","sourceId","sourceSpec","ensureLayersAddedToMap","getLayer","addLayer","beforeID","ensureAddedToMapWithVisibility","addLayersToMap","emptyFeatureCollection","features","GeoJSONSourceWithLayers","promoteId","shownFeatures","show","featureCollection","setData","findFeature","find","f","putEventState","mode","feature","properties","eventState","state","cleanEventState","cleanEventStates","changed","states","waitUntilMapIsReady","async","tomtomMap","mapReady","mapLibreMap","once","deserializeFeatures","JSON","parse","_e","changeLayerProps","newLayerProps","prevLayerProps","layerId","maxzoom","minzoom","setLayerZoomRange","getMinZoom","getMaxZoom","setFilter","layout","paint","setPaintProperty","changeLayersProps","layoutPaint","addLayers","layersToAdd","layerIdsAlreadyOnMap","visibility","mapIdDependency","idsWeCanProcess","console","error","stringify","updateStyleWithModule","style","styleModule","include","cannotAddStyleModuleToCustomStyle","ensureAddedToStyle","isStyleLoaded","setStyle","isSourceLoaded","waitUntilSourceIsLoaded","addOrUpdateImage","imageId","imageToLoad","warn","addOrUpdateToMap","imgElement","hasImage","addImage","ensureImageLoaded","complete","naturalWidth","onload","onerror","loadImage","getStandardStyleTheme","standardStyleID","getStyleLightDarkTheme","styleInput","standardStyle","AbstractMapModule","sourceType","config","_initializing","moduleReady","eventsProxy","_eventsProxy","initSourcesWithLayers","applyConfig","addStyleChangeHandler","onStyleAboutToChange","onStyleChanged","restoreDataAndConfig","restore","sourcesWithLayers","_initSourcesWithLayers","fromEntries","sourceWithLayers","updateIfRegistered","waitUntilModuleReady","interval","setInterval","clearInterval","_applyConfig","resetConfig","setTimeout","restoreDataAndConfigImpl","getConfig","EventsModule","eventProxy","on","handler","addEventHandler","off","AbstractEventProxy","interactiveLayerIDs","handlers","findHandlers","flatMap","sourceEventTypeHandlers","ensureInteractiveLayerIDsAdded","handlerFn","fn","matchesLayers","removeAll","hasSourceID","sourceHandlers","isHighPriority","eventType","featureId","featuresToUpdate","i","findFeatureById","updatedFeature","removeEventStateAndShow","newEventType","rawFeature","prevFeaturesToUpdate","updateEventState","eventFeature","prevEventFeature","prevSourceWithLayers","updatedIndex","featureB","featureA","eventsProxyDefaultConfig","precisionMode","paddingBoxPx","cursorOnHover","cursorOnMouseDown","cursorOnMap","longHoverDelayAfterMapMoveMS","longHoverDelayOnStillMapMS","EventsProxy","enabled","firstDelayedHoverSinceMapMove","mapCanvas","getCanvas","cursor","lastCursorStyle","listenToEvents","ev","onMouseMove","onMouseStart","onMouseOut","onMouseDown","onMouseUp","onMapClick","enable","clearLongHoverTimeout","toPaddedBounds","point","padding","x","y","isEnabled","isMoving","getRenderedFeatures","precision","renderedFeatures","queryRenderedFeatures","window","clearTimeout","longHoverTimeoutHandlerID","restartLongHoverTimeout","handleLongHoverTimeout","hoveringSourceWithLayers","hoveringFeature","hoveringLngLat","hoveringFeatures","hoveredTopFeature","hoverChanged","mouseInMotionOverHoveredFeature","hoveringPoint","prevHoveredPoint","prevHoveredFeature","detectHoverState","lngLat","prevHoveredSourceWithLayers","firstHandler","updateHoverCursor","hoverHandlers","clickType","clickedFeatures","prevClickedFeature","lastClickedFeature","prevClickedSourceWithLayers","lastClickedSourceWithLayers","clickHandlers","mapStyleLayerIDs","country","lowestPlaceLabel","poi","lowestLabel","lowestRoadLine","lowestBuilding","POI_SOURCE_ID","HILLSHADE_SOURCE_ID","BASE_MAP_SOURCE_ID","TRAFFIC_INCIDENTS_SOURCE_ID","TRAFFIC_FLOW_SOURCE_ID","poiLayerIDs","mapDisplayPoiCategoryMappings","ACCESS_GATEWAY","ADVENTURE_SPORTS_FACILITY","ADVENTURE_SPORTS_VENUE","AGRICULTURE","AIRPORT","AMUSEMENT_PARK","AQUATIC_ZOO","ASHRAM","ATM","AUTOMOTIVE_DEALER","BANK","BEACH","BUS_STOP","BUSINESS_PARK","CAFE_PUB","CAMPING_GROUND","CAR_WASH","CASH_DISPENSER","CASINO","CHURCH","CINEMA","CLOTHING_SHOP","CLUB_ASSOCIATION","COLLEGE_UNIVERSITY","COMMERCIAL_BUILDING","COMMUNITY_CENTER","COMPANY","CONCERT_HALL","COURTHOUSE","CULTURAL_CENTER","DENTIST","DEPARTMENT_STORE","DOCTOR","ELECTRIC_VEHICLE_STATION","EMBASSY","EMERGENCY_MEDICAL_SERVICE","EMERGENCY_ROOM","ENTERTAINMENT","EXCHANGE","EXHIBITION_CONVENTION_CENTER","FERRY_TERMINAL","FIRE_STATION_BRIGADE","FRONTIER_CROSSING","FUEL_FACILITIES","GAS_STATION","GEOGRAPHIC_FEATURE","GOLD_EXCHANGE","GOLF_COURSE","GOVERNMENT_OFFICE","GURUDWARA","HEALTH_CARE_SERVICE","HELIPAD_HELICOPTER_LANDING","HILL","HOLIDAY_RENTAL","HOSPITAL","HOSPITAL_POLYCLINIC","HOTEL_MOTEL","ICE_SKATING_RINK","IMPORTANT_TOURIST_ATTRACTION","INDUSTRIAL_BUILDING","LEISURE_CENTER","LIBRARY","MANUFACTURING_FACILITY","MARINA","MARKET","MEDIA_FACILITY","MILITARY_INSTALLATION","MOSQUE","MOTORING_ORGANIZATION_OFFICE","MOUNTAIN_PASS","MOUNTAIN_PEAK","MOVIE_THEATER","MUSEUM","NATIVE_RESERVATION","NIGHTLIFE","NON_GOVERNMENTAL_ORGANIZATION","OPEN_PARKING_AREA","OPERA_HOUSE","PAGODA","PARK_RECREATION_AREA","PARKING_GARAGE","PETROL_STATION","PHARMACY","PLACE_OF_WORSHIP","POLICE_STATION","PORT_WAREHOUSE_FACILITY","POST_OFFICE","PRIMARY_RESOURCE_UTILITY","PRISON_CORRECTIONAL_FACILITY","PUBLIC_AMENITY","PUBLIC_TRANSPORT_STOP","RAILWAY_STATION","RENT_A_CAR_FACILITY","RENT_A_CAR_PARKING","REPAIR_FACILITY","RESEARCH_FACILITY","RESIDENTIAL_ACCOMMODATION","REST_AREA","RESTAURANT","RESTAURANT_AREA","SCENIC_PANORAMIC_VIEW","SCHOOL","SHOP","SHOPPING_CENTER","SPORTS_CENTER","STADIUM","SUPERMARKETS_HYPERMARKETS","SWIMMING_POOL","SYNAGOG","TAXI_STAND","TEMPLE","TENNIS_COURT","THEATER","TOLL_GATE","TOURIST_INFORMATION_OFFICE","TRAFFIC_CONTROL_DEPARTMENT","TRAFFIC_SERVICE_CENTER","TRAIL_SYSTEM","TRAILS","TRANSPORT_AUTHORITY_VEHICLE_REGISTRATION","TRUCK_STOP","VACATION_RENTAL","VETERINARIAN","WATER_SPORT","WEIGH_STATION","WELFARE_ORGANIZATION","WINERY","ZOOS_ARBORETA_BOTANICAL_GARDEN","completeMapDisplayPoiCategoryMappings","SECURED_ENTRANCE","AGRICULTURAL_BUSINESS","FARM","HORTICULTURE","PRIMARY_PRODUCER","AIRFIELD","AIRLINE_ACCESS","MILITARY_AIRPORT","PRIVATE_AIRPORT","PUBLIC_AIRPORT","ATV_DEALER","BOAT_DEALER","BUS_DEALER","CAR_DEALER","MOTORCYCLE_DEALER","RECREATIONAL_VEHICLE_DEALER","TRUCK_DEALER","VAN_DEALER","DIVERSIFIED_FINANCIALS","SAVINGS_INSTITUTION","BEACH_CLUB","BAR","CAFE","COCKTAIL_BAR","COFFEE_SHOP","INTERNET_CAFE","PUB","TEA_HOUSE","WINE_BAR","CARAVAN_SITE","RECREATIONAL_CAMPING_GROUND","REST_CAMP","TRUCK_WASH","DRIVE_IN_MOVIES","CHILDRENS_CLOTHES","MENS_CLOTHING","SPECIALTY_CLOTHING_SHOP","WOMENS_CLOTHING","PRIVATE_CLUB","JUNIOR_COLLEGE_COMMUNITY_COLLEGE","BUILDING","ADVERTISING_COMPANY","AGRICULTURAL_TECHNOLOGY","AIRLINE_COMPANY","AUTOMOBILE_COMPANY","BUSINESS_SERVICES","BUS_CHARTER_COMPANY","CABLE_TELEPHONE_COMPANY","CLEANING_SERVICES","COMPUTER_DATA_SERVICES","CONSTRUCTION_COMPANY","DELIVERY_SERVICE","ELECTRONICS_COMPANY","EQUIPMENT_RENTAL","FUNERAL_SERVICE_MORTUARIES","IMPORT_EXPORT_AND_DISTRIBUTION","INSURANCE_COMPANY","INVESTMENT_ADVISOR","LEGAL_SERVICES","MINING_COMPANY","MOVING_STORAGE_COMPANY","OIL_NATURAL_GAS","PHARMACEUTICAL_COMPANY","PUBLIC_HEALTH_TECHNOLOGY_COMPANY","PUBLISHING_TECHNOLOGIES","REAL_ESTATE_AGENT","REAL_ESTATE_COMPANY","SERVICE_COMPANY","SOFTWARE_COMPANY","TAX_SERVICES","TELECOMMUNICATIONS","TRANSPORT_COMPANY","TRAVEL_AGENT","WEDDING_SERVICES","GENERAL_PRACTITIONER","SPECIALIST","RIDGE","AMBULANCE_UNIT","ROAD_RESCUE","AMUSEMENT_ARCADE","AMUSEMENT_PLACE","BETTING_STATION","FAIRGROUND","MUSIC_CENTER","CHECKPOINT","BAY","BRIDGE","BRIDGE_TUNNEL_OPERATIONS","CAPE","COVE","DAM","DUNE","ISLAND","LAGOON","LAKESHORE","LOCALE","MARSH","OASIS","PAN","PARKWAY","PLAIN_FLAT","PLATEAU","RAPIDS","REEF","RESERVOIR","RIVER_CROSSING","RIVER_SCENIC_AREA","ROCKS","SEASHORE","TUNNEL","VALLEY","WATER_HOLE","WELL","BUNGALOW_RENTAL","CABINS_LODGES","CHALET_RENTAL","COTTAGE_RENTAL","VILLA_RENTAL","BLOOD_BANK","HOSPITAL_FOR_WOMEN_AND_CHILDREN","HOSPITAL_OF_CHINESE_MEDICINE","SPECIAL_HOSPITAL","B_B_GUEST_HOUSE","HOSTEL","HOTEL","MOTEL","RESORT","QUARRY","AUTOMOBILE_MANUFACTURING","CHEMICAL_COMPANY","MANUFACTURING_COMPANY","MECHANICAL_ENGINEERING","MICROBREWERY","OEM","BOAT_LAUNCHING_RAMP","HARBOR","YACHT_BASIN","FARMERS_MARKET","FOOD_MARKET","INFORMAL_MARKET","PUBLIC_MARKET","PLANETARIUM","CABARET_THEATER","COMEDY_CLUB","DISCO_CLUB","JAZZ_CLUB","KARAOKE_CLUB","FISHING_HUNTING_AREA","FOREST_AREA","HISTORICAL_PARK","NATURAL_RECREATION_ATTRACTION","PARK","PICNIC_AREA","PRESERVE","RECREATION_AREA","WILDERNESS_AREA","OPEN_CAR_PARKING_AREA","DRUG_STORE","MARIJUANA_DISPENSARY","MEDICINAL_MARIJUANA_DISPENSARY","RECREATIONAL_MARIJUANA_DISPENSARY","COURIER_DROP_BOX","LOCAL_POST_OFFICE","PUBLIC_CALL_BOX","PUBLIC_TOILET","BUS_LINES","COACH_STOP","PASSENGER_TRANSPORT_TICKET_OFFICE","PEDESTRIAN_SUBWAY","STREETCAR_STOP","SUBWAY_STATION","INTERNATIONAL_RAILROAD_STATION","NATIONAL_RAILROAD_STATION","RAILROAD_SIDING","STATION_ACCESS","URBAN_STATION","BODYSHOP","CAR_GLASS_REPLACEMENT_SHOP","CAR_REPAIR_AND_SERVICE","HOME_APPLIANCE_REPAIR","MOTORCYCLE_REPAIR","OTHER_REPAIR_SHOPS","REPAIR_SHOP","TIRE_SERVICE","TRUCK_REPAIR_AND_SERVICE","AFGHAN_RESTAURANT","AFRICAN_RESTAURANT","ALGERIAN_RESTAURANT","AMERICAN_RESTAURANT","ARABIAN_RESTAURANT","ARGENTINIAN_RESTAURANT","ARMENIAN_RESTAURANT","ASIAN_RESTAURANT","AUSTRALIAN_RESTAURANT","AUSTRIAN_RESTAURANT","BANQUET_ROOMS","BARBECUE_RESTAURANT","BASQUE_RESTAURANT","BELGIAN_RESTAURANT","BISTRO","BOLIVIAN_RESTAURANT","BOSNIAN_RESTAURANT","BRAZILIAN_RESTAURANT","BRITISH_RESTAURANT","BUFFET_RESTAURANT","BULGARIAN_RESTAURANT","BURMESE_RESTAURANT","CAFETERIA","CALIFORNIAN_RESTAURANT","CAMBODIAN_RESTAURANT","CANADIAN_RESTAURANT","CARIBBEAN_RESTAURANT","CATERING_SERVICES","CHICKEN_RESTAURANT","CHILEAN_RESTAURANT","CHINESE_RESTAURANT","COLOMBIAN_RESTAURANT","CORSICAN_RESTAURANT","CREOLE_RESTAURANT","CREPERIE","CUBAN_RESTAURANT","CYPRIOT_RESTAURANT","CZECH_RESTAURANT","DANISH_RESTAURANT","DINNER_THEATER","DOMINICAN_RESTAURANT","DONGBEI_RESTAURANT","DOUGHNUT_RESTAURANT","DUTCH_RESTAURANT","EGYPTIAN_RESTAURANT","ENGLISH_RESTAURANT","EROTIC_RESTAURANT","ETHIOPIAN_RESTAURANT","EXOTIC_RESTAURANT","FAST_FOOD","FINNISH_RESTAURANT","FONDUE_RESTAURANT","FRENCH_RESTAURANT","FUSION_RESTAURANT","GERMAN_RESTAURANT","GREEK_RESTAURANT","GRILL_RESTAURANT","GUANGDONG_RESTAURANT","HAMBURGER_RESTAURANT","HAWAIIAN_RESTAURANT","HOT_POT_RESTAURANT","HUNAN_RESTAURANT","HUNGARIAN_RESTAURANT","ICE_CREAM_PARLOR","INDIAN_RESTAURANT","INDONESIAN_RESTAURANT","INTERNATIONAL_RESTAURANT","IRANIAN_RESTAURANT","IRISH_RESTAURANT","ISRAELI_RESTAURANT","ITALIAN_RESTAURANT","JAMAICAN_RESTAURANT","JAPANESE_RESTAURANT","JEWISH_RESTAURANT","KOREAN_RESTAURANT","KOSHER_RESTAURANT","LATIN_AMERICAN_RESTAURANT","LEBANESE_RESTAURANT","LUXEMBOURGIAN_RESTAURANT","MACROBIOTIC_RESTAURANT","MAGHRIB_RESTAURANT","MALTESE_RESTAURANT","MAURITIAN_RESTAURANT","MEDITERRANEAN_RESTAURANT","MEXICAN_RESTAURANT","MIDDLE_EASTERN_RESTAURANT","MONGOLIAN_RESTAURANT","MOROCCAN_RESTAURANT","MUSSELS_RESTAURANT","NEPALESE_RESTAURANT","NORWEGIAN_RESTAURANT","ORGANIC_FOOD_RESTAURANT","ORIENTAL_RESTAURANT","PAKISTANI_RESTAURANT","PERUVIAN_RESTAURANT","PHILIPPINE_RESTAURANT","PIZZERIA","POLISH_RESTAURANT","POLYNESIAN_RESTAURANT","PORTUGUESE_RESTAURANT","PROVENCAL_RESTAURANT","PUB_FOOD","ROADSIDE_RESTAURANT","ROMANIAN_RESTAURANT","RUSSIAN_RESTAURANT","SALAD_BAR","SANDWICH_RESTAURANT","SAVOY_RESTAURANT","SCANDINAVIAN_RESTAURANT","SCOTTISH_RESTAURANT","SEAFOOD","SHANDONG_RESTAURANT","SHANGHAI_RESTAURANT","SICHUAN_RESTAURANT","SICILIAN_RESTAURANT","SLAVIC_RESTAURANT","SLOVAK_RESTAURANT","SNACKS_RESTAURANT","SOUL_FOOD","SOUP_RESTAURANT","SPANISH_RESTAURANT","STEAK_HOUSE","SUDANESE_RESTAURANT","SURINAMESE_RESTAURANT","SUSHI_RESTAURANT","SWEDISH_RESTAURANT","SWISS_RESTAURANT","SYRIAN_RESTAURANT","TAIWANESE_RESTAURANT","TAKEOUT_FOOD","TAPAS_RESTAURANT","TEPPANYAKI_RESTAURANT","THAI_RESTAURANT","TIBETAN_RESTAURANT","TUNISIAN_RESTAURANT","TURKISH_RESTAURANT","URUGUAYAN_RESTAURANT","VEGETARIAN_RESTAURANT","VENEZUELAN_RESTAURANT","VIETNAMESE_RESTAURANT","WELSH_RESTAURANT","WESTERN_RESTAURANT","YOGURT_JUICE_BAR","ART_SCHOOL","CHILD_CARE_FACILITY","CULINARY_SCHOOL","DANCE_STUDIO_SCHOOL","DRIVING_SCHOOL","HIGH_SCHOOL","LANGUAGE_SCHOOL","MIDDLE_SCHOOL","PRE_SCHOOL","PRIMARY_SCHOOL","SENIOR_HIGH_SCHOOL","SPECIAL_SCHOOL","SPORT_SCHOOL","TECHNICAL_SCHOOL","VOCATIONAL_SCHOOL","AGRICULTURAL_SUPPLIES","ANTIQUE_ART_SHOP","BAGS_LEATHERWEAR","BAKERY","BEAUTY_SALON","BEAUTY_SUPPLIES","BOATING_EQUIPMENT_ACCESSORIES","BOOK_SHOP","BUTCHER","CAMERAS_PHOTOGRAPHY","CARPET_FLOOR_COVERINGS","CAR_ACCESSORIES","CHRISTMAS_HOLIDAY_SHOP","COMPUTER_COMPUTER_SUPPLIES","CONSTRUCTION_MATERIAL_EQUIPMENT","CONSUMER_ELECTRONICS","CONVENIENCE_STORE","CURTAINS_TEXTILES","C_DS_DVD_VIDEOS","DELICATESSEN","DO_IT_YOURSELF_CENTERS","DRIVE_THROUGH_BOTTLE_SHOP","DRY_CLEANER","ELECTRICAL_APPLIANCES_SHOP","FACTORY_OUTLET","FISHMONGER","FLORISTS","FOOTWEAR_SHOE_REPAIRS","FURNITURE_HOME_FURNISHINGS","GARDEN_CENTERS_SERVICES","GIFTS_CARDS_NOVELTIES_SOUVENIRS","GLASSWARE_CERAMIC_SHOP","GLASS_WINDOWS_STORE","GREENGROCER","GROCERY_STORE","HAIRDRESSER","HARDWARE_STORE","HOBBY_SHOP","HOUSE_GARDEN_FURNITURE_FITTINGS","JEWELRY_CLOCKS_WATCHES","KITCHENS_BATHROOMS","LAUNDRY","LIGHTING_SHOPS","LOCAL_SPECIALITIES_SHOP","LOTTERY_SHOP","MARINE_ELECTRONIC_EQUIPMENT","MEDICAL_SUPPLIES_EQUIPMENT","MOBILE_PHONE_SHOP","MUSIC_INSTRUMENTS_STORE","NAIL_SALON","NEWSAGENTS_TOBACCONISTS","OFFICE_EQUIPMENT","OPTICIAN","OTHER_FOOD_SHOPS","PAINTING_DECORATING","PAWN_SHOP","PERSONAL_CARE_FACILITY","PERSONAL_SERVICE","PET_SUPPLIES","PHOTOCOPY_SHOP","PHOTO_LAB_DEVELOPMENT","RECYCLING_SHOP","RETAIL_OUTLET","SAUNA_SOLARIUM_MASSAGE","SECURITY_PRODUCTS","SHOPPING_SERVICE","SPECIALTY_FOODS","SPORTS_EQUIPMENT_CLOTHING","STAMP_SHOP","TAILOR_SHOP","TOYS_GAMES_SHOP","VARIETY_STORE","VIDEO_RENTAL_SHOP","WHOLESALE_CLUB","WINE_SPIRITS","ATHLETICS_TRACK","BASEBALL_PARK","BASKETBALL_ARENA","BOWLING_CENTER","CRICKET_GROUND","FITNESS_CLUB_CENTER","FLYING_CLUB","HOCKEY_CLUB","HORSE_RACING_TRACK","HORSE_RIDING_CENTER","ICE_HOCKEY_ARENA","OTHER_WINTER_SPORT","RACE_TRACK","RUGBY_GROUND","SKI_RESORT","SNOOKER_POOL_BILLIARD","THEMATIC_SPORT_CENTER","FOOTBALL_STADIUM","MOTOR_RACING_STADIUM","MULTI_PURPOSE_STADIUM","NETBALL_STADIUM","SOCCER_STADIUM","STOCK_EXCHANGE","TAXI_LIMOUSINE_SHUTTLE_SERVICE","AMPHITHEATER","ARCH","BATTLEFIELD","CAVE","CEMETERY","HISTORIC_SITE","MAUSOLEUM_GRAVE","MEMORIAL","MINERAL_HOT_SPRINGS","MONUMENT","NATURAL_TOURIST_ATTRACTION","OBSERVATORY","STATUE","TOURIST_ATTRACTION","TOWER","ROAD_TRAFFIC_CONTROL_CENTER","ADVENTURE_VEHICLE_TRAIL","HIKING_TRAIL","HORSE_RIDING_TRAIL","MOUNTAIN_BIKE_TRAIL","ROCK_CLIMBING_TRAIL","APARTMENT_RENTAL","CONDOMINIUM_COMPLEX","FLATS_APARTMENT_COMPLEX","RESIDENTIAL_ESTATE","RETIREMENT_COMMUNITY","TOWNHOUSE_COMPLEX","ANIMAL_SERVICES","ANIMAL_SHELTER","WEIGH_SCALES","WILDLIFE_PARK","ZOO","toBaseMapPOICategory","category","MAP_BOLD_FONT","DEFAULT_MAX_PIN_SCALE","TITLE","ICON_ID","DEFAULT_TEXT_OFFSET_Y","DEFAULT_TEXT_OFFSET_X","DEFAULT_PLACE_ICON_ID","pinIconBaseLayout","pinIconBasePaint","pinTextBaseLayout","pinTextBasePaint","pinLayerBaseSpec","suffixNumber","text","numberToSuffix","calculateIconScale","image","theme","dimensions","svgElement","viewBox","getAttribute","parts","split","width","Number","parseFloat","height","naturalHeight","extractImageDimensions","heightScale","widthScale","hasChargingAvailability","chargingPark","Boolean","availability","isEVStationWithAvailability","place","classifications","code","getChargingPointAvailability","chargingPointAvailability","available","statusCounts","Available","availableCount","totalCount","ratio","defaultFormatAvailabilityText","total","getAvailabilityRatio","getAvailabilityColorExpression","threshold","buildAnchorOffsets","topOffset","sideOffset","pinVerticalAdjustment","customTextOffset","hasCustomOffset","top","left","right","getTextOffset","iconSizeExpression","iconTextOffsetScales","iconScaleMultiplier","expression","lastValue","at","extractMaxIconScale","isBaseMapTheme","fallbackSideOffset","fallbackOffsets","fallbackAnchorOffset","offsetCaseExpression","iconId","scales","offsets","buildLayoutConfig","layerName","textField","textConfig","customLayer","hasCustomIcons","baseLayout","font","iconSize","assign","buildPaintConfig","lightDark","textColor","baseTextColor","haloColor","baseHaloColor","getThemeAdaptiveTextColors","color","haloWidth","isClickEventState","getTextSizeSpec","textSize","replaceAll","hasEventState","SELECTED_COLOR","pinLayerSpec","selectedPinLayerSpec","withConfig","textFieldExpression","evAvailabilityEnabled","evAvailability","buildTextFieldExpression","title","buildPlacesLayerSpecs","styleLightDarkTheme","instanceIndex","customIcons","icon","categoryIcons","suffixedIconId","availabilityLevel","availabilitySuffixedId","buildCustomIconScalesMap","main","selected","poiLikeLayerSpec","poiLayer","buildPoiLikeLayerSpec","additional","defaultPin","supportedPinSubcategories","buildPlaceTitle","address","freeformAddress","toImageID","poiCategory","iconTheme","defaultPlaceIconID","categoryID","substring","toPinImageID","poiCategoriesToID","imageID","getIconIDForPlace","imageMapping","mapping","to","evAvailabilityIconID","requiredLevel","customIconWithAvailability","customIcon","getEVAvailabilityIconID","matchingCustomIcon","getPOILayerCategoryForPlace","toPlaces","places","mergeEVAvailabilityProps","extraFeatureProps","evAvailabilityConfig","hasEVStations","hasEVStationsWithAvailability","evAvailabilityText","formatText","buildAvailabilityText","evAvailabilityRatio","preparePlacesForDisplay","placesInput","mergedExtraFeatureProps","generateId","geometry","bbox","iconID","_PlacesModule","lastInstanceIndex","layerIDPrefix","buildLayerSpecs","layerSpecTemplates","updateLayersAndData","previousShownFeatures","applyTheme","applyConfigPart","applyIconConfig","iconConfig","applyTextConfig","partialConfig","applyExtraFeatureProps","updateData","setupImages","newLayerSpecs","newLayerSpecsArray","oldLayerSpecsArray","pixelRatio","default","events","PlacesModule","isExpressionFilter","getMergedAnyFilter","filters","legacy","getMergedAllFilter","filterToAdd","originalFilter","buildMappedValuesFilter","propName","showMode","comparator","filterArrayNew","buildValuesFilter","valuesMapping","poiCategoryGroups","FOOD_DRINKS_GROUP","SHOPPING_GROUP","TRANSPORTATION_GROUP","HEALTH_GROUP","PARKING_GROUP","HOLIDAY_TOURISM_GROUP","EV_CHARGING_STATIONS_GROUP","GAS_STATIONS_GROUP","ACCOMMODATION_GROUP","ENTERTAINMENT_GROUP","SPORTS_LEISURE_GROUP","EDUCATION_GROUP","GOVERNMENT_GROUP","getStyleCategories","categories","categoryIds","POIsModule","poiRuntimeSource","mainLayer","getFilter","setVisible","isVisible","filterCategories","categoriesFilter","poiFilter","layerGroupMappings","land","layerIDMatches","layerTypes","borders","water","buildings2D","buildings3D","houseNumbers","roadLines","roadLabels","roadShields","placeLabels","smallerTownLabels","cityLabels","capitalLabels","stateLabels","countryLabels","isMatching","group","part","toLowerCase","buildBaseMapLayerGroupFilter","layerGroupsFilter","layerGroups","groups","names","filterLayerByGroups","BaseMapModule","vectorTiles","layerGroupsVisibility","buildLayerGroupFilter","baseMapLayerGroupNames","GEOMETRY_TITLE_PROP","GEOMETRY_COLOR_PROP","colorPalettes","warm","browns","cold","fadedBlues","blues","greens","fadedGreenToBlue","blueToRed","greenToYellow","pastel","retro","contrastRetro","fadedRainbow","pastelRainbow","defaultColor","geometryFillSpec","geometryOutlineSpec","buildGeometryLayerSpecs","fillLayerId","outlineLayerId","colorConfig","lineConfig","fillOpacity","lineColor","lineWidth","lineOpacity","buildGeometryTitleLayerSpec","prepareGeometryForDisplay","buildTitle","palette","buildColor","prepareTitleForDisplay","geometries","coordinates","placeCoordinates","biggestPolygon","flat","reduce","coord","getLongestArray","bboxFromCoordsArray","bboxCenter","_GeometriesModule","titleSourceID","layerIdPrefix","fillLayerID","outlineLayerID","titleLayerID","titleLayerSpec","titleLayerSpecs","geometryFillLayerSpecs","geometryOutlineLayerSpecs","geometryLabel","updateLayerAndData","beforeLayerConfig","moveBeforeLayer","moveBeforeLayerID","beforeLayerId","moveLayer","layerConfig","newTitleLayerSpecs","GeometriesModule","HillshadeModule","hillshadeSource","hillshade","standardStyleIDs","styleModules","ROUTE_LINE_FOREGROUND_COLOR","ROUTE_LINE_OUTLINE_COLOR","DESELECTED_FOREGROUND_COLOR","DESELECTED_OUTLINE_COLOR","DESELECTED_SECONDARY_COLOR","ROUTE_LINE_FOREGROUND_WIDTH","SELECTED_ROUTE_FILTER","DESELECTED_ROUTE_FILTER","MAJOR_DELAY_COLOR","MODERATE_DELAY_COLOR","MINOR_DELAY_LABEL_COLOR","UNKNOWN_DELAY_COLOR","chargingStopTextField","chargingStopSymbol","commonProps","commonLineProps","instructionOutline","instructionLine","INSTRUCTION_ARROW_IMAGE_ID","instructionArrow","routeFerriesLine","routeFerriesSymbol","routeLineBaseTemplate","outlineLineWidth","routeDeselectedOutline","routeDeselectedLine","routeOutline","routeLineArrows","SELECTED_SUMMARY_POPUP_IMAGE_ID","DESELECTED_SUMMARY_POPUP_IMAGE_ID","routeTollRoadsOutline","routeTollRoadsSymbol","EXTRA_FOREGROUND_LINE_WIDTH","routeIncidentsBGLine","routeIncidentsDashedLine","magnitudeOfDelayTextColor","routeIncidentsSymbolBase","routeIncidentsJamSymbol","routeIncidentsCauseSymbol","routeTunnelsLine","routeVehicleRestrictedBackgroundLine","routeVehicleRestrictedDottedLine","TRAFFIC_CLEAR_IMAGE_ID","TRAFFIC_MAJOR_IMAGE_ID","TRAFFIC_MODERATE_IMAGE_ID","TRAFFIC_MINOR_IMAGE_ID","hasFormattedTraffic","buildSummaryBubbleSymbolPoint","selectedImageID","deselectedImageID","trafficClearID","trafficMajorID","trafficModerateID","trafficMinorID","summaryBubbleSymbolPoint","START_INDEX","MIDDLE_INDEX","FINISH_INDEX","INDEX_TYPE","STOP_DISPLAY_INDEX","WAYPOINT_START_IMAGE_ID","WAYPOINT_STOP_IMAGE_ID","WAYPOINT_SOFT_IMAGE_ID","WAYPOINT_FINISH_IMAGE_ID","pinIndexLabelLayout","waypointSymbols","waypointLabels","prefixBeforeID","startsWith","prefixBeforeIDs","suffixImageID","buildRoutingLayers","configLayers","configSectionLayers","sections","mainColor","mainLines","routeLine","waypoints","routeWaypointSymbol","routeWaypointLabel","chargingStops","routeChargingStopSymbol","incident","routeIncidentJamSymbol","routeIncidentCauseSymbol","routeIncidentBackgroundLine","routeIncidentDashedLine","ferry","routeFerryLine","routeFerrySymbol","tollRoad","routeTollRoadOutline","routeTollRoadSymbol","tunnel","routeTunnelLine","vehicleRestricted","routeVehicleRestrictedForegroundLine","instructionLines","routeInstructionLine","routeInstructionOutline","instructionArrows","routeInstructionArrowSymbol","summaryBubbles","routeSummaryBubbleSymbol","defaultRoutingLayers","instructionArrowIconImg","summaryMapBubbleImg","svg","summaryBubbleImageOptions","stretchX","stretchY","content","trafficImg","waypointIcon","foregroundSvg","svgOptions","appendChild","mapLayerSpecs","createLayersSpecs","layerConfigs","ferries","incidents","tollRoads","tunnels","routeModuleConfigWithDefaults","globalDisplayUnits","TomTomConfig","instance","displayUnits","getIconID","chargingStop","basedOn","chargingConnectionInfo","chargingSpeed","formatTitle","chargingParkName","chargingParkOperatorName","toDisplayChargingStops","routes","displayChargingStops","route","leg","summary","chargingInformationAtEndOfLeg","chargingParkId","chargingPower","chargingPowerInkW","chargingDuration","formatDuration","chargingTimeInSeconds","time","routeState","hasJam","sectionProps","toDisplayTrafficSectionProps","delayInSeconds","jamIconID","magnitudeOfDelay","toTrafficJamIconSuffix","toJamIconID","causeIconID","toCauseIconID","getImageIDForWaypoint","waypoint","indexType","radiusMeters","baseImageID","toDisplayWaypoints","hardWaypointIndex","waypointInput","asWaypoint","arrayLength","indexTypeFor","hardWaypoint","isHardWaypoint","placeProperties","buildWaypointTitle","entryPoints","getPosition","useEntryPoint","stopDisplayIndex","degreesToRadians","degrees","PI","getCoord","bearing","final","bear","calculateFinalBearing","coordinates1","coordinates2","lon1","lon2","lat1","lat2","a","sin","cos","b","atan2","index_default","toDisplayRouteSections","sectionType","displaySectionPropsBuilder","startPointIndex","endPointIndex","routeIndex","buildRouteSectionsFromRoute","showFeaturesWithRouteSelection","routesWithSelection","toDisplayRoutes","selectedIndex","routesCollection","hasMagnitude","magnitude","section","toDisplayRouteSummaries","routeCoordinates","formattedTraffic","trafficDelayInSeconds","trafficSections","traffic","summaryDelayMagnitude","round","formattedDistance","formatDistance","lengthInMeters","distance","formattedDuration","travelTimeInSeconds","_RoutingModule","createSourcesWithLayers","layersSpecs","sourcePrefix","routingSourcesWithLayers","svgIconOptions","waypointStartImageId","waypointStopImageId","waypointSoftImageId","waypointFinishImageId","instructionArrowImageId","selectedSummaryPopupImageId","deselectedSummaryPopupImageId","trafficClearImageId","trafficMajorImageId","trafficModerateImageId","trafficMinorImageId","addImageIfNotExisting","waypointStartIcon","softWaypointIcon","waypointFinishIcon","customChargingStopIcon","mergedConfig","newLayersSpecs","layersSpecID","oldLayersSpecs","newLayersMap","acc","cur","oldLayersMap","layersToRemove","newLayersToUpdate","oldLayersToUpdate","removeLayer","toBeAddedLayerSpec","updateLayersAndSource","listOfSources","previouslyShown","item","showRoutes","displayRoutes","guidance","instructions","instruction","routePath","pathPoint","toDisplayInstructions","instructionLastSegment","lastPointBearingDegrees","calcBearing","toDisplayInstructionArrows","clearRoutes","selectRoute","updatedRoutes","showWaypoints","displayWaypoints","clearWaypoints","getLayerToRenderLinesUnder","RoutingModule","DEFAULT_STANDARD_STYLE_ID","standardStyleModulesValues","standardLight","trafficIncidents","trafficFlow","standardDark","drivingLight","drivingDark","monoLight","monoDark","satellite","baseMapStyleUrlTemplate","suffix","baseMapStyleUrlTemplates","buildStandardStyleUrl","baseUrl","apiKey","styleURL","URL","version","searchParams","append","buildStyleInput","mapParams","commonBaseURL","url","givenUrl","withApiKey","json","TomTomMap","tomtomMapParams","params","styleChangeHandlers","keepState","effectiveStyle","previousStyle","withPreviousStyleParts","_params","handleStyleData","mergeFromGlobal","ensureMapLibreCSSLoaded","validateStyle","maxTileCacheZoomLevels","cancelPendingTileRequestsWhileZooming","mapLibre","attributionControl","compact","transformRequest","resourceType","headers","generateTomTomHeaders","loadRTLTextPlugin","getRTLTextPluginStatus","setRTLTextPlugin","catch","from","querySelectorAll","textContent","link","rel","href","head","_setLanguage","language","mapLanguage","isLayerLocalizable","textFieldValue","setLanguage","getBBox","getBounds","toArray","setSprite","addPinCategoriesSpriteToStyle","incidentCategories","incidentCategoriesMapping","unknown","accident","fog","dangerous_conditions","rain","ice","jam","lane_closed","road_closed","road_works","wind","flooding","broken_down_vehicle","roadCategories","tertiaryRoadCategories","streetRoadCategories","toMultiSyntaxAllFilter","newSyntaxExpressions","legacySyntaxExpressions","addFilter","addValuesFilter","valuesFilter","addCommonFilterExpressions","sdkFilter","roadSubCategories","buildMapLibreIncidentsFilter","incidentCategoryFilter","magnitudes","magnitudesFilter","indexedMagnitudes","indexOf","delays","delayFilter","mustHaveDelay","minDelayMinutes","delaySeconds","delayFilterToMapLibre","buildMapLibreIncidentFilters","incidentFilters","any","mapLibreFilters","mapLibreFilter","buildMapLibreFlowFilter","showRoadClosures","operator","applyFilter","originalFilters","TrafficFlowModule","flowSource","getLayers","_filter","updateConfig","filterExpression","flowFilters","buildMapLibreFlowFilters","TrafficIncidentsModule","incidentsSource","_setVisible","icons","setIconsVisible","iconFilters","incidentFilterExpression","getNonSymbolLayers","iconFilterExpression","getSymbolLayers","anyIconLayersVisible","getRelativeElementBounds","elementRect","containerRect","bottom","isElementOutsideContainer","bounds","containerWidth","containerHeight","adjustForHorizontalBar","currentVisible","min","adjustForVerticalBar","adjustVisibleBoundsForElement","mapWidthPX","mapHeightPX","clampedBounds","clampBoundsToContainer","spansFullWidth","spansFullHeight","touchesLeft","touchesRight","touchesTop","touchesBottom","distanceFromLeft","distanceFromRight","distanceFromTop","distanceFromBottom","minDistance","adjustForFloatingElement","toElement","ref","getMapLibreMap","calculateVisibleAreaBounds","surroundingElements","paddingPX","getContainer","getBoundingClientRect","visibleAreaBounds","elementRef","elementBounds","calculatePaddedBBox","sw","unproject","ne","lng","lat","calculatePaddedCenter","west","south","east","north","calculateFittingBBox","toBeContainedBBox","leftRatio","rightRatio","topRatio","widthRatio","heightRatio","fullWidth","fullHeight","expandedWest","expandedNorth"],"mappings":"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ACA,UACA,UACA,UACA,UACA,WAEJC,OAAQ,CACJ,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,KAAM,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WAC/FC,WAAY,CACR,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,MAAO,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WAChGC,OAAQ,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WACtFC,iBAAkB,CACd,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,UAAW,CACP,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,cAAe,CACX,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,OAAQ,CACJ,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,MAAO,CACH,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,cAAe,CACX,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAEJC,aAAc,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,WACvGC,cAAe,CACX,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,YAMFC,GAAe,UAKRC,GAA8D,CACvEv+C,KAAM,OACNqb,MAAO,CACH,aAAc,CAAC,WAAY,CAAC,MAAOiiC,IAAsBgB,IACzD,eAAgB,IAChB,kBAAkB,IAObE,GAAiE,CAC1Ex+C,KAAM,OACNqb,MAAO,CACH,aAAcijC,GACd,eAAgB,IAChB,aAAc,IChJTG,GAA0B,CACnCC,EACAC,EACA1gC,KAEA,MAAM2gC,EAAc3gC,GAAQ2gC,YACtBC,EAAa5gC,GAAQ4gC,WAuB3B,MAAO,CArBe,IACfN,GACH3oC,GAAI8oC,EACJrjC,MAAO,IACAkjC,GAAiBljC,UACfnJ,GAAM0sC,GAAaE,cAAgB,CAAE,eAAgBF,GAAaE,gBACnEF,GAAaxpC,WAAa,CAAE,aAAc,CAAC,MAAO,YAIrC,IAClBopC,GACH5oC,GAAI+oC,EACJtjC,MAAO,IACAmjC,GAAoBnjC,UAClBnJ,GAAM2sC,GAAYE,YAAc,CAAE,aAAcF,GAAYE,eAC5D7sC,GAAM2sC,GAAYG,YAAc,CAAE,aAAcH,GAAYG,eAC5D9sC,GAAM2sC,GAAYI,cAAgB,CAAE,eAAgBJ,GAAYI,iBAkDpEC,GAA8B,CACvCrkC,EACAoD,KAEA,MAAM2zB,EAAa3zB,GAAQ2zB,WAE3B,MAAO,CACH5xC,KAAM,SACN4V,GAAIiF,EACJO,OAAQ,CACJ,aAAc,CAAC,MAAOiiC,OAClBzL,GAAYD,WAAa,CAAE,aAAcC,EAAWD,WACxD,eAAgB,EAChB,YAAa,GACb,YAAa,CAAChF,IACd,mBAAoB,SAExBtxB,MAAO,CACH,aAAc,UACd,kBAAmB,UACnB,kBAAmB,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,EAAG,GAAI,KACnE,wBAAyB,cAaxB8jC,GAA4B,CACrCjI,EACAj5B,EAAiC,UAE9Bi5B,EACHt+B,SAAUs+B,EAASt+B,SAASxR,IAAI,CAACoS,EAASha,KACtC,MAAMi0C,EAAQj6B,EAAQC,YAAYg6B,OA7EvB,EACfj6B,EACAyE,IAEIA,EAAO2zB,YAAYD,UACZ1zB,EAAO2zB,WAAWD,UAGtBn4B,EAAQC,YAAYo7B,SAASC,gBAqEWsK,CAAW5lC,EAASyE,GACzDy0B,EAAQl5B,EAAQC,YAAYi5B,OA9DvB,EACfz0B,EACAze,KAEA,MAAMkzC,EAAQz0B,GAAQ2gC,aAAaxpC,UAEnC,GAAqB,iBAAVs9B,GAAsB6K,GAAc7K,GAA+B,CAC1E,MAAM2M,EAAU9B,GAAc7K,GAC9B,OAAO2M,EAAQ7/C,EAAQ6/C,EAAQ5/C,OACnC,CAEA,OAAOizC,GAmDwC4M,CAAWrhC,EAAQze,GAC9D,MAAO,IACAga,EACHC,WAAY,IACLD,EAAQC,cACPg6B,GAAS,CAAEA,YACXf,GAAS,CAAEA,SACf98B,GAAI4D,EAAQC,YAAY7D,IAAMqhC,UAwBjCsI,GAA0BC,IACnC,MAAM5mC,EAAW4mC,EAAW5mC,SAASxR,IAAKoS,IACtC,IAAIimC,EAEJ,GAAIjmC,EAAQC,YAAYimC,iBACpBD,EAAcjmC,EAAQC,YAAYimC,sBACtC,GAAqC,iBAA1BlmC,EAAQ09B,SAASl3C,KAAyB,CACjD,MAAM2/C,EAnBM,CAACF,GACrBA,EAAYG,OAAOC,OAAO,CAAC7gD,EAAQ8gD,IAAWA,EAAMrgD,OAAST,EAAOS,OAASqgD,EAAQ9gD,EAAS,IAkB/D+gD,CAAgBvmC,EAAQ09B,SAASuI,aAClDtI,EAAO6I,EAAoBL,GACjCF,EAAetI,GAAQ8I,EAAW9I,IAAU,IAChD,MACIsI,EAAcjmC,EAAQ09B,SAASuI,YAAYG,OAG/C,MAAMhqC,EAAK4D,EAAQ5D,IAAM4D,EAAQC,YAAY7D,IAAMqhC,IACnD,MAAO,CACHj3C,KAAM,UACN4V,KACAshC,SAAU,CAAEl3C,KAAM,QAASy/C,eAC3BhmC,WAAY,IACLD,EAAQC,WACX7D,SAKZ,MAAO,CAAE5V,KAAM,oBAAqBm3C,KAAMqI,EAAWrI,KAAMv+B,aCzDlDsnC,GAAN,MAAMA,UAAyBniC,GA4ElC,gBAAalX,CAAIqT,EAAsB+D,GAEnC,aADMjE,GAAoBE,GACnB,IAAIgmC,EAAiBhmC,EAAW+D,EAC3C,CAEQ,WAAA3a,CAAY8D,EAAgB6W,GAChCjG,MAAM,UAAW5Q,EAAK6W,EAC1B,CAKU,sBAAAa,CAAuBb,EAAiCW,GAC9D,IAAKA,EAAS,CACVshC,EAAiB5I,oBACjBjxC,KAAK0Q,SAAW,YAAYmpC,EAAiB5I,oBAC7CjxC,KAAK85C,cAAgB,iBAAiBD,EAAiB5I,oBACvD,MAAM8I,EAAgB,YAAYF,EAAiB5I,oBACnDjxC,KAAKg6C,YAAc,GAAGD,SACtB/5C,KAAKi6C,eAAiB,GAAGF,YACzB/5C,KAAKk6C,aAAe,GAAGH,SAC3B,CAEA,MAAO7B,EAAkBC,GAAuBC,GAC5Cp4C,KAAKg6C,YACLh6C,KAAKi6C,eACLriC,GAEEuiC,EAAiBtB,GAA4B74C,KAAKk6C,aAActiC,GAKtE,OAJA5X,KAAKo6C,gBAAkBD,EACvBn6C,KAAKq6C,uBAAyBnC,EAC9Bl4C,KAAKs6C,0BAA4BnC,EAE1B,CACHtH,SAAU,IAAIr+B,GAAwBxS,KAAK+T,YAAa/T,KAAK0Q,SAAU,CACnE,IAAKwnC,GACL,IAAKC,KAEToC,cAAe,IAAI/nC,GAAwBxS,KAAK+T,YAAa/T,KAAK85C,cAAe,CAC7EK,IAGZ,CAKU,YAAAlhC,CAAarB,GAOnB,OANIA,GAAQ2zB,YAAc3zB,GAAQ2gC,aAAe3gC,GAAQ4gC,aACrDx4C,KAAKw6C,mBAAmB5iC,GAExBA,GAAQ6iC,mBACRz6C,KAAK06C,gBAAgB9iC,EAAO6iC,mBAEzB7iC,CACX,CAEQ,iBAAA+iC,CAAkBC,GACtB,IAAA,MAAWvqC,KAASrQ,KAAKwY,kBAAkBq4B,SAAS3/B,kBAAkBP,SAClE3Q,KAAK+T,YAAY8mC,UAAUxqC,EAAOuqC,EAE1C,CA4BA,eAAAF,CAAgBI,GACZ96C,KAAK4X,OAAS,IAAK5X,KAAK4X,OAAQ6iC,kBAAmBK,GACnD96C,KAAK26C,kBAAkC,QAAhBG,EAAwB96C,KAAKk6C,aAAev6B,GAAiBm7B,GACxF,CA+BA,eAAAnJ,CAAgBpG,GACZ,MAAM3zB,EAAS,IAAK5X,KAAK4X,OAAQ2zB,cACjCvrC,KAAKw6C,mBAAmB5iC,GAExB5X,KAAKwY,kBAAkB+hC,cAAc5nC,KACjCumC,GAAuBl5C,KAAKwY,kBAAkBq4B,SAASn+B,gBAE3D1S,KAAK4X,OAASA,CAClB,CAEQ,kBAAA4iC,CAAmB5iC,GACvB,MAAOsgC,EAAkBC,GAAuBC,GAC5Cp4C,KAAKg6C,YACLh6C,KAAKi6C,eACLriC,GAEEmjC,EAAqBlC,GAA4B74C,KAAKk6C,aAActiC,GAE1EvD,GAAiB6jC,EAAkBl4C,KAAKq6C,uBAAwBr6C,KAAK+T,aACrEM,GAAiB8jC,EAAqBn4C,KAAKs6C,0BAA2Bt6C,KAAK+T,aAC3EM,GAAiB0mC,EAAoB/6C,KAAKo6C,gBAAiBp6C,KAAK+T,aAEhE/T,KAAKq6C,uBAAyBnC,EAC9Bl4C,KAAKs6C,0BAA4BnC,EACjCn4C,KAAKo6C,gBAAkBW,CAC3B,CAKU,wBAAA3hC,GACN,MAAMk4B,EAAwBtxC,KAAKwY,kBAAkBq4B,SAASn+B,cAC9D1S,KAAKiY,sBAAsBjY,KAAK4X,QAAQ,GACxC5X,KAAK4X,QAAU5X,KAAKiZ,aAAajZ,KAAK4X,QACtC5X,KAAK2S,KAAK2+B,EACd,CA+DA,UAAM3+B,CAAKwmC,SACDn5C,KAAK6Y,uBACX,MAAMg4B,EAAW7wC,KAAKwY,kBAAkBq4B,SACxCA,EAASl+B,KAAKmmC,GAA0BK,EAAYn5C,KAAK4X,SACzD5X,KAAKwY,kBAAkB+hC,cAAc5nC,KAAKumC,GAAuBrI,EAASn+B,eAC9E,CAmBA,WAAMzS,SACID,KAAK6Y,uBACX7Y,KAAKwY,kBAAkBq4B,SAAS5wC,OACpC,CA+CA,UAAIoyC,GACA,OAAO,IAAI/4B,GAAatZ,KAAK6T,UAAUmE,aAAchY,KAAKwY,kBAAkBq4B,SAAU7wC,KAAK4X,QAAQy6B,OACvG,GApXAwH,GAAe5I,mBAAoB,EADhC,IAAM+J,GAANnB,GC9EA,MAAMoB,WAAwBvjC,GA0CjC,gBAAalX,CAAIO,EAAgB6W,GAG7B,aAFMjE,GAAoB5S,SACpBmV,GAAmBnV,EAAKof,GAAqB,aAC5C,IAAI86B,GAAgBl6C,EAAK6W,EACpC,CAEQ,WAAA3a,CAAY8D,EAAgB6W,GAChCjG,MAAM,QAAS5Q,EAAK6W,EACxB,CAKU,sBAAAa,GACN,MAAMyiC,EAAkBl7C,KAAK+T,YAAYpE,UAAUwQ,IACnD,IAAK+6B,EACD,MAAMxtC,GAAc,QAAQutC,GAAgB3xC,uBAAuB6W,MAEvE,MAAO,CAAEg7B,UAAW,IAAIzpC,GAAsB1R,KAAK+T,YAAamnC,GACpE,CAKU,YAAAjiC,CAAarB,GAEnB,OADA5X,KAAK00C,WAAW98B,GAAQ9G,UAAW,GAC5B8G,CACX,CAgBA,UAAA88B,CAAW5jC,GACP9Q,KAAK4X,OAAS,IACP5X,KAAK4X,OACR9G,WAGA9Q,KAAK6T,UAAUC,UACf9T,KAAKwY,kBAAkB2iC,UAAUtqC,iBAAiBC,EAE1D,CAcA,SAAA6jC,GACI,OAAO30C,KAAKwY,kBAAkB2iC,UAAUlrC,mBAC5C,CAqBA,UAAIoiC,GACA,OAAO,IAAI/4B,GAAatZ,KAAK6T,UAAUmE,aAAchY,KAAKwY,kBAAkB2iC,UAAWn7C,KAAK4X,QAAQy6B,OACxG,EClJG,MAAM+I,GAAmB,CAC5B,gBACA,eAEA,eACA,cACA,YACA,WACA,aAkLSC,GAAe,CAAC,mBAAoB,cAAe,aC7NnDC,GAA8B,UAM9BC,GAA2B,UAM3BC,GAA8B,UAM9BC,GAA2B,UAK3BC,GAA6B,UAM7BC,GAAuD,CAChE,cACA,CAAC,UACD,CAAC,QACD,EACA,EACA,EACA,EACA,GACA,EACA,GACA,IAcSC,GAAiD,CAAC,KAAM,CAAC,MAAO,cAAe,YAa/EC,GAAmD,CAAC,KAAM,CAAC,MAAO,cAAe,cAKjFC,GAAoB,UAIpBC,GAAuB,UAIvBC,GAA0B,UAI1BC,GAAsB,UChF7BC,GACFtkC,IAEwB,IAApBA,GAAQ9G,QACD,GAIP8G,GAAQw1B,OAAS,CACb,SACA,CAAC,MAAO,SACR,KACA,CAAC,MAAO,iBACR,QACA,CAAC,MAAO,qBASP+O,GACTvkC,IAEO,IACAqvB,GACH/2B,OAAQ0rC,GACRlnC,QAAS,EACTK,OAAQ,IACDkyB,GAAiBlyB,OACpB,aAAcmnC,GAAsBtkC,GAAQuvB,OAEhDnyB,MAAO,IACAiyB,GAAiBjyB,SCzC1BonC,GAAc,CAChBlsC,OAAQ0rC,GACRlnC,QAAS,IAGP2nC,GAA6D,IAC5DD,GACHziD,KAAM,OACNob,OAAQ,CAAE,WAAY,UAMbunC,GAAgE,IACtED,GACHrnC,MAAO,CACH,aAAc,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,GAAI,GAAI,GAAI,IAChE,aAAc,SAOTunC,GAA6D,IACnEF,GACHrnC,MAAO,CACH,aAAc,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,GAAI,GAAI,GAAI,IAChE,aAAc,UAOTwnC,GAA6B,oBAK7BC,GAAgE,IACtEL,GACHziD,KAAM,SACNob,OAAQ,CACJ,sBAAsB,EACtB,aAAcynC,GACd,0BAA2B,MAC3B,cAAe,CAAC,MAAO,2BACvB,YAAa,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,GAAI,EAAG,GAAI,KC9CzDE,GAA8D,CACvExsC,OAAQ0rC,GACRjiD,KAAM,OACNob,OAAQ,CACJ,YAAa,SAEjBC,MAAO,CACH,aAAc2mC,GACd,aAAc,YAOTgB,GAAkE,CAC3EzsC,OAAQ0rC,GACRjiD,KAAM,SACN+a,QAAS,EAETD,QAAS,KACTM,OAAQ,CACJ,mBAAoB,QACpB,sBAAsB,EACtB,aAAc,qBACd,YAAa,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,GAAK,KAAM,GAEjE,yBAAyB,ICnBpB6nC,GAAmE,CAC5EjjD,KAAM,OACNob,OAAQ,CACJ,YAAa,QACb,WAAY,QACZ,gBAAiB,CAAC,MAAO,WAI3B8nC,GAA4C,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,IAKnGC,GAAoE,IAC1EF,GACH1sC,OAAQ2rC,GACR7mC,MAAO,CACH,aAAcymC,GACd,aAAcoB,KAOTE,GAAiE,IACvEH,GACH1sC,OAAQ2rC,GACR7mC,MAAO,CACH,aAAcwmC,GACd,aAAcG,KAOTqB,GAA0D,IAChEJ,GACH1sC,OAAQ0rC,GACR5mC,MAAO,CACH,aAAcumC,GACd,aAAcsB,KAmBTI,GAA+D,CACxEtjD,KAAM,SACNob,OAAQ,CACJ,mBAAoB,OACpB,aAAc,oBAEd,cAAe,MAOVmoC,GAAkC,+BAIlCC,GAAoC,iCCvFpCC,GAAmE,CAC5EltC,OAAQ0rC,GACRjiD,KAAM,OACNob,OAAQ,CACJ,YAAa,QACb,WAAY,SAEhBC,MAAO,CACH,aAAc,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,IAC7E,aAAc,YAOTqoC,GAAoE,CAC7EntC,OAAQ0rC,GACRjiD,KAAM,SACN+a,QAAS,EACTK,OAAQ,CACJ,mBAAoB,QACpB,sBAAsB,EACtB,aAAc,iBACd,YAAa,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,GAAK,KAAM,KCpBnEuoC,GAAuD,CACzD,cACA,CAAC,UACD,CAAC,QACD,EACA,EACA,EACA,EACA,GACA,EACA,GACA,GAMSC,GAAkE,CAC3E5jD,KAAM,OACNob,OAAQ,CAAE,WAAY,SACtBC,MAAO,CACH,aAAcsoC,GACd,aAAc,CACV,QACA,CAAC,MAAO,oBACR,QACA,UACA,WACAvB,GACA,QACAD,GAEA,aAQC0B,GAAsE,CAC/E7jD,KAAM,OACNuW,OAAQ,CAAC,KAAM,CAAC,MAAO,oBAAqB,CAAC,UAAW,CAAC,UAAW,gBACpE6E,OAAQ,CAAE,YAAa,SACvBC,MAAO,CACH,aAAcsoC,GACd,aAAc,CACV,QACA,CAAC,MAAO,oBACR,UACA,uBAEA,0BAEJ,iBAAkB,CAAC,IAAK,KAOnBG,GAAqD,CAC9D,QACA,CAAC,MAAO,oBACR,QACAzB,GACA,WACAD,GACA,QACAD,GACA,aACA,UAEAG,IAGEyB,GAAwE,CAC1ExtC,OAAQ0rC,GACRjiD,KAAM,SACN+a,QAAS,EACTK,OAAQ,CACJ,mBAAoB,QACpB,sBAAsB,EACtB,yBAAyB,IAOpB4oC,GAAuE,IAC7ED,GACHxtC,OAAQ,CAAC,MAAO,CAAC,MAAO,aAAcwtC,GAAyBxtC,QAC/D6E,OAAQ,IACD2oC,GAAyB3oC,OAC5B,aAAc,CAAC,MAAO,aACtB,cAAe,cACf,cAAe,cAEf,aAAc,CAAC,MAAO,SACtB,YAAa,CAACuxB,IACd,cAAe,CAAC,KAAK,KACrB,YAAa,IAEjBtxB,MAAO,IACA0oC,GAAyB1oC,MAC5B,aAAcyoC,GACd,kBAAmB,UACnB,kBAAmB,IAOdG,GAAyE,IAC/EF,GACHxtC,OAAQ,CAAC,MAAO,CAAC,MAAO,eAAgBwtC,GAAyBxtC,QACjE6E,OAAQ,IACD2oC,GAAyB3oC,OAC5B,aAAc,CAAC,MAAO,eACtB,cAAe,gBAGnBC,MAAO,IAAK0oC,GAAyB1oC,QChI5B6oC,GAA8D,CACvE3tC,OAAQ0rC,GACRjiD,KAAM,OACNob,OAAQ,CACJ,YAAa,SAEjBC,MAAO,CACH,aAAc2mC,GACd,aAAc,UACd,eAAgB,KCJXmC,GAAkF,CAC3F5tC,OAAQ0rC,GACRjiD,KAAM,OACNob,OAAQ,CACJ,YAAa,SAEjBC,MAAO,CACH,aAAcumC,GACd,aAAcI,KAOToC,GAA8E,CACvF7tC,OAAQ0rC,GACRjiD,KAAM,OACNob,OAAQ,CACJ,YAAa,QACb,WAAY,SAEhBC,MAAO,CACH,aAAcsmC,GACd,aAAc,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,EAAG,EAAG,EAAG,EAAG,GAAI,EAAG,GAAI,GAC3E,iBAAkB,CAAC,EAAG,OC1BjB0C,GAAyB,gBAIzBC,GAAyB,gBAIzBC,GAA4B,mBAI5BC,GAAyB,gBAEhCC,GAA+C,CAAC,MAAO,oBAOhDC,GAAiC9Q,IAC1C,MAAM+Q,OACgB,IAAlB/Q,EACMrG,GAAagW,GAAiC3P,GAC9C2P,GACJqB,OACgB,IAAlBhR,EACMrG,GAAaiW,GAAmC5P,GAChD4P,GACJqB,OACgB,IAAlBjR,EAA8BrG,GAAa8W,GAAwBzQ,GAAiByQ,GAClFS,OACgB,IAAlBlR,EAA8BrG,GAAa+W,GAAwB1Q,GAAiB0Q,GAClFS,OACgB,IAAlBnR,EACMrG,GAAagX,GAA2B3Q,GACxC2Q,GACJS,OACgB,IAAlBpR,EAA8BrG,GAAaiX,GAAwB5Q,GAAiB4Q,GAExF,MAAO,CACHxkD,KAAM,SACNob,OAAQ,CACJ,aAAc,CAAC,OAAQ6mC,GAAuB0C,EAAiBC,GAC/D,mBAAoB,QACpB,0BAA2B,WAC3B,0BAA2B,WAC3B,kBAAmB,CAAC,OAAQ3C,GAAuB,EAAG,GACtD,gBAAiB,OACjB,wBAAyB,CAAC,GAAI,EAAG,EAAG,IACpC,YAAa,CpCUM,eoCTnB,YAAa,GACb,eAAgB,EAChB,eAAgB,OAChB,mBAAoB,IACpB,aAAc,CACV,SACA,CAAC,MAAO,qBACR,CACI,YAAa,CAAC,UAAW,CAACtV,KAC1B,aAAc,CAAC,OAAQsV,GAAuB,QAASF,KAE3D,CAAC,SAAU,OAAQ,CAAC,MAAO,sBAC3B,CAAE,aAAcA,IAChB,CAAC,OAAQ0C,GAAqB,KAAM,IACpC,CAAA,EACA,CACI,QACA,CACI,OACAA,GACA,CACI,QACA,CAAC,MAAO,oBACR,QACAK,EACA,WACAC,EACA,QACAC,EACAH,GAEJ,KAGR,CAAA,EACA,CAAC,OAAQJ,GAAqB,CAAC,SAAU,KAAM,CAAC,MAAO,qBAAsB,IAC7E,CACI,YAAa,CAAC,UAAW,CAAC9X,KAC1B,aAAcmX,MAI1BzoC,MAAO,CACH,iBAAkB,CAAC,GAAG,IACtB,iBAAkB,CAAC,GAAG,OASrB4pC,GAAwEP,KC/GxEQ,GAAc,QAIdC,GAAe,SAIfC,GAAe,SA6GfC,GAAa,YAKbC,GAAqB,mBC/GrBC,GAA0B,gBAS1BC,GAAyB,eASzBC,GAAyB,eAMzBC,GAA2B,iBAYlCC,GAA0D,CAE5D,aAAc,CAAC,MAAOL,IACtB,YAAa,CAAC3Y,IACd,YAAa,CAAC,cAAe,CAAC,UAAW,CAAC,QAAS,GAAI,GAAI,GAAI,IAC/D,cAAe,CAAC,GAAG,KAEnB,cAAe,CACX,OAlBwC,CAC5C,MACA,CAAC,KAAM,CAAC,MAAO0Y,IAAaF,IAC5B,CAAC,IAAK,CAAC,MAAOG,MAiBV,SAEA,UAEJ,sBAAsB,GAObM,GAA+D,CACxE5lD,KAAM,SACNqb,MAAO,IACA8xB,GA3BP,aAAc,WA8Bd/xB,OAAQ,IACD8xB,MACAyY,GACH,kBAAmB,CACf,OACA,CAAC,KAAM,CAAC,MAAO7Y,IAAU2Y,IACzB,EACA,CAAC,MAAO,CAAC,IAAK,CAAC,MAAO,SAAU,SAQ/BI,GAA8D,CACvE7lD,KAAM,SACNqb,MAAO,IACAgyB,GACH,aAAc,QACd,kBAAmB,IACnB,kBAAmB,WAEvBjyB,OAAQ,IACDgyB,GACH,cAAe,MACf,cAAe,CAAC,EAAG,MC7ErB0Y,GAAiB,CAACttC,EAA8B++B,IAC7C/+B,GAAa++B,IAId/+B,EAASutC,WAAW,UAAYvtC,EAASutC,WAAW,aAC7C,GAAGxO,KAAiB/+B,IAJpBA,EAaTwtC,GAAkB,CACpBvR,EACA8C,IAEK9C,GAAe8C,EAIb35C,OAAOmhB,YACVnhB,OAAOwI,QAAQquC,GAAYrtC,IAAI,EAAE/F,EAAKqV,KAAW,CAC7CrV,EACAqV,GAAO8B,SAAW,IAAK9B,EAAO8B,SAAUstC,GAAepvC,EAAM8B,SAAU++B,IAAmB7gC,KANvF+9B,EAeTwR,GAAgB,CAAC1Q,EAA6B3B,IAC3C2B,QAA6B,IAAlB3B,EAGT,GAAG2B,KAAW3B,IAFV2B,EAYF2Q,GAAqB,CAC9BjoC,EAA8B,GAC9Bs5B,EACA3D,KAEA,MAAMuS,EAAeloC,EAAOpG,OACtBuuC,EAAsBD,GAAcE,SACpCC,EAAYroC,EAAO2vB,OAAO0Y,UAEhC,MAAO,CACHC,UAAW,CACPjD,gBAAiB,IACVA,GACH9qC,SAAUwN,GAAiBI,eACxB+/B,GAAcI,WAAWjD,iBAEhCkD,UAAW,KR5BOx4C,EQ6BG,CAAE0kC,MAAO4T,GR7BZ,IACvBrD,GACH1sC,OAAQ0rC,GACR5mC,MAAO,CACH,aAAcrN,GAAO0kC,OAASiP,GAC9B,aAAcK,MQyBNxpC,SAAUstC,GAAe,8BAA+BvO,MACrD4O,GAAcI,WAAWC,WAEhCnD,aAAc,IACPA,GACH7qC,SAAUstC,GAAe,YAAavO,MACnC4O,GAAcI,WAAWlD,cAEhCD,oBAAqB,IACdA,GACH5qC,SAAUstC,GAAe,eAAgBvO,MACtC4O,GAAcI,WAAWnD,qBAEhCD,uBAAwB,IACjBA,GACH3qC,SAAUstC,GAAe,sBAAuBvO,MAC7C4O,GAAcI,WAAWpD,2BAE7B6C,GAAgBG,GAAcI,WAAW9R,WAAY8C,IAE5DkP,UAAW,CACPC,oBAAqB,IACdd,GACHptC,SAAUstC,GAAe,2BAA4BvO,MAClD4O,GAAcM,WAAWC,qBAEhCC,mBAAoB,IACbd,GACHrtC,SAAUstC,GAAe,sBAAuBvO,MAC7C4O,GAAcM,WAAWE,uBAE7BX,GAAgBG,GAAcM,WAAWhS,WAAY8C,IAE5DqP,cAAe,CACXC,wBAAyB,IAClBrE,GAAmBvkC,EAAO2oC,eAC7BpuC,SAAUstC,GAAe,sBAAuBvO,MAC7C4O,GAAcS,eAAeC,4BAEjCb,GAAgBG,GAAcS,eAAenS,WAAY8C,IAEhE8O,SAAU,CACNS,SAAU,CACNC,uBAAwB,IACjB/C,GACHxrC,SAAUstC,GAAe,0BAA2BvO,MACjD6O,GAAqBU,UAAUC,wBAEtCC,yBAA0B,IACnB/C,GACHzrC,SAAUstC,GAAe,0BAA2BvO,MACjD6O,GAAqBU,UAAUE,0BAEtCC,4BAA6B,IACtBrD,GACHprC,SAAUstC,GAAe,0BAA2BvO,MACjD6O,GAAqBU,UAAUG,6BAEtCC,wBAAyB,IAClBrD,GACHrrC,SAAUstC,GAAe,kBAAmBvO,MACzC6O,GAAqBU,UAAUI,4BAEnClB,GAAgBI,GAAqBU,UAAUrS,WAAY8C,IAElE4P,MAAO,CACHC,eAAgB,IACTrE,GACHvqC,SAAUstC,GAAe,kBAAmBvO,MACzC6O,GAAqBe,OAAOC,gBAEnCC,iBAAkB,IACXrE,GACHxqC,SAAUstC,GAAe,yBAA0BvO,MAChD6O,GAAqBe,OAAOE,qBAEhCrB,GAAgBI,GAAqBe,OAAO1S,WAAY8C,IAE/D+P,SAAU,CACNC,qBAAsB,IACf9D,GACHjrC,SAAUstC,GAAe,yBAA0BvO,MAChD6O,GAAqBkB,UAAUC,sBAEtCC,oBAAqB,IACd9D,GACHlrC,SAAUstC,GAAe,0BAA2BvO,MACjD6O,GAAqBkB,UAAUE,wBAEnCxB,GAAgBI,GAAqBkB,UAAU7S,WAAY8C,IAElEkQ,OAAQ,CACJC,gBAAiB,IACVxD,GACH1rC,SAAUstC,GAAe,kBAAmBvO,MACzC6O,GAAqBqB,QAAQC,oBAEjC1B,GAAgBI,GAAqBqB,QAAQhT,WAAY8C,IAEhEoQ,kBAAmB,CACfxD,qCAAsC,IAC/BA,GACH3rC,SAAUstC,GAAe,uCAAwCvO,MAC9D6O,GAAqBuB,mBAAmBxD,sCAE/CyD,qCAAsC,IAC/BxD,GACH5rC,SAAUwN,GAAiBI,eACxBggC,GAAqBuB,mBAAmBC,yCAE5C5B,GAAgBI,GAAqBuB,mBAAmBlT,WAAY8C,KAG/EsQ,iBAAkB,CACdC,qBAAsB,IACflF,GACHpqC,SAAUwN,GAAiBI,eACxB+/B,GAAc0B,kBAAkBC,sBAEvCC,wBAAyB,IAClBpF,GACHnqC,SAAUstC,GAAe,uBAAwBvO,MAC9C4O,GAAc0B,kBAAkBE,4BAEpC/B,GAAgBG,GAAc0B,kBAAkBpT,WAAY8C,IAEnEyQ,kBAAmB,CACfC,4BAA6B,IACtBnF,GACHtqC,SAAUstC,GAAe,uBAAwBvO,WAC3B,IAAlB3D,GAA+B,CAC/Bx4B,OAAQ,IACD0nC,GAAiB1nC,OACpB,aAAc6qC,GAAcnD,GAAiB1nC,SAAS,cAAyBw4B,QAGpFuS,GAAc6B,mBAAmBC,gCAErCjC,GAAgBG,GAAc6B,mBAAmBvT,WAAY8C,IAEpE2Q,eAAgB,CACZC,yBAA0B,SACA,IAAlBvU,EACE8Q,GAA8B9Q,GAC9BqR,MACHkB,GAAc+B,gBAAgBC,6BAElCnC,GAAgBG,GAAc+B,gBAAgBzT,WAAY8C,KRjL5C,IAACvpC,GQ2MjBo6C,GAAoDlC,KCjQjE,IAAImC,GAGAn0C,OACAm0C,GAA0B/zC,GAASO,GCfxB,6bD0BR,MAAMyzC,GAAuB5V,IAEhC,IAAKx+B,KACD,OAEJ,MAAMq0C,EAAkB1zC,GE/Bb,4bFkCX,OAFA0zC,EAAIlzC,cAAc,YAAYC,aAAa,OAAQo9B,GACnD6V,EAAIlzC,cAAc,SAASC,aAAa,OAAQo9B,GACzCp+B,GAASi0C,IAQPC,GAAyD,CAClEhQ,WAAY,EACZiQ,SAAU,CACN,CAAC,GAAI,IACL,CAAC,IAAK,MAEVC,SAAU,CAAC,CAAC,GAAI,KAChBC,QAAS,CAAC,GAAI,GAAI,IAAK,KAOdC,GAAclW,IAEvB,IAAKx+B,KACD,OAEJ,MAAMq0C,EAAkB1zC,GG7Db,ylDH8DLu/B,EAAOmU,EAAIlzC,cAAc,SAG/B,OAFA++B,EAAK9+B,aAAa,YAAa,YAC/B8+B,EAAK9+B,aAAa,OAAQo9B,GACnBp+B,GAASi0C,IAMPM,GAAe,CACxBC,EACAC,KAGA,IAAK70C,KACD,OAEJ,MAAMq0C,EAAMtzC,GAAO8zC,GAInB,OAHID,GACAP,EAAIS,YAAYF,GAEbx0C,GAASi0C,II1EdU,GAAgB,CAClB9yC,EAAkE,CAAA,EAClEohC,IAGA35C,OAAOwI,QAAQ+P,GAAY/O,IACvB,EAAEwO,EAAIC,MAAI,IAECA,EACHD,GAAI2hC,EAAgB,GAAGA,KAAiB3hC,IAAOA,KAOlDszC,GAAoB,CAC7BC,EAAkC,CAAA,EAClC5R,KAAA,CAEAgP,UAAW0C,GAAcE,EAAa5C,UAAWhP,GACjDkP,UAAWwC,GAAcE,EAAa1C,UAAWlP,GACjDqP,cAAeqC,GAAcE,GAAcvC,cAAerP,GAC1D6R,QAASH,GAAcE,EAAa9C,UAAUc,MAAO5P,GACrD8R,UAAWJ,GAAcE,EAAa9C,UAAUS,SAAUvP,GAC1D+R,UAAWL,GAAcE,EAAa9C,UAAUiB,SAAU/P,GAC1DgS,QAASN,GAAcE,EAAa9C,UAAUoB,OAAQlQ,GACtDoQ,kBAAmBsB,GAAcE,EAAa9C,UAAUsB,kBAAmBpQ,GAC3EsQ,iBAAkBoB,GAAcE,EAAatB,iBAAkBtQ,GAC/DyQ,kBAAmBiB,GAAcE,EAAanB,kBAAmBzQ,GACjE2Q,eAAgBe,GAAcE,EAAajB,eAAgB3Q,KAMlDiS,GAAgC,CACzCvrC,EACAs5B,EACA3D,KAEA,MAAM6V,EAAqBC,EAAaC,SAAS9iD,MAAM+iD,aACjDA,EAAe3rC,GAAQ2rC,aAC7B,MAAO,IAEA3rC,KACC2rC,EAAe,CAAA,EAAK,CAAEA,aAAcH,GACxC5xC,OAAQquC,GAAmBjoC,EAAQs5B,EAAe3D,KC3CpDiW,GAAY,CAACC,EAA4B7rC,KAC3C,MAAM85B,EAAa95B,GAAQ2oC,eAAe9S,KAC1C,GAAIiE,GAAYrC,QAAS,CACrB,MAAMA,EAAUqC,EAAWrC,QAC3B,OAAQA,EAAQqU,SACZ,IAAK,gBACD,GAAID,EAAarwC,WAAWuwC,wBAAwBC,cAChD,OAAOvU,EAAQh3C,MAAMorD,EAAarwC,WAAWuwC,wBAAwBC,eAEzE,MACJ,IAAK,SACD,OAAOvU,EAAQj1B,GAAGqpC,GAE9B,CAGA,MAAO,QAGLI,GAAeJ,IACjB,MAAMrwC,EAAaqwC,EAAarwC,WAChC,OAAOA,EAAW0wC,kBAAqB1wC,EAAW2wC,0BAmBzCC,GAAyB,CAClCC,EACArsC,KAEA,MAAMssC,EAA0D,GAEhE,IAAuC,IAAnCtsC,GAAQ2oC,eAAezvC,QACvB,IAAA,MAAWqzC,KAASF,EAAO1xC,SACvB,IAAA,MAAW6xC,KAAOD,EAAM/wC,WAAW4sC,SAASoE,IAAK,CAC7C,MAAMX,EAAeW,EAAIC,QAAQC,8BAEjC,GAAIb,EAAc,CACd,MAAMrwC,EAAaqwC,EAAarwC,WAChC8wC,EAAqBllD,KAAK,IACnBykD,EACHrwC,WAAY,IACLqwC,EAAarwC,WAChB7D,GAAIk0C,EAAarwC,WAAWmxC,gBAAkB3T,IAC9CG,OAAQyS,GAAUC,EAAc7rC,GAChCw1B,MAAOyW,GAAYJ,GACnBe,cAAe,GAAGpxC,EAAWuwC,wBAAwBc,uBACrDC,iBAAkBC,EACdvxC,EAAWwxC,sBACXhtC,GAAQ2rC,cAAcsB,MAE1BC,WAAYX,EAAM/wC,WAAW0xC,aAGzC,CACJ,CAGR,MAAO,CAAEnrD,KAAM,oBAAqB4Y,SAAU2xC,IClF5Ca,GAAUC,GAA+CA,EAAa5Q,WAAW3iC,SAAS,OAoEnFwzC,GACTD,IAEA,MAAM5X,EArES,CAAC4X,IAChB,GAAID,GAAOC,GACP,OAAOL,EAAeK,EAAaE,iBAmEzBnM,CAAWiM,GACnBG,EA/CU,EAACH,EAAmC5X,IAC/C2X,GAAOC,GAIL,eADWA,EAAaI,kBAAoB,aApBxB,CAAChY,GACvBA,GAAOh0C,OAGRg0C,EAAMh0C,OAAS,EAER,QAEPg0C,EAAMh0C,OAAS,EAER,SAGJ,QAXI,YAmBwBisD,CAAuBjY,KAH/C,KA6COkY,CAAYN,EAAc5X,GACtCmY,EAxCY,CAACP,IAEnB,OAD4BA,EAAa5Q,WAAWrhC,KAAMszB,GAA0B,QAAbA,IAEnE,IAAK,WACD,MAAO,6BACX,IAAK,YACD,MAAO,8BACX,IAAK,cACD,MAAO,gCACX,IAAK,SACL,IAAK,kBACD,MAAO,2BACX,IAAK,sBACD,MAAO,wCACX,IAAK,cACL,IAAK,eACD,MAAO,gCACX,IAAK,OACD,MAAO,yBACX,IAAK,MACD,MAAO,wBACX,IAAK,OACD,MAAO,yBACX,IAAK,QACD,MAAO,0BACX,IAAK,WACD,MAAO,6BACX,QACI,OAAO,OAYKmf,CAAcR,GAClC,MAAO,IACAA,KACCG,GAAa,CAAEA,gBACfI,GAAe,CAAEA,kBACjBnY,GAAS,CAAEA,WCtDVqY,GAAwB,CACjCC,EACAC,EACApY,KAEA,GAAImY,EAAStyC,WAAWwyC,aACpB,YAAyB,IAAlBrY,EACDrG,GAAakY,GAAwB7R,GACrC6R,GAEV,IAAIyG,EACJ,OAAQF,GACJ,IAAK,QACDE,EAAc3G,GACd,MACJ,IAAK,SACD2G,EAAcxG,GACd,MACJ,QACIwG,EAAc1G,GAGtB,YAAyB,IAAlB5R,EAA8BrG,GAAa2e,EAAatY,GAAiBsY,GA0CvEC,GAAqB,CAC9B1F,EACAvxC,EACA0+B,KAIA,IAAIwY,GAAoB,EACxB,MAAO,CACHpsD,KAAM,oBACN4Y,SAAU6tC,EACLr/C,IAAI,CAACilD,EAAe7sD,KACjB,IAAK6sD,EAID,OAFAD,IAEO,KAEX,MAAML,EAzCH,CAACM,IAChB,OAAI3sD,MAAMC,QAAQ0sD,GAjBU,CAC5BrsD,KAAM,UACNk3C,SAAU,CACNl3C,KAAM,QACNy/C,YAc8B4M,GAZlC5yC,WAAY,CAAA,GAce,UAAvB4yC,EAAcrsD,KAXO,CACzBA,KAAM,UACNk3C,SAFyBxzB,EAYM2oC,EAT/B5yC,WAAY,CAAA,KACRiK,EAAMyzB,MAAQ,CAAEA,KAAMzzB,EAAMyzB,OAUzBkV,EAvBoB,IASF3oC,GAgDc4oC,CAAWD,GAChCL,EA/FD,EAACxsD,EAAe+sD,IACvB,IAAV/sD,EAAc0lD,GAAc1lD,EAAQ+sD,EAAc,EAAIpH,GAAeC,GA8FvCoH,CAAahtD,EAAOinD,EAAUhnD,QAC1CgtD,EA5BQ,CAACV,IAAiCA,EAAStyC,WAAWwyC,aA4B/CS,CAAeX,GAChCU,GACAL,IAEJ,MAAM3Y,EA7FY,CAACsY,IAC/B,MAAMY,EAAkBZ,GAAUtyC,WAClC,OAAOkzC,GAAiBxmC,KAAKxW,MAAQg9C,GAAiB9X,SAASC,sBAAmB,GA2FxD8X,CAAmBb,GAC3Bn2C,EAAMm2C,EAASn2C,IAAiBqhC,IACtC,MAAO,IACA8U,KAC0B,wBAAzB72C,GAAS23C,aAAyC,CAClD3V,SAAU,CACNl3C,KAAM,QAENy/C,YAAaqN,EAAYf,EAAU,CAAEgB,cAAe,0BAG5Dn3C,KACA6D,WAAY,IACLsyC,EAAStyC,WACZ7D,KACApW,QACAwsD,eACIvY,GAAS,CAAEA,SACf2D,OAAQ0U,GAAsBC,EAAUC,EAAWpY,MAC/C6Y,GAAgBT,IAAc7G,IAAgB,CAAE6H,iBAAkBZ,OAIjF71C,OAAQiD,GAAYA,KCsFjC,SAASyzC,GAAiBC,GAExB,OAD0BA,EAAU,IACTlqD,KAAKmqD,GAAK,GACvC,CCjOA,SAASC,GAAStN,GAChB,IAAKA,EACH,MAAM,IAAI7rC,MAAM,qBAElB,IAAKvU,MAAMC,QAAQmgD,GAAQ,CACzB,GAAmB,YAAfA,EAAM9/C,MAAyC,OAAnB8/C,EAAM5I,UAA6C,UAAxB4I,EAAM5I,SAASl3C,KACxE,MAAO,IAAI8/C,EAAM5I,SAASuI,aAE5B,GAAmB,UAAfK,EAAM9/C,KACR,MAAO,IAAI8/C,EAAML,YAErB,CACA,GAAI//C,MAAMC,QAAQmgD,IAAUA,EAAMrgD,QAAU,IAAMC,MAAMC,QAAQmgD,EAAM,MAAQpgD,MAAMC,QAAQmgD,EAAM,IAChG,MAAO,IAAIA,GAEb,MAAM,IAAI7rC,MAAM,qDAClB,CCfA,SAASo5C,GAAQx7C,EAAOC,EAAKoD,EAAU,CAAA,GACrC,IAAsB,IAAlBA,EAAQo4C,MACV,OAYJ,SAA+Bz7C,EAAOC,GACpC,IAAIy7C,EAAOF,GAAQv7C,EAAKD,GAExB,OADA07C,GAAQA,EAAO,KAAO,IACfA,CACT,CAhBWC,CAAsB37C,EAAOC,GAEtC,MAAM27C,EAAeL,GAASv7C,GACxB67C,EAAeN,GAASt7C,GACxB67C,EAAOV,GAAiBQ,EAAa,IACrCG,EAAOX,GAAiBS,EAAa,IACrCG,EAAOZ,GAAiBQ,EAAa,IACrCK,EAAOb,GAAiBS,EAAa,IACrCK,EAAI/qD,KAAKgrD,IAAIJ,EAAOD,GAAQ3qD,KAAKirD,IAAIH,GACrCI,EAAIlrD,KAAKirD,IAAIJ,GAAQ7qD,KAAKgrD,IAAIF,GAAQ9qD,KAAKgrD,IAAIH,GAAQ7qD,KAAKirD,IAAIH,GAAQ9qD,KAAKirD,IAAIL,EAAOD,GAC9F,OAAwB3qD,KAAKmrD,MAAMJ,EAAGG,IF8MD,EAAIlrD,KAAKmqD,IACnB,IAAMnqD,KAAKmqD,EE9MxC,CAMA,IAAIiB,GAAgBf,GCTb,MCgCMgB,GAAyB,CAIlC/D,EACAgE,EACAC,KAAA,CAKAvuD,KAAM,oBACN4Y,SAAU0xC,EAAO1xC,SAASyH,QAASmqC,GArDH,EAIhCA,EACA8D,EACAC,IAKC/D,EAAM/wC,WAAW4sC,SAASiI,IAAsBlnD,IAAKikD,IAClD,MAAMz1C,EAAKy1C,EAAaz1C,IAAMqhC,IAC9B,MAAO,CACHj3C,KAAM,UACN4V,KACAshC,SAAU,CACNl3C,KAAM,aACNy/C,YAAa+K,EAAMtT,SAASuI,YAAY9xC,MACpC09C,EAAamD,gBACbnD,EAAaoD,cAAgB,IAGrCh1C,WAAY,IACJ80C,EACEA,EAA2BlD,EAAcb,EAAM/wC,YAC/C4xC,EACNF,WAAYX,EAAM/wC,WAAW0xC,WAC7BuD,WAAYlE,EAAM/wC,WAAWja,MAC7BoW,UAGN,GAsBF+4C,CAAkCnE,EAAO8D,EAAaC,MChCjDK,GAAiC,CAC1CC,EACA7vC,KAEAA,SAAiBhG,MApBjBsxC,EAoBwDuE,EAnBxD51C,EAmB6E+F,EAAiBjG,cAnB9F,IAEGE,EACHL,SAAUK,EAAkBL,SAASxR,IAAKwR,IAAA,IACnCA,EACHa,WAAY,IACLb,EAASa,WACZ0xC,WAAYb,EAAO1xC,SAASA,EAASa,WAAWi1C,YAAc,GAAGj1C,WAAW0xC,kBATvC,IAC7Cb,EACArxC,GCKS61C,GAAkB,CAACxE,EAAwByE,EAAgB,KACpE,MAAMC,EAA2B,aAAc1E,EAASA,EAAS,CAAEtqD,KAAM,oBAAqB4Y,SAAU,CAAC0xC,IACzG,MAAO,IACA0E,EACHp2C,SAAUo2C,EAAiBp2C,SAASxR,IAAI,CAACojD,EAAOhrD,KAC5C,MAAMoW,EAAK40C,EAAM50C,IAAMqhC,IACvB,MAAO,IACAuT,EACH50C,KACA6D,WAAY,IACL+wC,EAAM/wC,WACT7D,KACAu1C,WAAY3rD,IAAUuvD,EAAgB,WAAa,mBAOjEE,GAAe,CAAC5I,EAAiC6I,IACnD7I,EAAS5vC,KAAM04C,GAAYA,EAAQ1D,mBAAqByD,GAsB/CE,GAA0B,CACnC9E,EACAV,KAAA,CAEA5pD,KAAM,oBACN4Y,SAAU0xC,EAAO1xC,SAASxR,IAAKojD,IAC3B,MAAME,EAAUF,EAAM/wC,WAAWixC,QAC3B2E,EAAmB7E,EAAMtT,SAASuI,YAClC6P,EAAmBtE,EAAeN,EAAQ6E,sBAAuB3F,GAAcsB,MAC/EO,EA7BgB,CAACjB,IAC3B,MAAMgF,EAAkBhF,EAAM/wC,WAAW4sC,SAASoJ,QAClD,GAAKD,GAAiB/vD,OAGtB,OAAIwvD,GAAaO,EAAiB,SACvB,QAEPP,GAAaO,EAAiB,YACvB,WAEPP,GAAaO,EAAiB,SACvB,aADX,GAkB6BE,CAAsBlF,GACzC50C,EAAK40C,EAAM50C,IAAMqhC,IACvB,MAAO,CACHj3C,KAAM,UACN4V,KACAshC,SAAU,CACNl3C,KAAM,QACNy/C,YAAa4P,EAAiBrsD,KAAK2sD,MAAMN,EAAiB5vD,OAAS,KAEvEga,WAAY,CACR7D,KACA84C,WAAYlE,EAAM/wC,WAAWja,MAC7B2rD,WAAYX,EAAM/wC,WAAW0xC,WAC7ByE,kBAAmBC,EAAenF,EAAQoF,eAAgBlG,GAAcmG,aACpEtE,GAAoB,CAAEA,uBACtB6D,GAAoB,CAAEA,oBAC1BU,kBAAmBhF,EAAeN,EAAQuF,oBAAqBrG,GAAcsB,YCyBhFgF,GAAN,MAAMA,UAAsBnyC,GA2C/B,gBAAalX,CAAIqT,EAAsB+D,GAEnC,aADMjE,GAAoBE,GACnB,IAAIg2C,EAAch2C,EAAW+D,EACxC,CAEQ,WAAA3a,CAAY8D,EAAgB6W,GAChCjG,MAAM,UAAW5Q,EAAK6W,EAC1B,CAEQ,uBAAAkyC,CAAwBC,GAC5B,MAAMC,EAAe9iB,GAAa,SAAUlnC,KAAKutC,eACjD,MAAO,CACH2S,UAAW,IAAI1tC,GACXxS,KAAK+T,YACL,GAAGi2C,cACHD,EAAY7J,WACZ,GAEJE,UAAW,IAAI5tC,GACXxS,KAAK+T,YACL,GAAGi2C,cACHD,EAAY3J,WACZ,GAEJ4C,UAAW,IAAIxwC,GACXxS,KAAK+T,YACL,GAAGi2C,cACHD,EAAY/G,WACZ,GAEJD,QAAS,IAAIvwC,GACTxS,KAAK+T,YACL,GAAGi2C,YACHD,EAAYhH,SACZ,GAEJxC,cAAe,IAAI/tC,GACfxS,KAAK+T,YACL,GAAGi2C,kBACHD,EAAYxJ,eACZ,GAEJ0C,UAAW,IAAIzwC,GACXxS,KAAK+T,YACL,GAAGi2C,cACHD,EAAY9G,WACZ,GAEJC,QAAS,IAAI1wC,GACTxS,KAAK+T,YACL,GAAGi2C,YACHD,EAAY7G,SACZ,GAEJ5B,kBAAmB,IAAI9uC,GACnBxS,KAAK+T,YACL,GAAGi2C,sBACHD,EAAYzI,mBACZ,GAEJE,iBAAkB,IAAIhvC,GAClBxS,KAAK+T,YACL,GAAGi2C,qBACHD,EAAYvI,kBACZ,GAEJG,kBAAmB,IAAInvC,GACnBxS,KAAK+T,YACL,GAAGi2C,sBACHD,EAAYpI,mBACZ,GAEJE,eAAgB,IAAIrvC,GAChBxS,KAAK+T,YACL,GAAGi2C,mBACHD,EAAYlI,gBACZ,GAGZ,CAKU,sBAAAppC,CAAuBb,EAA8BW,GAEtDA,IACDsxC,EAAc5Y,oBACdjxC,KAAKutC,cAAgBsc,EAAc5Y,kBACnCjxC,KAAKkxC,cAAgBhK,GAAa,SAAUlnC,KAAKutC,gBAGrDvtC,KAAK+pD,YAAclH,GACfM,GAA8BvrC,EAAQ5X,KAAKkxC,cAAelxC,KAAKutC,eAAe/7B,OAC9ExR,KAAKkxC,eAET,MAAM+Y,EAAqDjqD,KAAK8pD,wBAAwB9pD,KAAK+pD,aAC7F30C,GACI7d,OAAOgL,OAAO0nD,GAA0BjwC,QAAS3T,GAAWA,EAAO0J,aACnE/P,KAAK+T,aAGT,MAAMm2C,EAAsC,CAExCn7C,UAAW6I,GAAQ2vB,OAAO0Y,aAEvBroC,GAAQwoC,WAAW3S,MAAM33B,OAE1BjH,EAAuC,CAAEsjC,WAAY,GAGrDgY,EAAuBjjB,GAAagY,GAAyBl/C,KAAKutC,eAClE6c,EAAsBljB,GAAaiY,GAAwBn/C,KAAKutC,eAChE8c,EAAsBnjB,GAAakY,GAAwBp/C,KAAKutC,eAChE+c,EAAwBpjB,GAAamY,GAA0Br/C,KAAKutC,eACpEgd,EAA0BrjB,GAAasV,GAA4Bx8C,KAAKutC,eACxEid,EAA8BtjB,GAAagW,GAAiCl9C,KAAKutC,eACjFkd,EAAgCvjB,GAAaiW,GAAmCn9C,KAAKutC,eACrFmd,EAAsBxjB,GAAa8W,GAAwBh+C,KAAKutC,eAChEod,EAAsBzjB,GAAa+W,GAAwBj+C,KAAKutC,eAChEqd,EAAyB1jB,GAAagX,GAA2Bl+C,KAAKutC,eACtEsd,EAAsB3jB,GAAaiX,GAAwBn+C,KAAKutC,eAGtEvtC,KAAK8qD,sBAAsBX,Ef1LF,CAACzH,IAE9B,GAAK70C,KAGL,OAAO20C,GAAah0C,GgB9FT,obhB8FgCk0C,IeqLUqI,CAAkBb,GAAiBr7C,GACpF7O,KAAK8qD,sBAAsBV,EAAqB5H,QAAa,EAAW0H,GAAiBr7C,GACzF7O,KAAK8qD,sBAAsBT,EftKH,MAE5B,GAAKx8C,KAGL,OAAOI,GAASO,GiBpHL,oMFqRyCw8C,GAAoBn8C,GACpE7O,KAAK8qD,sBAAsBR,EflLD,CAAC5H,IAE/B,GAAK70C,KAGL,OAAO20C,GAAah0C,GkBzGT,wXlByGiCk0C,Ie6KUuI,CAAmBf,GAAiBr7C,GACtF7O,KAAK8qD,sBAAsBP,EAAyBvI,GAAyBnzC,GAC7E7O,KAAK8qD,sBACDN,EACAvI,GAAoB,SACpBE,IAEJniD,KAAK8qD,sBACDL,EACAxI,GAAoB,WACpBE,IAEJniD,KAAK8qD,sBAAsBJ,EAAqBnI,GAAWtG,IAAsBptC,GACjF7O,KAAK8qD,sBAAsBH,EAAqBpI,GAAWzG,IAAoBjtC,GAC/E7O,KAAK8qD,sBAAsBF,EAAwBrI,GAAWxG,IAAuBltC,GACrF7O,KAAK8qD,sBAAsBD,EAAqBtI,GAAWvG,IAA0BntC,GAGrF,IAAA,MAAWq8C,KAA0BtzC,GAAQ2oC,eAAe9S,MAAMD,aAAe,GAC7ExtC,KAAK8qD,sBAAsBI,EAAuB37C,GAAI27C,EAAuB5jB,MAAiB,CAC1F6K,WAAY+Y,EAAuB/Y,YAAc,IAIzD,OAAO8X,CACX,CAKU,YAAAhxC,CAAarB,GACnB,MAAMuzC,EAAehI,GAA8BvrC,EAAQ5X,KAAKkxC,cAAelxC,KAAKutC,eAGpF,GAAIvtC,KAAK4X,OAAQ,CAEb,MAAMwzC,EAAiBvI,GAAkBsI,EAAa35C,OAAQxR,KAAKkxC,eAGnE35C,OAAO2C,KAAKkxD,GAAgB5jD,QAAS6jD,IACjC,MAAM97C,EAAK87C,EjEtJU,EACjCD,EACAE,EACA3yC,EACA5X,KAGA,MAAMwqD,EAAgEH,EAAe5R,OACjF,CAACgS,EAAKC,KAAA,IAAcD,EAAK,CAACC,EAAIl8C,IAAKk8C,IACnC,CAAA,GAEEC,EAAgEJ,EAAe9R,OACjF,CAACgS,EAAKC,KAAA,IAAcD,EAAK,CAACC,EAAIl8C,IAAKk8C,IACnC,CAAA,GAIEp2C,EAAwB,GACxBs2C,EAA2B,GAC3BC,EAAuD,GACvDC,EAAuD,GAC7Dt0D,OAAO2C,KAAKqxD,GAAc/jD,QAASxM,IAC3B0wD,EAAa1wD,IACb4wD,EAAkB5sD,KAAKusD,EAAavwD,IACpC6wD,EAAkB7sD,KAAK0sD,EAAa1wD,KAEpCqa,EAAYrW,KAAKhE,KAGzBzD,OAAO2C,KAAKwxD,GAAclkD,QAASxM,IAC1BuwD,EAAavwD,IACd2wD,EAAe3sD,KAAKhE,KAK5B,MAAM8U,EAAmC6I,EAAiB5I,YAC1D47C,EAAenkD,QAASgN,IACpBzT,EAAI+qD,YAAYt3C,GAChB,IAAA,IAASqG,EAAI,EAAGA,EAAI/K,EAAW1W,OAAQyhB,IACnC,GAAI/K,EAAW+K,GAAGtL,KAAOiF,EAAS,CAC9B1E,EAAWpP,OAAOma,EAAG,GACrB,KACJ,IAIRxF,EAAY7N,QAASgN,IAEjB,MAAMu3C,EAAyC,IACxCR,EAAa/2C,GAChBnO,OAAQsS,EAAiBtS,OAAOkJ,IAEpCO,EAAW9Q,KAAK+sD,KAEpBpzC,EAAiB3I,2BAEjBkF,GAAkB02C,EAAmBC,EAAmB9qD,IiE8F5CirD,CACIZ,EAAe77C,GACfvP,KAAK+pD,YAAYx6C,GACjBvP,KAAKwY,kBAAkBjJ,GACvBvP,KAAK+T,eAIb,MAAMk4C,EAAgB10D,OAAOgL,OAAOvC,KAAKwY,mBACzCpD,GACI62C,EAAcjyC,QAAS3T,GAAWA,EAAO0J,aACzC/P,KAAK+T,aAGTk4C,EAAczkD,QAASnB,GAAWA,EAAOwK,mBAAmBxK,EAAOqM,cAAcH,SAASnZ,SAC1F4G,KAAK+pD,YAAcqB,CACvB,CAaA,OARKx/C,GAAQ5L,KAAK4X,QAAQ2rC,aAAc4H,EAAa5H,eACjDvjD,KAAKwY,kBAAkBqpC,eAAenvC,cAAcH,SAASnZ,QAE7D4G,KAAKwY,kBAAkBqpC,eAAelvC,KAClCo2C,GAAwB/oD,KAAKwY,kBAAkB0nC,UAAUxtC,cAAey4C,EAAa5H,eAItF4H,CACX,CAKU,wBAAA/xC,GACN,MAAM8yC,EAAkB30D,OAAOwI,QAAQC,KAAKwY,mBACvCzX,IAAKb,IAAA,CACF,CAACA,EAAM,IAAKA,EAAM,GAAGwS,iBAExB8mC,OAAO,CAACgS,EAAKW,KAAA,IAAeX,KAAQW,IAAS,IAElDnsD,KAAKiY,sBAAsBjY,KAAK4X,QAAQ,GACxC5X,KAAKiZ,aAAajZ,KAAK4X,QAEvB,IAAA,MAAW5c,KAAOzD,OAAO2C,KAAKgyD,GAC1BlsD,KAAKwY,kBAAkBxd,GAAK2X,KAAKu5C,EAAgBlxD,GAEzD,CAEQ,qBAAA8vD,CACJt0C,EACA8wB,EACAz4B,GAEA0H,GAAiB,EAAoBC,EAAS8wB,EAAOtnC,KAAK+T,YAAalF,EAC3E,CAsDA,gBAAMu9C,CAAWnI,EAAwBp1C,GACrC,MAAMw9C,EAAgB5D,GAAgBxE,EAAQp1C,GAAS65C,qBACjD1oD,KAAK6Y,uBACX7Y,KAAKwY,kBAAkB0nC,UAAUvtC,KAAK05C,GACtCrsD,KAAKwY,kBAAkB8oC,kBAAkB3uC,KAAKq1C,GAAuBqE,EAAe,sBACpFrsD,KAAKwY,kBAAkBwqC,UAAUrwC,KAC7Bq1C,GAAuBqE,EAAe,UAAWpH,KAErDjlD,KAAKwY,kBAAkB+nC,cAAc5tC,KAAKqxC,GAAuBqI,EAAersD,KAAK4X,SACrF5X,KAAKwY,kBAAkBuqC,QAAQpwC,KAAKq1C,GAAuBqE,EAAe,UAC1ErsD,KAAKwY,kBAAkB0qC,QAAQvwC,KAAKq1C,GAAuBqE,EAAe,WAC1ErsD,KAAKwY,kBAAkByqC,UAAUtwC,KAAKq1C,GAAuBqE,EAAe,SAC5ErsD,KAAKwY,kBAAkBgpC,iBAAiB7uC,KJ5aX,CAACsxC,IAAA,CAClCtqD,KAAM,oBACN4Y,SAAU0xC,EAAO1xC,SAASyH,QACtB,CAACmqC,EAAOkE,IACJlE,EAAM/wC,WAAWk5C,UAAUC,cACrBr8C,OAAQs8C,GAAgBA,EAAYC,WAAWrzD,QAChD2H,IACIyrD,IAAA,CACG7yD,KAAM,UACNk3C,SAAU,CACNl3C,KAAM,aACNy/C,YAAaoT,EAAYC,UAAU1rD,IAAK2rD,GAAcA,EAAUrvC,QAEpEjK,WAAY,IACLo5C,EACHj9C,GAAIqhC,IACJyX,aACAvD,WAAYX,EAAM/wC,WAAW0xC,gBAGpC,MIwZgC6H,CAAsBN,IACnErsD,KAAKwY,kBAAkBmpC,kBAAkBhvC,KJlZP,CAACsxC,IAAA,CACvCtqD,KAAM,oBACN4Y,SAAU0xC,EAAO1xC,SAASyH,QACtB,CAACmqC,EAAOkE,IACJlE,EAAM/wC,WAAWk5C,UAAUC,cACrBr8C,OAAQs8C,GAAgBA,EAAYC,WAAWrzD,QAAUozD,EAAYC,UAAUrzD,OAAS,GACzF2H,IAAKyrD,IACF,MAAMI,EAAyB,CAC3BJ,EAAYC,UAAUD,EAAYC,UAAUrzD,OAAS,IAAIikB,MACzDmvC,EAAYC,UAAUD,EAAYC,UAAUrzD,OAAS,IAAIikB,OAG7D,MAAO,CACH1jB,KAAM,UACNk3C,SAAU,CAAEl3C,KAAM,QAASy/C,YAAawT,EAAuB,IAC/Dx5C,WAAY,IACLo5C,EACHj9C,GAAIqhC,IACJyX,aACAvD,WAAYX,EAAM/wC,WAAW0xC,WAC7B+H,wBAAyBC,GAAYF,EAAuB,GAAIA,EAAuB,SAG7F,MI2XgCG,CAA2BV,IACzErsD,KAAKwY,kBAAkBqpC,eAAelvC,KAAKo2C,GAAwBsD,EAAersD,KAAK4X,QAAQ2rC,cACnG,CAeA,iBAAMyJ,SACIhtD,KAAK6Y,uBACX,IAAA,MAAW7d,KAAOzD,OAAO2C,KAAK8F,KAAKwY,mBACnB,cAARxd,GACAgF,KAAKwY,kBAAkBxd,GAAuCiF,OAG1E,CA6BA,iBAAMgtD,CAAY9zD,GACd,MAAM+zD,EAAgBzE,GAAgBzoD,KAAKwY,kBAAkB0nC,UAAUxtC,cAAevZ,SAEhF6G,KAAK6Y,uBACX7Y,KAAKwY,kBAAkB0nC,UAAUvtC,KAAKu6C,GAEtCltD,KAAKwY,kBAAkB+nC,cAAc5tC,KAAKqxC,GAAuBkJ,EAAeltD,KAAK4X,SACrF2wC,GAA+B2E,EAAeltD,KAAKwY,kBAAkB8oC,mBACrEiH,GAA+B2E,EAAeltD,KAAKwY,kBAAkBwqC,WACrEuF,GAA+B2E,EAAeltD,KAAKwY,kBAAkBuqC,SACrEwF,GAA+B2E,EAAeltD,KAAKwY,kBAAkByqC,WACrEsF,GAA+B2E,EAAeltD,KAAKwY,kBAAkB0qC,SACrEqF,GAA+B2E,EAAeltD,KAAKwY,kBAAkBgpC,kBACrE+G,GAA+B2E,EAAeltD,KAAKwY,kBAAkBmpC,mBACrE4G,GAA+B2E,EAAeltD,KAAKwY,kBAAkBqpC,eACzE,CAMA,mBAAMsL,CAAc/M,GAChB,MAAMgN,EAAmB/zD,MAAMC,QAAQ8mD,GACjC0F,GAAmB1F,EAAWpgD,KAAK4X,QAAQwoC,UAAWpgD,KAAKutC,eAE3DuY,GAAmB1F,EAAU7tC,SAAgCvS,KAAK4X,QAAQwoC,UAAWpgD,KAAKutC,qBAC1FvtC,KAAK6Y,uBACX7Y,KAAKwY,kBAAkB4nC,UAAUztC,KAAKy6C,EAC1C,CAMA,oBAAMC,SACIrtD,KAAK6Y,uBACX7Y,KAAKwY,kBAAkB4nC,UAAUngD,OACrC,CAMA,UAAIoyC,GACA,MAAO,CACH6N,UAAW,IAAI5mC,GACXtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkB0nC,UACvBlgD,KAAK4X,QAAQy6B,QAEjB+N,UAAW,IAAI9mC,GACXtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkB4nC,UACvBpgD,KAAK4X,QAAQy6B,QAEjBkO,cAAe,IAAIjnC,GACftZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkB+nC,cACvBvgD,KAAK4X,QAAQy6B,QAEjBwP,eAAgB,IAAIvoC,GAChBtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkBqpC,eACvB7hD,KAAK4X,QAAQy6B,QAEjB2Q,UAAW,IAAI1pC,GACXtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkBwqC,UACvBhjD,KAAK4X,QAAQy6B,QAEjBiP,kBAAmB,IAAIhoC,GACnBtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkB8oC,kBACvBthD,KAAK4X,QAAQy6B,QAEjB0Q,QAAS,IAAIzpC,GACTtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkBuqC,QACvB/iD,KAAK4X,QAAQy6B,QAEjB4Q,UAAW,IAAI3pC,GACXtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkByqC,UACvBjjD,KAAK4X,QAAQy6B,QAEjB6Q,QAAS,IAAI5pC,GACTtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkB0qC,QACvBljD,KAAK4X,QAAQy6B,QAEjBmP,iBAAkB,IAAIloC,GAClBtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkBgpC,iBACvBxhD,KAAK4X,QAAQy6B,QAGzB,CAOA,0BAAAib,GACI,OAAO3tC,GAAiBI,WAC5B,GA3eA8pC,GAAe5Y,mBAAoB,EADhC,IAAMsc,GAAN1D,SIxGM2D,GAA6C,gBAGpDC,GAAmF,CACrFC,cAAe,CACXC,iBAAkB,kBAClBC,YAAa,sBACbzS,UAAW,mBAEf0S,aAAc,CACVF,iBAAkB,iBAClBC,YAAa,qBACbzS,UAAW,kBAEf2S,aAAc,CACVH,iBAAkB,kBAClBC,YAAa,sBACbzS,UAAW,mBAEf4S,YAAa,CACTJ,iBAAkB,iBAClBC,YAAa,qBACbzS,UAAW,kBAEf6S,UAAW,CACPL,iBAAkB,kBAClBC,YAAa,sBACbzS,UAAW,wBAEf8S,SAAU,CACNN,iBAAkB,iBAClBC,YAAa,qBACbzS,UAAW,uBAEf+S,UAAW,CACPP,iBAAkB,kBAClBC,YAAa,sBACbzS,UAAW,wBAIbgT,GAA2BC,GAA2B,gGAAqBA,IAE3EC,GAA4D,CAC9DX,cAAeS,GAAwB,sBACvCN,aAAcM,GAAwB,qBACtCL,aAAcK,GAAwB,8BACtCJ,YAAaI,GAAwB,6BACrCH,UAAWG,GAAwB,oBACnCF,SAAUE,GAAwB,mBAClCD,UAAWC,GAAwB,2BAGjCG,GAAwB,CAAC72C,EAA8B82C,EAAiBC,KAC1E,MAAMl3C,EAAkBG,EAAclI,IAAMi+C,GAEtCiB,EAAW,IAAIC,IACjBL,GAAyB/2C,GACpB3c,QAAQ,aAAc4zD,GACtB5zD,QAAQ,aAAc8c,EAAck3C,SAAW,WAC/Ch0D,QAAQ,YAAa6zD,IAG9B,IAAA,MAAW/wD,KAAUga,EAAczB,SAAWqlC,GAC1CoT,EAASG,aAAaC,OAAOpxD,EAAQgwD,GAA2Bn2C,GAAiB7Z,IAGrF,OAAOgxD,EAASx2D,YAqBP62D,GAAmBC,IAC5B,MAAMj5C,EAAQi5C,EAAUj5C,MAClBy4C,EAAUQ,EAAUC,cACpBR,EAASO,EAAUP,OAEzB,MAAqB,iBAAV14C,EACAw4C,GAAsB,CAAE/+C,GAAIuG,GAASy4C,EAASC,GAC9B,aAAhB14C,GAAOnc,KACP20D,GAAsBx4C,EAAOy4C,EAASC,GACtB,WAAhB14C,GAAOnc,MAAqBmc,GAAOm5C,IA3B/B,EAACC,EAAkBV,KAClC,MAAMS,EAAM,IAAIP,IAAIQ,GASpB,OARKD,EAAIL,aAAaruD,IAAI,OAGtBmV,QAAQgB,KACJ,kKAHJu4C,EAAIL,aAAazuD,IAAI,MAAOquD,GAOzBS,EAAIh3D,YAkBAk3D,CAAWr5C,EAAMm5C,IAAKT,GACN,WAAhB14C,GAAOnc,MAAqBmc,GAAOs5C,KACnCt5C,EAAMs5C,KAIVd,GAAsB,CAAE/+C,GAAIi+C,IAA6Be,EAASC,ICqCtE,MAAMa,GA4IT,WAAApyD,CAAY8xD,GCpRe,IAACO,EvEqE3BC,EsEoFDvvD,KAAA8T,UAAW,EAqDX9T,KAAiBwvD,oBAA4C,GA8L7DxvD,KAAAoW,SAAW,CAACN,EAAmBjH,EAAmC,CAAE4gD,WAAW,MAC3EzvD,KAAK8T,UAAW,EAChB,IAAA,MAAW2F,KAAWzZ,KAAKwvD,oBACvB,IACI/1C,EAAQrB,wBACZ,OAAS1f,GACLgd,QAAQC,MAAMjd,EAClB,CAEJ,MAAMg3D,EAAiB7gD,EAAQ4gD,UD1SD,EAAC35C,EAAmB65C,IAElDA,GACyB,iBAAlBA,GACgB,aAAvBA,EAAch2D,MACdg2D,EAAc35C,UAEO,iBAAVF,GAAsC,aAAfA,EAAMnc,OAAwBmc,EAAME,SAC3D,CACHrc,KAAM,WACN4V,GAAqB,iBAAVuG,EAAqBA,EAAQA,EAAMvG,GAC9CyG,QAAU25C,EAAgC35C,SAI/CF,EC2RwC85C,CAAuB95C,EAAO9V,KAAK6vD,QAAQ/5C,OAASA,EAC/F9V,KAAK6vD,QAAU,IAAK7vD,KAAK6vD,QAAS/5C,MAAO45C,GACzC1vD,KAAKstC,oBAAsB/1B,GAAuBm4C,GAClD1vD,KAAK+T,YAAYC,KAAK,YAAa,MAI1BhU,KAAK8T,UAAYlI,GAAQ8jD,EAAgB1vD,KAAK6vD,QAAQ/5C,QACvD9V,KAAK8vD,gBAAgBjhD,EAAQ4gD,YAAa,KAGlDzvD,KAAK+T,YAAYqC,SAAS04C,GAAgB9uD,KAAK6vD,SAAU,CAAE5+C,UAAU,KA2CzEjR,KAAAuR,SAAW,IACAvR,KAAK6vD,QAAQ/5C,MAvLpB9V,KAAK6vD,QAAUE,EAAgBhB,QACJ,IAAvB/uD,KAAK6vD,QAAQ/5C,QACb9V,KAAK6vD,QAAU,IAAK7vD,KAAK6vD,QAAS/5C,MAAO03C,KAE7CxtD,KAAKstC,oBAAsB/1B,GAAuBvX,KAAK6vD,QAAQ/5C,OAC/D9V,KAAKgwD,0BAELhwD,KAAK+T,YAAc,IAAIlT,EC3RpB,CAEHovD,eAAe,EACfC,uBAAwB,GACxBC,uCAAuC,MALfb,ED4RmBtvD,KAAK6vD,SCrR7BO,SAEnBt6C,MAAOg5C,GAAgBQ,GACvBe,mBAAoB,CAAEC,SAAS,GAC/BC,kBvE0DHhB,EuE1DyCD,EvE2D1C,CAACL,EAAauB,IACNvB,EAAIx9C,SAAS,cACQ,UAAjB++C,EACO,CAAEvB,OAEN,CAAEA,MAAKwB,QAAS,IAAKC,EAAsBnB,KAE/C,CAAEN,UsEgNTjvD,KAAK+T,YAAYC,KAAK,YAAa,KAC/BhU,KAAK8vD,iBAAgB,KAEzB9vD,KAAKgY,aAAe,IAAImE,GAAYnc,KAAK+T,YAAa/T,KAAK6vD,SAASxd,QAEpEryC,KAAK2wD,mBACT,CAEQ,iBAAAA,GAEJx3C,WAAW,KACF,CAAC,WAAY,UAAU1H,SAASm/C,MACjCC,EACI,iFACA,GACFC,MAAOn7C,GAAUD,QAAQC,MAAM,+CAAgDA,KAG7F,CAKQ,uBAAAq6C,GACJ,GAAwB,oBAAbliD,SACP,OAMJ,GAHqBzU,MAAM03D,KAAKjjD,SAASkjD,iBAAiB,kCAAkC5gD,KAAMtB,GAC9FA,EAAQmiD,aAAax/C,SAAS,oBAG9B,OAIJ,MAAMy/C,EAAOpjD,SAASM,cAAc,QACpC8iD,EAAKC,IAAM,aACXD,EAAKE,KAAO,4DACZtjD,SAASujD,KAAK1O,YAAYuO,EAC9B,CA0IQ,YAAAI,CAAaC,GACjBvxD,KAAK6vD,QAAU,IAAK7vD,KAAK6vD,QAAS0B,YAClC,MAAMC,EAAcD,GAAU9/C,SAAS,KAAO8/C,EAAS1pB,MAAM,KAAK,GAAK0pB,EACvEvxD,KAAK+T,YAAYxC,WAAWC,OAAOhK,QAAS6I,IACxC,GAAmB,WAAfA,EAAM1W,MEvdY,CAAC0W,IAC/B,MAAMi7B,EAAaj7B,EAAM0E,SAAS,eAAiB,GACnD,QAAOu2B,IAGa,WAAdA,GAC0B,IAArBA,EAAUlyC,QAAiC,SAAjBkyC,EAAU,IAGf,IAArBA,EAAUlyC,QACPC,MAAMC,QAAQgyC,EAAU,KACG,iBAApBA,EAAU,GAAG,IACpBA,EAAU,GAAG,GAAG75B,SAAS,UACzBpY,MAAMC,QAAQgyC,EAAU,KACxBA,EAAU,GAAG75B,SAAS,UFycGggD,CAAmBphD,GAAQ,CACtD,MAAMqhD,EAAiBF,EACjB,CAAC,WAAY,CAAC,MAAO,QAAQA,KAAgB,CAAC,MAAO,SACrD,CAAC,MAAO,QACdxxD,KAAK+T,YAAY/C,kBAAkBX,EAAMd,GAAI,aAAcmiD,EAAgB,CAAEzgD,UAAU,GAC3F,GAER,CAsDA,WAAA0gD,CAAYJ,GACJvxD,KAAK8T,SACL9T,KAAKsxD,aAAaC,GAElBvxD,KAAK+T,YAAYC,KAAK,YAAa,IAAMhU,KAAK2xD,YAAYJ,GAElE,CAiDA,OAAAK,GACI,OAAO5xD,KAAK+T,YAAY89C,YAAYC,UAAUvY,MAClD,CAEQ,eAAAuW,CAAgBL,GAGpB,IAAA,MAAWp/C,KAASe,GAAsBpR,KAAK+T,YAAa,CACxDsM,GACAC,GACAH,KAEAngB,KAAK+T,YAAY/C,kBAAkBX,EAAMd,GAAI,aAAc,OAAQ,CAAE0B,UAAU,IAUnF,GtE3LqC2C,OAAOm7C,EAAoCh7C,KACpFA,EAAYg+C,UACR,GAAGhD,EAAUC,0DAA0DD,EAAUP,kBAAkBj3C,GAAuBw3C,EAAUj5C,yCACpI,CAAE7E,UAAU,KsEmLZ+gD,CAA8BhyD,KAAK6vD,QAAS7vD,KAAK+T,aAEjD/T,KAAK6vD,QAAQ0B,UAAYvxD,KAAKsxD,aAAatxD,KAAK6vD,QAAQ0B,UAExDvxD,KAAK8T,UAAW,EACZ27C,EACA,IAAA,MAAWh2C,KAAWzZ,KAAKwvD,oBACvB,IACI/1C,EAAQpB,kBACZ,OAAS3f,GACLgd,QAAQC,MAAMjd,EAClB,CAGZ,CAgHA,qBAAAyf,CAAsBsB,GAClBzZ,KAAKwvD,oBAAoBxwD,KAAKya,EAClC,EGttBG,MAAMw4C,GAAqB,CAC9B,UACA,WACA,MACA,uBACA,OACA,MACA,MACA,cACA,cACA,aACA,OACA,WACA,uBAgCSC,GAA8D,CACvEC,QAAS,EACTC,SAAU,EACVC,IAAK,EACLC,qBAAsB,EACtBC,KAAM,EACNC,IAAK,EACLC,IAAK,EACLC,YAAa,EACbC,YAAa,EACbC,WAAY,EACZC,KAAM,GACNC,SAAU,GACVC,oBAAqB,IAYZC,GAAiB,CAAC,WAAY,QAAS,UAAW,YAAa,WAAY,UA6B3EC,GAAyB,CAAC,aAAc,eAwBxCC,GAAuB,CAAC,QAAS,eCjHxCC,GAAyB,CAC3BC,EACAC,IAEKD,EAAqBh6D,OAGU,IAAhCg6D,EAAqBh6D,OACd,CACHoxC,WAAY4oB,EAAqB,GACjC1gB,OAAQ2gB,EAAwB,IAGjC,CACH7oB,WAAY,CAAC,SAAU4oB,GACvB1gB,OAAQ,CAAC,SAAU2gB,IAVZ,KAwCTC,GAAY,CACdpjD,EACAkjD,EACAC,KAEInjD,IACAkjD,EAAqBp0D,KAAKkR,EAAOs6B,YACjC6oB,EAAwBr0D,KAAKkR,EAAOwiC,UAItC6gB,GAAkB,CACpBC,EACAzgB,EACAqgB,EACAC,KAEIG,GACAF,GAAUngB,GAAkBJ,EAAUygB,GAAeJ,EAAsBC,IAI7EI,GAA6B,CAC/BC,EACAN,EACAC,KAEAE,GAAgBG,EAAUV,eAAgB,gBAAiBI,EAAsBC,GACjFE,GAAgBG,EAAUC,kBAAmB,mBAAoBP,EAAsBC,IAGrFO,GAAgCF,IAClC,MAAMN,EAAkC,GAClCC,EAAqC,GAI3C,GAFAI,GAA2BC,EAAWN,EAAsBC,GAExDK,EAAUzB,mBAAoB,CAC9B,MAAM4B,EAAyB1gB,GAC3B,kBACAugB,EAAUzB,mBACT55D,GAAU65D,GAA0B75D,IAEzCi7D,GAAUO,EAAwBT,EAAsBC,EAC5D,CACA,GAAIK,EAAUI,WAAY,CACtB,MAAMC,EAAmB5gB,GAAkB,YAAaugB,EAAUI,WAAajL,GAC3EmL,EAAkBC,QAAQpL,IAE9ByK,GAAUS,EAAkBX,EAAsBC,EACtD,CAKA,OAJIK,EAAUQ,QACVZ,GA9EsB,CAACa,IAC3B,MAAMf,EAAuB,GACvBC,EAA0B,GAChC,GAAIc,EAAYC,eAAiBD,EAAYE,gBAAiB,CAE1D,MAAMC,EAA6C,GAA9BH,EAAYE,gBACjCjB,EAAqBp0D,KAAK,CAAC,KAAM,CAAC,MAAO,SAAUs1D,IACnDjB,EAAwBr0D,KAAK,CAAC,KAAM,QAASs1D,GACjD,MAAA,GAAWH,EAAYC,cAEnBhB,EAAqBp0D,KAAK,CAAC,IAAK,CAAC,MAAO,SAAU,IAClDq0D,EAAwBr0D,KAAK,CAAC,IAAK,QAAS,SAChD,GAAWm1D,EAAYE,gBAAiB,CAEpC,MAAMC,EAA6C,GAA9BH,EAAYE,gBACjCjB,EAAqBp0D,KAAK,CACtB,MACA,CAAC,IAAK,CAAC,MAAO,UACd,CAAC,KAAM,CAAC,MAAO,SAAU,GACzB,CAAC,KAAM,CAAC,MAAO,SAAUs1D,KAE7BjB,EAAwBr0D,KAAK,CAAC,MAAO,CAAC,OAAQ,SAAU,CAAC,KAAM,QAAS,GAAI,CAAC,KAAM,QAASs1D,IAChG,CACA,OAAOnB,GAAuBC,EAAsBC,IAuDtCkB,CAAsBb,EAAUQ,QAASd,EAAsBC,GAGtEF,GAAuBC,EAAsBC,IAM3CmB,GAAgCC,IACzC,IAAKA,GAAiBC,KAAKt7D,OACvB,OAAO,KAEX,MAAMu7D,EAAkBF,EAAgBC,IACnC3zD,IAAI6yD,IACJ1jD,OAAQ0kD,IAAoB/oD,GAAM+oD,IACvC,OAAOpiB,GAAmBmiB,IAGxBE,GAA2BnB,IAC7B,MAAMN,EAAkC,GAClCC,EAAqC,GAG3C,GADAI,GAA2BC,EAAWN,EAAsBC,GACxDK,EAAUoB,iBAAkB,CAC5B,MAAMC,EAA0C,SAA/BrB,EAAUoB,iBAA8B,KAAO,KAChE1B,EAAqBp0D,KAAK,CAAC+1D,EAAU,CAAC,MAAO,iBAAiB,IAC9D1B,EAAwBr0D,KAAK,CAAC+1D,EAAU,gBAAgB,GAC5D,CAEA,OAAO5B,GAAuBC,EAAsBC,IAuB3C2B,GAAc,CACvB9kD,EACAsB,EACAuC,EACAkhD,KAEA,IAAA,MAAW5kD,KAASmB,EAChBuC,EAAYe,UACRzE,EAAMd,GACNW,EAASyiC,GAAmBziC,EAAQ+kD,EAAgB5kD,EAAMd,KAAO0lD,EAAgB5kD,EAAMd,MCnF5F,MAAM2lD,WAA0Bx9C,GA4CnC,gBAAalX,CAAIO,EAAgB6W,GAG7B,aAFMjE,GAAoB5S,SACpBmV,GAAmBnV,EAAKuf,GAAwB,eAC/C,IAAI40C,GAAkBn0D,EAAK6W,EACtC,CAEQ,WAAA3a,CAAY8D,EAAgB6W,GAChCjG,MAAM,QAAS5Q,EAAK6W,EACxB,CAKU,sBAAAa,GACN,MAAM08C,EAAan1D,KAAK+T,YAAYpE,UAAU2Q,IAC9C,IAAK60C,EACD,MAAMznD,GAAc,QAAQwnD,GAAkB5rD,uBAAuBgX,MAEzEtgB,KAAKi1D,gBAAkB,CAAA,EACvB,IAAA,MAAW5kD,KAASrQ,KAAKo1D,YACrBp1D,KAAKi1D,gBAAgB5kD,EAAMd,IAAMc,EAAMH,OAE3C,MAAO,CAAE09C,YAAa,IAAIl8C,GAAsB1R,KAAK+T,YAAaohD,GACtE,CAKU,YAAAl8C,CAAarB,GAGnB,OAFA5X,KAAK00C,WAAW98B,GAAQ9G,UAAW,GACnC9Q,KAAKq1D,QAAQz9C,GAAQ66B,SAAS,GACvB76B,CACX,CAEQ,SAAAw9C,GACJ,OAAOhkD,GAAsBpR,KAAK6T,UAAUE,YAAa,CAACuM,IAC9D,CAwEA,MAAApQ,CAAOuiC,GACHzyC,KAAKq1D,QAAQ5iB,EACjB,CAEQ,OAAA4iB,CAAQ5iB,EAAyC6iB,GAAe,GACpE,GAAIt1D,KAAK6T,UAAUC,SACf,GAAI2+B,GAASiiB,KAAKt7D,OAAQ,CACtB,MAAMm8D,EDtGkB,CAACC,IACrC,IAAKA,GAAad,KAAKt7D,OACnB,OAAO,KAEX,MAAMu7D,EAAkBa,EAAYd,IAC/B3zD,IAAI8zD,IACJ3kD,OAAQ0kD,IAAoB/oD,GAAM+oD,IACvC,OAAOpiB,GAAmBmiB,IC+FWc,CAAyBhjB,GAC9C8iB,GACAP,GAAYO,EAAkBv1D,KAAKo1D,YAAap1D,KAAK+T,YAAa/T,KAAKi1D,gBAE/E,MAAWj1D,KAAK4X,QAAQ66B,SAASiiB,KAAKt7D,QAClC47D,QAAY,EAAWh1D,KAAKo1D,YAAap1D,KAAK+T,YAAa/T,KAAKi1D,iBAIpEK,IACAt1D,KAAK4X,OAASxK,GAAO,IAAKpN,KAAK4X,OAAQ66B,WAAW5mC,IAE1D,CAaA,UAAA6oC,CAAW5jC,GACP9Q,KAAK4X,OAAS,IAAK5X,KAAK4X,OAAQ9G,WAC5B9Q,KAAK6T,UAAUC,UACf9T,KAAKwY,kBAAkBo1C,YAAY/8C,iBAAiBC,EAE5D,CAKA,SAAA6jC,GACI,OAAO30C,KAAKwY,kBAAkBo1C,YAAY39C,mBAC9C,CAMA,UAAIoiC,GACA,OAAO,IAAI/4B,GAAatZ,KAAK6T,UAAUmE,aAAchY,KAAKwY,kBAAkBo1C,YAAa5tD,KAAK4X,QAAQy6B,OAC1G,ECvKG,MAAMqjB,WAA+Bh+C,GA4CxC,gBAAalX,CAAIO,EAAgB6W,GAG7B,aAFMjE,GAAoB5S,SACpBmV,GAAmBnV,EAAKsf,GAA6B,oBACpD,IAAIq1C,GAAuB30D,EAAK6W,EAC3C,CAEQ,WAAA3a,CAAY8D,EAAgB6W,GAChCjG,MAAM,QAAS5Q,EAAK6W,EACxB,CAKU,sBAAAa,GACN,MAAMk9C,EAAkB31D,KAAK+T,YAAYpE,UAAU0Q,IACnD,IAAKs1C,EACD,MAAMjoD,GAAc,QAAQgoD,GAAuBpsD,uBAAuB+W,MAE9ErgB,KAAKi1D,gBAAkB,CAAA,EACvB,IAAA,MAAW5kD,KAASrQ,KAAKo1D,YACrBp1D,KAAKi1D,gBAAgB5kD,EAAMd,IAAMc,EAAMH,OAE3C,MAAO,CAAEy9C,iBAAkB,IAAIj8C,GAAsB1R,KAAK+T,YAAa4hD,GAC3E,CAKU,YAAA18C,CAAarB,GAOnB,OALA5X,KAAK41D,YAAYh+C,GAAQ9G,UAAW,EAAO,CAAEwkD,cAAc,IACtDzpD,GAAM+L,GAAQi+C,OAAO/kD,UACtB9Q,KAAK81D,gBAAgBl+C,EAAOi+C,MAAM/kD,SAEtC9Q,KAAKq1D,QAAQz9C,GAAQ66B,QAAS76B,GAAQi+C,OAAOpjB,SAAS,GAC/C76B,CACX,CA8EA,MAAA1H,CAAOukD,EAA2CsB,GAC9C/1D,KAAKq1D,QAAQZ,EAAiBsB,EAClC,CAEQ,OAAAV,CACJZ,EACAsB,EACAT,GAAe,GAEf,GAAIt1D,KAAK6T,UAAUC,SAAU,CACzB,GAAI2gD,GAAiBC,KAAKt7D,OAAQ,CAC9B,MAAM48D,EAA2BxB,GAA6BC,GAC9D,GAAIuB,EAA0B,CAC1B,MAAMxkD,EAASukD,EAAc/1D,KAAKi2D,qBAAuBj2D,KAAKo1D,YAC9DJ,GAAYgB,EAA0BxkD,EAAQxR,KAAK+T,YAAa/T,KAAKi1D,gBACzE,CACJ,MAAWj1D,KAAK4X,QAAQ66B,SAASiiB,KAAKt7D,QAClC47D,QAAY,EAAWh1D,KAAKo1D,YAAap1D,KAAK+T,YAAa/T,KAAKi1D,iBAEpE,GAAIc,GAAarB,KAAKt7D,OAAQ,CAC1B,MAAM88D,EAAuB1B,GAA6BuB,GACtDG,GACAlB,GAAYkB,EAAsBl2D,KAAKm2D,kBAAmBn2D,KAAK+T,YAAa/T,KAAKi1D,gBAEzF,CACJ,CAGIK,IACAt1D,KAAK4X,OAASxK,GACV,IACOpN,KAAK4X,OACR66B,QAASgiB,EACToB,MAAO,IAAK71D,KAAK4X,QAAQi+C,MAAOpjB,QAASsjB,IAE7ClqD,IAGZ,CAEQ,SAAAupD,GACJ,OAAOhkD,GAAsBpR,KAAK6T,UAAUE,YAAa,CAACsM,IAC9D,CAEQ,eAAA81C,GACJ,OAAOn2D,KAAKo1D,YAAYllD,OAAQG,GAAyB,WAAfA,EAAM1W,KACpD,CAEQ,kBAAAs8D,GACJ,OAAOj2D,KAAKo1D,YAAYllD,OAAQG,GAAwB,UAAdA,EAAM1W,KACpD,CAmBA,eAAAm8D,CAAgBhlD,GAEZ9Q,KAAK4X,OAAS,IAAK5X,KAAK4X,OAAQi+C,MAAO,IAAK71D,KAAK4X,QAAQi+C,MAAO/kD,YAE5D9Q,KAAK6T,UAAUC,UACf9T,KAAKwY,kBAAkBm1C,iBAAiB98C,iBACpCC,EACCC,GAAiC,WAAnBA,EAAUpX,KAGrC,CAgBA,UAAA+6C,CAAW5jC,GACP9Q,KAAK41D,YAAY9kD,EACrB,CAEQ,WAAA8kD,CAAY9kD,EAAkBjC,IACbA,GAASymD,eAAgB,YAGnCt1D,KAAK4X,QAAQi+C,OAAO/kD,QAE3B9Q,KAAK4X,OAAS,IAAKxK,GAAO,IAAKpN,KAAK4X,QAAUjM,IAAUmF,YAExD9Q,KAAK6T,UAAUC,UACf9T,KAAKwY,kBAAkBm1C,iBAAiB98C,iBAAiBC,EAEjE,CAcA,SAAA6jC,GACI,OAAO30C,KAAKwY,kBAAkBm1C,iBAAiB19C,mBACnD,CAcA,oBAAAmmD,GACI,QAASp2D,KAAKwY,kBAAkBm1C,kBAAkB19C,kBAAmBc,GAAiC,WAAnBA,EAAUpX,KACjG,CAMA,UAAI04C,GACA,OAAO,IAAI/4B,GACPtZ,KAAK6T,UAAUmE,aACfhY,KAAKwY,kBAAkBm1C,iBACvB3tD,KAAK4X,QAAQy6B,OAErB,EC3aJ,MAAMgkB,GAA2B,CAACC,EAAsBC,KAAA,CACpDrsB,KAAMosB,EAAYpsB,KAAOqsB,EAAcrsB,KACvCD,IAAKqsB,EAAYrsB,IAAMssB,EAActsB,IACrCE,MAAOmsB,EAAYnsB,MAAQosB,EAAcrsB,KACzCssB,OAAQF,EAAYE,OAASD,EAActsB,MAGzCwsB,GAA4B,CAACC,EAAkBC,EAAwBC,IACzEF,EAAOvsB,OAAS,GAAKusB,EAAOxsB,MAAQysB,GAAkBD,EAAOF,QAAU,GAAKE,EAAOzsB,KAAO2sB,EAGxFC,GAAyB,CAC3BH,EACAI,EACAF,EACAt5C,KAEwBo5C,EAAOzsB,KACJ2sB,EAAkBF,EAAOF,OAEhDM,EAAe7sB,IAAMttC,KAAKC,IAAIk6D,EAAe7sB,IAAKysB,EAAOF,OAASl5C,GAElEw5C,EAAeN,OAAS75D,KAAKo6D,IAAID,EAAeN,OAAQE,EAAOzsB,IAAM3sB,IAKvE05C,GAAuB,CACzBN,EACAI,EACAH,EACAr5C,KAEyBo5C,EAAOxsB,MACNysB,EAAiBD,EAAOvsB,MAE9C2sB,EAAe5sB,KAAOvtC,KAAKC,IAAIk6D,EAAe5sB,KAAMwsB,EAAOvsB,MAAQ7sB,GAEnEw5C,EAAe3sB,MAAQxtC,KAAKo6D,IAAID,EAAe3sB,MAAOusB,EAAOxsB,KAAO5sB,IAyCtE25C,GAAgC,CAClCP,EACAI,EACAI,EACAC,EACA75C,KAGA,MAAM85C,EAfqB,EAACV,EAAkBC,EAAwBC,KAAA,CACtE1sB,KAAMvtC,KAAKC,IAAI,EAAG85D,EAAOxsB,MACzBD,IAAKttC,KAAKC,IAAI,EAAG85D,EAAOzsB,KACxBE,MAAOxtC,KAAKo6D,IAAIJ,EAAgBD,EAAOvsB,OACvCqsB,OAAQ75D,KAAKo6D,IAAIH,EAAiBF,EAAOF,UAWnBa,CAAuBX,EAAQQ,EAAYC,GAI3DG,EAAiBZ,EAAOxsB,MAAQ,GAAKwsB,EAAOvsB,OAAS+sB,EACrDK,EAAkBb,EAAOzsB,KAAO,GAAKysB,EAAOF,QAAUW,EAG5D,GAAIG,IAAmBC,EAEnB,YADAV,GAAuBO,EAAeN,EAAgBK,EAAa75C,GAKvE,GAAIi6C,IAAoBD,EAEpB,YADAN,GAAqBI,EAAeN,EAAgBI,EAAY55C,GAKpE,MAAMk6C,EAAcd,EAAOxsB,MAAQ,EAC7ButB,EAAef,EAAOvsB,OAAS+sB,EAC/BQ,EAAahB,EAAOzsB,KAAO,EAC3B0tB,EAAgBjB,EAAOF,QAAUW,GAIlCK,IAAeC,GAAkBC,GAAeC,GAKhDD,IAAcC,GAAmBH,GAAgBC,EA5EzB,EAC7Bf,EACAI,EACAH,EACAC,EACAt5C,KAEA,MAAMs6C,EAAmBlB,EAAOxsB,KAC1B2tB,EAAoBlB,EAAiBD,EAAOvsB,MAC5C2tB,EAAkBpB,EAAOzsB,IACzB8tB,EAAqBnB,EAAkBF,EAAOF,OAC9CwB,EAAcr7D,KAAKo6D,IAAIa,EAAkBC,EAAmBC,EAAiBC,GAE/EC,IAAgBJ,EAChBd,EAAe5sB,KAAOvtC,KAAKC,IAAIk6D,EAAe5sB,KAAMwsB,EAAOvsB,MAAQ7sB,GAC5D06C,IAAgBH,EACvBf,EAAe3sB,MAAQxtC,KAAKo6D,IAAID,EAAe3sB,MAAOusB,EAAOxsB,KAAO5sB,GAC7D06C,IAAgBF,EACvBhB,EAAe7sB,IAAMttC,KAAKC,IAAIk6D,EAAe7sB,IAAKysB,EAAOF,OAASl5C,GAElEw5C,EAAeN,OAAS75D,KAAKo6D,IAAID,EAAeN,OAAQE,EAAOzsB,IAAM3sB,IAgEzE26C,CAAyBb,EAAeN,EAAgBI,EAAYC,EAAa75C,GAN7E05C,GAAqBI,EAAeN,EAAgBI,EAAY55C,GALhEu5C,GAAuBO,EAAeN,EAAgBK,EAAa75C,IAoBrE46C,GAAaC,GACI,iBAARA,EACArqD,SAASkB,cAAcmpD,GAE3BA,EASLC,GAAkBr3D,GAChB,gBAAiBA,EACVA,EAAIgT,YAERhT,EAaLs3D,GAA6B,CAC/Bt3D,EACAu3D,EACAC,KAEA,MAAMhC,EAAgB6B,GAAer3D,GAAKy3D,eAAeC,yBACjD3wB,MAAOovB,EAAYjvB,OAAQkvB,GAAgBZ,EAG7CmC,EAA8B,CAChCxuB,KAAMquB,EACNtuB,IAAKsuB,EACLpuB,MAAO+sB,EAAaqB,EACpB/B,OAAQW,EAAcoB,GAG1B,IAAA,MAAWI,KAAcL,EAAqB,CAC1C,MAAMxpD,EAAUopD,GAAUS,GAC1B,IAAK7pD,EACD,SAEJ,MAAMwnD,EAAcxnD,EAAQ2pD,wBACtBG,EAAgBvC,GAAyBC,EAAaC,GAExDE,GAA0BmC,EAAe1B,EAAYC,IAIzDF,GAA8B2B,EAAeF,EAAmBxB,EAAYC,EAAaoB,EAC7F,CAEA,OAAIG,EAAkBxuB,MAAQwuB,EAAkBvuB,OAASuuB,EAAkBzuB,KAAOyuB,EAAkBlC,OACzF,KAGJ,CAAEkC,oBAAmBxB,aAAYC,gBAe/B0B,GAAuBhqD,IAChC,MAAM9N,IAAEA,EAAAu3D,oBAAKA,EAAAC,UAAqBA,EAAY,GAAM1pD,EAE9ClW,EAAS0/D,GAA2Bt3D,EAAKu3D,EAAqBC,GACpE,IAAK5/D,EACD,OAAO,KAGX,MAAM+/D,kBAAEA,GAAsB//D,EACxBob,EAAcqkD,GAAer3D,GAC7B+3D,EAAK/kD,EAAYglD,UAAU,CAACL,EAAkBxuB,KAAMwuB,EAAkBlC,SACtEwC,EAAKjlD,EAAYglD,UAAU,CAACL,EAAkBvuB,MAAOuuB,EAAkBzuB,MAE7E,MAAO,CAAC6uB,EAAGG,IAAKH,EAAGI,IAAKF,EAAGC,IAAKD,EAAGE,MAgB1BC,GAAyBtqD,IAClC,MAAM9N,IAAEA,EAAAu3D,oBAAKA,GAAwBzpD,EAC/BiiC,EAAO+nB,GAAoB,CAAE93D,MAAKu3D,wBACxC,IAAKxnB,EACD,OAAO,KAEX,MAAOsoB,EAAMC,EAAOC,EAAMC,GAASzoB,EACnC,MAAO,EAAEsoB,EAAOE,GAAQ,GAAID,EAAQE,GAAS,IAkBpCC,GAAwB3qD,IACjC,MAAM9N,IAAEA,EAAA04D,kBAAKA,EAAAnB,oBAAmBA,EAAAC,UAAqBA,EAAY,GAAM1pD,EAEjElW,EAAS0/D,GAA2Bt3D,EAAKu3D,EAAqBC,GACpE,IAAK5/D,EACD,OAAO,KAGX,MAAM+/D,kBAAEA,EAAAxB,WAAmBA,EAAAC,YAAYA,GAAgBx+D,EAIjD+gE,EAAYhB,EAAkBxuB,KAAOgtB,EACrCyC,EAAajB,EAAkBvuB,MAAQ+sB,EACvC0C,EAAWlB,EAAkBzuB,IAAMktB,EAInC0C,EAAaF,EAAaD,EAC1BI,EAJcpB,EAAkBlC,OAASW,EAIbyC,GAG3BR,EAAMC,EAAOC,EAAMC,GAASE,EAM7BM,GALcT,EAAOF,GAKKS,EAC1BG,GALeT,EAAQF,GAKKS,EAI5BG,EAAeb,EAAOM,EAAYK,EAKlCG,EAAgBX,EAAQK,EAAWI,EAGzC,MAAO,CAACC,EAFcC,EAAgBF,EALjBC,EAAeF,EAOeG","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,230,231,232]}
|