mobility-toolbox-js 1.3.9 → 1.3.11

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://mobility-toolbox-js/webpack/universalModuleDefinition","webpack://mobility-toolbox-js/webpack/bootstrap","webpack://mobility-toolbox-js/external \"ol/proj\"","webpack://mobility-toolbox-js/external \"ol/style\"","webpack://mobility-toolbox-js/external \"ol/Observable\"","webpack://mobility-toolbox-js/external \"ol/geom\"","webpack://mobility-toolbox-js/external \"ol/extent\"","webpack://mobility-toolbox-js/external \"query-string\"","webpack://mobility-toolbox-js/external \"ol/layer\"","webpack://mobility-toolbox-js/external \"ol/format/GeoJSON\"","webpack://mobility-toolbox-js/external \"ol/Feature\"","webpack://mobility-toolbox-js/external \"ol/Object\"","webpack://mobility-toolbox-js/external \"ol/layer/Layer\"","webpack://mobility-toolbox-js/external \"mapbox-gl\"","webpack://mobility-toolbox-js/external \"ol/source/Source\"","webpack://mobility-toolbox-js/external \"ol/source\"","webpack://mobility-toolbox-js/external \"ol/geom/GeometryType\"","webpack://mobility-toolbox-js/external \"ol\"","webpack://mobility-toolbox-js/external \"ol/format\"","webpack://mobility-toolbox-js/external \"ol/Map\"","webpack://mobility-toolbox-js/external \"ol/control\"","webpack://mobility-toolbox-js/external \"ol/layer/Group\"","webpack://mobility-toolbox-js/external \"uuid\"","webpack://mobility-toolbox-js/external \"ol/geom/Point\"","webpack://mobility-toolbox-js/external \"ol/interaction\"","webpack://mobility-toolbox-js/external \"ol/events/condition\"","webpack://mobility-toolbox-js/./src/common/layers/Layer.js","webpack://mobility-toolbox-js/./src/ol/layers/Layer.js","webpack://mobility-toolbox-js/./src/common/controls/Control.js","webpack://mobility-toolbox-js/./src/common/mixins/MapMixin.js","webpack://mobility-toolbox-js/./src/common/mixins/CopyrightMixin.js","webpack://mobility-toolbox-js/./src/common/utils/removeDuplicate.js","webpack://mobility-toolbox-js/./src/ol/controls/CopyrightControl.js","webpack://mobility-toolbox-js/./src/ol/Map.js","webpack://mobility-toolbox-js/./src/common/utils/getMapboxMapCopyrights.js","webpack://mobility-toolbox-js/./src/common/utils/getMapboxStyleUrl.js","webpack://mobility-toolbox-js/./src/ol/layers/MapboxLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/RoutingLayer.js","webpack://mobility-toolbox-js/./src/common/Tracker.js","webpack://mobility-toolbox-js/./src/common/trackerConfig.js","webpack://mobility-toolbox-js/./src/common/mixins/TrackerLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TrackerLayer.js","webpack://mobility-toolbox-js/./src/common/timeUtils.js","webpack://mobility-toolbox-js/./src/common/api/api.js","webpack://mobility-toolbox-js/./src/api/stops/StopsAPI.js","webpack://mobility-toolbox-js/./src/api/trajserv/TrajservAPIUtils.js","webpack://mobility-toolbox-js/./src/api/trajserv/TrajservAPI.js","webpack://mobility-toolbox-js/./src/api/tralis/WebSocketConnector.js","webpack://mobility-toolbox-js/./src/api/tralis/TralisAPIUtils.js","webpack://mobility-toolbox-js/./src/api/tralis/TralisAPI.js","webpack://mobility-toolbox-js/./src/common/mixins/TrajservLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TrajservLayer.js","webpack://mobility-toolbox-js/./src/common/mixins/TralisLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TralisLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/VectorLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/WMSLayer.js","webpack://mobility-toolbox-js/./src/common/mixins/SearchMixin.js","webpack://mobility-toolbox-js/./src/ol/controls/StopFinderControl.js","webpack://mobility-toolbox-js/./src/mapbox/controls/CopyrightControl.js","webpack://mobility-toolbox-js/./src/mapbox/Map.js","webpack://mobility-toolbox-js/./src/mapbox/utils.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TrackerLayer.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TralisLayer.js","webpack://mobility-toolbox-js/./src/index.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TrajservLayer.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","require","Layer","options","defineProperties","isQueryable","copyrights","onClick","children","visible","properties","isBaseLayer","uid","uuid","dfltName","this","toLowerCase","isReactSpatialLayer","writable","set","newCopyrights","arrValue","Array","isArray","undefined","map","clickCallbacks","terminate","dispatchEvent","type","target","stopPropagationDown","stopPropagationUp","stopPropagationSiblings","filter","child","hasChildren","find","layer","unshift","length","splice","Promise","resolve","features","coordinate","callback","Error","includes","push","idx","indexOf","Observable","olLayer","setVisible","olListenersKeys","getLayers","on","evt","element","attributions","Group","getArray","forEach","getSource","setAttributions","unByKey","newOptions","LayerCommon","Control","active","render","newActive","activate","deactivate","parentNode","removeChild","targett","getContainer","createDefaultElement","appendChild","BaseObject","MapMixin","Base","layers","controls","mobilityLayers","mobilityControls","control","addControl","addLayer","position","addMobilityControl","removeMobilityControl","CopyrightMixin","innerHTML","getCopyrights","join","document","createElement","id","assign","style","bottom","right","fontSize","padding","removeDuplicate","array","arrWithoutEmptyValues","val","trim","lowerCasesValues","str","Set","uniqueStr","CopyrightControl","onPostRender","frameState","layerStatesArray","layerState","inView","viewState","getAttributions","concat","un","mixin","Map","defaultControls","attribution","getTargetElement","init","OLMap","getMapboxMapCopyrights","sourceCaches","values","sourceCache","used","source","replace","split","getMapboxStyleUrl","apiKey","apiKeyName","styleUrl","parsedStyle","qs","parseUrl","query","stringifyUrl","console","warn","MapboxLayer","mbLayer","OLLayer","Source","mbMap","changed","canvas","getCanvas","getVisible","renderState","display","opacity","getOpacity","rotation","rotateTo","Math","PI","animate","zoom","center","jumpTo","toLonLat","size","getSize","isStyleLoaded","_frame","cancel","_render","err","url","updateAttribution","format","GeoJSON","featureProjection","getView","getProjection","loadMbMap","resize","getCenter","x","y","createStyleUrl","mapboxgl","attributionControl","boxZoom","container","interactive","fadeDuration","preserveDrawingBuffer","once","loaded","mapboxCanvas","tabIndex","setAttribute","removeAttribute","newAttributions","toString","pixel","project","queryRenderedFeatures","feature","olFeature","readFeature","off","triggerRepaint","remove","Tracker","opts","interpolate","trajectories","renderedTrajectories","getPixelFromCoordinate","hoverVehicleId","selectedVehicleId","iconScale","width","height","canvasContext","getContext","visibility","sort","clearRect","offsetX","offsetY","oldLeft","parseFloat","left","oldTop","top","currTime","Date","now","resolution","noInterpolate","clear","hoverVehicleImg","hoverVehiclePx","hoverVehicleWidth","hoverVehicleHeight","selectedVehicleImg","selectedVehiclePx","selectedVehicleWidth","selectedVehicleHeight","currResolution","traj","geometry","timeIntervals","timeOffset","coord","start","end","startFrac","endFrac","timeFrac","j","getType","GeomType","POINT","getCoordinates","LINE_STRING","min","geomFrac","getCoordinateAt","endFraction","getFirstCoordinate","getLastCoordinate","error","px","rendered","vehicleImg","imgWidth","imgHeight","floor","drawImage","olEventsKeys","trackerRadiusMapping","0","1","2","3","4","5","6","7","8","9","types","bgColors","textColors","timeSteps","getTypeIndex","matched","RegExp","test","getBgColor","typeIdx","e","getDelayColor","delayInMs","cancelled","isDelayText","TrackerLayerMixin","isHoverActive","cuurSpeed","speed","isTrackerLayer","defaultStyle","newSpeed","tracker","setFilter","setSort","styleCache","lastUpdateTime","useRequestAnimationFrame","default","setStyle","props","visibilityRef","stop","destroy","renderTrajectories","startUpdateTime","stopUpdateTime","updateTimeInterval","setInterval","newTime","getTime","setCurrTime","getRefreshTimeInMs","clearInterval","time","requestId","cancelAnimationFrame","requestAnimationFrame","mustRender","filterFc","getTrajectories","nb","Infinity","ext","buffer","vehicles","containsCoordinate","roundedZoom","round","timeStep","max","text","ctx","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","font","strokeText","fillText","TrackerLayer","renderWhenZooming","oldPx","moveCanvas","view","getResolution","getAnimating","getInteracting","currentZoom","getZoom","z","vehicle","getVehiclesAtCoordinate","cursor","getUTCDateString","month","getUTCMonth","day","getUTCDate","getUTCFullYear","getUTCTimeString","date","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","API","path","params","config","urlParams","clone","keys","fetch","stringify","then","response","json","data","reject","StopsAPI","abortController","signal","featureCollection","translateDates","dates","newDates","year","translateTrajStationsResp","newData","prop","destination","hs","vehicleType","longName","ln","shortName","sn","wheelchairAccessible","wa","bicyclesAllowed","ba","realTime","rt","feedsId","fid","routeIdentifier","rid","bgColor","datacolor","tc","a","operator","operatorUrl","u","operatorTimeZone","tz","f","publisher","publisherUrl","publisherTimeZone","tt","dateNotOperatingDays","dateAdditionalOperatingDays","operatingPeriod","dataStations","sts","notOperatingDays","additionalOperatingDays","backgroundColor","color","stations","stationId","sid","stationName","coordinates","arrivalTime","at","departureTime","dt","arrivalDate","ap","departureDate","dp","arrivalDelay","ad","departureDelay","dd","noDropOff","dot","noPickUp","put","stWheelchairAccessible","operatingInformations","translateTrajCollResponse","LineString","ID","ProductIdentifier","PublishedLineName","RouteIdentifier","directionText","DirectionText","Operator","OperatorURL","Publisher","PublisherURL","license","License","licenseUrl","LicenseUrl","licenseNote","LicenseNote","Color","journeyIdentifier","JourneyIdentifier","realtimeAvailable","RealtimeAvailable","operatorProvidesRealtime","OperatorProvidesRealtime","dayOfOperation","DayOfOperation","delay","Delay","TimeIntervals","textColor","TextColor","Cancelled","TrajservAPI","WebSocketConnector","subscriptions","connect","send","subscribed","method","reqStr","channel","args","websocket","readyState","CLOSED","close","WebSocket","currentProj","setProjection","currentBbox","setBbox","subscribe","cb","errorCb","onclose","clearTimeout","reconnectTimeout","setTimeout","getRequestString","listen","message","CONNECTING","addEventListener","onMessage","JSON","parse","client_reference","onMessageCb","onErrorCb","quiet","removeEventListener","getModeSuffix","modes","SCHEMATIC","compareDepartures","b","sortByMinArrivalTime","topStates","aTop","has_fzo","state","bTop","aDuration","bDuration","min_arrival_time","cleanStopTime","content","station","arrivalTimeWithDelay","departureTimeWithDelay","TralisModes","RAW","TOPOGRAPHIC","TralisAPI","wsUrl","subscribedStationUic","departureUpdateTimeout","maxDepartureAge","extraGeoms","prefix","conn","projection","bbox","onSuccess","onError","suffix","unsubscribe","depObject","departures","k","future","setMinutes","getMinutes","past","departureArray","platformsBoarding","previousDeparture","platform","to","abs","line","unsubscribeDepartures","departureObject","tDiff","timestamp","timediff","call_id","filterDepartures","uic","stationUpdateTimeout","unsubscribeStations","extraGeom","ref","unsubscribeTrajectory","unsubscribeDeletedVehicles","ids","promises","getFullTrajectory","all","unsubscribeFullTrajectory","log","getStopSequence","fullTrajectoryUpdateTimeout","unsubscribeStopSequence","unsubscribeHealthCheck","TrajservLayerMixin","defaultApi","regexPublishedLineName","publishedLineName","tripNumber","requestIntervalSeconds","api","apiOptions","showVehicleTraj","delayDisplay","delayOutlineColor","useDelayStyle","newRequestIntervalSeconds","newPublishedLineName","updateFilters","newTripNumber","newOperator","newRegex","sortFc","startUpdateTrajectories","journeyId","stopUpdateTrajectories","abortFetchTrajectories","parameters","location","search","route","regexLine","filterList","regexLineList","some","tr","lineList","toUpperCase","routeList","item","parseInt","routeId","operatorList","op","createFilters","abort","trajId","getParams","fetchTrajectoryStations","extraParams","requestIntervalInMs","intervalMs","diff","later","btime","etime","cd","nm","fl","updateTrajectories","updateInterval","AbortController","fetchTrajectories","attr_det","catch","setTrajectories","hover","selected","radius","getRadius","isDisplayStrokeAndDelay","radiusDelay","markerSize","margin","circleFillColor","origin","save","beginPath","restore","textAlign","textBaseline","delayText","String","fromCodePoint","rounded","getDelayText","setLineDash","textSize","newText","measureText","getTextSize","getTextColor","TrajservLayer","vectorLayer","VectorLayer","VectorSource","insertAt","removeLayer","onMapClick","onMoveEnd","highlightTrajectory","geom","Point","Feature","updateTrajectoryStations","trajStations","stationsCoords","lineGeometry","vehiculeColor","vectorSource","MultiPoint","aboveStationsFeature","Style","zIndex","image","Circle","Fill","belowStationsFeature","addFeatures","lineFeat","Stroke","addFeature","transformCoords","fetchTrajectoryById","multiLine","lineCoords","point","drawFullTrajectory","calculateExtent","getWidth","TralisLayerMixin","debug","refreshTimeInMs","onDeleteMessage","dfltIconScale","dfltIconHighlightScale","minIconScale","subscribeTrajectory","subscribeDeletedVehicles","feat","transform","setGeometry","addTrajectory","getProperties","removeTrajectoryByAttribute","addOnTop","findIndex","train_id","time_intervals","trajectory","len","attributeName","removeTrajectory","TralisLayer","hitTolerance","getFeaturesAtPixel","layerFilter","singleClickRef","getFeatureInfoAtCoordinate","callClickCallbacks","WMSLayer","getFeatureInfoUrl","info_format","query_layers","resp","MBMap","bounds","getBounds","toArray","extent","fromLonLat","xResolution","yResolution","getHeight","getSourceCoordinates","onMapZoomEnd","onMapMouseMove","setIconScale","clientWidth","updateIconScale","pixelRatio","devicePixelRatio","lng","lat","isMoving","isRotating","isZooming","lngLat","onMove","beforeId","onZoomEnd","addSource","paint","setCoordinates","mapbox","onVisibilityChange","layout","listeners","listener","removeSource","getLayer","vehicleWithStations","southWest","northEast","mbTralisLayer","ol","olWMSLayer","olMapboxLayer","olTrajservLayer","olTralisLayer","olVectorLayer"],"mappings":"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","file":"index.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"mobility-toolbox-js\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"mobility-toolbox-js\"] = factory();\n\telse\n\t\troot[\"mobility-toolbox-js\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 24);\n","module.exports = require(\"ol/proj\");","module.exports = require(\"ol/style\");","module.exports = require(\"ol/Observable\");","module.exports = require(\"ol/geom\");","module.exports = require(\"ol/extent\");","module.exports = require(\"query-string\");","module.exports = require(\"ol/layer\");","module.exports = require(\"ol/format/GeoJSON\");","module.exports = require(\"ol/Feature\");","module.exports = require(\"ol/Object\");","module.exports = require(\"ol/layer/Layer\");","module.exports = require(\"mapbox-gl\");","module.exports = require(\"ol/source/Source\");","module.exports = require(\"ol/source\");","module.exports = require(\"ol/geom/GeometryType\");","module.exports = require(\"ol\");","module.exports = require(\"ol/format\");","module.exports = require(\"ol/Map\");","module.exports = require(\"ol/control\");","module.exports = require(\"ol/layer/Group\");","module.exports = require(\"uuid\");","module.exports = require(\"ol/geom/Point\");","module.exports = require(\"ol/interaction\");","module.exports = require(\"ol/events/condition\");","import Observable from 'ol/Observable';\nimport { v4 as uuid } from 'uuid';\n\n/**\n * A class representing a layer to display on map.\n *\n * @example\n * const layer = new Layer({\n * name: 'myLayer',\n * });\n *\n * @classproperty {string} name - Name of the layer\n * @classproperty {string} key - Identifier of the layer. Must be unique.\n * @classproperty {boolean} isBaseLayer - Define if the layer is a base layer. Read-only.\n * @classproperty {boolean} isQueryable - Define if the layer can be queried. Read-only.\n * @classproperty {boolean} isReactSpatialLayer - Custom property for duck typing since `instanceof` is not working when the instance was created on different bundles. Read-only.\n * @classproperty {Layer[]} children - List of children.\n * @classproperty {String[]} copyrights - Array of copyrights.\n * @classproperty {boolean} visible - Define if the layer is visible or not.\n * @classproperty {Object} properties - Custom properties.\n * @classproperty {ol/Map~Map|mapboxgl.Map} map - The map where the layer is displayed.\n */\nexport default class Layer extends Observable {\n /**\n * Constructor\n *\n * @param {Object} options\n * @param {string} [options.name=uuid()] Layer name. Default use a generated uuid.\n * @param {string} [options.key=uuid().toLowerCase()] Layer key, will use options.name.toLowerCase() if not specified.\n * @param {string} [options.copyrights=undefined] Array of copyrights.\n * @param {Array<Layer>} [options.children=[]] Sublayers.\n * @param {Object} [options.properties={}] Application-specific layer properties.\n * @param {boolean} [options.visible=true] If true this layer is visible on the map.\n * @param {boolean} [options.isBaseLayer=false] If true this layer is a baseLayer.\n * @param {boolean} [options.isQueryable=true] If true feature information can be queried by the react-spatial LayerService. Default is true.\n */\n constructor(options) {\n super();\n this.defineProperties({ isQueryable: true, ...options });\n\n if (options.copyrights) {\n this.copyrights = options.copyrights;\n }\n\n // Add click callback\n const { onClick } = options;\n if (onClick) {\n this.onClick(onClick);\n }\n }\n\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const {\n name,\n key,\n children,\n visible,\n properties,\n isBaseLayer,\n isQueryable,\n } = options;\n const uid = uuid();\n const dfltName = name || uid;\n Object.defineProperties(this, {\n // options is used for clone function.\n options: {\n value: options,\n },\n name: {\n value: dfltName,\n },\n key: {\n value: key || dfltName.toLowerCase(),\n },\n isBaseLayer: {\n value: !!isBaseLayer,\n },\n isQueryable: {\n value: !!isQueryable,\n },\n // Custom property for duck typing since `instanceof` is not working\n // when the instance was created on different bundles.\n isReactSpatialLayer: {\n value: true,\n },\n children: {\n value: children || [],\n writable: true,\n },\n copyrights: {\n get: () => {\n return this.get('copyrights');\n },\n set: (newCopyrights) => {\n const arrValue = !Array.isArray(newCopyrights)\n ? [newCopyrights]\n : newCopyrights;\n return this.set('copyrights', arrValue);\n },\n },\n visible: {\n value: visible === undefined ? true : visible,\n writable: true,\n },\n properties: {\n value: { ...(properties || {}) },\n },\n map: {\n writable: true,\n },\n /**\n * Callback function when a user click on a vehicle.\n */\n clickCallbacks: {\n value: [],\n },\n });\n }\n\n /**\n * Initialize the layer with the map passed in parameters.\n *\n * @param {ol/Map~Map|mapboxgl.Map} map A map.\n */\n init(map) {\n this.terminate();\n /** @ignore */\n this.map = map;\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n // eslint-disable-next-line class-methods-use-this\n terminate() {}\n\n /**\n * Get a layer property.\n *\n * @param {string} name Property name.\n * @returns {property} Property\n */\n get(name) {\n return this.properties[name];\n }\n\n /**\n * Set a layer property.\n *\n * @param {string} name Property name.\n * @param {string} value Value.\n */\n set(name, value) {\n this.properties[name] = value;\n this.dispatchEvent({\n type: `change:${name}`,\n target: this,\n });\n }\n\n /**\n * Change the visibility of the layer\n *\n * @param {boolean} visible Defines the visibility of the layer\n * @param {boolean} [stopPropagationDown]\n * @param {boolean} [stopPropagationUp]\n * @param {boolean} [stopPropagationSiblings]\n */\n setVisible(\n visible,\n stopPropagationDown = false,\n stopPropagationUp = false,\n stopPropagationSiblings = false,\n ) {\n if (visible === this.visible) {\n return;\n }\n\n /** @ignore */\n this.visible = visible;\n\n this.dispatchEvent({\n type: 'change:visible',\n target: this,\n stopPropagationDown,\n stopPropagationUp,\n stopPropagationSiblings,\n });\n }\n\n /**\n * Returns an array with visible child layers\n *\n * @returns {Layer[]} Visible children\n */\n getVisibleChildren() {\n return this.children.filter((child) => child.visible);\n }\n\n /**\n * Checks whether the layer has child layers with visible set to True\n *\n * @returns {boolean} True if the layer has visible child layers\n */\n hasVisibleChildren() {\n return !!this.hasChildren(true);\n }\n\n /**\n * Checks whether the layer has any child layers with visible equal to the input parameter\n *\n * @param {boolean} visible The state to check the childlayers against\n * @returns {boolean} True if the layer has children with the given visibility\n */\n hasChildren(visible) {\n return !!this.children.find((child) => child.visible === visible);\n }\n\n /**\n * Add a child layer\n *\n * @param {Layer} layer Add a child layer\n */\n addChild(layer) {\n this.children.unshift(layer);\n this.dispatchEvent({\n type: `change:children`,\n target: this,\n });\n }\n\n /**\n * Removes a child layer by layer name\n *\n * @param {string} name Layer's name\n */\n removeChild(name) {\n for (let i = 0; i < this.children.length; i += 1) {\n if (this.children[i].name === name) {\n this.children.splice(i, 1);\n return;\n }\n }\n this.dispatchEvent({\n type: `change:children`,\n target: this,\n });\n }\n\n /**\n * Request feature information for a given coordinate.\n * This function must be implemented by inheriting layers.\n *\n * @returns {Promise<{layer: Layer, features: ol/Feature~Feature[0], coordinate: null}}>} An empty response.\n */\n getFeatureInfoAtCoordinate() {\n // This layer returns no feature info.\n // The function is implemented by inheriting layers.\n return Promise.resolve({\n layer: this,\n features: [],\n coordinate: null,\n });\n }\n\n /**\n * Listens to click events on the layer.\n * @param {function} callback Callback function, called with the clicked\n * features,\n * the layer instance and the click event.\n */\n onClick(callback) {\n if (typeof callback === 'function') {\n if (!this.clickCallbacks.includes(callback)) {\n this.clickCallbacks.push(callback);\n }\n } else {\n throw new Error('callback must be of type function.');\n }\n }\n\n /**\n * Unlistens to click events on the layer.\n * @param {function} callback Callback function, called with the clicked\n * features,\n * the layer instance and the click event.\n */\n unClick(callback) {\n if (typeof callback === 'function') {\n const idx = this.clickCallbacks.indexOf(callback);\n if (idx >= -1) {\n this.clickCallbacks.splice(idx, 1);\n }\n }\n }\n}\n","import { unByKey } from 'ol/Observable';\nimport Group from 'ol/layer/Group';\nimport LayerCommon from '../../common/layers/Layer';\n\n/**\n * A class representing a layer to display on an OpenLayers map.\n *\n * @example\n * import { Layer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new Layer({\n * olLayer: ...,\n * });\n *\n * @see <a href=\"/example/ol-map\">Map example</a>\n *\n * @extends {Layer}\n */\nclass Layer extends LayerCommon {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {ol/layer/Layer~Layer} options.olLayer The layer (required).\n * @param {string} [options.name=uuid()] Layer name. Default use a generated uuid.\n * @param {string} [options.key=uuid().toLowerCase()] Layer key, will use options.name.toLowerCase() if not specified.\n * @param {string} [options.copyright=undefined] Copyright-Statement.\n * @param {Array<Layer>} [options.children=[]] Sublayers.\n * @param {Object} [options.properties={}] Application-specific layer properties.\n * @param {boolean} [options.visible=true] If true this layer is the currently visible layer on the map.\n * @param {boolean} [options.isBaseLayer=false] If true this layer is a baseLayer.\n * @param {boolean} [options.isQueryable=true] If true feature information can be queried by the react-spatial LayerService. Default is true.\n */\n constructor(options) {\n super(options);\n\n if (this.olLayer) {\n this.olLayer.setVisible(this.visible);\n }\n }\n\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n super.defineProperties(options);\n Object.defineProperties(this, {\n olLayer: { value: options.olLayer, writable: true },\n olListenersKeys: {\n value: [],\n },\n });\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map || !this.olLayer) {\n return;\n }\n\n this.olListenersKeys.push(\n this.map.getLayers().on('remove', (evt) => {\n if (evt.element === this.olLayer) {\n this.terminate();\n }\n }),\n );\n\n // We set the copyright to the source used by the layer.\n if (this.copyrights) {\n const attributions = this.copyrights || [];\n if (this.olLayer instanceof Group) {\n this.olLayer\n .getLayers()\n .getArray()\n .forEach((layer) => {\n layer.getSource().setAttributions(attributions);\n });\n } else {\n this.olLayer.getSource().setAttributions(attributions);\n }\n }\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n unByKey(this.olListenersKeys);\n super.terminate();\n }\n\n /**\n * Change the visibility of the layer\n *\n * @param {boolean} visible Defines the visibility of the layer\n * @param {boolean} [stopPropagationDown]\n * @param {boolean} [stopPropagationUp]\n * @param {boolean} [stopPropagationSiblings]\n */\n setVisible(\n visible,\n stopPropagationDown = false,\n stopPropagationUp = false,\n stopPropagationSiblings = false,\n ) {\n if (visible === this.visible) {\n return;\n }\n\n super.setVisible(\n visible,\n stopPropagationDown,\n stopPropagationUp,\n stopPropagationSiblings,\n );\n\n if (this.olLayer) {\n this.olLayer.setVisible(this.visible);\n }\n }\n\n /**\n * Create a copy of the Layer.\n * @param {Object} newOptions Options to override\n * @returns {Layer} A Layer\n */\n clone(newOptions) {\n return new Layer({ ...this.options, ...newOptions });\n }\n}\nexport default Layer;\n","import BaseObject from 'ol/Object';\n\n/**\n * A class representing a control to display on map.\n *\n * @example\n * const control = new Control();\n *\n * @classproperty {ol/Map~Map|mapboxgl.Map} map - The map which the control refers to.\n * @classproperty {boolean} active - Active the control.\n * @classproperty {function} render - Render function called whenever the control needs to be rerendered.\n * @classproperty {HTMLElement} element - The HTML element used to render the control. Read only.\n * @classproperty {HTMLElement} target - The HTML element where to render the element property. Default is the map's element. Read only.\n */\nclass Control extends BaseObject {\n /**\n * Constructor\n *\n * @param {Object} [options] Control options.\n * @param {boolean} [options.active = true] Whether the control is active or not.\n * @param {HTMLElement} [options.element] The HTML element used to render the control.\n * @param {HTMLElement} [options.target] The HTML element where to render the element property. Default is the map's element.\n * @param {HTMLElement} [options.render] Render function called whenever the control needs to be rerendered.\n */\n constructor(options = {}) {\n super(options);\n this.defineProperties(options);\n\n const { active } = {\n active: options.active !== false,\n ...options,\n };\n\n /**\n * @ignore\n */\n this.active = active;\n }\n\n /**\n * Define control's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const { target, element, render } = {\n ...options,\n };\n\n Object.defineProperties(this, {\n active: {\n get: () => {\n return this.get('active');\n },\n set: (newActive) => {\n this.set('active', newActive);\n if (newActive) {\n this.activate();\n } else {\n this.deactivate();\n }\n this.render();\n },\n },\n map: {\n get: () => {\n return this.get('map');\n },\n set: (map) => {\n // Remove previous node.\n if (this.map && this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n\n // Clean listeners\n this.deactivate();\n\n this.set('map', map);\n\n if (this.map) {\n // Add new node\n const targett = this.target || this.map.getContainer();\n\n if (!this.element) {\n this.createDefaultElement();\n }\n\n if (this.element) {\n targett.appendChild(this.element);\n }\n\n // Add listeners\n if (this.active) {\n this.activate();\n }\n }\n this.render();\n },\n },\n target: {\n value: target,\n },\n element: {\n value: element,\n writable: true,\n },\n render: {\n /**\n * @ignore\n */\n value: render || this.render,\n writable: true,\n },\n });\n }\n\n /**\n * Add listeners then renders the control.\n * To be defined in inherited classes.\n */\n activate() {\n this.deactivate();\n }\n\n /**\n * Remove listeners added by activate() function then renders the control.\n * To be defined in inherited classes.\n */\n // eslint-disable-next-line class-methods-use-this\n deactivate() {}\n\n /**\n * The default render function. It renders content in the HTML element.\n * To be defined in inherited classes.\n */\n render() {}\n\n /**\n * The default element to display if this.element is not defined.\n * To be defined in inherited classes.\n * @private\n */\n // eslint-disable-next-line class-methods-use-this\n createDefaultElement() {}\n}\n\nexport default Control;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable class-methods-use-this */\n// eslint-disable-next-line max-classes-per-file\nimport Control from '../controls/Control';\n\n/**\n * Map interface.\n */\nexport class MapInterface {\n /**\n * Constructor.\n *\n * @param {Object} options Map options\n * @param {Array<Layer>} [options.layers] Custom layers of the map.\n * @param {Array<Control>} [options.controls] Custom controls of the map.\n */\n // eslint-disable-next-line no-unused-vars\n constructor(options = {}) {}\n\n /**\n * Returns the HTML element of the map.\n * @returns {HTMLElement}\n */\n getContainer() {}\n\n /**\n * Returns a list of mobility layers.\n * @returns {Layer[]}\n */\n getMobilityLayers() {}\n\n /**\n * Returns a list of mobility controls.\n * @returns {Control[]}\n */\n getMobilityControls() {}\n}\n\n/**\n * Mixin for MapInterface.\n * @ignore\n */\nconst MapMixin = (Base) =>\n class extends Base {\n constructor(options = {}) {\n super({ ...options, layers: [], controls: [] });\n this.mobilityLayers = [];\n this.mobilityControls = [];\n\n // Add controls\n (options.controls || []).forEach((control) => {\n this.addControl(control);\n });\n\n // Add layers\n (options.layers || []).forEach((layer) => {\n this.addLayer(layer);\n });\n }\n\n getMobilityLayers() {\n return this.mobilityLayers;\n }\n\n getMobilityControls() {\n return this.mobilityControls;\n }\n\n addMobilityControl(control) {\n this.mobilityControls.push(control);\n // eslint-disable-next-line no-param-reassign\n control.map = this;\n }\n\n removeMobilityControl(control) {\n // eslint-disable-next-line no-param-reassign\n control.map = null;\n this.mobilityControls = this.mobilityControls.filter(\n (c) => c !== control,\n );\n }\n\n /** Documentation in inherited classes */\n addControl(control, position) {\n if (control instanceof Control) {\n this.addMobilityControl(control);\n } else {\n super.addControl(control, position);\n }\n }\n\n /** Documentation in inherited classes */\n removeControl(control) {\n if (control instanceof Control) {\n this.removeMobilityControl(control);\n } else {\n super.removeControl(control);\n }\n }\n };\n\nexport default MapMixin;\n","/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\n\n/**\n * Copyright control interface.\n *\n */\nexport class CopyrightInterface {\n /**\n * Return an array of layer's copyright.\n *\n * @returns {String[]} A list of copyrights to render.\n */\n getCopyrights() {}\n}\n\n/**\n * Mixin for CopyrightInterface.\n *\n * @param {Class} Base A class to extend with {CopyrightInterface} functionnalities.\n * @return {Class} A class that implements <CopyrightInterface> class and extends Base;\n * @private\n */\nconst CopyrightMixin = (Base) =>\n class extends Base {\n render() {\n if (!this.element) {\n return;\n }\n this.element.innerHTML = this.active\n ? this.getCopyrights().join(' | ')\n : '';\n }\n\n createDefaultElement() {\n this.element = document.createElement('div');\n this.element.id = 'mbt-copyright';\n Object.assign(this.element.style, {\n position: 'absolute',\n bottom: 0,\n right: 0,\n fontSize: '.8rem',\n padding: '0 10px',\n });\n }\n };\n\nexport default CopyrightMixin;\n","/**\n * This function remove duplicates lower case string value of an array.\n * It removes also null, undefined or non string values.\n *\n * @param {array} array Array of values.\n * @ignore\n */\nconst removeDuplicate = (array) => {\n const arrWithoutEmptyValues = array.filter(\n (val) => val !== undefined && val !== null && val.trim && val.trim(),\n );\n const lowerCasesValues = arrWithoutEmptyValues.map((str) =>\n str.toLowerCase(),\n );\n const uniqueLowerCaseValues = [...new Set(lowerCasesValues)];\n const uniqueValues = uniqueLowerCaseValues.map((uniqueStr) => {\n return arrWithoutEmptyValues.find((str) => str.toLowerCase() === uniqueStr);\n });\n return uniqueValues;\n};\n\nexport default removeDuplicate;\n","import { inView } from 'ol/layer/Layer';\nimport Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/CopyrightMixin';\nimport removeDuplicate from '../../common/utils/removeDuplicate';\n\n/**\n * Display layer's copyrights.\n *\n * @example\n * import { Map, CopyrightControl } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * controls: [\n * new CopyrightControl()\n * ]\n * });\n *\n *\n * @see <a href=\"/example/ol-copyright\">Openlayers copyright example</a>\n *\n * @extends {Control}\n * @implements {CopyrightInterface}\n */\nclass CopyrightControl extends mixin(Control) {\n constructor(options) {\n super(options);\n this.onPostRender = this.onPostRender.bind(this);\n }\n\n getCopyrights() {\n if (!this.frameState) {\n return [];\n }\n let copyrights = [];\n\n // This code loop comes mainly from ol.\n this.frameState.layerStatesArray.forEach((layerState) => {\n const { layer } = layerState;\n if (\n inView(layerState, this.frameState.viewState) &&\n layer &&\n layer.getSource &&\n layer.getSource() &&\n layer.getSource().getAttributions()\n ) {\n copyrights = copyrights.concat(\n layer.getSource().getAttributions()(this.frameState),\n );\n }\n });\n return removeDuplicate(copyrights);\n }\n\n activate() {\n super.activate();\n if (this.map) {\n this.map.on('postrender', this.onPostRender);\n }\n }\n\n deactivate() {\n if (this.map) {\n this.map.un('postrender', this.onPostRender);\n }\n super.deactivate();\n }\n\n onPostRender(evt) {\n if (this.map && this.element) {\n /**\n * @ignore\n */\n this.frameState = evt.frameState;\n this.render();\n }\n }\n}\n\nexport default CopyrightControl;\n","import OLMap from 'ol/Map';\nimport { defaults as defaultControls } from 'ol/control';\nimport Layer from './layers/Layer';\nimport mixin from '../common/mixins/MapMixin';\nimport CopyrightControl from './controls/CopyrightControl';\n\n/**\n * An OpenLayers map for handling mobility layers and controls.\n *\n * @example\n * import { Map } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * view: new View({\n * center: [0, 0],\n * zoom: 1,\n * }),\n * });\n *\n * @see <a href=\"/example/ol-map\">Map example</a>\n *\n * @extends {ol/Map~Map}\n */\nclass Map extends mixin(OLMap) {\n /**\n * Constructor.\n *\n * @param {Object} options See [ol/Map~Map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html) options documentation.\n * @param {Array<Layer|ol/layer/Layer~Layer>} [options.layers] Array of layers.\n */\n constructor(options = {}) {\n super({\n controls: [\n ...defaultControls({ attribution: false }).getArray(),\n new CopyrightControl(),\n ],\n ...options,\n });\n }\n\n /**\n * Get the HTML element containing the map.\n *\n * @return {HTMLElement} The HTML element of the container.\n */\n getContainer() {\n return this.getTargetElement();\n }\n\n /**\n * Adds a layer to the map.\n * @param {Layer|ol/layer/Layer~Layer} layer The layer to add.\n */\n addLayer(layer) {\n if (layer instanceof Layer) {\n // layer is an mobility layer\n layer.init(this);\n this.mobilityLayers.push(layer);\n\n if (layer.olLayer) {\n super.addLayer(layer.olLayer);\n }\n\n this.dispatchEvent({\n type: 'change:mobilityLayers',\n target: this,\n });\n } else {\n // layer is an OpenLayer layer\n super.addLayer(layer);\n }\n }\n\n /**\n * Removes a given layer from the map.\n * @param {Layer|ol/layer/Layer~Layer} layer The layer to remove.\n */\n removeLayer(layer) {\n if (layer instanceof Layer) {\n layer.terminate();\n this.mobilityLayers = this.mobilityLayers.filter((l) => l !== layer);\n if (layer.olLayer) {\n super.removeLayer(layer);\n }\n } else {\n // layer is an OpenLayer layer\n super.removeLayer(layer);\n }\n }\n\n /**\n * Adds a given control to the map.\n * @param {Control|ol/control/Control~Control} control The control to add.\n */\n addControl(control) {\n super.addControl(control);\n }\n\n /**\n * Removes a given control to the map.\n * @param {Control|ol/control/Control~Control} control The control to remove.\n */\n removeControl(control) {\n super.removeControl(control);\n }\n}\n\nexport default Map;\n","import removeDuplicate from './removeDuplicate';\n\n/**\n * Return the copyright a Mapbox map.\n * @param {mapboxgl.Map} map A Mapbox map\n * @ignore\n */\nconst getMapboxMapCopyrights = (map) => {\n if (!map || !map.style) {\n return [];\n }\n const { sourceCaches } = map.style;\n let copyrights = [];\n Object.values(sourceCaches).forEach((sourceCache) => {\n if (sourceCache.used) {\n const source = sourceCache.getSource();\n const attribution =\n source.attribution || (source.options && source.options.attribution);\n if (attribution) {\n copyrights = copyrights.concat(\n attribution.replace(/&copy;/g, '©').split(/(<a.*?<\\/a>)/),\n );\n }\n }\n });\n\n return removeDuplicate(copyrights);\n};\n\nexport default getMapboxMapCopyrights;\n","import qs from 'query-string';\n\n/**\n * Return the styleUrl with apiKey parameters set.\n * @param {string} apiKey apiKey value for the mapbox request.\n * @param {string} apiKeyName parameter name for apiKey in the mapbox request.\n * @param {string} styleUrl mapbox styleUrl value.\n * @ignore\n */\nconst getMapboxStyleUrl = (apiKey, apiKeyName, styleUrl) => {\n if (apiKey === false) {\n return styleUrl;\n }\n const parsedStyle = qs.parseUrl(styleUrl);\n if (!apiKey && parsedStyle.query[apiKeyName]) {\n return styleUrl;\n }\n if (!apiKey) {\n // eslint-disable-next-line no-console\n console.warn(`No apiKey is defined for request to ${styleUrl}`);\n return null;\n }\n return qs.stringifyUrl({\n ...parsedStyle,\n query: {\n ...parsedStyle.query,\n [apiKeyName]: apiKey,\n },\n });\n};\n\nexport default getMapboxStyleUrl;\n","/* eslint-disable no-underscore-dangle */\nimport { toLonLat } from 'ol/proj';\nimport mapboxgl from 'mapbox-gl';\nimport Source from 'ol/source/Source';\nimport OLLayer from 'ol/layer/Layer';\nimport GeoJSON from 'ol/format/GeoJSON';\nimport Layer from './Layer';\nimport getMapboxMapCopyrights from '../../common/utils/getMapboxMapCopyrights';\nimport getMapboxStyleUrl from '../../common/utils/getMapboxStyleUrl';\n\n/**\n * A class representing Mapboxlayer to display on BasicMap\n *\n * @example\n * import { MapboxLayer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new MapboxLayer({\n * url: 'https://maps.geops.io/styles/travic_v2/style.json',\n * apikey: 'yourApiKey',\n * });\n *\n * @extends {Layer}\n */\nexport default class MapboxLayer extends Layer {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {boolean} [options.preserveDrawingBuffer=false] If true able to export the canvas.\n * @param {number} [options.fadeDuration=300] Duration of the fade effect in ms.\n */\n constructor(options = {}) {\n const mbLayer = new OLLayer({\n source: new Source({}),\n render: (frameState) => {\n if (!this.mbMap) {\n // eslint-disable-next-line no-console\n console.warn(\"Mapbox map doesn't exist.\");\n return null;\n }\n let changed = false;\n const canvas = this.mbMap.getCanvas();\n const { viewState } = frameState;\n\n const visible = this.olLayer.getVisible();\n if (this.renderState.visible !== visible) {\n canvas.style.display = visible ? 'block' : 'none';\n this.renderState.visible = visible;\n // Needed since mapbox-gl 1.9.0.\n // Without you don't see others ol layers on top.\n canvas.style.position = 'absolute';\n }\n\n const opacity = this.olLayer.getOpacity();\n if (this.renderState.opacity !== opacity) {\n canvas.style.opacity = opacity;\n this.renderState.opacity = opacity;\n }\n\n // adjust view parameters in mapbox\n const { rotation } = viewState;\n if (this.renderState.rotation !== rotation) {\n this.mbMap.rotateTo((-(rotation || 0) * 180) / Math.PI, {\n animate: false,\n });\n changed = true;\n this.renderState.rotation = rotation;\n }\n\n if (\n this.renderState.zoom !== viewState.zoom ||\n this.renderState.center[0] !== viewState.center[0] ||\n this.renderState.center[1] !== viewState.center[1]\n ) {\n this.mbMap.jumpTo({\n center: toLonLat(viewState.center),\n zoom: viewState.zoom - 1,\n animate: false,\n });\n changed = true;\n this.renderState.zoom = viewState.zoom;\n this.renderState.center = viewState.center;\n }\n\n const size = this.map.getSize();\n if (\n this.renderState.size[0] !== size[0] ||\n this.renderState.size[1] !== size[1]\n ) {\n changed = true;\n this.renderState.size = size;\n }\n\n // cancel the scheduled update & trigger synchronous redraw\n // see https://github.com/mapbox/mapbox-gl-js/issues/7893#issue-408992184\n // NOTE: THIS MIGHT BREAK WHEN UPDATING MAPBOX\n if (\n this.mbMap &&\n this.mbMap.style &&\n this.mbMap.isStyleLoaded() &&\n changed\n ) {\n try {\n if (this.mbMap._frame) {\n this.mbMap._frame.cancel();\n this.mbMap._frame = null;\n }\n this.mbMap._render();\n } catch (err) {\n // ignore render errors because it's probably related to\n // a render during an update of the style.\n // eslint-disable-next-line no-console\n console.warn(err);\n }\n }\n\n return canvas;\n },\n });\n\n super({\n ...options,\n olLayer: mbLayer,\n });\n\n /**\n * Url of the mapbox style.\n * @type {string}\n * @private\n */\n this.styleUrl = options.url;\n\n /**\n * Api key for the url of the mapbox style.\n * If set to false, the apiKey is not required.\n * @type {string}\n * @private\n */\n this.apiKey = options.apiKey;\n\n /**\n * Name of the apiKey to set in the url request.\n * Default is 'key'.\n * @type {string}\n * @private\n */\n this.apiKeyName = options.apiKeyName || 'key';\n\n /**\n * @ignores\n */\n this.updateAttribution = this.updateAttribution.bind(this);\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map || this.mbMap) {\n return;\n }\n\n /**\n * The feature format.\n * @type {ol/format/GeoJSON}\n */\n this.format = new GeoJSON({\n featureProjection: this.map.getView().getProjection(),\n });\n\n this.loadMbMap();\n\n this.olListenersKeys.push(\n this.map.on('change:size', () => {\n try {\n if (this.mbMap) {\n this.mbMap.resize();\n }\n } catch (err) {\n // ignore render errors\n // eslint-disable-next-line no-console\n console.warn(err);\n }\n }),\n );\n }\n\n /**\n * Returns a style URL with apiKey & apiKeyName infos.\n */\n createStyleUrl() {\n return getMapboxStyleUrl(this.apiKey, this.apiKeyName, this.styleUrl);\n }\n\n /**\n * Create the mapbox map.\n * @private\n */\n loadMbMap() {\n this.olListenersKeys.push(\n this.map.on('change:target', () => {\n this.loadMbMap();\n }),\n );\n\n if (!this.map.getTargetElement()) {\n return;\n }\n\n if (!this.visible) {\n // On next change of visibility we load the map\n this.olListenersKeys.push(\n this.once('change:visible', () => {\n this.loadMbMap();\n }),\n );\n return;\n }\n\n // If the map hasn't been resized, the center could be [NaN,NaN].\n // We set default good value for the mapbox map, to avoid the app crashes.\n let [x, y] = this.map.getView().getCenter();\n if (!x || !y) {\n x = 0;\n y = 0;\n }\n\n const style = this.createStyleUrl();\n try {\n /**\n * A mapbox map\n * @type {mapboxgl.Map}\n */\n this.mbMap = new mapboxgl.Map({\n style,\n attributionControl: false,\n boxZoom: false,\n center: toLonLat([x, y]),\n container: this.map.getTargetElement(),\n interactive: false,\n fadeDuration:\n 'fadeDuration' in this.options ? this.options.fadeDuration : 300,\n // Needs to be true to able to export the canvas, but could lead to performance issue on mobile.\n preserveDrawingBuffer: this.options.preserveDrawingBuffer || false,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn('Failed creating mapbox map: ', err);\n }\n\n // Options the last render run did happen. If something changes\n // we have to render again\n /** @ignore */\n this.renderState = {\n center: [x, y],\n zoom: null,\n rotation: null,\n visible: null,\n opacity: null,\n size: [0, 0],\n };\n\n this.mbMap.once('load', () => {\n /**\n * Is the map loaded.\n * @type {boolean}\n */\n this.loaded = true;\n\n this.copyrights =\n this.copyrights || getMapboxMapCopyrights(this.mbMap) || [];\n\n this.olLayer.getSource().setAttributions(this.copyrights);\n\n this.dispatchEvent({\n type: 'load',\n target: this,\n });\n });\n\n const mapboxCanvas = this.mbMap.getCanvas();\n if (mapboxCanvas) {\n if (this.options.tabIndex) {\n mapboxCanvas.setAttribute('tabindex', this.options.tabIndex);\n } else {\n // With a tabIndex='-1' the mouse events works but the map is not focused when we click on it\n // so we remove completely the tabIndex attribute.\n mapboxCanvas.removeAttribute('tabindex');\n }\n }\n\n this.mbMap.on('idle', this.updateAttribution);\n }\n\n updateAttribution(evt) {\n const newAttributions =\n this.copyrights || getMapboxMapCopyrights(evt.target) || [];\n if (this.copyrights.toString() !== newAttributions.toString()) {\n this.olLayer.getSource().setAttributions(newAttributions);\n }\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate Coordinate to request the information at.\n * @param {Object} options A [mapboxgl.Map#queryrenderedfeatures](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#queryrenderedfeatures) options parameter.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit. The original Mapbox feature is available as a property named 'mapboxFeature'.\n */\n getFeatureInfoAtCoordinate(coordinate, options) {\n // Ignore the getFeatureInfo until the mapbox map is loaded\n if (\n !options ||\n !this.format ||\n !this.mbMap ||\n !this.mbMap.isStyleLoaded()\n ) {\n return Promise.resolve({ coordinate, features: [], layer: this });\n }\n\n const pixel = coordinate && this.mbMap.project(toLonLat(coordinate));\n // At this point we get GeoJSON Mapbox feature, we transform it to an OpenLayers\n // feature to be consistent with other layers.\n const features = this.mbMap\n .queryRenderedFeatures(pixel, options)\n .map((feature) => {\n const olFeature = this.format.readFeature(feature);\n if (olFeature) {\n // We save the original mapbox feature to avoid losing informations\n // potentially needed for other functionnality like highlighting\n // (id, layer id, source, sourceLayer ...)\n olFeature.set('mapboxFeature', feature);\n }\n return olFeature;\n });\n\n return Promise.resolve({\n layer: this,\n features,\n coordinate,\n });\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n if (this.mbMap) {\n this.mbMap.off('idle', this.updateAttribution);\n // Some asynchrone repaints are triggered even if the mbMap has been removed,\n // to avoid display of errors we set an empty function.\n this.mbMap.triggerRepaint = () => {};\n this.mbMap.remove();\n this.mbMap = null;\n }\n this.loaded = false;\n super.terminate();\n }\n\n /**\n * Create a copy of the MapboxLayer.\n * @param {Object} newOptions Options to override\n * @returns {MapboxLayer} A MapboxLayer\n */\n clone(newOptions) {\n return new MapboxLayer({ ...this.options, ...newOptions });\n }\n}\n","import { Circle, Fill, Stroke, Style } from 'ol/style';\nimport { Vector as VectorSource } from 'ol/source';\nimport { Vector } from 'ol/layer';\nimport Layer from './Layer';\n\nconst defaultStyleFunction = (feature, resolution) => {\n const mot = feature.get('mot');\n const viaPointIdx = feature.get('viaPointIdx');\n const minResolution = feature.get('minResolution');\n const maxResolution = feature.get('maxResolution');\n const inRange = resolution <= minResolution && resolution > maxResolution;\n\n // Default style for via points\n const image =\n viaPointIdx !== undefined &&\n new Circle({\n radius: 6,\n fill: new Fill({\n color: [255, 0, 0, 1],\n }),\n stroke: new Stroke({\n color: [0, 0, 0, 1],\n width: 1,\n }),\n });\n\n if (inRange === false) {\n return [new Style({ image })];\n }\n\n // Default style for route lines\n const stroke =\n mot &&\n new Stroke({\n color: [255, 0, 0, 1],\n width: 3,\n lineDash: mot === 'foot' ? [1, 10] : undefined,\n });\n\n const style = new Style({\n stroke,\n image,\n });\n\n const blackBorder = new Style({\n stroke: new Stroke({\n color: [0, 0, 0, mot === 'foot' ? 0 : 1],\n width: 5,\n }),\n });\n return [blackBorder, style];\n};\n\n/**\n * A class use to display vector data.\n *\n * @extends {Layer}\n */\nclass RoutingLayer extends Layer {\n /**\n * Constructor.\n * @param {Object} [options]\n * @param {number} [options.style] Style to be used for routes, uses (ol/StyleLike) [https://openlayers.org/en/latest/apidoc/module-ol_style_Style.html#~StyleLike] instances\n */\n constructor(options = {}) {\n super(options);\n\n this.olLayer =\n options.olLayer ||\n new Vector({\n source: new VectorSource(),\n style: options.style || defaultStyleFunction,\n });\n }\n\n /**\n * Create a copy of the RoutingLayer.\n * @param {Object} newOptions Options to override\n * @returns {RoutingLayer} A RoutingLayer\n */\n clone(newOptions) {\n return new RoutingLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default RoutingLayer;\n","import { unByKey } from 'ol/Observable';\nimport GeomType from 'ol/geom/GeometryType';\n\n/**\n * Tracker. This class stores and allows to draw trajectories on a canvas.\n * @class\n * @param {Object} options\n * @private\n */\nexport default class Tracker {\n /**\n * @private\n */\n constructor(options) {\n const opts = {\n interpolate: true,\n ...options,\n };\n\n /**\n * Array of trajectories.\n * @type {Array<trajectory>}\n */\n this.trajectories = [];\n\n /**\n * Array of trajectories that are currently drawn.\n * @type {Array<key>}\n */\n this.renderedTrajectories = [];\n\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<key>}\n */\n this.interpolate = !!opts.interpolate;\n\n /**\n * Function to Convert coordinate to canvas pixel.\n * @type {function}\n */\n this.getPixelFromCoordinate = opts.getPixelFromCoordinate;\n\n /**\n * Id of the trajectory which is hovered.\n * @type {string}\n */\n this.hoverVehicleId = null;\n\n /**\n * Id of the trajectory which is selected.\n * @type {string}\n */\n this.selectedVehicleId = null;\n\n /**\n * Scale the vehicle icons with this value.\n * @type {number}\n */\n this.iconScale = opts.iconScale;\n\n // we draw directly on the canvas since openlayers is too slow.\n /**\n * HTML <canvas> element.\n * @type {Canvas}\n */\n this.canvas = opts.canvas || document.createElement('canvas');\n this.canvas.width = opts.width;\n this.canvas.height = opts.height;\n this.canvas.setAttribute(\n 'style',\n [\n 'position: absolute',\n 'top: 0',\n 'bottom: 0',\n 'width: 100%',\n 'height: 100%',\n 'pointer-events: none',\n 'visibility: visible',\n 'margin-top: inherit', // for scrolling behavior.\n ].join(';'),\n );\n /**\n * 2d drawing context on the canvas.\n * @type {CanvasRenderingContext2D}\n */\n this.canvasContext = this.canvas.getContext('2d');\n }\n\n /**\n * Set visibility of the canvas.\n * @param {boolean} visible The visibility of the layer\n */\n setVisible(visible) {\n if (this.canvas) {\n this.canvas.style.visibility = visible ? 'visible' : 'hidden';\n }\n }\n\n /**\n * Define the trajectories.\n * @param {array<ol/Feature~Feature>} trajectories\n */\n setTrajectories(trajectories = []) {\n if (this.sort) {\n trajectories.sort(this.sort);\n }\n\n this.trajectories = trajectories;\n }\n\n /**\n * Return the trajectories.\n * @returns {array<trajectory>} trajectories\n */\n getTrajectories() {\n return this.trajectories || [];\n }\n\n /**\n * Return rendered trajectories.\n * Use this to avoid race conditions while rendering.\n * @returns {array<trajectory>} trajectories\n */\n getRenderedTrajectories() {\n return this.renderedTrajectories;\n }\n\n /**\n * Clear the canvas.\n * @private\n */\n clear() {\n if (this.canvasContext) {\n this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n }\n\n /**\n * Set the filter for tracker features.\n * @param {function} filter Filter function.\n */\n setFilter(filter) {\n /**\n * Current filter function.\n * @type {function}\n */\n this.filter = filter;\n }\n\n /**\n * Set the sort for tracker features.\n * @param {function} sort Sort function.\n */\n setSort(sort) {\n /**\n * The sort function for tracker features.\n * @type {function}\n */\n this.sort = sort;\n }\n\n /**\n * Set the id of the trajectory which is hovered.\n * @param {string} id Id of a vehicle.\n * @private\n */\n setHoverVehicleId(id) {\n if (id !== this.hoverVehicleId) {\n this.hoverVehicleId = id;\n }\n }\n\n /**\n * Set the id of the trajectory which is selected.\n * @param {string} id Id of a vehicle.\n * @private\n */\n setSelectedVehicleId(id) {\n if (id !== this.selectedVehicleId) {\n this.selectedVehicleId = id;\n }\n }\n\n /**\n * set the scale of the vehicle icons.\n * @param {number} iconScale Scale value.\n */\n setIconScale(iconScale) {\n this.iconScale = iconScale;\n }\n\n /**\n * Set the tracker style.\n * @param {function} s OpenLayers style function.\n */\n setStyle(s) {\n /**\n * Style function.\n * @type {function}\n */\n this.style = s;\n }\n\n /**\n * Move the canvas.\n * @param {number} offsetX Offset X.\n * @param {number} offsetY Offset Y.\n * @private\n */\n moveCanvas(offsetX, offsetY) {\n const oldLeft = parseFloat(this.canvas.style.left);\n const oldTop = parseFloat(this.canvas.style.top);\n this.canvas.style.left = `${oldLeft - offsetX}px`;\n this.canvas.style.top = `${oldTop - offsetY}px`;\n }\n\n /**\n * Draw all the trajectories available to the canvas.\n * @param {Date} currTime The date to render.\n * @param {number[2]} size Size ([width, height]) of the canvas to render.\n * @param {number} resolution Which resolution of the map to render.\n * @param {boolean} noInterpolate If true trajectories are not interpolated but\n * drawn at the last known coordinate. Use this for performance optimization\n * during map navigation.\n * @private\n */\n renderTrajectories(\n currTime = Date.now(),\n size = [],\n resolution,\n noInterpolate = false,\n ) {\n this.clear();\n this.canvas.style.left = '0px';\n this.canvas.style.top = '0px';\n\n const [width, height] = size;\n if (\n width &&\n height &&\n (this.canvas.width !== width || this.canvas.height !== height)\n ) {\n [this.canvas.width, this.canvas.height] = [width, height];\n }\n /**\n * Current resolution.\n * @type {number}\n */\n this.currResolution = resolution || this.currResolution;\n let hoverVehicleImg;\n let hoverVehiclePx;\n let hoverVehicleWidth;\n let hoverVehicleHeight;\n let selectedVehicleImg;\n let selectedVehiclePx;\n let selectedVehicleWidth;\n let selectedVehicleHeight;\n\n this.renderedTrajectories = [];\n\n for (let i = (this.trajectories || []).length - 1; i >= 0; i -= 1) {\n const traj = this.trajectories[i];\n\n // We simplify the traj object\n const { geometry, timeIntervals, timeOffset } = traj;\n\n if (this.filter && !this.filter(traj, i, this.trajectories)) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n let coord = null;\n let rotation;\n\n if (traj.coordinate && (noInterpolate || !this.interpolate)) {\n coord = traj.coordinate;\n } else if (timeIntervals && timeIntervals.length > 1) {\n const now = currTime - (timeOffset || 0);\n let start;\n let end;\n let startFrac;\n let endFrac;\n let timeFrac;\n\n // Search th time interval.\n for (let j = 0; j < timeIntervals.length - 1; j += 1) {\n // Rotation only available in tralis layer.\n [start, startFrac, rotation] = timeIntervals[j];\n [end, endFrac] = timeIntervals[j + 1];\n\n if (start <= now && now <= end) {\n break;\n } else {\n start = null;\n end = null;\n }\n }\n // The geometry can also be a Point\n if (geometry.getType() === GeomType.POINT) {\n coord = geometry.getCoordinates();\n } else if (geometry.getType() === GeomType.LINE_STRING) {\n if (start && end) {\n // interpolate position inside the time interval.\n timeFrac = this.interpolate\n ? Math.min((now - start) / (end - start), 1)\n : 0;\n\n const geomFrac = this.interpolate\n ? timeFrac * (endFrac - startFrac) + startFrac\n : 0;\n\n coord = geometry.getCoordinateAt(geomFrac);\n\n // We set the rotation and the timeFraction of the trajectory (used by tralis).\n this.trajectories[i].rotation = rotation;\n this.trajectories[i].endFraction = timeFrac;\n\n // It happens that the now date was some ms before the first timeIntervals we have.\n } else if (now < timeIntervals[0][0]) {\n [[, , rotation]] = timeIntervals;\n timeFrac = 0;\n coord = geometry.getFirstCoordinate();\n } else if (now > timeIntervals[timeIntervals.length - 1][0]) {\n [, , rotation] = timeIntervals[timeIntervals.length - 1];\n timeFrac = 1;\n coord = geometry.getLastCoordinate();\n }\n } else {\n // eslint-disable-next-line no-console\n console.error(\n 'This geometry type is not supported. Only Point or LineString are. Current geometry: ',\n geometry,\n );\n }\n // We set the rotation and the timeFraction of the trajectory (used by tralis).\n // if rotation === null that seems there is no rotation available.\n this.trajectories[i].rotation = rotation;\n this.trajectories[i].endFraction = timeFrac || 0;\n }\n\n if (coord) {\n // We set the rotation of the trajectory (used by tralis).\n this.trajectories[i].coordinate = coord;\n const px = this.getPixelFromCoordinate(coord);\n\n if (!px) {\n // eslint-disable-next-line no-continue\n continue;\n }\n // Trajectory with pixel (i.e. within map extent) will be in renderedTrajectories.\n this.trajectories[i].rendered = true;\n this.renderedTrajectories.push(this.trajectories[i]);\n const vehicleImg = this.style(traj, this.currResolution);\n\n if (!vehicleImg) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n let imgWidth = vehicleImg.width;\n let imgHeight = vehicleImg.height;\n\n if (this.iconScale) {\n imgHeight = Math.floor(imgHeight * this.iconScale);\n imgWidth = Math.floor(imgWidth * this.iconScale);\n }\n\n if (\n this.hoverVehicleId !== traj.id &&\n this.selectedVehicleId !== traj.id\n ) {\n this.canvasContext.drawImage(\n vehicleImg,\n px[0] - imgWidth / 2,\n px[1] - imgHeight / 2,\n imgWidth,\n imgHeight,\n );\n }\n if (this.hoverVehicleId === traj.id) {\n // Store the canvas to draw it at the end\n hoverVehicleImg = vehicleImg;\n hoverVehiclePx = px;\n hoverVehicleWidth = imgWidth;\n hoverVehicleHeight = imgHeight;\n }\n\n if (this.selectedVehicleId === traj.id) {\n // Store the canvas to draw it at the end\n selectedVehicleImg = vehicleImg;\n selectedVehiclePx = px;\n selectedVehicleWidth = imgWidth;\n selectedVehicleHeight = imgHeight;\n }\n }\n }\n\n if (selectedVehicleImg) {\n this.canvasContext.drawImage(\n selectedVehicleImg,\n selectedVehiclePx[0] - selectedVehicleWidth / 2,\n selectedVehiclePx[1] - selectedVehicleHeight / 2,\n selectedVehicleWidth,\n selectedVehicleHeight,\n );\n }\n\n if (hoverVehicleImg) {\n this.canvasContext.drawImage(\n hoverVehicleImg,\n hoverVehiclePx[0] - hoverVehicleWidth / 2,\n hoverVehiclePx[1] - hoverVehicleHeight / 2,\n hoverVehicleWidth,\n hoverVehicleHeight,\n );\n }\n }\n\n /**\n * Clean the canvas and the events the tracker.\n * @private\n */\n destroy() {\n unByKey(this.olEventsKeys);\n this.renderedTrajectories = [];\n this.clear();\n }\n}\n","const trackerRadiusMapping = {\n 0: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 1: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 2: [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],\n 3: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 4: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 5: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 6: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 7: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 8: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 9: [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],\n};\n\n/**\n * @ignore\n */\nexport const types = [\n 'Tram',\n 'Subway / Metro / S-Bahn',\n 'Train',\n 'Bus',\n 'Ferry',\n 'Cable Car',\n 'Gondola',\n 'Funicular',\n 'Long distance bus',\n 'Rail', // New endpoint use Rail instead of Train.\n];\n\n/**\n * @ignore\n */\nexport const bgColors = [\n '#ffb400',\n '#ff5400',\n '#ff8080',\n '#ea0000',\n '#3000ff',\n '#ffb400',\n '#41a27b',\n '#00d237',\n '#b5b5b5',\n '#ff8080',\n];\n\n/**\n * @ignore\n */\nexport const textColors = [\n '#000000',\n '#ffffff',\n '#000000',\n '#ffffff',\n '#ffffff',\n '#000000',\n '#ffffff',\n '#000000',\n '#000000',\n '#000000',\n];\n\n/**\n * @ignore\n */\nexport const timeSteps = [\n 100000,\n 50000,\n 40000,\n 30000,\n 20000,\n 15000,\n 10000,\n 5000,\n 2000,\n 1000,\n 400,\n 300,\n 250,\n 180,\n 90,\n 60,\n 50,\n 50,\n 50,\n 50,\n 50,\n];\n\n/**\n * @ignore\n */\nconst getTypeIndex = (type) => {\n if (typeof type === 'string') {\n const matched = types.find((t) => new RegExp(type).test(t));\n return types.indexOf(matched);\n }\n return type;\n};\n\n/**\n * @ignore\n */\nexport const getRadius = (type = 0, zoom) => {\n try {\n const typeIdx = getTypeIndex(type);\n return trackerRadiusMapping[typeIdx][zoom];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getBgColor = (type = 0) => {\n try {\n const typeIdx = getTypeIndex(type);\n return bgColors[typeIdx];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getTextColor = (type = 0) => {\n try {\n const typeIdx = getTypeIndex(type);\n return textColors[typeIdx];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getTextSize = (ctx, markerSize, text, fontSize) => {\n ctx.font = `bold ${fontSize}px Arial`;\n let newText = ctx.measureText(text);\n\n const maxiter = 25;\n let i = 0;\n\n while (newText.width > markerSize - 6 && i < maxiter) {\n // eslint-disable-next-line no-param-reassign\n fontSize -= 0.5;\n ctx.font = `bold ${fontSize}px arial, sans-serif`;\n newText = ctx.measureText(text);\n i += 1;\n }\n return fontSize;\n};\n\n/**\n * @ignore\n * @param {number} delayInMs Delay in milliseconds.\n * @param {boolean} cancelled true if the journey is cancelled.\n * @param {boolean} isDelayText true if the color is used for delay text of the symbol.\n */\nexport const getDelayColor = (delayInMs, cancelled, isDelayText) => {\n if (cancelled) {\n return isDelayText ? '#ff0000' : '#a0a0a0'; // red or gray\n }\n if (delayInMs >= 3600000) {\n return '#ed004c'; // pink { r: 237, g: 0, b: 76, s: '237,0,76' };\n }\n if (delayInMs >= 500000) {\n return '#e80000'; // red { r: 232, g: 0, b: 0, s: '232,0,0' };\n }\n if (delayInMs >= 300000) {\n return '#ff4a00'; // orange { r: 255, g: 74, b: 0, s: '255,74,0' };\n }\n if (delayInMs >= 180000) {\n return '#f7bf00'; // yellow { r: 247, g: 191, b: 0, s: '247,191,0' };\n }\n if (delayInMs === null) {\n return '#a0a0a0'; // grey { r: 160, g: 160, b: 160, s: '160,160,160' };\n }\n return '#00a00c'; // green { r: 0, g: 160, b: 12, s: '0,160,12' };\n};\n\n/**\n * @ignore\n */\nexport const getDelayText = (delayInMs, cancelled) => {\n if (cancelled) {\n return String.fromCodePoint(0x00d7);\n }\n if (delayInMs > 3600000) {\n const rounded = Math.round(delayInMs / 3600000);\n return `+${rounded}h`;\n }\n\n if (delayInMs > 59000) {\n const rounded = Math.round(delayInMs / 60000);\n return `+${rounded}m`;\n }\n\n if (delayInMs > 0) {\n return `+${delayInMs}s`;\n }\n\n return '';\n};\n","/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport { buffer, containsCoordinate } from 'ol/extent';\nimport { unByKey } from 'ol/Observable';\nimport Tracker from '../Tracker';\nimport { timeSteps } from '../trackerConfig';\n\n/**\n * TrackerLayerInterface.\n *\n * @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.\n * @classproperty {boolean} isHoverActive - Activate/deactivate pointer hover effect.\n * @classproperty {function} style - Style of the vehicle.\n * @classproperty {FilterFunction} filter - Time speed.\n * @classproperty {function} sort - Set the filter for tracker features.\n * @classproperty {boolean} useRequestAnimationFrame - If true, encapsulates the renderTrajectories calls in a requestAnimationFrame. Experimental.\n */\nexport class TrackerLayerInterface {\n /**\n * Initalize the Tracker.\n * @param {ol/Map~Map} map\n * @param {Object} options\n * @param {number} [options.width] Canvas's width.\n * @param {number} [options.height] Canvas's height.\n * @param {function} [options.getPixelFromCoordinate] Convert an EPSG:3857 coordinate to a canvas pixel (origin top-left).\n */\n // eslint-disable-next-line no-unused-vars\n init(map, options) {}\n\n /**\n * Destroy the Tracker.\n */\n terminate() {}\n\n /**\n * Start the clock.\n *\n * @param {Array<number>} size Map's size: [width, height].\n * @param {number} zoom Map's zoom level.\n * @param {number} resolution Map's resolution.\n */\n // eslint-disable-next-line no-unused-vars\n start(size, zoom, resolution) {}\n\n /**\n * Stop the time.\n * @private\n * @param {number} zoom\n */\n // eslint-disable-next-line no-unused-vars\n startUpdateTime(zoom) {}\n\n /**\n * Stop the clock.\n */\n stop() {}\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n *\n * @param {Date} time The date to render.\n * @param {number[2]} size Size of the canvas to render.\n * @param {number} resolution Map's resolution to render.\n * @param {boolean} [mustRender=true] If false bypass the rendering of vehicles.\n */\n // eslint-disable-next-line no-unused-vars\n setCurrTime(time, size, resolution, mustRender = true) {}\n\n /**\n * Get vehicle.\n * @param {function} filterFc A function use to filter results.\n */\n // eslint-disable-next-line no-unused-vars\n getVehicle(filterFc) {}\n\n /**\n * Returns the list of vehicles which are at the given coordinates.\n * Returns an empty array when no vehicle is located at the given\n * coordinates.\n *\n * @param {number[2]} coordinate A coordinate ([x,y]).\n * @param {number} [resolution=1] The resolution of the map.\n * @param {number} [nb=Infinity] nb The max number of vehicles to return.\n * @returns {Array<ol/Feature~Feature>} Array of vehicles.\n */\n // eslint-disable-next-line no-unused-vars\n getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {}\n\n /**\n * Get the duration before the next update depending on zoom level.\n * @private\n * @param {number} zoom\n */\n // eslint-disable-next-line no-unused-vars\n getRefreshTimeInMs(zoom) {}\n\n /**\n * Define a default style of the vehicle.s\n * Draw a blue circle with the id of the props parameter.\n *\n * @param {Object} props Properties\n * @private\n */\n // eslint-disable-next-line no-unused-vars\n defaultStyle(props) {}\n}\n\n/**\n * Mixin for TrackeLayerInterface.\n *\n * @param {Class} Base A class to extend with {TrackerLayerInterface} functionnalities.\n * @return {Class} A class that implements <TrackerLayerInterface> class and extends Base;\n * @private\n */\nconst TrackerLayerMixin = (Base) =>\n class extends Base {\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const { isHoverActive, style, speed } = {\n isHoverActive: true,\n ...options,\n };\n let cuurSpeed = speed || 1;\n super.defineProperties(options);\n Object.defineProperties(this, {\n isTrackerLayer: { value: true },\n isHoverActive: {\n value: !!isHoverActive,\n writable: true,\n },\n style: {\n value: style || this.defaultStyle,\n },\n speed: {\n get: () => cuurSpeed,\n set: (newSpeed) => {\n cuurSpeed = newSpeed;\n this.start();\n },\n },\n filter: {\n get: () => this.tracker.filter,\n set: (filter) => {\n if (this.tracker) {\n this.tracker.setFilter(filter);\n }\n },\n },\n sort: {\n get: () => this.tracker.sort,\n set: (sort) => {\n if (this.sort) {\n this.tracker.setSort(sort);\n }\n },\n },\n\n /**\n * The tracker that renders the trajectories.\n */\n tracker: { value: null, writable: true },\n\n /**\n * Canvas cache object for trajectories drawn.\n */\n styleCache: { value: {} },\n\n /**\n * Time used to display the trajectories.\n */\n currTime: {\n value: new Date(),\n writable: true,\n },\n\n /**\n * Keep track of the last time used to render trajectories.\n * Useful when the speed increase.\n */\n lastUpdateTime: {\n value: new Date(),\n writable: true,\n },\n\n /**\n * Keep track of which trajectories are currently drawn.\n */\n renderedTrajectories: {\n get: () => this.tracker.renderedTrajectories,\n },\n\n /**\n * Id of the hovered vehicle.\n */\n hoverVehicleId: {\n get: () => {\n return this.tracker.hoverVehicleId;\n },\n set: (hoverVehicleId) => {\n this.tracker.hoverVehicleId = hoverVehicleId;\n },\n },\n\n /**\n * Id of the selected vehicle.\n */\n selectedVehicleId: {\n get: () => {\n return this.tracker.selectedVehicleId;\n },\n set: (selectedVehicleId) => {\n this.tracker.selectedVehicleId = selectedVehicleId;\n },\n },\n\n /**\n * If true, encapsulates the renderTrajectories calls in a requestAnimationFrame\n */\n useRequestAnimationFrame: {\n default: false,\n writable: true,\n },\n });\n }\n\n /**\n * Initalize the Tracker.\n * @param {ol/Map~Map} map\n * @param {Object} options\n * @param {Number} [options.width] Canvas's width.\n * @param {Number} [options.height] Canvas's height.\n * @param {function} [options.getPixelFromCoordinate] Convert an EPSG:3857 coordinate to a canvas pixel (origin top-left).\n */\n init(map, options) {\n super.init(map);\n this.tracker = new Tracker(options);\n this.tracker.setStyle((props, r) => this.style(props, r));\n\n if (this.visible) {\n this.start();\n }\n\n this.visibilityRef = this.on('change:visible', (evt) => {\n if (evt.target.visible) {\n this.start();\n } else {\n this.stop();\n }\n });\n }\n\n /**\n * Destroy the Tracker.\n */\n terminate() {\n this.stop();\n unByKey(this.visibilityRef);\n if (this.tracker) {\n this.tracker.destroy();\n this.tracker = null;\n }\n super.terminate();\n }\n\n /**\n * Start the clock.\n *\n * @param {Array<Number>} size Map's size: [width, height].\n * @param {Number} zoom Map's zoom level.\n * @param {Number} resolution Map's resolution.\n */\n start(size, zoom, resolution) {\n this.stop();\n this.tracker.setVisible(true);\n this.renderTrajectories(this.currTime, size, resolution);\n this.startUpdateTime(zoom);\n }\n\n /**\n * Start the time.\n * @private\n * @param {number} zoom\n */\n startUpdateTime(zoom) {\n this.stopUpdateTime();\n this.updateTimeInterval = setInterval(() => {\n const newTime =\n this.currTime.getTime() +\n (new Date() - this.lastUpdateTime) * this.speed;\n this.setCurrTime(newTime);\n }, this.getRefreshTimeInMs(zoom));\n }\n\n /**\n * Stop the clock.\n */\n stop() {\n this.stopUpdateTime();\n if (this.tracker) {\n this.tracker.setVisible(false);\n this.tracker.clear();\n }\n }\n\n /**\n * Stop the time.\n * @private\n */\n stopUpdateTime() {\n if (this.updateTimeInterval) {\n clearInterval(this.updateTimeInterval);\n }\n }\n\n /**\n * Render the trajectories requesting an animation frame and cancelling the previous one\n * @private\n */\n renderTrajectories(time, size, resolution) {\n if (this.requestId) {\n cancelAnimationFrame(this.requestId);\n }\n if (this.useRequestAnimationFrame) {\n this.requestId = requestAnimationFrame(() => {\n this.tracker.renderTrajectories(time, size, resolution);\n });\n } else {\n this.tracker.renderTrajectories(time, size, resolution);\n }\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n * @param {dateString | value} time\n * @param {Array<number>} size\n * @param {number} resolution\n * @param {boolean} [mustRender=true]\n */\n setCurrTime(time, size, resolution, mustRender = true) {\n const newTime = new Date(time);\n this.currTime = newTime;\n this.lastUpdateTime = new Date();\n if (mustRender) {\n this.renderTrajectories(this.currTime, size, resolution);\n }\n }\n\n /**\n * Get vehicle.\n * @param {function} filterFc A function use to filter results.\n * @returns {Array<Object>} Array of vehicle.\n */\n getVehicle(filterFc) {\n return this.tracker.getTrajectories().filter(filterFc);\n }\n\n /**\n * Returns an array of vehicles located at the given coordinates and resolution.\n *\n * @param {number[2]} coordinate A coordinate ([x,y]).\n * @param {number} [resolution=1] The resolution of the map.\n * @param {number} [nb=Infinity] The max number of vehicles to return.\n * @returns {Array<ol/Feature~Feature>} Array of vehicle.\n */\n getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {\n const ext = buffer([...coordinate, ...coordinate], 10 * resolution);\n const trajectories = this.tracker.getTrajectories();\n const vehicles = [];\n for (let i = 0; i < trajectories.length; i += 1) {\n if (\n trajectories[i].coordinate &&\n containsCoordinate(ext, trajectories[i].coordinate)\n ) {\n vehicles.push(trajectories[i]);\n }\n if (vehicles.length === nb) {\n break;\n }\n }\n\n return vehicles;\n }\n\n /**\n * Get the duration before the next update depending on zoom level.\n * @private\n * @param {number} zoom\n */\n getRefreshTimeInMs(zoom) {\n const roundedZoom = Math.round(zoom);\n const timeStep = timeSteps[roundedZoom] || 25;\n const nextTick = Math.max(25, timeStep / this.speed);\n return nextTick;\n }\n\n /**\n * Define a default style of the vehicle.s\n * Draw a blue circle with the id of the props parameter.\n *\n * @param {Object} props Properties\n * @private\n */\n defaultStyle(props) {\n const { id: text } = props;\n if (this.styleCache[text]) {\n return this.styleCache[text];\n }\n const canvas = document.createElement('canvas');\n canvas.width = 200;\n canvas.height = 15;\n const ctx = canvas.getContext('2d');\n ctx.arc(8, 8, 5, 0, 2 * Math.PI, false);\n ctx.fillStyle = '#8ED6FF';\n ctx.fill();\n ctx.lineWidth = 3;\n ctx.strokeStyle = 'black';\n ctx.stroke();\n ctx.font = 'bold 12px arial';\n ctx.strokeStyle = 'white';\n ctx.lineWidth = 3;\n ctx.strokeText(text, 20, 10);\n ctx.fillStyle = 'black';\n ctx.fillText(text, 20, 10);\n this.styleCache[text] = canvas;\n return this.styleCache[text];\n }\n };\n\nexport default TrackerLayerMixin;\n","import { Layer as OLLayer, Group } from 'ol/layer';\nimport { unByKey } from 'ol/Observable';\nimport Source from 'ol/source/Source';\nimport mixin from '../../common/mixins/TrackerLayerMixin';\nimport Layer from './Layer';\n\n/**\n * Responsible for loading tracker data.\n *\n * @extends {Layer}\n * @implements {TrackerLayerInterface}\n */\nclass TrackerLayer extends mixin(Layer) {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {boolean} options.useDelayStyle Set the delay style.\n * @private\n */\n constructor(options = {}) {\n // We use a group to be able to add custom vector layer in extended class.\n // For example TrajservLayer use a vectorLayer to display the complete trajectory.\n super({\n ...options,\n });\n\n /**\n * Function to define when allowing the render of trajectories depending on the zoom level. Default the fundtion return true.\n * It's useful to avoid rendering the map when the map is animating or interacting\n * @type {function}\n */\n this.renderWhenZooming = options.renderWhenZooming || (() => true);\n\n this.olLayer =\n options.olLayer ||\n new Group({\n layers: [\n new OLLayer({\n source: new Source({}),\n render: (frameState) => {\n if (!this.tracker || !this.tracker.canvas) {\n return null;\n }\n const { zoom, center, resolution } = frameState.viewState;\n\n if (zoom !== this.renderState.zoom) {\n this.renderState.zoom = zoom;\n this.renderState.center = center;\n\n if (!this.renderWhenZooming(zoom)) {\n this.tracker.clear();\n return this.tracker.canvas;\n }\n\n this.renderTrajectories(\n this.currTime,\n frameState.size,\n resolution,\n true,\n );\n } else if (\n this.renderState.center[0] !== center[0] ||\n this.renderState.center[1] !== center[1]\n ) {\n const px = this.map.getPixelFromCoordinate(center);\n const oldPx = this.map.getPixelFromCoordinate(\n this.renderState.center,\n );\n this.tracker.moveCanvas(px[0] - oldPx[0], px[1] - oldPx[1]);\n this.renderState.center = center;\n }\n\n return this.tracker.canvas;\n },\n }),\n ],\n });\n\n // Options the last render run did happen. If something changes\n // we have to render again\n /** @ignore */\n this.renderState = {\n center: [0, 0],\n zoom: null,\n };\n\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<ol/events~EventsKey>}\n * @private\n */\n this.olEventsKeys = []; // Be careful to not override this value in child classe.\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map A OpenLayers map.\n * @private\n */\n init(map) {\n if (!map) {\n return;\n }\n\n super.init(map, {\n getPixelFromCoordinate: map.getPixelFromCoordinate.bind(map),\n });\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n * @param {dateString | value} time\n */\n setCurrTime(time) {\n const view = this.map.getView();\n super.setCurrTime(\n time,\n this.map.getSize(),\n view.getResolution(),\n !this.map.getView().getAnimating() &&\n !this.map.getView().getInteracting(),\n );\n }\n\n /**\n * Trackerlayer is started.\n * @private\n */\n start() {\n super.start(\n this.map.getSize(),\n this.currentZoom || this.map.getView().getZoom(),\n this.map.getView().getResolution(),\n );\n\n this.olEventsKeys = [\n this.map.on('moveend', () => {\n const z = this.map.getView().getZoom();\n\n if (z !== this.currentZoom) {\n /**\n * Current value of the zoom.\n * @type {number}\n */\n this.currentZoom = z;\n this.startUpdateTime(z);\n }\n }),\n this.map.on('pointermove', (evt) => {\n if (\n this.map.getView().getInteracting() ||\n this.map.getView().getAnimating() ||\n !this.isHoverActive\n ) {\n return;\n }\n const [vehicle] = this.getVehiclesAtCoordinate(evt.coordinate, 1);\n const id = vehicle && vehicle.id;\n if (this.hoverVehicleId !== id) {\n this.map.getTargetElement().style.cursor = vehicle\n ? 'pointer'\n : 'auto';\n this.hoverVehicleId = id;\n\n // We doesn´t wait the next render, we force it.\n this.renderTrajectories(this.currTime);\n }\n }),\n ];\n }\n\n /**\n * Stop current layer.\n * @private\n */\n stop() {\n super.stop();\n unByKey(this.olEventsKeys);\n this.olEventsKeys = [];\n }\n\n /**\n * Returns the vehicle which are at the given coordinates.\n * Returns null when no vehicle is located at the given coordinates.\n * @param {ol/coordinate~Coordinate} coordinate\n * @param {number} nb Number of vehicles to return;\n * @returns {Array<ol/Feature~Feature>} Vehicle feature.\n * @override\n */\n getVehiclesAtCoordinate(coordinate, nb) {\n const resolution = this.map.getView().getResolution();\n return super.getVehiclesAtCoordinate(coordinate, resolution, nb);\n }\n\n /**\n * Create a copy of the TrackerLayer.\n * @param {Object} newOptions Options to override\n * @returns {TrackerLayer} A TrackerLayer\n */\n clone(newOptions) {\n return new TrackerLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TrackerLayer;\n","/**\n * Get a Date object as UTC date string .\n * ex: 2019 09 01\n * @ignore\n */\nexport const getUTCDateString = (now = new Date()) => {\n let month = (now.getUTCMonth() + 1).toString();\n month = month.length === 1 ? `0${month}` : month;\n let day = now.getUTCDate().toString();\n day = day.length === 1 ? `0${day}` : day;\n\n return [now.getUTCFullYear(), month, day].join('');\n};\n\n/**\n * Get the UTC time string of Date object.\n * ex: 09:05:01.123\n * @ignore\n */\nexport const getUTCTimeString = (date) =>\n [\n date.getUTCHours(),\n date.getUTCMinutes(),\n `${date.getUTCSeconds()}.${date.getUTCMilliseconds()}`,\n ].join(':');\n\n/**\n * Returns a string representation of a number, with a zero if the number is lower than 10.\n * @ignore\n */\nexport const pad = (integer) => (integer < 10 ? `0${integer}` : integer);\n\n/**\n * Returns a 'hh:mm' string from a time in ms.\n * @param {Number} timeInMs Time in milliseconds.\n * @ignore\n */\nexport const getHoursAndMinutes = (timeInMs) => {\n if (!timeInMs || timeInMs <= 0) {\n return '';\n }\n const date = new Date(timeInMs);\n return `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n};\n\n/**\n * Returns a string representing a delay.\n * @param {Number} timeInMs Delay time in milliseconds.\n * @ignore\n */\nexport const getDelayString = (timeInMs) => {\n const h = Math.floor(timeInMs / 3600000);\n const m = Math.floor((timeInMs % 3600000) / 60000);\n const s = Math.floor(((timeInMs % 3600000) % 60000) / 1000);\n\n if (s === 0 && h === 0 && m === 0) {\n return '0';\n }\n if (s === 0 && h === 0) {\n return `${m}m`;\n }\n if (s === 0) {\n return `${h}h${m}m`;\n }\n if (m === 0 && h === 0) {\n return `${s}s`;\n }\n if (h === 0) {\n return `${m}m${s}s`;\n }\n return `${h}h${m}m${s}s`;\n};\n","import qs from 'query-string';\nimport BaseObject from 'ol/Object';\n\n/**\n * Common class to access to a geOps api.\n *\n * @example\n * import { API } from 'mobility-toolbox-js/api';\n *\n * const api = new API({\n * url: [yourUrl],\n * apiKey: [yourApiKey]\n * });\n *\n * @classproperty {string} url Url of the service.\n * @classproperty {string} apiKey Api key to access the service.\n */\nclass API extends BaseObject {\n constructor(options = {}) {\n super();\n /** @ignore */\n this.url = options.url;\n\n /** @ignore */\n this.apiKey = options.apiKey;\n }\n\n /**\n * Append the apiKey before sending the request.\n * @ignore\n */\n fetch(path = '', params = {}, config) {\n // Clean requets parameters, removing undefined and null values.\n const urlParams = { ...params, key: this.apiKey };\n const clone = { ...urlParams };\n Object.keys(urlParams).forEach(\n (key) =>\n (clone[key] === undefined || clone[key] === null) && delete clone[key],\n );\n if (!this.apiKey) {\n // eslint-disable-next-line no-console\n return Promise.reject(\n new Error(`No apiKey defined for request to ${this.url}`),\n );\n }\n return fetch(`${this.url}${path}?${qs.stringify(clone)}`, config).then(\n (response) => {\n try {\n return response.json().then((data) => {\n if (data.error) {\n throw new Error(data.error);\n }\n return data;\n });\n } catch (err) {\n return Promise.reject(new Error(err));\n }\n },\n );\n }\n}\n\nexport default API;\n","import API from '../../common/api/api';\n\n/**\n * Access to the [Stops service](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n *\n * @example\n * import { StopsAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new StopsAPI({\n * url: 'https://api.geops.io/stops/v1/',\n * apiKey: [yourApiKey]\n * });\n *\n */\nclass StopsAPI extends API {\n /**\n * Constructor\n *\n * @param {Object} options Options.\n * @param {string} [options.url='https://api.geops.io/stops/v1/'] Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n */\n constructor(options = {}) {\n super({ url: 'https://api.geops.io/stops/v1/', ...options });\n }\n\n /**\n * Search.\n *\n * @param {StopsSearchParams} params Request parameters. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<GeoJSONFeature[]>} An array of GeoJSON features with coordinates in [EPSG:4326](http://epsg.io/4326).\n */\n search(params, abortController = {}) {\n return this.fetch('', params, {\n signal: abortController.signal,\n }).then((featureCollection) => featureCollection.features);\n }\n}\n\nexport default StopsAPI;\n","import { LineString } from 'ol/geom';\n\n/**\n * Translate the response date object into a readable object.\n * @returns {array<Date>}\n * @ignore\n */\nconst translateDates = (dates = []) => {\n const newDates = [];\n\n for (let i = 0; i < dates.length; i += 1) {\n const { d: day, m: month, y: year } = dates[i];\n newDates.push({\n day,\n month,\n year,\n });\n }\n return newDates;\n};\n\n/**\n * Translate the trajstations response into a readable object.\n * @returns {Object} returns a readable object\n * @private\n */\nexport const translateTrajStationsResp = (data) => {\n const newData = { ...data };\n\n // MAke sure all property exists.\n ['a', 'f', 'tt'].forEach((prop) => {\n if (!newData[prop]) {\n newData[prop] = {};\n }\n });\n\n const {\n id,\n hs: destination,\n t: vehicleType,\n ln: longName,\n sn: shortName,\n wa: wheelchairAccessible,\n ba: bicyclesAllowed,\n rt: realTime,\n fid: feedsId,\n rid: routeIdentifier,\n c: bgColor,\n tc: datacolor,\n a: { n: operator, u: operatorUrl, tz: operatorTimeZone },\n f: { n: publisher, u: publisherUrl, tz: publisherTimeZone },\n tt: {\n n: dateNotOperatingDays,\n p: dateAdditionalOperatingDays,\n t: operatingPeriod,\n },\n sts: dataStations,\n } = newData;\n\n const notOperatingDays = translateDates(dateNotOperatingDays);\n const additionalOperatingDays = translateDates(dateAdditionalOperatingDays);\n const backgroundColor = bgColor && `#${bgColor}`;\n const color = datacolor && `#${datacolor}`;\n\n const stations = [];\n for (let i = 0; i < (dataStations || []).length; i += 1) {\n const {\n sid: stationId,\n n: stationName,\n p: coordinates,\n at: arrivalTime,\n dt: departureTime,\n ap: arrivalDate,\n dp: departureDate,\n ad: arrivalDelay,\n dd: departureDelay,\n dot: noDropOff,\n put: noPickUp,\n c: cancelled,\n wa: stWheelchairAccessible,\n } = dataStations[i];\n\n stations.push({\n stationId,\n stationName,\n coordinates,\n arrivalTime: arrivalTime !== -1 ? arrivalDate * 1000 : null,\n departureTime: departureTime !== -1 ? departureDate * 1000 : null,\n arrivalDelay,\n departureDelay,\n noDropOff: !!noDropOff,\n noPickUp: !!noPickUp,\n cancelled: !!cancelled,\n wheelchairAccessible: !!stWheelchairAccessible,\n });\n }\n\n return {\n id,\n destination,\n backgroundColor,\n color,\n vehicleType,\n routeIdentifier,\n longName,\n shortName,\n stations,\n wheelchairAccessible: !!wheelchairAccessible,\n bicyclesAllowed: !!bicyclesAllowed,\n realTime,\n feedsId,\n operatingInformations: {\n operatingPeriod,\n notOperatingDays,\n additionalOperatingDays,\n },\n operator,\n operatorUrl,\n operatorTimeZone,\n publisher,\n publisherUrl,\n publisherTimeZone,\n };\n};\n\n/**\n * Translate the trajectory_collection response into a js usable object.\n * @returns {Array} returns an array of trajectories.\n * @ignore\n */\nexport const translateTrajCollResponse = (features = []) => {\n const trajectories = [];\n for (let i = 0; i < features.length; i += 1) {\n const traj = features[i];\n const geometry = new LineString(traj.geometry.coordinates);\n const {\n ID: id,\n ProductIdentifier: type,\n PublishedLineName: name,\n RouteIdentifier: routeIdentifier,\n DirectionText: directionText,\n Operator: operator,\n OperatorURL: operatorUrl,\n Publisher: publisher,\n PublisherURL: publisherUrl,\n License: license,\n LicenseUrl: licenseUrl,\n LicenseNote: licenseNote,\n Color: color,\n JourneyIdentifier: journeyIdentifier,\n RealtimeAvailable: realtimeAvailable,\n OperatorProvidesRealtime: operatorProvidesRealtime,\n DayOfOperation: dayOfOperation,\n Delay: delay,\n TimeIntervals: timeIntervals,\n TextColor: textColor,\n Cancelled: cancelled,\n } = traj.properties;\n\n trajectories.push({\n id,\n type,\n name,\n routeIdentifier,\n directionText,\n operator,\n operatorUrl,\n publisher,\n publisherUrl,\n license,\n licenseUrl,\n licenseNote,\n journeyIdentifier,\n realtimeAvailable,\n operatorProvidesRealtime,\n dayOfOperation,\n delay,\n timeIntervals,\n color: color && `#${color}`,\n textColor: textColor && `#${textColor}`,\n geometry,\n cancelled,\n });\n }\n return trajectories;\n};\n\nexport default {\n translateTrajCollResponse,\n translateTrajStationsResp,\n};\n","import {\n translateTrajCollResponse,\n translateTrajStationsResp,\n} from './TrajservAPIUtils';\nimport API from '../../common/api/api';\n\n/**\n * Access to the [Realtime service](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/).\n *\n * @example\n * import { TrajservAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TrajservAPI({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey]\n * });\n *\n */\nclass TrajservAPI extends API {\n /**\n * Constructor\n *\n * @param {Object} options Options.\n * @param {string} [options.url='https://api.geops.io/tracker/v1'] Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n */\n constructor(options = {}) {\n super({ url: 'https://api.geops.io/tracker/v1', ...options });\n }\n\n /**\n * Fetch a trajectory by id.\n *\n * @param {GetTrajectoryByIdParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajectorybyid).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<TrajservTrajectory>} A trajectory.\n */\n fetchTrajectoryById(params, abortController = {}) {\n return this.fetch(`/trajectorybyid`, params, {\n signal: abortController.signal,\n });\n }\n\n /**\n * Fetch trajectories.\n *\n * @param {GetTrajectoriesParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajectory_collection).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<Trajectory[]>} A list of trajectories.\n */\n fetchTrajectories(params, abortController = {}) {\n return this.fetch(`/trajectory_collection`, params, {\n signal: abortController.signal,\n }).then((data) => {\n return translateTrajCollResponse(data.features);\n });\n }\n\n /**\n * Fetch stations informations about a trajectory.\n *\n * @param {GetTrajectoryStationsParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajstations).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<TrajectoryStation[]>} A list of stations.\n */\n fetchTrajectoryStations(params, abortController = {}) {\n return this.fetch(`/trajstations`, params, {\n signal: abortController.signal,\n }).then((data) => {\n return translateTrajStationsResp(data);\n });\n }\n}\n\nexport default TrajservAPI;\n","/**\n * Class use to facilitate connection to a WebSocket\n * @private\n */\nclass WebSocketConnector {\n constructor(url) {\n /**\n * Array of subscriptions.\n * @type {Array<subscription>}\n */\n this.subscriptions = [];\n this.connect(url);\n\n // keep websocket alive\n setInterval(() => {\n this.send('PING');\n }, 10000);\n this.subscribed = {};\n }\n\n /**\n * Get the websocket request string.\n * @param {string} method Request mehtod {GET, SUB}.\n * @param {Object} params Request parameters.\n * @param {string} params.channel Channel name\n * @param {string} [params.args] Request arguments\n * @param {Number} [params.id] Request identifier\n * @returns {string} request string\n * @private\n */\n static getRequestString(method, params) {\n let reqStr = `${method} ${params.channel}`;\n reqStr += params.args ? ` ${params.args}` : '';\n reqStr += params.id ? ` ${params.id}` : '';\n return reqStr.trim();\n }\n\n /**\n * (Re)connect the websocket.\n * @param {string} url url to connect to\n * @private\n */\n connect(url) {\n if (this.websocket && this.websocket.readyState !== this.websocket.CLOSED) {\n this.websocket.close();\n }\n\n /** @ignore */\n this.websocket = new WebSocket(url);\n\n if (this.currentProj) {\n this.setProjection(this.currentProj);\n }\n\n if (this.currentBbox) {\n this.setBbox(this.currentBbox);\n }\n\n [...this.subscriptions].forEach((s) => {\n this.subscribe(s.params, s.cb, s.errorCb, true);\n });\n\n // reconnect on close\n this.websocket.onclose = () => {\n window.clearTimeout(this.reconnectTimeout);\n /** @ignore */\n this.reconnectTimeout = window.setTimeout(() => this.connect(url), 100);\n };\n }\n\n /**\n * Sends a get request to the websocket.\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @private\n */\n get(params, cb, errorCb) {\n const reqStr = WebSocketConnector.getRequestString('GET', params);\n this.send(reqStr);\n this.listen(params, cb, errorCb);\n }\n\n /**\n * Sends a message to the websocket.\n * @param {message} message Message to send.\n * @private\n */\n send(message) {\n const send = () => {\n this.websocket.send(message);\n };\n\n if (this.websocket.readyState === WebSocket.CONNECTING) {\n this.websocket.addEventListener('open', send);\n } else {\n send();\n }\n }\n\n /**\n * Set the projection for websocket responses.\n * @param {string} value projection value to be set\n * @private\n */\n setProjection(value) {\n /**\n * The projection for websocket responses\n * @type {string}\n */\n this.currentProj = value;\n this.send(`PROJECTION ${value}`);\n }\n\n /**\n * Set the BBOX for websocket responses.\n * @param {Array<Array<number>>} coordinates array of coordinates\n * @private\n */\n setBbox(coordinates) {\n /**\n * The BBOX for websocket responses\n * @type {Array<Array<number>>}\n */\n this.currentBbox = coordinates;\n this.send(`BBOX ${coordinates.join(' ')}`);\n this.subscriptions.forEach((s) => {\n this.get(s.params, s.cb, s.errorCb);\n });\n }\n\n /**\n * Listen to websocket responses.\n * @private\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @returns {{onMessage: function, errorCb: function}} Object with onMessage and error callbacks\n */\n listen(params, cb, errorCb) {\n const onMessage = (e) => {\n const data = JSON.parse(e.data);\n let source = params.channel;\n source += params.args ? ` ${params.args}` : '';\n\n if (\n data.source === source &&\n (!params.id || params.id === data.client_reference)\n ) {\n cb(data);\n }\n };\n\n this.websocket.addEventListener('message', onMessage);\n\n if (errorCb) {\n this.websocket.addEventListener('error', errorCb);\n this.websocket.addEventListener('close', errorCb);\n }\n\n return { onMessageCb: onMessage, onErrorCb: errorCb };\n }\n\n /**\n * Subscribe to a given channel.\n * @private\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @param {boolean} quiet if subscribe should be quiet\n */\n subscribe(params, cb, errorCb, quiet) {\n const { onMessageCb, onErrorCb } = this.listen(params, cb, errorCb);\n const reqStr = WebSocketConnector.getRequestString('', params);\n\n if (!quiet) {\n this.subscriptions.push({ params, cb, errorCb, onMessageCb, onErrorCb });\n }\n\n if (!this.subscribed[reqStr]) {\n this.send(`GET ${reqStr}`);\n this.send(`SUB ${reqStr}`);\n this.subscribed[reqStr] = true;\n }\n }\n\n /**\n * Unsubscribe from a channel.\n * @param {string} source source to unsubscribe from\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n * @private\n */\n unsubscribe(source, cb) {\n this.subscriptions\n .filter((s) => {\n return s.params.channel === source && (!cb || s.cb === cb);\n })\n .forEach(({ onMessageCb, onErrorCb }) => {\n this.websocket.removeEventListener('message', onMessageCb);\n if (onErrorCb) {\n this.websocket.removeEventListener('error', onErrorCb);\n this.websocket.removeEventListener('close', onErrorCb);\n }\n });\n\n this.subscriptions = this.subscriptions.filter(\n (s) => s.params.channel !== source || (cb && s.cb !== cb),\n );\n\n // If there is no more subscriptions to this channel we DEL it.\n if (\n source &&\n this.subscribed[source] &&\n !this.subscriptions.find((s) => s.params.channel === source)\n ) {\n this.send(`DEL ${source}`);\n this.subscribed[source] = false;\n }\n }\n}\n\nexport default WebSocketConnector;\n","/**\n * Get the websocket channel suffix, depending on the current mode.\n * @param {String} mode Mode 'topographic' ou 'schematic'.\n * @private\n */\nexport const getModeSuffix = (mode, modes) =>\n mode === modes.SCHEMATIC ? '_schematic' : '';\n\n/**\n * Compare two given departures for sort alogithm,\n * @param {Object} a First departure.\n * @param {Object} b Second departure.\n * @private\n */\nexport const compareDepartures = (a, b, sortByMinArrivalTime = false) => {\n // First LEAVING and HIDDEN, then BOARDING and then sorted by time.\n const topStates = ['HIDDEN', 'LEAVING', 'BOARDING'];\n const aTop = a.has_fzo && topStates.indexOf(a.state) > -1;\n const bTop = b.has_fzo && topStates.indexOf(b.state) > -1;\n\n if (aTop || bTop) {\n if (aTop !== bTop) {\n return aTop ? -1 : 1;\n }\n\n if (a.state !== b.state) {\n // one is leaving\n return topStates.indexOf(a.state) - topStates.indexOf(b.state);\n }\n }\n\n let aDuration = null;\n let bDuration = null;\n const now = Date.now();\n\n if (sortByMinArrivalTime) {\n aDuration = new Date(a.min_arrival_time || a.time).getTime() - now;\n bDuration = new Date(b.min_arrival_time || b.time).getTime() - now;\n } else {\n aDuration = new Date(a.time).getTime() - now;\n bDuration = new Date(b.time).getTime() - now;\n }\n\n return aDuration - bDuration;\n};\n\n/**\n * Remove the delay from arrivalTime and departureTime\n * @private\n */\nexport const cleanStopTime = (content) => {\n if (!content) {\n return;\n }\n content.stations.forEach((station) => {\n // eslint-disable-next-line no-param-reassign\n station.arrivalTimeWithDelay = station.arrivalTime;\n if (station.departureTime) {\n // eslint-disable-next-line no-param-reassign\n station.departureTimeWithDelay = station.departureTime;\n }\n if (station.arrivalDelay) {\n // eslint-disable-next-line no-param-reassign\n station.arrivalTime -= station.arrivalDelay;\n if (station.departureTime) {\n // eslint-disable-next-line no-param-reassign\n station.departureTime -= station.arrivalDelay;\n }\n }\n });\n // eslint-disable-next-line consistent-return\n return content;\n};\n","import WebSocketConnector from './WebSocketConnector';\nimport {\n getModeSuffix,\n cleanStopTime,\n compareDepartures,\n} from './TralisAPIUtils';\n\n/**\n * Enum for Tralis modes.\n * @readonly\n * @typedef {string} TralisMode\n * @property {string} RAW \"raw\"\n * @property {string} SCHEMATIC \"schematic\"\n * @property {string} TOPOGRAPHIC \"topographic\"\n * @enum {TralisMode}\n */\nexport const TralisModes = {\n RAW: 'raw',\n TOPOGRAPHIC: 'topographic',\n SCHEMATIC: 'schematic',\n};\n\n/**\n * Access to Tralis service.\n *\n * @example\n * import { TralisAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TralisAPI({\n * url: \"yourUrl\",\n * apiKey: \"yourApiKey\"\n * });\n *\n * @example\n * import { TralisAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TralisAPI(\"yourUrl\");\n */\nclass TralisAPI {\n /**\n * Constructor\n *\n * @param {Object|string} options A string representing the url of the service or an object containing the url and the apiKey.\n * @param {string} options.url Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n * @param {string} [options.prefix=''] Service prefix to specify tenant.\n * @param {string} [options.projection='epsg:3857'] The epsg code of the projection for features.\n * @param {number[4]} [options.bbox=[minX, minY, maxX, maxY] The bounding box to receive data from.\n */\n constructor(options = {}) {\n let wsUrl = null;\n\n if (typeof options === 'string') {\n wsUrl = options;\n } else {\n wsUrl = options.url;\n }\n\n if (options.apiKey) {\n wsUrl = `${wsUrl}?key=${options.apiKey}`;\n }\n\n /** @ignore */\n this.subscribedStationUic = null;\n\n /** @ignore */\n this.departureUpdateTimeout = null;\n\n /** @ignore */\n this.maxDepartureAge = 30;\n\n /** @ignore */\n this.extraGeoms = {};\n\n /** @ignore */\n this.prefix = options.prefix || '';\n\n /** @ignore */\n this.conn = new WebSocketConnector(wsUrl);\n this.conn.setProjection(options.projection || 'epsg:3857');\n\n if (options.bbox) {\n this.conn.setBbox(options.bbox);\n }\n }\n\n /**\n * Subscribe to a channel.\n *\n * @param {string} channel Name of the websocket channel to subscribe.\n * @param {function} onSuccess Callback when the subscription succeeds.\n * @param {function} onError Callback when the subscription fails.\n * @param {boolean} [quiet=false] If true avoid to store the subscription in the subscriptions list.\n * @private\n */\n subscribe(channel, onSuccess, onError, quiet = false) {\n this.conn.subscribe({ channel }, onSuccess, onError, quiet);\n }\n\n /**\n * Unsubscribe to a channel.\n *\n * @param {string} channel Name of the websocket channel to unsubscribe.\n * @param {string} [suffix=''] Suffix to add to the channel name.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n * @private\n */\n unsubscribe(channel, suffix = '', cb) {\n this.conn.unsubscribe(\n `${channel}${getModeSuffix(TralisModes.SCHEMATIC, TralisModes)}${suffix}`,\n cb,\n );\n this.conn.unsubscribe(\n `${channel}${getModeSuffix(\n TralisModes.TOPOGRAPHIC,\n TralisModes,\n )}${suffix}`,\n cb,\n );\n }\n\n /**\n * Filter departures and return an array.\n *\n * @param {Object} depObject The object containing departures by id.\n * @param {boolean} [sortByMinArrivalTime=false] If true sort departures by arrival time.\n * @returns {Array<departure>} Return departures array.\n * @private\n */\n filterDepartures(depObject, sortByMinArrivalTime = false) {\n const departures = Object.keys(depObject).map((k) => depObject[k]);\n departures.sort((a, b) => compareDepartures(a, b, sortByMinArrivalTime));\n\n let future = new Date();\n future.setMinutes(future.getMinutes() + this.maxDepartureAge);\n future = future.getTime();\n\n let past = new Date();\n past.setMinutes(past.getMinutes() - this.maxDepartureAge);\n past = past.getTime();\n\n const departureArray = [];\n const platformsBoarding = [];\n let previousDeparture = null;\n\n for (let i = departures.length - 1; i >= 0; i -= 1) {\n const d = departures[i];\n const t = new Date(d.time).getTime();\n\n // Only show departures within the next 30 minutes\n if (t > past && t < future) {\n // If 2 trains are boarding at the same platform,\n // remove the older one.\n if (d.state === 'BOARDING') {\n if (platformsBoarding.indexOf(d.platform) === -1) {\n platformsBoarding.push(d.platform);\n } else {\n d.state = 'HIDDEN';\n }\n }\n\n // If two trains with the same line number and destinatin\n // and a departure difference < 1 minute, hide the second one.\n if (\n previousDeparture &&\n d.to[0] === previousDeparture.to[0] &&\n Math.abs(t - previousDeparture.time) < 1000 &&\n d.line.name === previousDeparture.line.name\n ) {\n d.state = 'HIDDEN';\n }\n\n if (/(STOP_CANCELLED|JOURNEY_CANCELLED)/.test(d.state)) {\n d.cancelled = true;\n }\n\n previousDeparture = d;\n previousDeparture.time = t;\n departureArray.unshift(d);\n }\n }\n\n return departureArray;\n }\n\n /**\n * Subscribe to departures channel of a given station.\n *\n * @param {number} stationId UIC of the station.\n * @param {Boolean} sortByMinArrivalTime Sort by minimum arrival time\n * @param {function(departures:Departure[])} onMessage Function called on each message of the channel.\n */\n subscribeDepartures(stationId, sortByMinArrivalTime = false, onMessage) {\n window.clearTimeout(this.departureUpdateTimeout);\n this.unsubscribeDepartures();\n this.subscribedStationUic = stationId;\n const channel = stationId ? `timetable_${stationId}` : null;\n const departureObject = {};\n this.subscribe(\n channel,\n (data) => {\n if (data.source === channel) {\n const content = data.content || {};\n const tDiff = new Date(content.timestamp).getTime() - Date.now();\n content.timediff = tDiff;\n departureObject[content.call_id] = content;\n\n window.clearTimeout(this.departureUpdateTimeout);\n this.departureUpdateTimeout = window.setTimeout(() => {\n const departures = this.filterDepartures(\n departureObject,\n sortByMinArrivalTime,\n );\n onMessage(departures);\n }, 100);\n }\n },\n () => {\n onMessage([]);\n },\n );\n }\n\n /**\n * Unsubscribe from current departures channel.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDepartures(cb) {\n if (this.subscribedStationUic) {\n this.unsubscribe(`timetable_${this.subscribedStationUic}`, '', cb);\n this.subscribedStationUic = null;\n }\n }\n\n /**\n * Subscribe to the disruptions channel for tenant.\n *\n * @param {function} onMessage Function called on each message of the channel.\n */\n subscribeDisruptions(onMessage) {\n this.subscribe(`${this.prefix}newsticker`, (data) => {\n onMessage(data.content);\n });\n }\n\n /**\n * Unsubscribe disruptions.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDisruptions(cb) {\n this.unsubscribe(`${this.prefix}newsticker`, '', cb);\n }\n\n /**\n * Return a station with a given uic number and a mode.\n *\n * @param {number} uic UIC of the station.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<Station>} A station.\n */\n getStation(uic, mode) {\n const params = {\n channel: `station${getModeSuffix(mode, TralisModes)}`,\n args: uic,\n };\n\n return new Promise((resolve, reject) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n resolve(data.content);\n } else {\n reject();\n }\n });\n });\n }\n\n /**\n * Update the model's station list for a given mode and a bbox.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {number[4]} bbox The extent where to request.\n * @returns {Promise<Station[]>} An array of stations.\n */\n getStations(mode, bbox) {\n const stations = [];\n if (bbox) {\n this.conn.setBbox(bbox);\n }\n const params = {\n channel: `station${getModeSuffix(mode, TralisModes)}`,\n };\n window.clearTimeout(this.stationUpdateTimeout);\n return new Promise((resolve, reject) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n stations.push(data.content);\n window.clearTimeout(this.stationUpdateTimeout);\n /** @ignore */\n this.stationUpdateTimeout = window.setTimeout(() => {\n resolve(stations);\n }, 50);\n } else {\n reject(data.content);\n }\n });\n });\n }\n\n /**\n * Subscribe to stations channel.\n * One message pro station.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {number[4]} bbox The extent where to request.\n * @param {function(station: Station)} onMessage Function called on each message of the channel.\n */\n subscribeStations(mode, bbox, onMessage) {\n this.unsubscribeStations();\n if (bbox) {\n this.conn.setBbox(bbox);\n }\n this.subscribe(`station${getModeSuffix(mode, TralisModes)}`, (data) => {\n if (data.content) {\n onMessage(data.content);\n }\n });\n }\n\n /**\n * Unsubscribe to stations channel.\n * @param {function} cb The listener callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribe.\n */\n unsubscribeStations(cb) {\n window.clearTimeout(this.stationUpdateTimeout);\n this.unsubscribe('station', '', cb);\n }\n\n /**\n * Subscribe to extra_geoms channel.\n *\n * @param {function(extraGeoms: GeosJSONFeature[])} onMessage Function called on each message of the channel.\n */\n subscribeExtraGeoms(onMessage) {\n this.subscribe('extra_geoms', (data) => {\n const extraGeom = data.content;\n\n if (extraGeom) {\n const { ref } = extraGeom.properties;\n\n if (extraGeom.type === 'Feature') {\n this.extraGeoms[ref] = extraGeom;\n } else {\n delete this.extraGeoms[ref];\n }\n\n onMessage(\n Object.keys(this.extraGeoms).map((key) => this.extraGeoms[key]),\n );\n }\n });\n }\n\n /**\n * Unsubscribe to extra_geoms channel.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeExtraGeoms(cb) {\n this.unsubscribe('extra_geoms', '', cb);\n }\n\n /**\n * Subscribe to trajectory channel.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {function(trajectory: TralisTrajectory)} onMessage Function called on each message of the channel.\n */\n subscribeTrajectory(mode, onMessage) {\n this.unsubscribeTrajectory(onMessage);\n this.subscribe(`trajectory${getModeSuffix(mode, TralisModes)}`, onMessage);\n }\n\n /**\n * Unsubscribe to trajectory channels.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeTrajectory(cb) {\n this.unsubscribe(`trajectory`, '', cb);\n }\n\n /**\n * Subscribe to deleted_vhicles channel.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {function(response: { content: Vehicle })} onMessage Function called on each message of the channel.\n */\n subscribeDeletedVehicles(mode, onMessage) {\n this.unsubscribeDeletedVehicles();\n this.subscribe(\n `deleted_vehicles${getModeSuffix(mode, TralisModes)}`,\n onMessage,\n );\n }\n\n /**\n * Unsubscribe to deleted_vhicles channels.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDeletedVehicles(cb) {\n this.unsubscribe('deleted_vehicles', '', cb);\n }\n\n /**\n * Get a full trajectory of a vehicule .\n *\n * @param {string} id A vehicle id.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<FullTrajectory>} Return a full trajectory.\n */\n getFullTrajectory(id, mode) {\n const params = {\n channel: `full_trajectory${getModeSuffix(mode, TralisModes)}_${id}`,\n };\n\n return new Promise((resolve) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n resolve(data.content);\n }\n });\n });\n }\n\n /**\n * Get full trajectories of a vehicules .\n *\n * @param {string[]} ids List of vehicles ids.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<FullTrajectory[]>} Return an array of full trajectories.\n */\n getFullTrajectories(ids, mode) {\n const promises = ids.map((id) => {\n return this.getFullTrajectory(id, mode);\n });\n return Promise.all(promises);\n }\n\n /**\n * Subscribe to full_trajectory channel of a given vehicle.\n *\n * @param {string} id A vehicle id.\n * @param {TralisMode} mode Tralis mode.\n */\n subscribeFullTrajectory(id, mode) {\n // window.clearTimeout(this.fullTrajectoryUpdateTimeout);\n this.unsubscribeFullTrajectory(id);\n this.subscribe(\n `full_trajectory${getModeSuffix(mode, TralisModes)}_${id}`,\n (data) => {\n // eslint-disable-next-line no-console\n console.log('subscribe full_trajectory', data);\n },\n (err) => {\n // eslint-disable-next-line no-console\n console.log('subscribe full_trajectory error', err);\n },\n );\n }\n\n /**\n * Unsubscribe from full_trajectory channel\n *\n * @param {string} id A vehicle id.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeFullTrajectory(id, cb) {\n this.unsubscribe('full_trajectory', `_${id}`, cb);\n }\n\n /**\n * Get the list of stops for this vehicle.\n *\n * @param {string} id A vehicle id.\n * @returns {Promise<StopSequence>} Returns a stop sequence object.\n */\n getStopSequence(id) {\n const params = {\n channel: `stopsequence_${id}`,\n };\n return new Promise((resolve, reject) => {\n this.conn.get(\n params,\n (data) => {\n // Remove the delay from arrivalTime nnd departureTime\n resolve(cleanStopTime(data.content && data.content[0]));\n },\n (err) => {\n reject(err);\n },\n );\n });\n }\n\n /**\n * Get a list of stops for a list of vehicles.\n *\n * @param {string[]} ids List of vehicles ids.\n * @returns {Promise<StopSequence[]>} Return an array of stop sequences.\n */\n getStopSequences(ids) {\n const promises = ids.map((id) => {\n return this.getStopSequence(id);\n });\n return Promise.all(promises);\n }\n\n /**\n * Subscribe to stopsequence channel of a given vehicle.\n *\n * @param {string} id A vehicle id.\n * @param {function(stopSequence: StopSequence)} onMessage Function called on each message of the channel.\n */\n subscribeStopSequence(id, onMessage) {\n window.clearTimeout(this.fullTrajectoryUpdateTimeout);\n this.unsubscribeStopSequence(id);\n\n this.subscribe(\n `stopsequence_${id}`,\n (data) => {\n // Remove the delay from arrivalTime nad departureTime\n onMessage(cleanStopTime(data.content && data.content[0]));\n },\n (err) => {\n // eslint-disable-next-line no-console\n console.log('subscribe stopsequence error', err);\n },\n );\n }\n\n /**\n * Unsubscribe from stopsequence channel\n *\n * @param {string} id A vehicle id.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeStopSequence(id, cb) {\n this.unsubscribe(`stopsequence`, `_${id}`, cb);\n }\n\n /**\n * Subscribe to healthcheck channel.\n * @param {function} onMessage Callback when the subscribe to healthcheck channel succeeds.\n */\n subscribeHealthCheck(onMessage) {\n this.unsubscribeHealthCheck();\n this.subscribe('healthcheck', onMessage);\n }\n\n /**\n * Unsubscribe to healthcheck channel.\n */\n unsubscribeHealthCheck() {\n this.unsubscribe('healthcheck');\n }\n}\nexport default TralisAPI;\n","/* eslint-disable no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport qs from 'query-string';\nimport { getUTCDateString, getUTCTimeString } from '../timeUtils';\nimport {\n getRadius,\n getBgColor,\n getDelayColor,\n getDelayText,\n getTextColor,\n getTextSize,\n} from '../trackerConfig';\nimport { TrajservAPI } from '../../api';\n\n/**\n * TrajservLayerInterface.\n *\n * @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.\n * @classproperty {boolean} isHoverActive - Activate/deactivate pointer hover effect.\n * @classproperty {function} style - Style of the vehicle.\n * @classproperty {FilterFunction} filter - Time speed.\n * @classproperty {function} sort - Set the filter for tracker features.\n *\n * @extends {TrackerLayerInterface}\n */\nexport class TrajservLayerInterface {\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map|mapboxgl.Map} map A map.\n * @override\n */\n init(map) {}\n\n /**\n * Start to update trajectories and initialize the filter.\n * @override\n */\n start() {}\n\n /**\n * Stop to update trajectories.\n * @override\n */\n stop() {}\n\n /**\n * Set the tracker filter property using class properties.\n * @private\n */\n addTrackerFilters() {}\n\n /**\n * Abort http requests.\n *\n * @private\n */\n abortFetchTrajectories() {}\n\n /**\n * Fetch stations information with a trajectory id.\n * @param {number} trajId The id of the trajectory.\n * @private\n */\n updateTrajectoryStations(trajId) {}\n\n /**\n * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {}\n\n /**\n * Start the update of trajectories.\n * @private\n */\n startUpdateTrajectories() {}\n\n /**\n * Stop the update of trajectories.\n * @private\n */\n stopUpdateTrajectories() {}\n\n /**\n * Update the trajectories\n * @private\n */\n updateTrajectories() {}\n\n /**\n * Define the style of the vehicle.\n * Draw a colored circle depending on train delay.\n *\n * @param {Object} props Properties\n * @private\n */\n defaultStyle(props) {}\n}\n\nconst LINE_FILTER = 'publishedlinename';\nconst ROUTE_FILTER = 'tripnumber';\nconst OPERATOR_FILTER = 'operator';\n\n/**\n * Create a array of filter functions based on some parameters.\n * @param {string} line\n * @param {string} route\n * @param {string} operator\n * @param {string} regexLine\n * @private\n */\nconst createFilters = (line, route, operator, regexLine) => {\n const filterList = [];\n\n if (!line && !route && !operator && !regexLine) {\n return null;\n }\n\n if (regexLine) {\n const regexLineList =\n typeof regexLine === 'string' ? [regexLine] : regexLine;\n const lineFilter = (t) =>\n regexLineList.some((tr) => new RegExp(tr, 'i').test(t.name));\n filterList.push(lineFilter);\n }\n\n if (line) {\n const lineFiltersList = typeof line === 'string' ? line.split(',') : line;\n const lineList = lineFiltersList.map((l) =>\n l.replace(/\\s+/g, '').toUpperCase(),\n );\n const lineFilter = (l) =>\n lineList.some((filter) => filter === l.name.toUpperCase());\n filterList.push(lineFilter);\n }\n\n if (route) {\n const routes = typeof route === 'string' ? route.split(',') : route;\n const routeList = routes.map((item) => parseInt(item, 10));\n const routeFilter = (item) => {\n const routeId = parseInt(item.routeIdentifier.split('.')[0], 10);\n return routeList.some((id) => id === routeId);\n };\n filterList.push(routeFilter);\n }\n\n if (operator) {\n const operatorList = typeof operator === 'string' ? [operator] : operator;\n const operatorFilter = (t) =>\n operatorList.some((op) => new RegExp(op, 'i').test(t.operator));\n filterList.push(operatorFilter);\n }\n\n if (!filterList.length) {\n return null;\n }\n\n return (t) => {\n for (let i = 0; i < filterList.length; i += 1) {\n if (!filterList[i](t)) {\n return false;\n }\n }\n return true;\n };\n};\n\n/**\n * Mixin for TrajservLayerInterface.\n *\n * @param {TrackerLayer} TrackerLayer A {TrackerLayer} class to extend with {TrajservLayerInterface} functionnalities.\n * @return {Class} A class that implements {TrajservLayerInterface} class and extends Base;\n * @private\n */\nconst TrajservLayerMixin = (TrackerLayer) =>\n class extends TrackerLayer {\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n super.defineProperties(options);\n let {\n regexPublishedLineName,\n publishedLineName,\n tripNumber,\n operator,\n } = options;\n\n let requestIntervalSeconds = 3;\n let defaultApi;\n if (!options.api) {\n const apiOptions = {};\n if (options.url) {\n apiOptions.url = options.url;\n }\n if (options.apiKey) {\n apiOptions.apiKey = options.apiKey;\n }\n defaultApi = new TrajservAPI(apiOptions);\n }\n Object.defineProperties(this, {\n showVehicleTraj: {\n value:\n options.showVehicleTraj !== undefined\n ? options.showVehicleTraj\n : true,\n writable: true,\n },\n delayDisplay: {\n value: options.delayDisplay || 300000,\n writable: true,\n },\n delayOutlineColor: {\n value: options.delayOutlineColor || '#000000',\n writable: true,\n },\n useDelayStyle: {\n value: options.useDelayStyle || false,\n writable: true,\n },\n requestIntervalSeconds: {\n get: () => {\n return requestIntervalSeconds;\n },\n set: (newRequestIntervalSeconds) => {\n if (newRequestIntervalSeconds !== requestIntervalSeconds) {\n requestIntervalSeconds = newRequestIntervalSeconds;\n if (this.visible) {\n // stop() is call within the start.\n this.start();\n }\n }\n },\n },\n publishedLineName: {\n get: () => {\n return publishedLineName;\n },\n set: (newPublishedLineName) => {\n publishedLineName = newPublishedLineName;\n this.updateFilters();\n },\n },\n tripNumber: {\n get: () => {\n return tripNumber;\n },\n set: (newTripNumber) => {\n tripNumber = newTripNumber;\n this.updateFilters();\n },\n },\n operator: {\n get: () => {\n return operator;\n },\n set: (newOperator) => {\n operator = newOperator;\n this.updateFilters();\n },\n },\n regexPublishedLineName: {\n get: () => {\n return regexPublishedLineName;\n },\n set: (newRegex) => {\n regexPublishedLineName = newRegex;\n this.updateFilters();\n },\n },\n api: {\n value: options.api || defaultApi,\n },\n });\n }\n\n init(map) {\n super.init(map);\n\n // Sort the trajectories.\n if (this.sortFc) {\n this.sort = this.sortFc;\n } else if (this.useDelayStyle) {\n // Automatic sorting depending on delay, higher delay on top.\n this.sort = (a, b) => {\n if (a.delay === null) return 1;\n return a.delay < b.delay ? 1 : -1;\n };\n }\n }\n\n start() {\n this.updateFilters();\n super.start();\n this.startUpdateTrajectories();\n }\n\n stop() {\n this.journeyId = null;\n this.stopUpdateTrajectories();\n this.abortFetchTrajectories();\n super.stop();\n }\n\n updateFilters() {\n // Setting filters from the permalink if no values defined by the layer.\n const parameters = qs.parse(window.location.search.toLowerCase());\n // filter is the property in TrackerLayerMixin.\n this.filter = createFilters(\n this.publishedLineName || parameters[LINE_FILTER],\n this.tripNumber || parameters[ROUTE_FILTER],\n this.operator || parameters[OPERATOR_FILTER],\n this.regexPublishedLineName,\n );\n }\n\n abortFetchTrajectories() {\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n updateTrajectoryStations(trajId) {\n const params = this.getParams({\n id: trajId,\n time: getUTCTimeString(new Date()),\n });\n return this.api.fetchTrajectoryStations(params);\n }\n\n getParams(extraParams = {}) {\n // The 5 seconds more are used as a buffer if the request takes too long.\n const requestIntervalInMs = (this.requestIntervalSeconds + 5) * 1000;\n const intervalMs = this.speed * requestIntervalInMs;\n const now = this.currTime;\n\n let diff = true;\n\n if (\n this.later &&\n now.getTime() >\n this.later.getTime() - this.requestIntervalSeconds * 1000\n ) {\n diff = false;\n }\n if (\n !this.later ||\n !diff ||\n this.later.getTime() - now.getTime() > intervalMs\n ) {\n const later = new Date(now.getTime() + intervalMs);\n this.later = later;\n }\n\n const params = {\n ...extraParams,\n btime: getUTCTimeString(now),\n etime: getUTCTimeString(this.later),\n date: getUTCDateString(now),\n rid: 1,\n a: 1,\n cd: 1,\n nm: 1,\n fl: 1,\n // toff: this.currTime.getTime() / 1000,\n };\n\n // Allow to load only differences between the last request,\n // but currently the Tracker render method doesn't manage to render only diff.\n /* if (diff) {\n // Not working\n params.diff = this.lastRequestTime;\n } */\n return params;\n }\n\n startUpdateTrajectories() {\n this.stopUpdateTrajectories();\n\n this.updateTrajectories();\n this.updateInterval = window.setInterval(() => {\n this.updateTrajectories();\n }, this.requestIntervalSeconds * 1000);\n }\n\n stopUpdateTrajectories() {\n clearInterval(this.updateInterval);\n }\n\n updateTrajectories() {\n this.abortFetchTrajectories();\n this.abortController = new AbortController();\n this.api\n .fetchTrajectories(\n this.getParams({\n attr_det: 1,\n }),\n this.abortController,\n )\n .catch((err) => {\n if (err.name === 'AbortError') {\n // Ignore abort error\n return;\n }\n throw err;\n })\n .then((trajectories) => {\n // Don't set trajectories when the user has aborted the request.\n if (trajectories) {\n this.tracker.setTrajectories(trajectories);\n this.renderTrajectories();\n }\n });\n }\n\n defaultStyle(props, zoom) {\n const {\n type,\n name,\n id,\n color,\n textColor,\n delay,\n cancelled,\n operatorProvidesRealtime,\n } = props;\n const z = Math.min(Math.floor(zoom || 1), 16);\n const hover = this.hoverVehicleId === id;\n const selected = this.selectedVehicleId === id;\n const key = `${z}${type}${name}${operatorProvidesRealtime}${delay}${hover}${selected}${cancelled}`;\n\n if (!this.styleCache[key]) {\n let radius = getRadius(type, z);\n const isDisplayStrokeAndDelay = radius >= 7;\n\n if (radius === 0) {\n this.styleCache[key] = null;\n return null;\n }\n\n if (hover || selected) {\n radius = isDisplayStrokeAndDelay ? radius + 5 : 14;\n }\n const margin = 1;\n const radiusDelay = radius + 2;\n const markerSize = radius * 2;\n\n const canvas = document.createElement('canvas');\n // add space for delay information\n canvas.width = radiusDelay * 2 + margin * 2 + 100;\n canvas.height = radiusDelay * 2 + margin * 2 + 100;\n const ctx = canvas.getContext('2d');\n const origin = canvas.width / 2;\n\n if (isDisplayStrokeAndDelay && delay !== null) {\n // Draw circle delay background\n ctx.save();\n ctx.beginPath();\n ctx.arc(origin, origin, radiusDelay, 0, 2 * Math.PI, false);\n ctx.fillStyle = getDelayColor(delay, cancelled);\n ctx.filter = 'blur(1px)';\n ctx.fill();\n ctx.restore();\n }\n\n // Show delay if feature is hovered or if delay is above 5mins.\n if (\n isDisplayStrokeAndDelay &&\n (hover || delay >= this.delayDisplay || cancelled)\n ) {\n // Draw delay text\n ctx.save();\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n ctx.font = `bold ${Math.max(\n cancelled ? 19 : 14,\n Math.min(cancelled ? 19 : 17, radius * 1.2),\n )}px arial, sans-serif`;\n ctx.fillStyle = getDelayColor(delay, cancelled, true);\n\n ctx.strokeStyle = this.delayOutlineColor;\n ctx.lineWidth = 1.5;\n const delayText = getDelayText(delay, cancelled);\n ctx.strokeText(delayText, origin + radiusDelay + margin, origin);\n ctx.fillText(delayText, origin + radiusDelay + margin, origin);\n ctx.restore();\n }\n\n // Draw colored circle with black border\n let circleFillColor;\n if (this.useDelayStyle) {\n circleFillColor = getDelayColor(delay, cancelled);\n } else {\n circleFillColor = color || getBgColor(type);\n }\n\n ctx.save();\n if (isDisplayStrokeAndDelay || hover || selected) {\n ctx.lineWidth = 1;\n ctx.strokeStyle = '#000000';\n }\n ctx.fillStyle = circleFillColor;\n ctx.beginPath();\n ctx.arc(origin, origin, radius, 0, 2 * Math.PI, false);\n ctx.fill();\n // Dashed outline if a provider provides realtime but we don't use it.\n if (\n isDisplayStrokeAndDelay &&\n this.useDelayStyle &&\n delay === null &&\n operatorProvidesRealtime === 'yes'\n ) {\n ctx.setLineDash([5, 3]);\n }\n if (isDisplayStrokeAndDelay || hover || selected) {\n ctx.stroke();\n }\n ctx.restore();\n\n // Draw text in the circle\n if (radius > 10) {\n const fontSize = Math.max(radius, 10);\n const textSize = getTextSize(ctx, markerSize, name, fontSize);\n\n // Draw a stroke to the text only if a provider provides realtime but we don't use it.\n if (\n this.useDelayStyle &&\n delay === null &&\n operatorProvidesRealtime === 'yes'\n ) {\n ctx.save();\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'center';\n ctx.font = `bold ${textSize + 2}px Arial`;\n ctx.strokeStyle = circleFillColor;\n ctx.strokeText(name, origin, origin);\n ctx.restore();\n }\n\n // Draw a text\n ctx.save();\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'center';\n ctx.fillStyle = !this.useDelayStyle\n ? textColor || getTextColor(type)\n : '#000000';\n ctx.font = `bold ${textSize}px Arial`;\n ctx.strokeStyle = circleFillColor;\n ctx.strokeText(name, origin, origin);\n ctx.fillText(name, origin, origin);\n ctx.restore();\n }\n\n this.styleCache[key] = canvas;\n }\n\n return this.styleCache[key];\n }\n };\n\nexport default TrajservLayerMixin;\n","import Feature from 'ol/Feature';\nimport { transform as transformCoords } from 'ol/proj';\nimport { buffer, getWidth } from 'ol/extent';\nimport { Point, MultiPoint, LineString } from 'ol/geom';\nimport { Style, Fill, Stroke, Circle } from 'ol/style';\nimport { Vector as VectorLayer } from 'ol/layer';\nimport { Vector as VectorSource } from 'ol/source';\nimport TrackerLayer from './TrackerLayer';\nimport { getUTCTimeString } from '../../common/timeUtils';\nimport { getBgColor } from '../../common/trackerConfig';\nimport mixin from '../../common/mixins/TrajservLayerMixin';\n\n/**\n * Responsible for loading and display data from a Trajserv service.\n *\n * @example\n * import { TrajservLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TrajservLayer({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/trajserv/TrajservAPI%20js~TrajservAPI%20html\">TrajservAPI</a>\n * @see <a href=\"/example/ol-tracker\">OL tracker example</a>\n *\n * @extends {TrackerLayer}\n * @implements {TrajservLayerInterface}\n */\nclass TrajservLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n // We use a group to be able to add custom vector layer in extended class.\n // For example TrajservLayer use a vectorLayer to display the complete trajectory.\n super({\n ...options,\n });\n\n /** @ignore */\n this.vectorLayer = new VectorLayer({\n source: new VectorSource({ features: [] }),\n });\n this.olLayer.getLayers().insertAt(0, this.vectorLayer);\n }\n\n /**\n * Initialize the layer.\n * @param {mapboxgl.Map} map the mapbox map.\n * @override\n */\n init(map) {\n if (!map) {\n return;\n }\n\n map.addLayer(this.vectorLayer);\n super.init(map);\n }\n\n /**\n * Terminate the layer.\n * @override\n */\n terminate() {\n if (this.map) {\n this.map.removeLayer(this.vectorLayer);\n }\n super.terminate();\n }\n\n /**\n * Start the layer.\n * @override\n */\n start() {\n if (!this.map) {\n return;\n }\n super.start();\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<ol/events~EventsKey>}\n */\n this.olEventsKeys = [\n ...this.olEventsKeys,\n this.map.on('singleclick', this.onMapClick.bind(this)),\n this.map.on('moveend', this.onMoveEnd.bind(this)),\n ];\n }\n\n /**\n * Callback on 'moveend' event.\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n if (this.selectedVehicleId && this.journeyId) {\n this.highlightTrajectory();\n }\n }\n\n /**\n * Callback on 'singleclick' event.\n * @param {ol/MapEvent~MapEvent} evt\n * @private\n */\n onMapClick(evt) {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n const [vehicle] = this.getVehiclesAtCoordinate(evt.coordinate, 1);\n const features = [];\n\n if (vehicle) {\n const geom = vehicle.coordinate ? new Point(vehicle.coordinate) : null;\n features.push(new Feature({ geometry: geom, ...vehicle }));\n\n if (features.length) {\n /**\n * Id of the selected vehicle\n * @type {string}\n */\n this.selectedVehicleId = features[0].get('id');\n /** @ignore */\n this.journeyId = features[0].get('journeyIdentifier');\n this.updateTrajectoryStations(this.selectedVehicleId).then(\n (trajStations) => {\n this.clickCallbacks.forEach((callback) =>\n callback({ ...vehicle, ...trajStations }, this, evt),\n );\n },\n );\n }\n } else {\n this.selectedVehicleId = null;\n this.vectorLayer.getSource().clear();\n this.clickCallbacks.forEach((callback) => callback(null, this, evt));\n }\n }\n\n /**\n * Draw the trajectory as a line with points for each stop.\n * @param {Array} stationsCoords Array of station coordinates.\n * @param {LineString|MultiLineString} lineGeometry A LineString or a MultiLineString.\n * @param {string} color The color of the line.\n * @private\n */\n drawFullTrajectory(stationsCoords, lineGeometry, color) {\n // Don't allow white lines, use red instead.\n const vehiculeColor = /#ffffff/i.test(color) ? '#ff0000' : color;\n const vectorSource = this.vectorLayer.getSource();\n vectorSource.clear();\n\n if (stationsCoords) {\n const geometry = new MultiPoint(stationsCoords);\n const aboveStationsFeature = new Feature(geometry);\n aboveStationsFeature.setStyle(\n new Style({\n zIndex: 1,\n image: new Circle({\n radius: 5,\n fill: new Fill({\n color: '#000000',\n }),\n }),\n }),\n );\n const belowStationsFeature = new Feature(geometry);\n belowStationsFeature.setStyle(\n new Style({\n zIndex: 4,\n image: new Circle({\n radius: 4,\n fill: new Fill({\n color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n }),\n }),\n }),\n );\n vectorSource.addFeatures([aboveStationsFeature, belowStationsFeature]);\n }\n\n const lineFeat = new Feature({\n geometry: lineGeometry,\n });\n lineFeat.setStyle([\n new Style({\n zIndex: 2,\n stroke: new Stroke({\n color: '#000000',\n width: 6,\n }),\n }),\n new Style({\n zIndex: 3,\n stroke: new Stroke({\n color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n width: 4,\n }),\n }),\n ]);\n vectorSource.addFeature(lineFeat);\n }\n\n /**\n * Fetch stations information with a trajectory ID\n * @param {number} trajId The ID of the trajectory\n * @returns {Promise<TrajectoryStation[]>} A list of stations.\n * @private\n */\n updateTrajectoryStations(trajId) {\n return super.updateTrajectoryStations(trajId).then((trajStations) => {\n /**\n * Array of station coordinates.\n * @type {Array<ol/coordinate~Coordinate>}\n */\n this.stationsCoords = [];\n trajStations.stations.forEach((station) => {\n this.stationsCoords.push(\n transformCoords(station.coordinates, 'EPSG:4326', 'EPSG:3857'),\n );\n });\n\n this.highlightTrajectory();\n return trajStations;\n });\n }\n\n /**\n * Highlight the trajectory of journey.\n * @private\n */\n highlightTrajectory() {\n this.api\n .fetchTrajectoryById(\n this.getParams({\n id: this.journeyId,\n time: getUTCTimeString(new Date()),\n }),\n )\n .then((traj) => {\n const { p: multiLine, t, c } = traj;\n const lineCoords = [];\n multiLine.forEach((line) => {\n line.forEach((point) => {\n lineCoords.push([point.x, point.y]);\n });\n });\n\n this.drawFullTrajectory(\n this.stationsCoords,\n new LineString(lineCoords),\n c ? `#${c}` : getBgColor(t),\n );\n })\n .catch(() => {\n this.vectorLayer.getSource().clear();\n });\n }\n\n /**\n * @override\n * * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {\n const ext = this.map.getView().calculateExtent();\n const bbox = buffer(ext, getWidth(ext) / 10).join(',');\n const zoom = this.map.getView().getZoom();\n\n return super.getParams({\n ...extraParams,\n bbox,\n s: zoom < 10 ? 1 : 0,\n z: zoom,\n });\n }\n\n /** @ignore */\n defaultStyle(props) {\n const zoom = this.map.getView().getZoom();\n return super.defaultStyle(props, zoom);\n }\n\n /**\n * Create a copy of the TrajservLayer.\n * @param {Object} newOptions Options to override\n * @returns {TrajservLayer} A TrajservLayer\n */\n clone(newOptions) {\n return new TrajservLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TrajservLayer;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport GeoJSON from 'ol/format/GeoJSON';\nimport Point from 'ol/geom/Point';\nimport { TralisAPI, TralisModes } from '../../api';\n\n/**\n * TralisLayerInterface.\n */\nexport class TralisLayerInterface {\n /*\n * Constructor\n\n * @param {Object} options Layer options.\n * @param {string} options.url Tralis service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n * @param {boolean} [options.debug=false] Display additional debug informations.\n * @param {TralisMode} [options.mode=TralisMode.TOPOGRAPHIC] - Mode.\n * @param {number} [options.dfltIconScale=0.6] - Scale of vehicle icons.\n * @param {number} [options.dfltIconHighlightScale=0.8] - Scale of vehicle icons when they are highlighted.\n */\n constructor(options = {}) {}\n\n /**\n * Subscribe to the Tralis service.\n *\n * @param {ol/Map~Map} map\n */\n init(map) {}\n\n /**\n * Unsubscribe to the Tralis service.\n */\n terminate() {}\n\n /**\n * Change the mode.\n *\n * @param {TralisMode} mode Tralis mode\n */\n setMode(mode) {}\n\n /**\n * Add a feature to the tracker.\n * @param {number} id The feature id\n * @param {Trajectory} traj Properties of the trajectory.\n * @param {boolean} [addOnTop=false] If true, the trajectory is added on top of\n * the trajectory object. This affects the draw order. If addOnTop is\n * true, the trajectory is drawn first and appears on bottom.\n * @private\n */\n addTrajectory(id, traj, addOnTop = false) {}\n\n /**\n * Remove a trajectory with a given id.\n * @param {number} id The trajectory id\n * @private\n */\n removeTrajectory(id) {}\n\n /**\n * Remove a trajectory by attribute.\n * @param {string} attributeName Name of the attribute.\n * @param {*} value Attribute value.\n * @private\n */\n removeTrajectoryByAttribute(attributeName, value) {}\n}\n\n/**\n * Mixin for TralisLayerInterface.\n *\n * @param {TrackerLayer} TrackerLayer A {TrackerLayer} class to extend with {TrajservLayerInterface} functionnalities.\n * @return {Class} A class that implements {TralisLayerInterface} class and extends Base;\n * @private\n */\nconst TralisLayerMixin = (TrackerLayer) =>\n class extends TrackerLayer {\n constructor(options = {}) {\n super({ ...options });\n this.debug = options.debug;\n this.mode = options.mode || TralisModes.TOPOGRAPHIC;\n this.trajectories = [];\n this.refreshTimeInMs = 1000 / 30;\n this.onMessage = this.onMessage.bind(this);\n this.onDeleteMessage = this.onDeleteMessage.bind(this);\n this.api = options.api || new TralisAPI(options);\n this.format = new GeoJSON();\n\n // These scales depends from the size specifed in the svgs.\n // For some reason the size must be specified in the svg (../img/lines) for firefox.\n this.dfltIconScale = options.dfltIconScale || 0.6;\n this.dfltIconHighlightScale = options.dfltIconHighlightScale || 0.8;\n this.minIconScale = this.dfltIconScale * 0.75;\n }\n\n init(map) {\n super.init(map);\n this.api.subscribeTrajectory(this.mode, this.onMessage);\n this.api.subscribeDeletedVehicles(this.mode, this.onDeleteMessage);\n }\n\n terminate() {\n this.api.unsubscribeTrajectory(this.onMessage);\n this.api.unsubscribeDeletedVehicles(this.onDeleteMessage);\n super.terminate();\n }\n\n setMode(mode) {\n if (this.mode === mode) {\n return;\n }\n this.mode = mode;\n this.api.subscribeTrajectory(this.mode, this.onMessage);\n this.api.subscribeDeletedVehicles(this.mode, this.onDeleteMessage);\n }\n\n onMessage(data) {\n if (!data.content) {\n return;\n }\n const feat = this.format.readFeature(data.content);\n\n feat.set('timeOffset', Date.now() - data.timestamp);\n\n // ignore old events [SBAHNM-97]\n if (feat.get('time_since_update') >= 0) {\n if (\n this.debug &&\n this.mode === TralisModes.TOPOGRAPHIC &&\n feat.get('raw_coordinates')\n ) {\n const point = new Point(feat.get('raw_coordinates'));\n point.transform('EPSG:4326', this.map.getView().getProjection());\n feat.setGeometry(point);\n }\n\n this.addTrajectory(\n feat.get('train_id'),\n feat.getProperties(),\n !feat.get('line'),\n );\n }\n }\n\n onDeleteMessage(data) {\n if (data.content) {\n this.removeTrajectoryByAttribute('train_id', data.content);\n }\n }\n\n addTrajectory(id, traj, addOnTop) {\n const idx = this.trajectories.findIndex((t) => t.train_id === id);\n const { time_intervals: timeIntervals } = traj;\n\n // Properties needed to display the vehicle.\n const trajectory = { ...traj, id, timeIntervals };\n if (addOnTop) {\n this.trajectories.unshift(trajectory);\n if (idx !== -1) {\n this.tracker.trajectories.splice(idx + 1, 1);\n }\n } else {\n this.trajectories.push(trajectory);\n if (idx !== -1) {\n this.tracker.trajectories.splice(idx, 1);\n }\n }\n\n this.updateTrajectories();\n }\n\n removeTrajectory(id) {\n for (let i = 0, len = this.trajectories.length; i < len; i += 1) {\n if (this.trajectories[i].id === id) {\n this.trajectories.splice(i, 1);\n break;\n }\n }\n }\n\n removeTrajectoryByAttribute(attributeName, value) {\n for (let i = 0, len = this.trajectories.length; i < len; i += 1) {\n if (this.trajectories[i][attributeName] === value) {\n this.removeTrajectory(this.trajectories[i].id);\n break;\n }\n }\n }\n\n updateTrajectories() {\n this.tracker.setTrajectories(this.trajectories);\n this.renderTrajectories();\n }\n\n getRefreshTimeInMs() {\n return this.refreshTimeInMs;\n }\n };\n\nexport default TralisLayerMixin;\n","import TrackerLayer from './TrackerLayer';\nimport mixin from '../../common/mixins/TralisLayerMixin';\n\n/**\n * Responsible for loading and display data from a Tralis service.\n *\n * @example\n * import { TralisLayer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new TralisLayer({\n * url: [yourUrl],\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html\">TralisAPI</a>\n *\n * @extends {TrackerLayer}\n * @implements {TralisLayerInterface}\n */\nclass TralisLayer extends mixin(TrackerLayer) {\n /**\n * Create a copy of the TralisLayer.\n * @param {Object} newOptions Options to override\n * @returns {TralisLayer} A TralisLayer\n */\n clone(newOptions) {\n return new TralisLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TralisLayer;\n","import { unByKey } from 'ol/Observable';\nimport Layer from './Layer';\n\n/**\n * A class use to display vector data.\n *\n * @extends {Layer}\n */\nclass VectorLayer extends Layer {\n /**\n * Constructor.\n *\n * @param {Object} [options]\n * @param {number} [options.hitTolerance=5] Pixel value of the click hitTolerance of clicks.\n */\n constructor(options = {}) {\n super(options);\n\n /** @ignore */\n this.hitTolerance = options.hitTolerance || 5;\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate the coordinate to request the information at.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit.\n * eslint-disable-next-line class-methods-use-this\n */\n getFeatureInfoAtCoordinate(coordinate) {\n let features = [];\n\n if (this.map) {\n const pixel = this.map.getPixelFromCoordinate(coordinate);\n features = this.map.getFeaturesAtPixel(pixel, {\n layerFilter: (l) => l === this.olLayer,\n hitTolerance: this.hitTolerance,\n });\n }\n\n return Promise.resolve({\n features,\n layer: this,\n coordinate,\n });\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n /**\n * ol click events key, returned by map.on('singleclick')\n * @type {ol/events~EventsKey}\n * @private\n */\n this.singleClickRef = this.map.on('singleclick', (e) => {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n this.getFeatureInfoAtCoordinate(e.coordinate)\n .then((d) => this.callClickCallbacks(d.features, d.layer, d.coordinate))\n .catch(() => this.callClickCallbacks([], this, e.coordinate));\n });\n }\n\n /**\n * Call click callbacks with given parameters.\n * This is done in a separate function for being able to modify the response.\n * @param {Array<ol/Feature~Feature>} features\n * @param {ol/layer/Layer~Layer} layer\n * @param {ol/coordinate~Coordinate} coordinate\n * @private\n */\n callClickCallbacks(features, layer, coordinate) {\n this.clickCallbacks.forEach((c) => c(features, layer, coordinate));\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n super.terminate();\n if (this.singleClickRef) {\n unByKey(this.singleClickRef);\n }\n }\n\n /**\n * Create a copy of the VectorLayer.\n * @param {Object} newOptions Options to override\n * @returns {VectorLayer} A VectorLayer\n */\n clone(newOptions) {\n return new VectorLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default VectorLayer;\n","import GeoJSON from 'ol/format/GeoJSON';\nimport { unByKey } from 'ol/Observable';\nimport Layer from './Layer';\n\n/**\n * Class use to display a WMS layer.\n *\n * @extends {Layer}\n */\nclass WMSLayer extends Layer {\n /**\n * @inheritdoc\n */\n constructor(options = {}) {\n super(options);\n\n /** @ignore */\n this.abortController = new AbortController();\n /** @ignore */\n this.format = new GeoJSON();\n }\n\n /**\n * Get features infos' Url.\n * @param {ol/coordinate~Coordinate} coord\n * @returns {ol/layer/Layer~Layer}\n */\n getFeatureInfoUrl(coord) {\n const projection = this.map.getView().getProjection();\n const resolution = this.map.getView().getResolution();\n\n if (this.olLayer.getSource().getFeatureInfoUrl) {\n return this.olLayer\n .getSource()\n .getFeatureInfoUrl(coord, resolution, projection, {\n info_format: 'application/json',\n query_layers: this.olLayer.getSource().getParams().layers,\n });\n }\n return false;\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate to request the information at.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit.\n * eslint-disable-next-line class-methods-use-this\n */\n getFeatureInfoAtCoordinate(coordinate) {\n this.abortController.abort();\n this.abortController = new AbortController();\n const { signal } = this.abortController;\n return fetch(this.getFeatureInfoUrl(coordinate), { signal })\n .then((resp) => resp.json())\n .then((r) => r.features)\n .then((data) => ({\n layer: this,\n coordinate,\n features: data.map((d) => this.format.readFeature(d)),\n }))\n .catch(() =>\n // resolve an empty feature array something fails\n Promise.resolve({\n features: [],\n coordinate,\n layer: this,\n }),\n );\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map An OpenLayers map.\n */\n init(map) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n /**\n * ol click events key, returned by map.on('singleclick')\n * @private\n * @type {ol/events~EventsKey}\n */\n this.singleClickRef = this.map.on('singleclick', (e) => {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n this.getFeatureInfoAtCoordinate(e.coordinate).then((data) =>\n this.callClickCallbacks(data.features, data.layer, data.coordinate),\n );\n });\n }\n\n /**\n * Call click callbacks with given parameters.\n * This is done in a separate function for being able to modify the response.\n * @param {Array<ol/Feature~Feature>} features\n * @param {ol/layer/Layer~Layer} layer\n * @param {ol/coordinate~Coordinate} coordinate\n * @private\n */\n callClickCallbacks(features, layer, coordinate) {\n this.clickCallbacks.forEach((c) => c(features, layer, coordinate));\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n super.terminate();\n if (this.singleClickRef) {\n unByKey(this.singleClickRef);\n }\n }\n\n /**\n * Create a copy of the WMSLayer.\n * @param {Object} newOptions Options to override\n * @returns {WMSLayer} A WMSLayer\n */\n clone(newOptions) {\n return new WMSLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default WMSLayer;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport StopsAPI from '../../api/stops/StopsAPI';\n\n/**\n * Search control interface.\n *\n * @classproperty {StopsSearchParams} apiParams - Default request parameters used by the search method. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n */\nexport class SearchInterface {\n /**\n * Constructor.\n *\n * @param {Object} options Map options\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/). See StopsAPI.\n * @param {string} [options.url='https://api.geops.io/tracker/v1'] Stops service url. See StopsAPI.\n * @param {string} [options.placeholder='Search for a stop...'] Input field placeholder.\n * @param {StopsSearchParams} [options.apiParams={ limit: 20 }] Request parameters. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n */\n // eslint-disable-next-line no-unused-vars\n constructor(options = {}) {}\n\n /**\n * Launch a search.\n *\n * @param {String} query The query to search for.\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<GeoJSONFeature[]>} An array of GeoJSON features with coordinates in [EPSG:4326](http://epsg.io/4326).\n */\n // eslint-disable-next-line no-unused-vars\n search(query, abortController) {}\n}\n\n/**\n * Mixin for SearchInterface.\n *\n * @param {Class} Base A class to extend with {SearchInterface} functionnalities.\n * @return {Class} A class that implements <SearchInterface> class and extends Base;\n * @private\n */\nconst SearchMixin = (Base) =>\n class extends Base {\n constructor(options = {}) {\n super(options);\n const { apiParams, apiKey, url } = options;\n\n this.apiParams = { limit: 20, ...(apiParams || {}) };\n this.placeholder = options.placeholder || 'Search for a stop...';\n\n const apiOptions = { apiKey };\n if (url) {\n apiOptions.url = url;\n }\n this.api = new StopsAPI(apiOptions);\n }\n\n render(suggestions = []) {\n if (!this.suggestionsElt) {\n return;\n }\n\n this.suggestionsElt.style.display = suggestions.length ? 'block' : 'none';\n\n this.suggestionsElt.innerHTML = '';\n\n suggestions.forEach((suggestion) => {\n const { properties } = suggestion;\n const suggElt = document.createElement('div');\n suggElt.innerHTML = properties.name;\n suggElt.onclick = () => {\n this.onSuggestionClick(suggestion);\n };\n Object.assign(suggElt.style, {\n padding: '5px 12px',\n });\n this.suggestionsElt.appendChild(suggElt);\n });\n }\n\n createDefaultElement() {\n /**\n * Define a default element.\n */\n this.element = document.createElement('div');\n this.element.id = 'mbt-search';\n Object.assign(this.element.style, {\n position: 'absolute',\n top: 0,\n left: '50px',\n margin: '10px',\n display: 'flex',\n flexDirection: 'column',\n width: '320px',\n });\n\n // Create input element\n this.inputElt = document.createElement('input');\n this.inputElt.type = 'text';\n this.inputElt.placeholder = this.placeholder;\n this.inputElt.autoComplete = 'off';\n this.inputElt.onkeyup = (evt) => {\n this.search(evt.target.value);\n };\n Object.assign(this.inputElt.style, {\n padding: '10px 30px 10px 10px',\n });\n this.element.appendChild(this.inputElt);\n\n // Create suggestions list element\n this.suggestionsElt = document.createElement('div');\n Object.assign(this.suggestionsElt.style, {\n backgroundColor: 'white',\n overflowY: 'auto',\n cursor: 'pointer',\n });\n this.element.appendChild(this.suggestionsElt);\n\n this.clearElt = document.createElement('div');\n Object.assign(this.clearElt.style, {\n display: 'none',\n position: 'absolute',\n right: '0',\n padding: '10px',\n fontSize: '200%',\n cursor: 'pointer',\n });\n this.clearElt.innerHTML = '×';\n this.clearElt.onclick = () => this.clear();\n this.element.appendChild(this.clearElt);\n }\n\n search(q, abortController) {\n if (q !== undefined || q !== null) {\n this.apiParams.q = q;\n }\n\n if (this.clearElt) {\n this.clearElt.style.display = 'block';\n }\n\n return this.api\n .search(this.apiParams, abortController)\n .then((data) => {\n this.render(data);\n })\n .catch(() => {\n this.render();\n });\n }\n\n /**\n * To be defined in inherited class\n */\n // eslint-disable-next-line no-unused-vars\n onSuggestionClick(suggestion) {}\n\n /**\n * Clear the search field and close the control.\n */\n clear() {\n if (!this.suggestionsElt) {\n return;\n }\n\n this.inputElt.value = '';\n this.suggestionsElt.innerHTML = '';\n this.clearElt.style.display = 'none';\n }\n };\n\nexport default SearchMixin;\n","import { fromLonLat } from 'ol/proj';\nimport Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/SearchMixin';\n\n/**\n * Search stations.\n *\n * @example\n * import { Map, StopFinderControl } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * controls: [\n * new StopFinderControl({\n * apiKey: [yourApiKey]\n * })\n * ]\n * });\n *\n *\n * @see <a href=\"/example/ol-search\">Openlayers search example</a>\n *\n * @extends {Control}\n * @implements {SearchInterface}\n */\nclass StopFinderControl extends mixin(Control) {\n /**\n * @private\n */\n onSuggestionClick({ geometry }) {\n const coord = fromLonLat(geometry.coordinates);\n this.map.getView().setCenter(coord);\n }\n}\n\nexport default StopFinderControl;\n","import Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/CopyrightMixin';\nimport getMapboxMapCopyrights from '../../common/utils/getMapboxMapCopyrights';\n\n/**\n * Display layer's copyrights.\n *\n * @example\n * import { Map, CopyrightControl } from 'mobility-toolbox-js/mapbox';\n *\n * const map = new Map({\n * container: 'map',\n * style: `https://maps.geops.io/styles/travic_v2/style.json?key=${window.apiKey}`,\n * controls: [\n * new CopyrightControl()\n * ]\n * });\n *\n *\n * @see <a href=\"/example/mb-copyright\">Mapbox copyright example</a>\n *\n * @extends {Control}\n * @implements {CopyrightInterface}\n */\nclass CopyrightControl extends mixin(Control) {\n constructor(options) {\n super(options);\n this.render = this.render.bind(this);\n }\n\n activate() {\n super.activate();\n if (this.map) {\n this.map.on('sourcedata', this.render);\n this.map.on('styledata', this.render);\n this.map.on('idle', this.render);\n }\n }\n\n deactivate() {\n if (this.map) {\n this.map.off('sourcedata', this.render);\n this.map.off('styledata', this.render);\n this.map.off('idle', this.render);\n }\n super.deactivate();\n }\n\n getCopyrights() {\n return getMapboxMapCopyrights(this.map);\n }\n}\n\nexport default CopyrightControl;\n","import { Map as MBMap } from 'mapbox-gl';\nimport Layer from '../common/layers/Layer';\nimport mixin from '../common/mixins/MapMixin';\nimport CopyrightControl from './controls/CopyrightControl';\nimport getMapboxStyleUrl from '../common/utils/getMapboxStyleUrl';\n\n/**\n * An Mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map) for handling mobility layers and controls.\n *\n * @extends {mapboxgl.Map}\n * @implements {MapInterface}\n */\nclass Map extends mixin(MBMap) {\n /**\n * Constructor.\n */\n constructor(options) {\n const { style } = options;\n const apiKey = options.apiKey || false;\n const apiKeyName = options.apiKeyName || 'key';\n let newStyle = options.style;\n if (typeof style === 'string') {\n newStyle = getMapboxStyleUrl(apiKey, apiKeyName, style);\n }\n super({\n attributionControl: false,\n controls: [new CopyrightControl()],\n ...options,\n style: newStyle,\n });\n }\n\n /**\n * Adds a layer to the map.\n * @param {Layer|mapboxgl.Layer} layer The layer to add.\n * @param {number} beforeId See [mapbox-gl-js doc](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer)\n */\n addLayer(layer, beforeId) {\n if (layer instanceof Layer) {\n this.mobilityLayers.push(layer);\n this.fire('change:mobilityLayers');\n\n if (this.isStyleLoaded()) {\n layer.init(this, beforeId);\n } else {\n this.on('load', () => {\n layer.init(this, beforeId);\n });\n }\n } else {\n super.addLayer(layer, beforeId);\n }\n }\n\n /**\n * Removes a given layer from the map.\n * @param {Layer|number} layer The layer to remove.\n * If it's a mapbox-layer, pass the id instead..\n */\n removeLayer(layer) {\n if (layer instanceof Layer) {\n layer.terminate();\n this.mobilityLayers = this.mobilityLayers.filter((l) => l !== layer);\n } else {\n super.removeLayer(layer);\n }\n }\n\n /**\n * Adds a given control to the map.\n * @param {Control|mapboxgl.IControl} control The control to add.\n * @param {mapboxgl.position} position Position of the control. Only if control parameter is an <mapboxgl.IControl>.\n */\n addControl(control, position) {\n super.addControl(control, position);\n }\n\n /**\n * Removes a given control to the map.\n * @param {Control|mapboxgl.IControl} control The control to remove.\n */\n removeControl(control) {\n super.removeControl(control);\n }\n}\n\nexport default Map;\n","import { fromLonLat } from 'ol/proj';\nimport { getWidth, getHeight } from 'ol/extent';\n\n/**\n * Get the current resolution of a Mapbox map.\n * @param {mapboxgl.Map} map A map object.\n * @private\n */\nexport const getResolution = (map) => {\n const bounds = map.getBounds().toArray();\n const extent = [...fromLonLat(bounds[0]), ...fromLonLat(bounds[1])];\n const { width, height } = map.getCanvas();\n const xResolution = getWidth(extent) / width;\n const yResolution = getHeight(extent) / height;\n return Math.max(xResolution, yResolution);\n};\n\n/**\n * Get the canvas source coordinates of the current map's extent.\n * @param {mapboxgl.Map} map A map object.\n * @private\n */\nexport const getSourceCoordinates = (map) => {\n const bounds = map.getBounds().toArray();\n return [\n [bounds[0][0], bounds[1][1]],\n [...bounds[1]],\n [bounds[1][0], bounds[0][1]],\n [...bounds[0]],\n ];\n};\n\nexport default {\n getResolution,\n getSourceCoordinates,\n};\n","import { toLonLat, fromLonLat } from 'ol/proj';\nimport Layer from '../../common/layers/Layer';\nimport mixin from '../../common/mixins/TrackerLayerMixin';\nimport { getResolution } from '../utils';\n\n/**\n * Responsible for loading tracker data.\n *\n * @extends {Layer}\n * @implements {TrackerLayerInterface}\n */\nclass TrackerLayer extends mixin(Layer) {\n constructor(options = {}) {\n super({\n ...options,\n });\n\n /** @ignores */\n this.onMapZoomEnd = this.onMapZoomEnd.bind(this);\n /** @ignores */\n this.onMapMouseMove = this.onMapMouseMove.bind(this);\n }\n\n /**\n * Update the icon scale if the window (and probably the canvas) is resized.\n * @private\n */\n updateIconScale(canvas) {\n this.tracker.setIconScale(canvas.width / canvas.clientWidth);\n }\n\n /**\n * Initialize the layer.\n *\n * @param {mapboxgl.Map} map A [mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map/).\n * @override\n */\n init(map) {\n if (!map) {\n return;\n }\n\n const canvas = map.getCanvas();\n const iconScale = canvas.width / canvas.clientWidth;\n map.on('resize', this.updateIconScale.bind(this, canvas));\n\n super.init(map, {\n width: canvas.width,\n height: canvas.height,\n iconScale,\n getPixelFromCoordinate: (coord) => {\n const pixelRatio = window.devicePixelRatio || 1;\n const [lng, lat] = toLonLat(coord);\n const { x, y } = this.map.project({ lng, lat });\n return [x * pixelRatio, y * pixelRatio];\n },\n });\n }\n\n terminate() {\n if (this.map) {\n this.map.off('resize', this.updateIconScale);\n }\n return super.terminate();\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n *\n * @param {Date} time The current time.\n */\n setCurrTime(time) {\n const canvas = this.map.getCanvas();\n super.setCurrTime(\n time,\n [canvas.width, canvas.height],\n getResolution(this.map),\n !this.map.isMoving() && !this.map.isRotating() && !this.map.isZooming(),\n );\n }\n\n /**\n * Start updating vehicles position.\n *\n * @listens {mapboxgl.map.event:zoomend} Listen to zoom end event.\n * @listens {mapboxgl.map.event:mousemove} Listen to mousemove end.\n * @override\n */\n start() {\n const canvas = this.map.getCanvas();\n super.start(\n [canvas.width, canvas.height],\n this.map.getZoom(),\n getResolution(this.map),\n );\n\n this.map.on('zoomend', this.onMapZoomEnd);\n\n if (this.isHoverActive) {\n this.map.on('mousemove', this.onMapMouseMove);\n }\n }\n\n /**\n * Stop updating vehicles position, and unlisten events.\n *\n * @override\n */\n stop() {\n super.stop();\n if (this.map) {\n this.map.off('zoomend', this.onMapZoomEnd);\n this.map.off('mousemove', this.onMapMouseMove);\n }\n }\n\n /**\n * Returns an array of vehicles located at the given coordinate.\n *\n * @param {Array<number>} coordinate\n * @param {number} nb Number of vehicles to return;\n * @returns {Array<ol/Feature~Feature>} Array of vehicle.\n * @override\n */\n getVehiclesAtCoordinate(coordinate, nb) {\n const resolution = getResolution(this.map);\n return super.getVehiclesAtCoordinate(coordinate, resolution, nb);\n }\n\n /**\n * On zoomend we adjust the time interval of the update of vehicles positions.\n *\n * @private\n */\n onMapZoomEnd() {\n this.startUpdateTime(this.map.getZoom());\n }\n\n /**\n * On mousemove, we detect if a vehicle is heovered then updates the cursor's style.\n *\n * @param {mapboxgl.MapMouseEvent} evt Map's mousemove event.\n * @private\n */\n onMapMouseMove(evt) {\n if (\n this.map.isMoving() ||\n this.map.isRotating() ||\n this.map.isZooming() ||\n !this.isHoverActive\n ) {\n this.map.getContainer().style.cursor = 'auto';\n return;\n }\n const [vehicle] = this.getVehiclesAtCoordinate(\n fromLonLat([evt.lngLat.lng, evt.lngLat.lat]),\n 1,\n );\n\n const id = vehicle && vehicle.id;\n if (this.hoverVehicleId !== id) {\n this.map.getContainer().style.cursor = vehicle ? 'pointer' : 'auto';\n this.hoverVehicleId = id;\n // We doesn´t wait the next render, we force it.\n this.renderTrajectories(this.currTime);\n }\n }\n}\n\nexport default TrackerLayer;\n","import TrackerLayer from './TrackerLayer';\nimport { getSourceCoordinates, getResolution } from '../utils';\nimport mixin from '../../common/mixins/TralisLayerMixin';\n\n/**\n * Responsible for loading and display data from a Tralis service.\n *\n * @example\n * import { TralisLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TralisLayer({\n * url: [yourUrl],\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html\">TralisAPI</a>\n *\n * @extends {TrackerLayer}\n * @implements {TralisLayerInterface}\n */\nclass TralisLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n super({ ...options });\n\n /** @ignore */\n this.onMove = this.onMove.bind(this);\n /** @ignore */\n this.onMoveEnd = this.onMoveEnd.bind(this);\n }\n\n /**\n * Add listeners from the Mapbox Map.\n *\n * @param {mapboxgl.Map} map\n * @param {string} beforeId See [mapboxgl.Map#addLayer](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer) beforeId documentation.\n */\n init(map, beforeId) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n this.map.on('zoomend', this.onZoomEnd);\n this.map.on('move', this.onMove);\n this.map.on('moveend', this.onMoveEnd);\n\n const { width, height } = this.map.getCanvas();\n this.tracker.canvas.width = width;\n this.tracker.canvas.height = height;\n\n this.map.addSource('canvas-source', {\n type: 'canvas',\n canvas: this.tracker.canvas,\n coordinates: getSourceCoordinates(this.map),\n // Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.\n animate: true,\n });\n this.map.addLayer(\n {\n id: 'canvas-layer',\n type: 'raster',\n source: 'canvas-source',\n paint: {\n 'raster-opacity': 1,\n 'raster-fade-duration': 0,\n },\n },\n beforeId,\n );\n }\n\n /**\n * Remove listeners from the Mapbox Map.\n */\n terminate() {\n if (this.map) {\n this.map.off('zoomend', this.onZoomEnd);\n this.map.off('move', this.onMove);\n this.map.off('moveend', this.onMoveEnd);\n }\n super.terminate();\n }\n\n /**\n * Callback on 'move' event.\n *\n * @private\n */\n onMove() {\n this.map\n .getSource('canvas-source')\n .setCoordinates(getSourceCoordinates(this.map));\n const { width, height } = this.map.getCanvas();\n this.renderTrajectories(\n this.currTime,\n [width, height],\n getResolution(this.map),\n );\n }\n\n /**\n * Callback on 'moveend' event.\n *\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n }\n}\n\nexport default TralisLayer;\n","import Map from './ol/Map';\nimport {\n Layer as olLayer,\n WMSLayer as olWMSLayer,\n MapboxLayer as olMapboxLayer,\n TrajservLayer as olTrajservLayer,\n TralisLayer as olTralisLayer,\n VectorLayer as olVectorLayer,\n} from './ol';\nimport {\n TrajservLayer as mbTrajservLayer,\n TralisLayer as mbTralisLayer,\n} from './mapbox';\n\nconst exports = {\n mapbox: {\n TrajservLayer: mbTrajservLayer,\n TralisLayer: mbTralisLayer,\n },\n ol: {\n Map,\n Layer: olLayer,\n WMSLayer: olWMSLayer,\n MapboxLayer: olMapboxLayer,\n TrajservLayer: olTrajservLayer,\n TralisLayer: olTralisLayer,\n VectorLayer: olVectorLayer,\n },\n};\n\nexport default exports;\n","import { fromLonLat } from 'ol/proj';\nimport { buffer, getWidth } from 'ol/extent';\nimport { unByKey } from 'ol/Observable';\nimport TrackerLayer from './TrackerLayer';\nimport mixin from '../../common/mixins/TrajservLayerMixin';\nimport { getUTCTimeString } from '../../common/timeUtils';\nimport { getSourceCoordinates, getResolution } from '../utils';\n\n/**\n * Responsible for loading and display data from a Trajserv service.\n *\n * @example\n * import { TrajservLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TrajservLayer({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey],\n * });\n *\n * @see <a href=\"/api/class/src/api/trajserv/TrajservAPI%20js~TrajservAPI%20html\">TrajservAPI</a>\n * @see <a href=\"/example/mapbox-tracker\">Mapbox tracker example</a>\n *\n * @extends {TrackerLayer}\n * @implements {TrajservLayerInterface}\n */\nclass TrajservLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n super({ ...options });\n this.onMapClick = this.onMapClick.bind(this);\n this.onMove = this.onMove.bind(this);\n this.onMoveEnd = this.onMoveEnd.bind(this);\n this.onVisibilityChange = this.onVisibilityChange.bind(this);\n }\n\n /**\n * Add the mapbox layer and source to the map.\n *\n * @param {mapboxgl.Map} map A Mapbox map.\n * @param {String} beforeId See [mapboxgl.Map#addLayer](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer) documentation.\n */\n init(map, beforeId) {\n if (!map) {\n return;\n }\n\n super.init(map);\n\n const { width, height } = map.getCanvas();\n this.tracker.canvas.width = width;\n this.tracker.canvas.height = height;\n\n const source = {\n type: 'canvas',\n canvas: this.tracker.canvas,\n coordinates: getSourceCoordinates(map),\n // Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.\n animate: true,\n attribution: this.copyrights,\n };\n\n this.beforeId = beforeId;\n this.layer = {\n id: this.key,\n type: 'raster',\n source: this.key,\n layout: {\n visibility: this.visible ? 'visible' : 'none',\n },\n paint: {\n 'raster-opacity': 1,\n 'raster-fade-duration': 0,\n 'raster-resampling': 'nearest', // important otherwise it looks blurry\n },\n };\n map.addSource(this.key, source);\n map.addLayer(this.layer, this.beforeId);\n\n this.listeners = [this.on('change:visible', this.onVisibilityChange)];\n }\n\n /**\n * Remove the mapbox layer and the mapbox source.\n *\n * @override\n */\n terminate() {\n if (this.map) {\n this.listeners.forEach((listener) => {\n unByKey(listener);\n });\n this.map.removeLayer(this.key);\n this.map.removeSource(this.key);\n }\n super.terminate();\n }\n\n start() {\n if (!this.map) {\n return;\n }\n super.start();\n this.map.on('click', this.onMapClick);\n this.map.on('move', this.onMove);\n this.map.on('moveend', this.onMoveEnd);\n }\n\n stop() {\n if (this.map) {\n this.map.off('click', this.onClick);\n this.map.off('move', this.onMove);\n this.map.off('moveend', this.onMoveEnd);\n }\n super.stop();\n }\n\n onVisibilityChange() {\n if (this.visible && !this.map.getLayer(this.key)) {\n this.map.addLayer(this.layer, this.beforeId);\n } else if (this.map.getLayer(this.key)) {\n this.map.removeLayer(this.key);\n }\n // We can't use setLayoutProperty it triggers an error probably a bug in mapbox\n // this.map.setLayoutProperty(\n // this.key,\n // 'visibilty',\n // this.visible ? 'visible' : 'none',\n // );\n }\n\n /**\n * Callback on 'move' event.\n * @private\n */\n onMove() {\n this.map.getSource(this.key).setCoordinates(getSourceCoordinates(this.map));\n\n const { width, height } = this.map.getCanvas();\n\n this.renderTrajectories(\n this.currTime,\n [width, height],\n getResolution(this.map),\n );\n }\n\n /**\n * Callback on 'moveend' event.\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n if (this.selectedVehicleId && this.journeyId) {\n this.highlightTrajectory();\n }\n }\n\n /**\n * Callback on 'mouseclick' event.\n * @param {mapboxgl.MapMouseEvent} evt\n * @private\n */\n onMapClick(evt) {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n const [vehicle] = this.getVehiclesAtCoordinate(\n fromLonLat([evt.lngLat.lng, evt.lngLat.lat]),\n 1,\n );\n\n if (vehicle) {\n /**\n * Id of the selected vehicle\n * @type {string}\n */\n this.selectedVehicleId = vehicle.id;\n /** @ignore */\n this.journeyId = vehicle.journeyIdentifier;\n this.updateTrajectoryStations(this.selectedVehicleId).then(\n (vehicleWithStations) => {\n /**\n * Array of station coordinates.\n * @type {Array<Array<number>>} Array of coordinates.\n */\n this.stationsCoords = [];\n vehicleWithStations.stations.forEach((station) => {\n this.stationsCoords.push(fromLonLat(station.coordinates));\n });\n this.clickCallbacks.forEach((callback) =>\n callback({ ...vehicle, ...vehicleWithStations }, this, evt),\n );\n },\n );\n } else {\n this.selectedVehicleId = null;\n this.clickCallbacks.forEach((callback) => callback(null, this, evt));\n }\n }\n\n /**\n * @override\n * * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {\n const bounds = this.map.getBounds().toArray();\n const southWest = fromLonLat(bounds[0]);\n const northEast = fromLonLat(bounds[1]);\n const ext = [...southWest, ...northEast];\n const bbox = buffer(ext, getWidth(ext) / 10).join(',');\n const zoom = this.map.getZoom();\n\n return super.getParams({\n ...extraParams,\n bbox,\n s: zoom < 10 ? 1 : 0,\n z: zoom,\n });\n }\n\n /** @ignore */\n defaultStyle(props) {\n const zoom = this.map.getZoom();\n return super.defaultStyle(props, zoom);\n }\n\n /**\n * Draw the trajectory as a line with points for each stop.\n * @param {Array} stationsCoords Array of station coordinates.\n * @param {ol/geom/LineString~LineString|ol/geom/MultiLineString~MultiLineString} lineGeometry A LineString or a MultiLineString.\n * @param {string} color The color of the line.\n * @private\n */\n // eslint-disable-next-line no-unused-vars,class-methods-use-this\n drawFullTrajectory(stationsCoords, lineGeometry, color) {\n // eslint-disable-next-line no-console\n console.log('to be implemented');\n // Don't allow white lines, use red instead.\n // const vehiculeColor = /#ffffff/i.test(color) ? '#ff0000' : color;\n // const vectorSource = this.olLayer.getSource();\n // vectorSource.clear();\n // if (stationsCoords) {\n // const geometry = new MultiPoint(stationsCoords);\n // const aboveStationsFeature = new Feature(geometry);\n // aboveStationsFeature.setStyle(\n // new Style({\n // zIndex: 1,\n // image: new Circle({\n // radius: 5,\n // fill: new Fill({\n // color: '#000000',\n // }),\n // }),\n // }),\n // );\n // const belowStationsFeature = new Feature(geometry);\n // belowStationsFeature.setStyle(\n // new Style({\n // zIndex: 4,\n // image: new Circle({\n // radius: 4,\n // fill: new Fill({\n // color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n // }),\n // }),\n // }),\n // );\n // vectorSource.addFeatures([aboveStationsFeature, belowStationsFeature]);\n // }\n // const lineFeat = new Feature({\n // geometry: lineGeometry,\n // });\n // lineFeat.setStyle([\n // new Style({\n // zIndex: 2,\n // stroke: new Stroke({\n // color: '#000000',\n // width: 6,\n // }),\n // }),\n // new Style({\n // zIndex: 3,\n // stroke: new Stroke({\n // color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n // width: 4,\n // }),\n // }),\n // ]);\n // vectorSource.addFeature(lineFeat);\n }\n\n /**\n * Highlight the trajectory of journey.\n * @param {String} journeyId The id of the journey.\n * @private\n */\n highlightTrajectory(journeyId) {\n this.api\n .fetchTrajectoryById({\n id: journeyId,\n time: getUTCTimeString(new Date()),\n })\n // .then((traj) => {\n // const { p: multiLine, t, c } = traj;\n // const lineCoords = [];\n // multiLine.forEach((line) => {\n // line.forEach((point) => {\n // lineCoords.push([point.x, point.y]);\n // });\n // });\n // this.drawFullTrajectory(\n // this.stationsCoords,\n // new LineString(lineCoords),\n // c ? `#${c}` : getBgColor(t),\n // );\n // })\n .catch(() => {\n if (this.map.getLayer('highlight-trajectory')) {\n this.map.removeLayer('highlight-trajectory');\n }\n });\n }\n}\n\nexport default TrajservLayer;\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://mobility-toolbox-js/webpack/universalModuleDefinition","webpack://mobility-toolbox-js/webpack/bootstrap","webpack://mobility-toolbox-js/external \"ol/proj\"","webpack://mobility-toolbox-js/external \"ol/style\"","webpack://mobility-toolbox-js/external \"ol/Observable\"","webpack://mobility-toolbox-js/external \"ol/geom\"","webpack://mobility-toolbox-js/external \"ol/extent\"","webpack://mobility-toolbox-js/external \"query-string\"","webpack://mobility-toolbox-js/external \"ol/layer\"","webpack://mobility-toolbox-js/external \"ol/format/GeoJSON\"","webpack://mobility-toolbox-js/external \"ol/Feature\"","webpack://mobility-toolbox-js/external \"ol/Object\"","webpack://mobility-toolbox-js/external \"ol/layer/Layer\"","webpack://mobility-toolbox-js/external \"mapbox-gl\"","webpack://mobility-toolbox-js/external \"ol/source/Source\"","webpack://mobility-toolbox-js/external \"ol/source\"","webpack://mobility-toolbox-js/external \"ol\"","webpack://mobility-toolbox-js/external \"ol/geom/GeometryType\"","webpack://mobility-toolbox-js/external \"ol/format\"","webpack://mobility-toolbox-js/external \"ol/Map\"","webpack://mobility-toolbox-js/external \"ol/control\"","webpack://mobility-toolbox-js/external \"ol/layer/Group\"","webpack://mobility-toolbox-js/external \"uuid\"","webpack://mobility-toolbox-js/external \"ol/geom/Point\"","webpack://mobility-toolbox-js/external \"ol/interaction\"","webpack://mobility-toolbox-js/external \"ol/events/condition\"","webpack://mobility-toolbox-js/./src/common/layers/Layer.js","webpack://mobility-toolbox-js/./src/ol/layers/Layer.js","webpack://mobility-toolbox-js/./src/common/controls/Control.js","webpack://mobility-toolbox-js/./src/common/mixins/MapMixin.js","webpack://mobility-toolbox-js/./src/common/mixins/CopyrightMixin.js","webpack://mobility-toolbox-js/./src/common/utils/removeDuplicate.js","webpack://mobility-toolbox-js/./src/ol/controls/CopyrightControl.js","webpack://mobility-toolbox-js/./src/ol/Map.js","webpack://mobility-toolbox-js/./src/common/utils/getMapboxStyleUrl.js","webpack://mobility-toolbox-js/./src/common/utils/getMapboxMapCopyrights.js","webpack://mobility-toolbox-js/./src/ol/layers/MapboxLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/RoutingLayer.js","webpack://mobility-toolbox-js/./src/common/Tracker.js","webpack://mobility-toolbox-js/./src/common/trackerConfig.js","webpack://mobility-toolbox-js/./src/common/mixins/TrackerLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TrackerLayer.js","webpack://mobility-toolbox-js/./src/common/timeUtils.js","webpack://mobility-toolbox-js/./src/common/api/api.js","webpack://mobility-toolbox-js/./src/api/stops/StopsAPI.js","webpack://mobility-toolbox-js/./src/api/trajserv/TrajservAPIUtils.js","webpack://mobility-toolbox-js/./src/api/trajserv/TrajservAPI.js","webpack://mobility-toolbox-js/./src/api/tralis/WebSocketConnector.js","webpack://mobility-toolbox-js/./src/api/tralis/TralisAPIUtils.js","webpack://mobility-toolbox-js/./src/api/tralis/TralisAPI.js","webpack://mobility-toolbox-js/./src/common/mixins/TrajservLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TrajservLayer.js","webpack://mobility-toolbox-js/./src/common/mixins/TralisLayerMixin.js","webpack://mobility-toolbox-js/./src/ol/layers/TralisLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/VectorLayer.js","webpack://mobility-toolbox-js/./src/ol/layers/WMSLayer.js","webpack://mobility-toolbox-js/./src/common/mixins/SearchMixin.js","webpack://mobility-toolbox-js/./src/ol/controls/StopFinderControl.js","webpack://mobility-toolbox-js/./src/mapbox/controls/CopyrightControl.js","webpack://mobility-toolbox-js/./src/mapbox/Map.js","webpack://mobility-toolbox-js/./src/mapbox/utils.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TrackerLayer.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TralisLayer.js","webpack://mobility-toolbox-js/./src/index.js","webpack://mobility-toolbox-js/./src/mapbox/layers/TrajservLayer.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","require","Layer","options","defineProperties","isQueryable","copyrights","onClick","children","visible","properties","isBaseLayer","uid","uuid","dfltName","this","toLowerCase","isReactSpatialLayer","writable","set","newCopyrights","arrValue","Array","isArray","undefined","map","clickCallbacks","terminate","dispatchEvent","type","target","stopPropagationDown","stopPropagationUp","stopPropagationSiblings","filter","child","hasChildren","find","layer","unshift","length","splice","Promise","resolve","features","coordinate","callback","Error","includes","push","idx","indexOf","Observable","olLayer","setVisible","olListenersKeys","getLayers","on","evt","element","attributions","Group","getArray","forEach","getSource","setAttributions","unByKey","newOptions","LayerCommon","Control","active","render","newActive","activate","deactivate","parentNode","removeChild","targett","getContainer","createDefaultElement","appendChild","BaseObject","MapMixin","Base","layers","controls","mobilityLayers","mobilityControls","control","addControl","addLayer","position","addMobilityControl","removeMobilityControl","CopyrightMixin","innerHTML","getCopyrights","join","document","createElement","id","assign","style","bottom","right","fontSize","padding","removeDuplicate","array","arrWithoutEmptyValues","val","trim","lowerCasesValues","str","Set","uniqueStr","CopyrightControl","onPostRender","frameState","layerStatesArray","layerState","inView","viewState","getAttributions","concat","un","mixin","Map","defaultControls","attribution","getTargetElement","init","OLMap","getMapboxStyleUrl","apiKey","apiKeyName","styleUrl","parsedStyle","qs","parseUrl","query","stringifyUrl","console","warn","getMapboxMapCopyrights","sourceCaches","values","sourceCache","used","source","replace","split","MapboxLayer","mbLayer","OLLayer","Source","mbMap","changed","canvas","getCanvas","getVisible","renderState","display","opacity","getOpacity","rotation","rotateTo","Math","PI","animate","zoom","center","jumpTo","toLonLat","size","getSize","isStyleLoaded","_frame","cancel","_render","err","url","updateAttribution","format","GeoJSON","featureProjection","getView","getProjection","loadMbMap","resize","getCenter","x","y","createStyleUrl","mapboxgl","attributionControl","boxZoom","container","interactive","fadeDuration","preserveDrawingBuffer","once","loaded","mapboxCanvas","tabIndex","setAttribute","removeAttribute","newAttributions","toString","pixel","project","queryRenderedFeatures","feature","olFeature","readFeature","off","triggerRepaint","remove","Tracker","opts","interpolate","trajectories","renderedTrajectories","getPixelFromCoordinate","hoverVehicleId","selectedVehicleId","iconScale","width","height","canvasContext","getContext","visibility","sort","clearRect","offsetX","offsetY","oldLeft","parseFloat","left","oldTop","top","currTime","Date","now","resolution","noInterpolate","clear","hoverVehicleImg","hoverVehiclePx","hoverVehicleWidth","hoverVehicleHeight","selectedVehicleImg","selectedVehiclePx","selectedVehicleWidth","selectedVehicleHeight","currResolution","traj","geometry","timeIntervals","timeOffset","coord","start","end","startFrac","endFrac","timeFrac","j","getType","GeomType","POINT","getCoordinates","LINE_STRING","min","geomFrac","getCoordinateAt","endFraction","getFirstCoordinate","getLastCoordinate","error","px","rendered","vehicleImg","imgWidth","imgHeight","floor","drawImage","olEventsKeys","trackerRadiusMapping","0","1","2","3","4","5","6","7","8","9","types","bgColors","textColors","timeSteps","getTypeIndex","matched","RegExp","test","getBgColor","typeIdx","e","getDelayColor","delayInMs","cancelled","isDelayText","TrackerLayerMixin","isHoverActive","cuurSpeed","speed","isTrackerLayer","defaultStyle","newSpeed","tracker","setFilter","setSort","styleCache","lastUpdateTime","useRequestAnimationFrame","default","setStyle","props","visibilityRef","stop","destroy","renderTrajectories","startUpdateTime","stopUpdateTime","updateTimeInterval","setInterval","newTime","getTime","setCurrTime","getRefreshTimeInMs","clearInterval","time","requestId","cancelAnimationFrame","requestAnimationFrame","mustRender","filterFc","getTrajectories","nb","Infinity","ext","buffer","vehicles","containsCoordinate","roundedZoom","round","timeStep","max","text","ctx","arc","fillStyle","fill","lineWidth","strokeStyle","stroke","font","strokeText","fillText","TrackerLayer","renderWhenZooming","oldPx","moveCanvas","view","getResolution","getAnimating","getInteracting","currentZoom","getZoom","z","vehicle","getVehiclesAtCoordinate","cursor","getUTCDateString","month","getUTCMonth","day","getUTCDate","getUTCFullYear","getUTCTimeString","date","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","API","path","params","config","urlParams","clone","keys","fetch","stringify","then","response","json","data","reject","StopsAPI","abortController","signal","featureCollection","translateDates","dates","newDates","year","translateTrajStationsResp","newData","prop","destination","hs","vehicleType","longName","ln","shortName","sn","wheelchairAccessible","wa","bicyclesAllowed","ba","realTime","rt","feedsId","fid","routeIdentifier","rid","bgColor","datacolor","tc","a","operator","operatorUrl","u","operatorTimeZone","tz","f","publisher","publisherUrl","publisherTimeZone","tt","dateNotOperatingDays","dateAdditionalOperatingDays","operatingPeriod","dataStations","sts","notOperatingDays","additionalOperatingDays","backgroundColor","color","stations","stationId","sid","stationName","coordinates","arrivalTime","at","departureTime","dt","arrivalDate","ap","departureDate","dp","arrivalDelay","ad","departureDelay","dd","noDropOff","dot","noPickUp","put","stWheelchairAccessible","operatingInformations","translateTrajCollResponse","LineString","ID","ProductIdentifier","PublishedLineName","RouteIdentifier","directionText","DirectionText","Operator","OperatorURL","Publisher","PublisherURL","license","License","licenseUrl","LicenseUrl","licenseNote","LicenseNote","Color","journeyIdentifier","JourneyIdentifier","realtimeAvailable","RealtimeAvailable","operatorProvidesRealtime","OperatorProvidesRealtime","dayOfOperation","DayOfOperation","delay","Delay","TimeIntervals","textColor","TextColor","Cancelled","TrajservAPI","WebSocketConnector","subscriptions","connect","send","subscribed","method","reqStr","channel","args","websocket","readyState","CLOSED","close","WebSocket","currentProj","setProjection","currentBbox","setBbox","subscribe","cb","errorCb","onclose","clearTimeout","reconnectTimeout","setTimeout","getRequestString","listen","message","CONNECTING","addEventListener","onMessage","JSON","parse","client_reference","onMessageCb","onErrorCb","quiet","removeEventListener","getModeSuffix","modes","SCHEMATIC","compareDepartures","b","sortByMinArrivalTime","topStates","aTop","has_fzo","state","bTop","aDuration","bDuration","min_arrival_time","cleanStopTime","content","station","arrivalTimeWithDelay","departureTimeWithDelay","TralisModes","RAW","TOPOGRAPHIC","TralisAPI","wsUrl","subscribedStationUic","departureUpdateTimeout","maxDepartureAge","extraGeoms","prefix","conn","projection","bbox","onSuccess","onError","suffix","unsubscribe","depObject","departures","k","future","setMinutes","getMinutes","past","departureArray","platformsBoarding","previousDeparture","platform","to","abs","line","unsubscribeDepartures","departureObject","tDiff","timestamp","timediff","call_id","filterDepartures","uic","stationUpdateTimeout","unsubscribeStations","extraGeom","ref","unsubscribeTrajectory","unsubscribeDeletedVehicles","ids","promises","getFullTrajectory","all","unsubscribeFullTrajectory","log","getStopSequence","fullTrajectoryUpdateTimeout","unsubscribeStopSequence","unsubscribeHealthCheck","TrajservLayerMixin","defaultApi","regexPublishedLineName","publishedLineName","tripNumber","requestIntervalSeconds","api","apiOptions","showVehicleTraj","delayDisplay","delayOutlineColor","useDelayStyle","newRequestIntervalSeconds","newPublishedLineName","updateFilters","newTripNumber","newOperator","newRegex","sortFc","startUpdateTrajectories","journeyId","stopUpdateTrajectories","abortFetchTrajectories","parameters","location","search","route","regexLine","filterList","regexLineList","some","tr","lineList","toUpperCase","routeList","item","parseInt","routeId","operatorList","op","createFilters","abort","trajId","getParams","fetchTrajectoryStations","extraParams","requestIntervalInMs","intervalMs","diff","later","btime","etime","cd","nm","fl","updateTrajectories","updateInterval","AbortController","fetchTrajectories","attr_det","catch","setTrajectories","hover","selected","radius","getRadius","isDisplayStrokeAndDelay","radiusDelay","markerSize","margin","circleFillColor","origin","save","beginPath","restore","textAlign","textBaseline","delayText","String","fromCodePoint","rounded","getDelayText","setLineDash","textSize","newText","measureText","getTextSize","getTextColor","TrajservLayer","vectorLayer","VectorLayer","VectorSource","insertAt","removeLayer","onMapClick","onMoveEnd","highlightTrajectory","geom","Point","Feature","updateTrajectoryStations","trajStations","stationsCoords","lineGeometry","vehiculeColor","vectorSource","MultiPoint","aboveStationsFeature","Style","zIndex","image","Circle","Fill","belowStationsFeature","addFeatures","lineFeat","Stroke","addFeature","transformCoords","fetchTrajectoryById","multiLine","lineCoords","point","drawFullTrajectory","calculateExtent","getWidth","TralisLayerMixin","debug","refreshTimeInMs","onDeleteMessage","dfltIconScale","dfltIconHighlightScale","minIconScale","subscribeTrajectory","subscribeDeletedVehicles","feat","transform","setGeometry","addTrajectory","getProperties","removeTrajectoryByAttribute","addOnTop","findIndex","train_id","time_intervals","trajectory","len","attributeName","removeTrajectory","TralisLayer","hitTolerance","getFeaturesAtPixel","layerFilter","singleClickRef","getFeatureInfoAtCoordinate","callClickCallbacks","WMSLayer","getFeatureInfoUrl","info_format","query_layers","resp","MBMap","bounds","getBounds","toArray","extent","fromLonLat","xResolution","yResolution","getHeight","getSourceCoordinates","onMapZoomEnd","onMapMouseMove","setIconScale","clientWidth","updateIconScale","pixelRatio","devicePixelRatio","lng","lat","isMoving","isRotating","isZooming","lngLat","onMove","beforeId","onZoomEnd","addSource","paint","setCoordinates","mapbox","onVisibilityChange","layout","listeners","listener","removeSource","getLayer","vehicleWithStations","southWest","northEast","mbTralisLayer","ol","olWMSLayer","olMapboxLayer","olTrajservLayer","olTralisLayer","olVectorLayer"],"mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,sBAAuB,GAAIH,GACR,iBAAZC,QACdA,QAAQ,uBAAyBD,IAEjCD,EAAK,uBAAyBC,IARhC,CASGK,QAAQ,WACX,O,YCTE,IAAIC,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUP,QAGnC,IAAIC,EAASI,EAAiBE,GAAY,CACzCC,EAAGD,EACHE,GAAG,EACHT,QAAS,IAUV,OANAU,EAAQH,GAAUI,KAAKV,EAAOD,QAASC,EAAQA,EAAOD,QAASM,GAG/DL,EAAOQ,GAAI,EAGJR,EAAOD,QA0Df,OArDAM,EAAoBM,EAAIF,EAGxBJ,EAAoBO,EAAIR,EAGxBC,EAAoBQ,EAAI,SAASd,EAASe,EAAMC,GAC3CV,EAAoBW,EAAEjB,EAASe,IAClCG,OAAOC,eAAenB,EAASe,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEV,EAAoBgB,EAAI,SAAStB,GACX,oBAAXuB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAenB,EAASuB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAenB,EAAS,aAAc,CAAEyB,OAAO,KAQvDnB,EAAoBoB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQnB,EAAoBmB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFAxB,EAAoBgB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOnB,EAAoBQ,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRvB,EAAoB2B,EAAI,SAAShC,GAChC,IAAIe,EAASf,GAAUA,EAAO2B,WAC7B,WAAwB,OAAO3B,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAK,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRV,EAAoBW,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG7B,EAAoBgC,EAAI,GAIjBhC,EAAoBA,EAAoBiC,EAAI,I,gBClFrDtC,EAAOD,QAAUwC,QAAQ,Y,cCAzBvC,EAAOD,QAAUwC,QAAQ,a,cCAzBvC,EAAOD,QAAUwC,QAAQ,kB,cCAzBvC,EAAOD,QAAUwC,QAAQ,Y,cCAzBvC,EAAOD,QAAUwC,QAAQ,c,cCAzBvC,EAAOD,QAAUwC,QAAQ,iB,cCAzBvC,EAAOD,QAAUwC,QAAQ,a,cCAzBvC,EAAOD,QAAUwC,QAAQ,sB,cCAzBvC,EAAOD,QAAUwC,QAAQ,e,cCAzBvC,EAAOD,QAAUwC,QAAQ,c,cCAzBvC,EAAOD,QAAUwC,QAAQ,mB,cCAzBvC,EAAOD,QAAUwC,QAAQ,c,cCAzBvC,EAAOD,QAAUwC,QAAQ,qB,cCAzBvC,EAAOD,QAAUwC,QAAQ,c,cCAzBvC,EAAOD,QAAUwC,QAAQ,O,cCAzBvC,EAAOD,QAAUwC,QAAQ,yB,cCAzBvC,EAAOD,QAAUwC,QAAQ,c,cCAzBvC,EAAOD,QAAUwC,QAAQ,W,cCAzBvC,EAAOD,QAAUwC,QAAQ,e,cCAzBvC,EAAOD,QAAUwC,QAAQ,mB,cCAzBvC,EAAOD,QAAUwC,QAAQ,S,cCAzBvC,EAAOD,QAAUwC,QAAQ,kB,cCAzBvC,EAAOD,QAAUwC,QAAQ,mB,cCAzBvC,EAAOD,QAAUwC,QAAQ,wB,+gECsBJC,E,sQAcnB,WAAYC,GAAS,O,4FAAA,UACnB,gBACKC,iBAAL,GAAwBC,aAAa,GAASF,IAE1CA,EAAQG,aACV,EAAKA,WAAaH,EAAQG,YALT,IASXC,EAAYJ,EAAZI,QATW,OAUfA,GACF,EAAKA,QAAQA,GAXI,E,sDAoBJJ,GAAS,WAEtB3B,EAOE2B,EAPF3B,KACAgB,EAMEW,EANFX,IACAgB,EAKEL,EALFK,SACAC,EAIEN,EAJFM,QACAC,EAGEP,EAHFO,WACAC,EAEER,EAFFQ,YACAN,EACEF,EADFE,YAEIO,EAAMC,eACNC,EAAWtC,GAAQoC,EACzBjC,OAAOyB,iBAAiBW,KAAM,CAE5BZ,QAAS,CACPjB,MAAOiB,GAET3B,KAAM,CACJU,MAAO4B,GAETtB,IAAK,CACHN,MAAOM,GAAOsB,EAASE,eAEzBL,YAAa,CACXzB,QAASyB,GAEXN,YAAa,CACXnB,QAASmB,GAIXY,oBAAqB,CACnB/B,OAAO,GAETsB,SAAU,CACRtB,MAAOsB,GAAY,GACnBU,UAAU,GAEZZ,WAAY,CACVxB,IAAK,WACH,OAAO,EAAKA,IAAI,eAElBqC,IAAK,SAACC,GACJ,IAAMC,EAAYC,MAAMC,QAAQH,GAE5BA,EADA,CAACA,GAEL,OAAO,EAAKD,IAAI,aAAcE,KAGlCZ,QAAS,CACPvB,WAAmBsC,IAAZf,GAA+BA,EACtCS,UAAU,GAEZR,WAAY,CACVxB,MAAO,EAAF,GAAQwB,GAAc,KAE7Be,IAAK,CACHP,UAAU,GAKZQ,eAAgB,CACdxC,MAAO,Q,2BAURuC,GACHV,KAAKY,YAELZ,KAAKU,IAAMA,I,+DAeTjD,GACF,OAAOuC,KAAKL,WAAWlC,K,0BASrBA,EAAMU,GACR6B,KAAKL,WAAWlC,GAAQU,EACxB6B,KAAKa,cAAc,CACjBC,KAAM,UAAF,OAAYrD,GAChBsD,OAAQf,S,iCAaVN,GAIA,IAHAsB,EAGA,wDAFAC,EAEA,wDADAC,EACA,wDACIxB,IAAYM,KAAKN,UAKrBM,KAAKN,QAAUA,EAEfM,KAAKa,cAAc,CACjBC,KAAM,iBACNC,OAAQf,KACRgB,sBACAC,oBACAC,+B,2CAUF,OAAOlB,KAAKP,SAAS0B,QAAO,SAACC,GAAD,OAAWA,EAAM1B,a,2CAS7C,QAASM,KAAKqB,aAAY,K,kCAShB3B,GACV,QAASM,KAAKP,SAAS6B,MAAK,SAACF,GAAD,OAAWA,EAAM1B,UAAYA,O,+BAQlD6B,GACPvB,KAAKP,SAAS+B,QAAQD,GACtBvB,KAAKa,cAAc,CACjBC,KAAM,kBACNC,OAAQf,S,kCASAvC,GACV,IAAK,IAAIP,EAAI,EAAGA,EAAI8C,KAAKP,SAASgC,OAAQvE,GAAK,EAC7C,GAAI8C,KAAKP,SAASvC,GAAGO,OAASA,EAE5B,YADAuC,KAAKP,SAASiC,OAAOxE,EAAG,GAI5B8C,KAAKa,cAAc,CACjBC,KAAM,kBACNC,OAAQf,S,mDAaV,OAAO2B,QAAQC,QAAQ,CACrBL,MAAOvB,KACP6B,SAAU,GACVC,WAAY,S,8BAURC,GACN,GAAwB,mBAAbA,EAKT,MAAM,IAAIC,MAAM,sCAJXhC,KAAKW,eAAesB,SAASF,IAChC/B,KAAKW,eAAeuB,KAAKH,K,8BAavBA,GACN,GAAwB,mBAAbA,EAAyB,CAClC,IAAMI,EAAMnC,KAAKW,eAAeyB,QAAQL,GACpCI,IAAQ,GACVnC,KAAKW,eAAee,OAAOS,EAAK,S,8BAlRLE,K,2qECoHpBlD,E,sQAzGb,WAAYC,GAAS,a,4FAAA,UACnB,cAAMA,IAEGkD,SACP,EAAKA,QAAQC,WAAW,EAAK7C,SAJZ,E,sDAaJN,GACf,oDAAuBA,GACvBxB,OAAOyB,iBAAiBW,KAAM,CAC5BsC,QAAS,CAAEnE,MAAOiB,EAAQkD,QAASnC,UAAU,GAC7CqC,gBAAiB,CACfrE,MAAO,Q,2BASRuC,GAAK,WAGR,GAFA,wCAAWA,GAENV,KAAKU,KAAQV,KAAKsC,UAIvBtC,KAAKwC,gBAAgBN,KACnBlC,KAAKU,IAAI+B,YAAYC,GAAG,UAAU,SAACC,GAC7BA,EAAIC,UAAY,EAAKN,SACvB,EAAK1B,gBAMPZ,KAAKT,YAAY,CACnB,IAAMsD,EAAe7C,KAAKT,YAAc,GACpCS,KAAKsC,mBAAmBQ,IAC1B9C,KAAKsC,QACFG,YACAM,WACAC,SAAQ,SAACzB,GACRA,EAAM0B,YAAYC,gBAAgBL,MAGtC7C,KAAKsC,QAAQW,YAAYC,gBAAgBL,M,kCAS7CM,kBAAQnD,KAAKwC,iBACb,gD,iCAYA9C,GAIA,IAHAsB,EAGA,wDAFAC,EAEA,wDADAC,EACA,wDACIxB,IAAYM,KAAKN,UAIrB,8CACEA,EACAsB,EACAC,EACAC,GAGElB,KAAKsC,SACPtC,KAAKsC,QAAQC,WAAWvC,KAAKN,Y,4BAS3B0D,GACJ,OAAO,IAAIjE,EAAJ,OAAea,KAAKZ,SAAYgE,S,8BArHvBC,G,k/DCgILC,E,sQA1Hb,aAA0B,MAAdlE,EAAc,uDAAJ,GAAI,WACxB,cAAMA,IACDC,iBAAiBD,GAFE,SAKtBmE,QAA2B,IAAnBnE,EAAQmE,QACbnE,GAFGmE,EAJgB,EAIhBA,OAJgB,OAYxB,EAAKA,OAASA,EAZU,E,sDAoBTnE,GAAS,kBAEnBA,GADG2B,EADgB,EAChBA,OAAQ6B,EADQ,EACRA,QAASY,EADD,EACCA,OAIzB5F,OAAOyB,iBAAiBW,KAAM,CAC5BuD,OAAQ,CACNxF,IAAK,WACH,OAAO,EAAKA,IAAI,WAElBqC,IAAK,SAACqD,GACJ,EAAKrD,IAAI,SAAUqD,GACfA,EACF,EAAKC,WAEL,EAAKC,aAEP,EAAKH,WAGT9C,IAAK,CACH3C,IAAK,WACH,OAAO,EAAKA,IAAI,QAElBqC,IAAK,SAACM,GAWJ,GATI,EAAKA,KAAO,EAAKkC,SAAW,EAAKA,QAAQgB,YAC3C,EAAKhB,QAAQgB,WAAWC,YAAY,EAAKjB,SAI3C,EAAKe,aAEL,EAAKvD,IAAI,MAAOM,GAEZ,EAAKA,IAAK,CAEZ,IAAMoD,EAAU,EAAK/C,QAAU,EAAKL,IAAIqD,eAEnC,EAAKnB,SACR,EAAKoB,uBAGH,EAAKpB,SACPkB,EAAQG,YAAY,EAAKrB,SAIvB,EAAKW,QACP,EAAKG,WAGT,EAAKF,WAGTzC,OAAQ,CACN5C,MAAO4C,GAET6B,QAAS,CACPzE,MAAOyE,EACPzC,UAAU,GAEZqD,OAAQ,CAINrF,MAAOqF,GAAUxD,KAAKwD,OACtBrD,UAAU,O,iCAUdH,KAAK2D,e,yJA3GaO,K,m0ECLf,IA6FQC,GA3DE,SAACC,GAAD,oB,kOAAA,iBAEb,aAA0B,MAAdhF,EAAc,uDAAJ,GAAI,mBACxB,qBAAWA,GAAX,IAAoBiF,OAAQ,GAAIC,SAAU,OACrCC,eAAiB,GACtB,EAAKC,iBAAmB,IAGvBpF,EAAQkF,UAAY,IAAItB,SAAQ,SAACyB,GAChC,EAAKC,WAAWD,OAIjBrF,EAAQiF,QAAU,IAAIrB,SAAQ,SAACzB,GAC9B,EAAKoD,SAASpD,MAZQ,EAFb,uDAmBX,OAAOvB,KAAKuE,iBAnBD,4CAuBX,OAAOvE,KAAKwE,mBAvBD,yCA0BMC,GACjBzE,KAAKwE,iBAAiBtC,KAAKuC,GAE3BA,EAAQ/D,IAAMV,OA7BH,4CAgCSyE,GAEpBA,EAAQ/D,IAAM,KACdV,KAAKwE,iBAAmBxE,KAAKwE,iBAAiBrD,QAC5C,SAAC5D,GAAD,OAAOA,IAAMkH,OApCJ,iCAyCFA,EAASG,GACdH,aAAmBnB,EACrBtD,KAAK6E,mBAAmBJ,GAExB,8CAAiBA,EAASG,KA7CjB,oCAkDCH,GACRA,aAAmBnB,EACrBtD,KAAK8E,sBAAsBL,GAE3B,iDAAoBA,OAtDX,GACDL,I,q4CCrCT,IAwCQW,GAxBQ,SAACX,GAAD,oB,mOAAA,qHAGZpE,KAAK4C,UAGV5C,KAAK4C,QAAQoC,UAAYhF,KAAKuD,OAC1BvD,KAAKiF,gBAAgBC,KAAK,OAC1B,MARa,6CAYjBlF,KAAK4C,QAAUuC,SAASC,cAAc,OACtCpF,KAAK4C,QAAQyC,GAAK,gBAClBzH,OAAO0H,OAAOtF,KAAK4C,QAAQ2C,MAAO,CAChCX,SAAU,WACVY,OAAQ,EACRC,MAAO,EACPC,SAAU,QACVC,QAAS,eAnBM,GACPvB,I,+uBCjBhB,IAcewB,GAdS,SAACC,GACvB,IAAMC,EAAwBD,EAAM1E,QAClC,SAAC4E,GAAD,OAASA,SAAqCA,EAAIC,MAAQD,EAAIC,UAE1DC,EAAmBH,EAAsBpF,KAAI,SAACwF,GAAD,OACjDA,EAAIjG,iBAMN,OAJ8B,GAAI,IAAIkG,IAAIF,IACCvF,KAAI,SAAC0F,GAC9C,OAAON,EAAsBxE,MAAK,SAAC4E,GAAD,OAASA,EAAIjG,gBAAkBmG,S,ygDC+DtDC,G,wQAtDb,WAAYjH,GAAS,a,4FAAA,UACnB,cAAMA,IACDkH,aAAe,EAAKA,aAAa5H,KAAlB,OAFD,E,qDAKL,WACd,IAAKsB,KAAKuG,WACR,MAAO,GAET,IAAIhH,EAAa,GAiBjB,OAdAS,KAAKuG,WAAWC,iBAAiBxD,SAAQ,SAACyD,GAAe,IAC/ClF,EAAUkF,EAAVlF,MAENmF,kBAAOD,EAAY,EAAKF,WAAWI,YACnCpF,GACAA,EAAM0B,WACN1B,EAAM0B,aACN1B,EAAM0B,YAAY2D,oBAElBrH,EAAaA,EAAWsH,OACtBtF,EAAM0B,YAAY2D,iBAAlBrF,CAAoC,EAAKgF,iBAIxCX,GAAgBrG,K,iCAIvB,+CACIS,KAAKU,KACPV,KAAKU,IAAIgC,GAAG,aAAc1C,KAAKsG,gB,mCAK7BtG,KAAKU,KACPV,KAAKU,IAAIoG,GAAG,aAAc9G,KAAKsG,cAEjC,mD,mCAGW3D,GACP3C,KAAKU,KAAOV,KAAK4C,UAInB5C,KAAKuG,WAAa5D,EAAI4D,WACtBvG,KAAKwD,e,gCAlDoBuD,GAAMzD,I,+gGCoFtB0D,G,wQA7Eb,aAA0B,IAAd5H,EAAc,uDAAJ,GAAI,kCAEtBkF,SAAU,GAAF,UACH2C,mBAAgB,CAAEC,aAAa,IAASnE,YADrC,CAEN,IAAIsD,MAEHjH,I,oDAUL,OAAOY,KAAKmH,qB,+BAOL5F,GACHA,aAAiBpC,GAEnBoC,EAAM6F,KAAKpH,MACXA,KAAKuE,eAAerC,KAAKX,GAErBA,EAAMe,SACR,8CAAef,EAAMe,SAGvBtC,KAAKa,cAAc,CACjBC,KAAM,wBACNC,OAAQf,QAIV,8CAAeuB,K,kCAQPA,GACNA,aAAiBpC,GACnBoC,EAAMX,YACNZ,KAAKuE,eAAiBvE,KAAKuE,eAAepD,QAAO,SAAChE,GAAD,OAAOA,IAAMoE,KAC1DA,EAAMe,SACR,iDAAkBf,IAIpB,iDAAkBA,K,iCAQXkD,GACT,gDAAiBA,K,oCAOLA,GACZ,mDAAoBA,Q,gCAhFNsC,GAAMM,M,mxBCfxB,IAsBeC,GAtBW,SAACC,EAAQC,EAAYC,GAC7C,IAAe,IAAXF,EACF,OAAOE,EAET,IAAMC,EAAcC,KAAGC,SAASH,GAChC,OAAKF,GAAUG,EAAYG,MAAML,GACxBC,EAEJF,EAKEI,KAAGG,aAAH,SACFJ,GADE,IAELG,MAAO,SACFH,EAAYG,OADZ,SAEFL,EAAaD,QAPhBQ,QAAQC,KAAR,8CAAoDP,IAC7C,OCSIQ,GAtBgB,SAACvH,GAC9B,IAAKA,IAAQA,EAAI6E,MACf,MAAO,GAF6B,IAI9B2C,EAAiBxH,EAAI6E,MAArB2C,aACJ3I,EAAa,GAcjB,OAbA3B,OAAOuK,OAAOD,GAAclF,SAAQ,SAACoF,GACnC,GAAIA,EAAYC,KAAM,CACpB,IAAMC,EAASF,EAAYnF,YACrBiE,EACJoB,EAAOpB,aAAgBoB,EAAOlJ,SAAWkJ,EAAOlJ,QAAQ8H,YACtDA,IACF3H,EAAaA,EAAWsH,OACtBK,EAAYqB,QAAQ,UAAW,KAAKC,MAAM,sBAM3C5C,GAAgBrG,I,gvGCJJkJ,G,wQAQnB,aAA0B,MAAdrJ,EAAc,uDAAJ,GAAI,WACxB,IAAMsJ,EAAU,IAAIC,KAAQ,CAC1BL,OAAQ,IAAIM,KAAO,IACnBpF,OAAQ,SAAC+C,GACP,IAAK,EAAKsC,MAGR,OADAd,QAAQC,KAAK,6BACN,KAET,IAAIc,GAAU,EACRC,EAAS,EAAKF,MAAMG,YAClBrC,EAAcJ,EAAdI,UAEFjH,EAAU,EAAK4C,QAAQ2G,aACzB,EAAKC,YAAYxJ,UAAYA,IAC/BqJ,EAAOxD,MAAM4D,QAAUzJ,EAAU,QAAU,OAC3C,EAAKwJ,YAAYxJ,QAAUA,EAG3BqJ,EAAOxD,MAAMX,SAAW,YAG1B,IAAMwE,EAAU,EAAK9G,QAAQ+G,aACzB,EAAKH,YAAYE,UAAYA,IAC/BL,EAAOxD,MAAM6D,QAAUA,EACvB,EAAKF,YAAYE,QAAUA,GAtBP,IA0BdE,EAAa3C,EAAb2C,SACJ,EAAKJ,YAAYI,WAAaA,IAChC,EAAKT,MAAMU,SAA6B,MAAjBD,GAAY,GAAYE,KAAKC,GAAI,CACtDC,SAAS,IAEXZ,GAAU,EACV,EAAKI,YAAYI,SAAWA,GAI5B,EAAKJ,YAAYS,OAAShD,EAAUgD,MACpC,EAAKT,YAAYU,OAAO,KAAOjD,EAAUiD,OAAO,IAChD,EAAKV,YAAYU,OAAO,KAAOjD,EAAUiD,OAAO,KAEhD,EAAKf,MAAMgB,OAAO,CAChBD,OAAQE,oBAASnD,EAAUiD,QAC3BD,KAAMhD,EAAUgD,KAAO,EACvBD,SAAS,IAEXZ,GAAU,EACV,EAAKI,YAAYS,KAAOhD,EAAUgD,KAClC,EAAKT,YAAYU,OAASjD,EAAUiD,QAGtC,IAAMG,EAAO,EAAKrJ,IAAIsJ,UAYtB,GAVE,EAAKd,YAAYa,KAAK,KAAOA,EAAK,IAClC,EAAKb,YAAYa,KAAK,KAAOA,EAAK,KAElCjB,GAAU,EACV,EAAKI,YAAYa,KAAOA,GAOxB,EAAKlB,OACL,EAAKA,MAAMtD,OACX,EAAKsD,MAAMoB,iBACXnB,EAEA,IACM,EAAKD,MAAMqB,SACb,EAAKrB,MAAMqB,OAAOC,SAClB,EAAKtB,MAAMqB,OAAS,MAEtB,EAAKrB,MAAMuB,UACX,MAAOC,GAIPtC,QAAQC,KAAKqC,GAIjB,OAAOtB,KArFa,OAyFxB,uBACK3J,GADL,IAEEkD,QAASoG,MAQNjB,SAAWrI,EAAQkL,IAQxB,EAAK/C,OAASnI,EAAQmI,OAQtB,EAAKC,WAAapI,EAAQoI,YAAc,MAKxC,EAAK+C,kBAAoB,EAAKA,kBAAkB7L,KAAvB,OAxHD,E,0CA+HrBgC,GAAK,WACR,0CAAWA,GAENV,KAAKU,MAAOV,KAAK6I,QAQtB7I,KAAKwK,OAAS,IAAIC,KAAQ,CACxBC,kBAAmB1K,KAAKU,IAAIiK,UAAUC,kBAGxC5K,KAAK6K,YAEL7K,KAAKwC,gBAAgBN,KACnBlC,KAAKU,IAAIgC,GAAG,eAAe,WACzB,IACM,EAAKmG,OACP,EAAKA,MAAMiC,SAEb,MAAOT,GAGPtC,QAAQC,KAAKqC,W,uCAUnB,OAAO/C,GAAkBtH,KAAKuH,OAAQvH,KAAKwH,WAAYxH,KAAKyH,Y,kCAOlD,WAOV,GANAzH,KAAKwC,gBAAgBN,KACnBlC,KAAKU,IAAIgC,GAAG,iBAAiB,WAC3B,EAAKmI,gBAIJ7K,KAAKU,IAAIyG,mBAId,GAAKnH,KAAKN,QAAV,CAXU,SAuBGM,KAAKU,IAAIiK,UAAUI,YAvBtB,GAuBLC,EAvBK,KAuBFC,EAvBE,KAwBLD,GAAMC,IACTD,EAAI,EACJC,EAAI,GAGN,IAAM1F,EAAQvF,KAAKkL,iBACnB,IAKElL,KAAK6I,MAAQ,IAAIsC,KAASnE,IAAI,CAC5BzB,QACA6F,oBAAoB,EACpBC,SAAS,EACTzB,OAAQE,oBAAS,CAACkB,EAAGC,IACrBK,UAAWtL,KAAKU,IAAIyG,mBACpBoE,aAAa,EACbC,aACE,iBAAkBxL,KAAKZ,QAAUY,KAAKZ,QAAQoM,aAAe,IAE/DC,sBAAuBzL,KAAKZ,QAAQqM,wBAAyB,IAE/D,MAAOpB,GAEPtC,QAAQC,KAAK,+BAAgCqC,GAM/CrK,KAAKkJ,YAAc,CACjBU,OAAQ,CAACoB,EAAGC,GACZtB,KAAM,KACNL,SAAU,KACV5J,QAAS,KACT0J,QAAS,KACTW,KAAM,CAAC,EAAG,IAGZ/J,KAAK6I,MAAM6C,KAAK,QAAQ,WAKtB,EAAKC,QAAS,EAEd,EAAKpM,WACH,EAAKA,YAAc0I,GAAuB,EAAKY,QAAU,GAE3D,EAAKvG,QAAQW,YAAYC,gBAAgB,EAAK3D,YAE9C,EAAKsB,cAAc,CACjBC,KAAM,OACNC,OAAQ,OAIZ,IAAM6K,EAAe5L,KAAK6I,MAAMG,YAC5B4C,IACE5L,KAAKZ,QAAQyM,SACfD,EAAaE,aAAa,WAAY9L,KAAKZ,QAAQyM,UAInDD,EAAaG,gBAAgB,aAIjC/L,KAAK6I,MAAMnG,GAAG,OAAQ1C,KAAKuK,wBAhFzBvK,KAAKwC,gBAAgBN,KACnBlC,KAAK0L,KAAK,kBAAkB,WAC1B,EAAKb,kB,wCAiFKlI,GAChB,IAAMqJ,EACJhM,KAAKT,YAAc0I,GAAuBtF,EAAI5B,SAAW,GACvDf,KAAKT,WAAW0M,aAAeD,EAAgBC,YACjDjM,KAAKsC,QAAQW,YAAYC,gBAAgB8I,K,iDAWlBlK,EAAY1C,GAAS,WAE9C,KACGA,GACAY,KAAKwK,QACLxK,KAAK6I,OACL7I,KAAK6I,MAAMoB,iBAEZ,OAAOtI,QAAQC,QAAQ,CAAEE,aAAYD,SAAU,GAAIN,MAAOvB,OAG5D,IAAMkM,EAAQpK,GAAc9B,KAAK6I,MAAMsD,QAAQrC,oBAAShI,IAGlDD,EAAW7B,KAAK6I,MACnBuD,sBAAsBF,EAAO9M,GAC7BsB,KAAI,SAAC2L,GACJ,IAAMC,EAAY,EAAK9B,OAAO+B,YAAYF,GAO1C,OANIC,GAIFA,EAAUlM,IAAI,gBAAiBiM,GAE1BC,KAGX,OAAO3K,QAAQC,QAAQ,CACrBL,MAAOvB,KACP6B,WACAC,iB,kCAQE9B,KAAK6I,QACP7I,KAAK6I,MAAM2D,IAAI,OAAQxM,KAAKuK,mBAG5BvK,KAAK6I,MAAM4D,eAAiB,aAC5BzM,KAAK6I,MAAM6D,SACX1M,KAAK6I,MAAQ,MAEf7I,KAAK2L,QAAS,EACd,kD,4BAQIvI,GACJ,OAAO,IAAIqF,EAAJ,SAAqBzI,KAAKZ,SAAYgE,S,gCAzVRjE,G,6BCjBzC,I,0+CCIqBwN,G,WAInB,WAAYvN,I,4FAAS,SACnB,IAAMwN,E,kWAAO,EACXC,aAAa,GACVzN,GAOLY,KAAK8M,aAAe,GAMpB9M,KAAK+M,qBAAuB,GAM5B/M,KAAK6M,cAAgBD,EAAKC,YAM1B7M,KAAKgN,uBAAyBJ,EAAKI,uBAMnChN,KAAKiN,eAAiB,KAMtBjN,KAAKkN,kBAAoB,KAMzBlN,KAAKmN,UAAYP,EAAKO,UAOtBnN,KAAK+I,OAAS6D,EAAK7D,QAAU5D,SAASC,cAAc,UACpDpF,KAAK+I,OAAOqE,MAAQR,EAAKQ,MACzBpN,KAAK+I,OAAOsE,OAAST,EAAKS,OAC1BrN,KAAK+I,OAAO+C,aACV,QACA,CACE,qBACA,SACA,YACA,cACA,eACA,uBACA,sBACA,uBACA5G,KAAK,MAMTlF,KAAKsN,cAAgBtN,KAAK+I,OAAOwE,WAAW,M,0DAOnC7N,GACLM,KAAK+I,SACP/I,KAAK+I,OAAOxD,MAAMiI,WAAa9N,EAAU,UAAY,Y,wCAQtB,IAAnBoN,EAAmB,uDAAJ,GACzB9M,KAAKyN,MACPX,EAAaW,KAAKzN,KAAKyN,MAGzBzN,KAAK8M,aAAeA,I,wCAQpB,OAAO9M,KAAK8M,cAAgB,K,gDAS5B,OAAO9M,KAAK+M,uB,8BAQR/M,KAAKsN,eACPtN,KAAKsN,cAAcI,UAAU,EAAG,EAAG1N,KAAK+I,OAAOqE,MAAOpN,KAAK+I,OAAOsE,U,gCAQ5DlM,GAKRnB,KAAKmB,OAASA,I,8BAORsM,GAKNzN,KAAKyN,KAAOA,I,wCAQIpI,GACZA,IAAOrF,KAAKiN,iBACdjN,KAAKiN,eAAiB5H,K,2CASLA,GACfA,IAAOrF,KAAKkN,oBACdlN,KAAKkN,kBAAoB7H,K,mCAQhB8H,GACXnN,KAAKmN,UAAYA,I,+BAOVlO,GAKPe,KAAKuF,MAAQtG,I,iCASJ0O,EAASC,GAClB,IAAMC,EAAUC,WAAW9N,KAAK+I,OAAOxD,MAAMwI,MACvCC,EAASF,WAAW9N,KAAK+I,OAAOxD,MAAM0I,KAC5CjO,KAAK+I,OAAOxD,MAAMwI,KAAlB,UAA4BF,EAAUF,EAAtC,MACA3N,KAAK+I,OAAOxD,MAAM0I,IAAlB,UAA2BD,EAASJ,EAApC,Q,2CAkBA,IAJAM,EAIA,uDAJWC,KAAKC,MAChBrE,EAGA,uDAHO,GACPsE,EAEA,uCADAC,EACA,wDACAtO,KAAKuO,QACLvO,KAAK+I,OAAOxD,MAAMwI,KAAO,MACzB/N,KAAK+I,OAAOxD,MAAM0I,IAAM,MAHxB,IAkBIO,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAzBJ,KAKwBhF,EALxB,GAKOqD,EALP,KAKcC,EALd,KAMA,GACED,GACAC,IACCrN,KAAK+I,OAAOqE,QAAUA,GAASpN,KAAK+I,OAAOsE,SAAWA,GACvD,OAC0C,CAACD,EAAOC,GAAjDrN,KAAK+I,OAAOqE,MADb,KACoBpN,KAAK+I,OAAOsE,OADhC,KAOFrN,KAAKgP,eAAiBX,GAAcrO,KAAKgP,eAUzChP,KAAK+M,qBAAuB,GAE5B,IAAK,IAAI7P,GAAK8C,KAAK8M,cAAgB,IAAIrL,OAAS,EAAGvE,GAAK,EAAGA,GAAK,EAAG,CACjE,IAAM+R,EAAOjP,KAAK8M,aAAa5P,GAGvBgS,EAAwCD,EAAxCC,SAAUC,EAA8BF,EAA9BE,cAAeC,EAAeH,EAAfG,WAEjC,IAAIpP,KAAKmB,QAAWnB,KAAKmB,OAAO8N,EAAM/R,EAAG8C,KAAK8M,cAA9C,CAKA,IAAIuC,EAAQ,KACR/F,OAAQ,EAEZ,IAAI2F,EAAKnN,aAAewM,GAAkBtO,KAAK6M,aAExC,GAAIsC,GAAiBA,EAAc1N,OAAS,EAAG,CASpD,IARA,IAAM2M,EAAMF,GAAYkB,GAAc,GAClCE,OAAK,EACLC,OAAG,EACHC,OAAS,EACTC,OAAO,EACPC,OAAQ,EAGHC,EAAI,EAAGA,EAAIR,EAAc1N,OAAS,EAAGkO,GAAK,EAAG,UAErBR,EAAcQ,GAFO,GAEnDL,EAFmD,KAE5CE,EAF4C,KAEjClG,EAFiC,cAGnC6F,EAAcQ,EAAI,GAHiB,GAKpD,GAFCJ,EAHmD,KAG9CE,EAH8C,KAKhDH,GAASlB,GAAOA,GAAOmB,EACzB,MAEAD,EAAQ,KACRC,EAAM,KAIV,GAAIL,EAASU,YAAcC,KAASC,MAClCT,EAAQH,EAASa,sBACZ,GAAIb,EAASU,YAAcC,KAASG,aACzC,GAAIV,GAASC,EAAK,CAEhBG,EAAW1P,KAAK6M,YACZrD,KAAKyG,KAAK7B,EAAMkB,IAAUC,EAAMD,GAAQ,GACxC,EAEJ,IAAMY,EAAWlQ,KAAK6M,YAClB6C,GAAYD,EAAUD,GAAaA,EACnC,EAEJH,EAAQH,EAASiB,gBAAgBD,GAGjClQ,KAAK8M,aAAa5P,GAAGoM,SAAWA,EAChCtJ,KAAK8M,aAAa5P,GAAGkT,YAAcV,OAG9B,GAAItB,EAAMe,EAAc,GAAG,GAAI,UACjBA,EADiB,gBAC9B7F,EAD8B,KAEpCoG,EAAW,EACXL,EAAQH,EAASmB,0BACZ,GAAIjC,EAAMe,EAAcA,EAAc1N,OAAS,GAAG,GAAI,UAC1C0N,EAAcA,EAAc1N,OAAS,GADK,GACtD6H,EADsD,KAE3DoG,EAAW,EACXL,EAAQH,EAASoB,0BAInBvI,QAAQwI,MACN,wFACArB,GAKJlP,KAAK8M,aAAa5P,GAAGoM,SAAWA,EAChCtJ,KAAK8M,aAAa5P,GAAGkT,YAAcV,GAAY,QA9D/CL,EAAQJ,EAAKnN,WAiEf,GAAIuN,EAAO,CAETrP,KAAK8M,aAAa5P,GAAG4E,WAAauN,EAClC,IAAMmB,EAAKxQ,KAAKgN,uBAAuBqC,GAEvC,IAAKmB,EAEH,SAGFxQ,KAAK8M,aAAa5P,GAAGuT,UAAW,EAChCzQ,KAAK+M,qBAAqB7K,KAAKlC,KAAK8M,aAAa5P,IACjD,IAAMwT,EAAa1Q,KAAKuF,MAAM0J,EAAMjP,KAAKgP,gBAEzC,IAAK0B,EAEH,SAGF,IAAIC,EAAWD,EAAWtD,MACtBwD,EAAYF,EAAWrD,OAEvBrN,KAAKmN,YACPyD,EAAYpH,KAAKqH,MAAMD,EAAY5Q,KAAKmN,WACxCwD,EAAWnH,KAAKqH,MAAMF,EAAW3Q,KAAKmN,YAItCnN,KAAKiN,iBAAmBgC,EAAK5J,IAC7BrF,KAAKkN,oBAAsB+B,EAAK5J,IAEhCrF,KAAKsN,cAAcwD,UACjBJ,EACAF,EAAG,GAAKG,EAAW,EACnBH,EAAG,GAAKI,EAAY,EACpBD,EACAC,GAGA5Q,KAAKiN,iBAAmBgC,EAAK5J,KAE/BmJ,EAAkBkC,EAClBjC,EAAiB+B,EACjB9B,EAAoBiC,EACpBhC,EAAqBiC,GAGnB5Q,KAAKkN,oBAAsB+B,EAAK5J,KAElCuJ,EAAqB8B,EACrB7B,EAAoB2B,EACpB1B,EAAuB6B,EACvB5B,EAAwB6B,KAK1BhC,GACF5O,KAAKsN,cAAcwD,UACjBlC,EACAC,EAAkB,GAAKC,EAAuB,EAC9CD,EAAkB,GAAKE,EAAwB,EAC/CD,EACAC,GAIAP,GACFxO,KAAKsN,cAAcwD,UACjBtC,EACAC,EAAe,GAAKC,EAAoB,EACxCD,EAAe,GAAKE,EAAqB,EACzCD,EACAC,K,gCAUJxL,kBAAQnD,KAAK+Q,cACb/Q,KAAK+M,qBAAuB,GAC5B/M,KAAKuO,a,kCC1aHyC,GAAuB,CAC3BC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,IACzDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACpDC,EAAG,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,KAM9CC,GAAQ,CACnB,OACA,0BACA,QACA,MACA,QACA,YACA,UACA,YACA,oBACA,QAMWC,GAAW,CACtB,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAMWC,GAAa,CACxB,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAMWC,GAAY,CACvB,IACA,IACA,IACA,IACA,IACA,KACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,GACA,GACA,GACA,GACA,GACA,IAMIC,GAAe,SAACjR,GACpB,GAAoB,iBAATA,EAAmB,CAC5B,IAAMkR,EAAUL,GAAMrQ,MAAK,SAAClD,GAAD,OAAO,IAAI6T,OAAOnR,GAAMoR,KAAK9T,MACxD,OAAOuT,GAAMvP,QAAQ4P,GAEvB,OAAOlR,GAkBIqR,GAAa,WAAc,IAAbrR,EAAa,uDAAN,EAChC,IACE,IAAMsR,EAAUL,GAAajR,GAC7B,OAAO8Q,GAASQ,GAChB,MAAOC,GACP,OAAO,IA0CEC,GAAgB,SAACC,EAAWC,EAAWC,GAClD,OAAID,EACKC,EAAc,UAAY,UAE/BF,GAAa,KACR,UAELA,GAAa,IACR,UAELA,GAAa,IACR,UAELA,GAAa,KACR,UAES,OAAdA,EACK,UAEF,W,kuFCnKF,IA+ZQG,GA9TW,SAACtO,GAAD,oB,mOAAA,6HAOLhF,GAAS,a,kWAAA,EAEtBuT,eAAe,GACZvT,GAFGuT,EADgB,EAChBA,cAAepN,EADC,EACDA,MAInBqN,EALoB,EACMC,OAIL,EACzB,sDAAuBzT,GACvBxB,OAAOyB,iBAAiBW,KAAM,CAC5B8S,eAAgB,CAAE3U,OAAO,GACzBwU,cAAe,CACbxU,QAASwU,EACTxS,UAAU,GAEZoF,MAAO,CACLpH,MAAOoH,GAASvF,KAAK+S,cAEvBF,MAAO,CACL9U,IAAK,kBAAM6U,GACXxS,IAAK,SAAC4S,GACJJ,EAAYI,EACZ,EAAK1D,UAGTnO,OAAQ,CACNpD,IAAK,kBAAM,EAAKkV,QAAQ9R,QACxBf,IAAK,SAACe,GACA,EAAK8R,SACP,EAAKA,QAAQC,UAAU/R,KAI7BsM,KAAM,CACJ1P,IAAK,kBAAM,EAAKkV,QAAQxF,MACxBrN,IAAK,SAACqN,GACA,EAAKA,MACP,EAAKwF,QAAQE,QAAQ1F,KAQ3BwF,QAAS,CAAE9U,MAAO,KAAMgC,UAAU,GAKlCiT,WAAY,CAAEjV,MAAO,IAKrB+P,SAAU,CACR/P,MAAO,IAAIgQ,KACXhO,UAAU,GAOZkT,eAAgB,CACdlV,MAAO,IAAIgQ,KACXhO,UAAU,GAMZ4M,qBAAsB,CACpBhP,IAAK,kBAAM,EAAKkV,QAAQlG,uBAM1BE,eAAgB,CACdlP,IAAK,WACH,OAAO,EAAKkV,QAAQhG,gBAEtB7M,IAAK,SAAC6M,GACJ,EAAKgG,QAAQhG,eAAiBA,IAOlCC,kBAAmB,CACjBnP,IAAK,WACH,OAAO,EAAKkV,QAAQ/F,mBAEtB9M,IAAK,SAAC8M,GACJ,EAAK+F,QAAQ/F,kBAAoBA,IAOrCoG,yBAA0B,CACxBC,SAAS,EACTpT,UAAU,OA9GM,2BA2HjBO,EAAKtB,GAAS,WACjB,0CAAWsB,GACXV,KAAKiT,QAAU,IAAItG,GAAQvN,GAC3BY,KAAKiT,QAAQO,UAAS,SAACC,EAAOzV,GAAR,OAAc,EAAKuH,MAAMkO,EAAOzV,MAElDgC,KAAKN,SACPM,KAAKsP,QAGPtP,KAAK0T,cAAgB1T,KAAK0C,GAAG,kBAAkB,SAACC,GAC1CA,EAAI5B,OAAOrB,QACb,EAAK4P,QAEL,EAAKqE,YAxIW,kCAiJpB3T,KAAK2T,OACLxQ,kBAAQnD,KAAK0T,eACT1T,KAAKiT,UACPjT,KAAKiT,QAAQW,UACb5T,KAAKiT,QAAU,MAEjB,kDAvJoB,4BAiKhBlJ,EAAMJ,EAAM0E,GAChBrO,KAAK2T,OACL3T,KAAKiT,QAAQ1Q,YAAW,GACxBvC,KAAK6T,mBAAmB7T,KAAKkO,SAAUnE,EAAMsE,GAC7CrO,KAAK8T,gBAAgBnK,KArKD,sCA6KNA,GAAM,WACpB3J,KAAK+T,iBACL/T,KAAKgU,mBAAqBC,aAAY,WACpC,IAAMC,EACJ,EAAKhG,SAASiG,WACb,IAAIhG,KAAS,EAAKkF,gBAAkB,EAAKR,MAC5C,EAAKuB,YAAYF,KAChBlU,KAAKqU,mBAAmB1K,MApLP,6BA2LpB3J,KAAK+T,iBACD/T,KAAKiT,UACPjT,KAAKiT,QAAQ1Q,YAAW,GACxBvC,KAAKiT,QAAQ1E,WA9LK,uCAuMhBvO,KAAKgU,oBACPM,cAActU,KAAKgU,sBAxMD,yCAgNHO,EAAMxK,EAAMsE,GAAY,WACrCrO,KAAKwU,WACPC,qBAAqBzU,KAAKwU,WAExBxU,KAAKsT,yBACPtT,KAAKwU,UAAYE,uBAAsB,WACrC,EAAKzB,QAAQY,mBAAmBU,EAAMxK,EAAMsE,MAG9CrO,KAAKiT,QAAQY,mBAAmBU,EAAMxK,EAAMsE,KAzN1B,kCAoOVkG,EAAMxK,EAAMsE,GAA+B,IAAnBsG,IAAmB,yDAC/CT,EAAU,IAAI/F,KAAKoG,GACzBvU,KAAKkO,SAAWgG,EAChBlU,KAAKqT,eAAiB,IAAIlF,KACtBwG,GACF3U,KAAK6T,mBAAmB7T,KAAKkO,SAAUnE,EAAMsE,KAzO3B,iCAkPXuG,GACT,OAAO5U,KAAKiT,QAAQ4B,kBAAkB1T,OAAOyT,KAnPzB,8CA8PE9S,GAItB,IAJiE,IAA/BuM,EAA+B,uDAAlB,EAAGyG,EAAe,uDAAVC,IACjDC,EAAMC,kBAAO,GAAD,UAAKnT,GAAL,GAAoBA,IAAa,GAAKuM,GAClDvB,EAAe9M,KAAKiT,QAAQ4B,kBAC5BK,EAAW,GACRhY,EAAI,EAAGA,EAAI4P,EAAarL,SAE7BqL,EAAa5P,GAAG4E,YAChBqT,8BAAmBH,EAAKlI,EAAa5P,GAAG4E,aAExCoT,EAAShT,KAAK4K,EAAa5P,IAEzBgY,EAASzT,SAAWqT,GAPe5X,GAAK,GAY9C,OAAOgY,IA9Qa,yCAsRHvL,GACjB,IAAMyL,EAAc5L,KAAK6L,MAAM1L,GACzB2L,EAAWxD,GAAUsD,IAAgB,GAE3C,OADiB5L,KAAK+L,IAAI,GAAID,EAAWtV,KAAK6S,SAzR1B,mCAoSTY,GAAO,IACN+B,EAAS/B,EAAbpO,GACR,GAAIrF,KAAKoT,WAAWoC,GAClB,OAAOxV,KAAKoT,WAAWoC,GAEzB,IAAMzM,EAAS5D,SAASC,cAAc,UACtC2D,EAAOqE,MAAQ,IACfrE,EAAOsE,OAAS,GAChB,IAAMoI,EAAM1M,EAAOwE,WAAW,MAc9B,OAbAkI,EAAIC,IAAI,EAAG,EAAG,EAAG,EAAG,EAAIlM,KAAKC,IAAI,GACjCgM,EAAIE,UAAY,UAChBF,EAAIG,OACJH,EAAII,UAAY,EAChBJ,EAAIK,YAAc,QAClBL,EAAIM,SACJN,EAAIO,KAAO,kBACXP,EAAIK,YAAc,QAClBL,EAAII,UAAY,EAChBJ,EAAIQ,WAAWT,EAAM,GAAI,IACzBC,EAAIE,UAAY,QAChBF,EAAIS,SAASV,EAAM,GAAI,IACvBxV,KAAKoT,WAAWoC,GAAQzM,EACjB/I,KAAKoT,WAAWoC,OA1TH,GACVpR,I,2uGC0FD+R,G,wQAzLb,aAA0B,MAAd/W,EAAc,uDAAJ,GAAI,mBAGxB,oBACKA,KAQAgX,kBAAoBhX,EAAQgX,mBAAsB,kBAAM,GAE7D,EAAK9T,QACHlD,EAAQkD,SACR,IAAIQ,SAAM,CACRuB,OAAQ,CACN,IAAIsE,SAAQ,CACVL,OAAQ,IAAIM,KAAO,IACnBpF,OAAQ,SAAC+C,GACP,IAAK,EAAK0M,UAAY,EAAKA,QAAQlK,OACjC,OAAO,KAFa,MAIexC,EAAWI,UAAxCgD,EAJc,EAIdA,KAAMC,EAJQ,EAIRA,OAAQyE,EAJA,EAIAA,WAEtB,GAAI1E,IAAS,EAAKT,YAAYS,KAAM,CAIlC,GAHA,EAAKT,YAAYS,KAAOA,EACxB,EAAKT,YAAYU,OAASA,GAErB,EAAKwM,kBAAkBzM,GAE1B,OADA,EAAKsJ,QAAQ1E,QACN,EAAK0E,QAAQlK,OAGtB,EAAK8K,mBACH,EAAK3F,SACL3H,EAAWwD,KACXsE,GACA,QAEG,GACL,EAAKnF,YAAYU,OAAO,KAAOA,EAAO,IACtC,EAAKV,YAAYU,OAAO,KAAOA,EAAO,GACtC,CACA,IAAM4G,EAAK,EAAK9P,IAAIsM,uBAAuBpD,GACrCyM,EAAQ,EAAK3V,IAAIsM,uBACrB,EAAK9D,YAAYU,QAEnB,EAAKqJ,QAAQqD,WAAW9F,EAAG,GAAK6F,EAAM,GAAI7F,EAAG,GAAK6F,EAAM,IACxD,EAAKnN,YAAYU,OAASA,EAG5B,OAAO,EAAKqJ,QAAQlK,aAS9B,EAAKG,YAAc,CACjBU,OAAQ,CAAC,EAAG,GACZD,KAAM,MAQR,EAAKoH,aAAe,GAxEI,E,0CAgFrBrQ,GACEA,GAIL,0CAAWA,EAAK,CACdsM,uBAAwBtM,EAAIsM,uBAAuBtO,KAAKgC,O,kCAQhD6T,GACV,IAAMgC,EAAOvW,KAAKU,IAAIiK,UACtB,iDACE4J,EACAvU,KAAKU,IAAIsJ,UACTuM,EAAKC,iBACJxW,KAAKU,IAAIiK,UAAU8L,iBACjBzW,KAAKU,IAAIiK,UAAU+L,oB,8BAQlB,WACN,2CACE1W,KAAKU,IAAIsJ,UACThK,KAAK2W,aAAe3W,KAAKU,IAAIiK,UAAUiM,UACvC5W,KAAKU,IAAIiK,UAAU6L,iBAGrBxW,KAAK+Q,aAAe,CAClB/Q,KAAKU,IAAIgC,GAAG,WAAW,WACrB,IAAMmU,EAAI,EAAKnW,IAAIiK,UAAUiM,UAEzBC,IAAM,EAAKF,cAKb,EAAKA,YAAcE,EACnB,EAAK/C,gBAAgB+C,OAGzB7W,KAAKU,IAAIgC,GAAG,eAAe,SAACC,GAC1B,IACE,EAAKjC,IAAIiK,UAAU+L,mBACnB,EAAKhW,IAAIiK,UAAU8L,gBAClB,EAAK9D,cAHR,CADkC,IAQ3BmE,EAR2B,GAQhB,EAAKC,wBAAwBpU,EAAIb,WAAY,GAR7B,MAS5BuD,EAAKyR,GAAWA,EAAQzR,GAC1B,EAAK4H,iBAAmB5H,IAC1B,EAAK3E,IAAIyG,mBAAmB5B,MAAMyR,OAASF,EACvC,UACA,OACJ,EAAK7J,eAAiB5H,EAGtB,EAAKwO,mBAAmB,EAAK3F,kB,6BAWnC,2CACA/K,kBAAQnD,KAAK+Q,cACb/Q,KAAK+Q,aAAe,K,8CAWEjP,EAAYgT,GAClC,IAAMzG,EAAarO,KAAKU,IAAIiK,UAAU6L,gBACtC,oEAAqC1U,EAAYuM,EAAYyG,K,4BAQzD1R,GACJ,OAAO,IAAI+S,EAAJ,SAAsBnW,KAAKZ,SAAYgE,S,gCA7LvB2D,GAAM5H,I,2BCPpB8X,GAAmB,WAAsB,IAArB7I,EAAqB,uDAAf,IAAID,KACrC+I,GAAS9I,EAAI+I,cAAgB,GAAGlL,WACpCiL,EAAyB,IAAjBA,EAAMzV,OAAN,WAAyByV,GAAUA,EAC3C,IAAIE,EAAMhJ,EAAIiJ,aAAapL,WAG3B,OAFAmL,EAAqB,IAAfA,EAAI3V,OAAJ,WAAuB2V,GAAQA,EAE9B,CAAChJ,EAAIkJ,iBAAkBJ,EAAOE,GAAKlS,KAAK,KAQpCqS,GAAmB,SAACC,GAAD,MAC9B,CACEA,EAAKC,cACLD,EAAKE,gBAFP,UAGKF,EAAKG,gBAHV,YAG6BH,EAAKI,uBAChC1S,KAAK,M,s/DCsCM2S,G,wQA5Cb,aAA0B,MAAdzY,EAAc,uDAAJ,GAAI,mBACxB,gBAEKkL,IAAMlL,EAAQkL,IAGnB,EAAK/C,OAASnI,EAAQmI,OANE,E,2JAaY,IAAhCuQ,EAAgC,uDAAzB,GAAIC,EAAqB,uDAAZ,GAAIC,EAAQ,uCAE9BC,EAAY,SAAKF,GAAR,IAAgBtZ,IAAKuB,KAAKuH,SACnC2Q,EAAQ,MAAKD,GAKnB,OAJAra,OAAOua,KAAKF,GAAWjV,SACrB,SAACvE,GAAD,YACkBgC,IAAfyX,EAAMzZ,IAAqC,OAAfyZ,EAAMzZ,YAAyByZ,EAAMzZ,MAEjEuB,KAAKuH,OAMH6Q,MAAM,GAAD,OAAIpY,KAAKsK,KAAT,OAAewN,EAAf,YAAuBnQ,KAAG0Q,UAAUH,IAAUF,GAAQM,MAChE,SAACC,GACC,IACE,OAAOA,EAASC,OAAOF,MAAK,SAACG,GAC3B,GAAIA,EAAKlI,MACP,MAAM,IAAIvO,MAAMyW,EAAKlI,OAEvB,OAAOkI,KAET,MAAOpO,GACP,OAAO1I,QAAQ+W,OAAO,IAAI1W,MAAMqI,QAd7B1I,QAAQ+W,OACb,IAAI1W,MAAJ,2CAA8ChC,KAAKsK,c,gCAzBzCpG,K,s/DCuBHyU,G,wQAlBb,aAA0B,IAAdvZ,EAAc,uDAAJ,GAAI,kCAChBkL,IAAK,kCAAqClL,I,4CAU7C2Y,GAA8B,IAAtBa,EAAsB,uDAAJ,GAC/B,OAAO5Y,KAAKoY,MAAM,GAAIL,EAAQ,CAC5Bc,OAAQD,EAAgBC,SACvBP,MAAK,SAACQ,GAAD,OAAuBA,EAAkBjX,iB,gCAtB9BgW,I,wVCPvB,IAAMkB,GAAiB,WAGrB,IAHqC,IAAfC,EAAe,uDAAP,GACxBC,EAAW,GAER/b,EAAI,EAAGA,EAAI8b,EAAMvX,OAAQvE,GAAK,EAAG,OACF8b,EAAM9b,GAAjCka,EAD6B,EAChC5Z,EAAW0Z,EADqB,EACxB5Z,EAAa4b,EADW,EACdjO,EAC1BgO,EAAS/W,KAAK,CACZkV,MACAF,QACAgC,SAGJ,OAAOD,GAQIE,GAA4B,SAACV,GACxC,IAAMW,E,kWAAU,IAAKX,GAGrB,CAAC,IAAK,IAAK,MAAMzV,SAAQ,SAACqW,GACnBD,EAAQC,KACXD,EAAQC,GAAQ,OAiCpB,IAvCiD,IAW/ChU,EAoBE+T,EApBF/T,GACIiU,EAmBFF,EAnBFG,GACGC,EAkBDJ,EAlBFhb,EACIqb,EAiBFL,EAjBFM,GACIC,EAgBFP,EAhBFQ,GACIC,EAeFT,EAfFU,GACIC,EAcFX,EAdFY,GACIC,EAaFb,EAbFc,GACKC,EAYHf,EAZFgB,IACKC,EAWHjB,EAXFkB,IACGC,EAUDnB,EAVF7b,EACIid,EASFpB,EATFqB,GAtB+C,EA+B7CrB,EARFsB,EAAQC,EAvBuC,EAuB1Chc,EAAgBic,EAvB0B,EAuB7BC,EAAoBC,EAvBS,EAuBbC,GAvBa,EA+B7C3B,EAPF4B,EAAQC,EAxBuC,EAwB1Ctc,EAAiBuc,EAxByB,EAwB5BL,EAAqBM,EAxBO,EAwBXJ,GAxBW,EA+B7C3B,EANFgC,GACKC,EA1B0C,EA0B7C1c,EACG2c,EA3B0C,EA2B7Ctc,EACGuc,EA5B0C,EA4B7Cnd,EAEGod,EACHpC,EADFqC,IAGIC,EAAmB3C,GAAesC,GAClCM,EAA0B5C,GAAeuC,GACzCM,EAAkBrB,GAAW,IAAJ,OAAQA,GACjCsB,EAAQrB,GAAa,IAAJ,OAAQA,GAEzBsB,EAAW,GACR5e,EAAI,EAAGA,GAAKse,GAAgB,IAAI/Z,OAAQvE,GAAK,EAAG,OAenDse,EAAate,GAbV6e,EAFgD,EAErDC,IACGC,EAHkD,EAGrDtd,EACGud,EAJkD,EAIrDld,EACImd,EALiD,EAKrDC,GACIC,EANiD,EAMrDC,GACIC,EAPiD,EAOrDC,GACIC,EARiD,EAQrDC,GACIC,EATiD,EASrDC,GACIC,EAViD,EAUrDC,GACKC,EAXgD,EAWrDC,IACKC,EAZgD,EAYrDC,IACG1K,EAbkD,EAarDjV,EACI4f,EAdiD,EAcrDrD,GAGFgC,EAAS5Z,KAAK,CACZ6Z,YACAE,cACAC,cACAC,aAA8B,IAAjBA,EAAmC,IAAdI,EAAqB,KACvDF,eAAkC,IAAnBA,EAAuC,IAAhBI,EAAuB,KAC7DE,eACAE,iBACAE,YAAaA,EACbE,WAAYA,EACZzK,YAAaA,EACbqH,uBAAwBsD,IAI5B,MAAO,CACL9X,KACAiU,cACAsC,kBACAC,QACArC,cACAa,kBACAZ,WACAE,YACAmC,WACAjC,uBAAwBA,EACxBE,kBAAmBA,EACnBE,WACAE,UACAiD,sBAAuB,CACrB7B,kBACAG,mBACAC,2BAEFhB,WACAC,cACAE,mBACAG,YACAC,eACAC,sBASSkC,GAA4B,WAEvC,IAF0D,IAAlBxb,EAAkB,uDAAP,GAC7CiL,EAAe,GACZ5P,EAAI,EAAGA,EAAI2E,EAASJ,OAAQvE,GAAK,EAAG,CAC3C,IAAM+R,EAAOpN,EAAS3E,GAChBgS,EAAW,IAAIoO,cAAWrO,EAAKC,SAASgN,aAFH,EAyBvCjN,EAAKtP,WArBH0F,EAJqC,EAIzCkY,GACmBzc,EALsB,EAKzC0c,kBACmB/f,EANsB,EAMzCggB,kBACiBpD,EAPwB,EAOzCqD,gBACeC,EAR0B,EAQzCC,cACUjD,EAT+B,EASzCkD,SACajD,EAV4B,EAUzCkD,YACW7C,EAX8B,EAWzC8C,UACc7C,EAZ2B,EAYzC8C,aACSC,EAbgC,EAazCC,QACYC,EAd6B,EAczCC,WACaC,EAf4B,EAezCC,YACOzC,EAhBkC,EAgBzC0C,MACmBC,EAjBsB,EAiBzCC,kBACmBC,EAlBsB,EAkBzCC,kBAC0BC,EAnBe,EAmBzCC,yBACgBC,EApByB,EAoBzCC,eACOC,EArBkC,EAqBzCC,MACe9P,EAtB0B,EAsBzC+P,cACWC,EAvB8B,EAuBzCC,UACW5M,EAxB8B,EAwBzC6M,UAGFvS,EAAa5K,KAAK,CAChBmD,KACAvE,OACArD,OACA4c,kBACAsD,gBACAhD,WACAC,cACAK,YACAC,eACA+C,UACAE,aACAE,cACAG,oBACAE,oBACAE,2BACAE,iBACAE,QACA7P,gBACA0M,MAAOA,GAAS,IAAJ,OAAQA,GACpBsD,UAAWA,GAAa,IAAJ,OAAQA,GAC5BjQ,WACAsD,cAGJ,OAAO1F,G,s/DC9GMwS,G,wQAhDb,aAA0B,IAAdlgB,EAAc,uDAAJ,GAAI,kCAChBkL,IAAK,mCAAsClL,I,yDAUjC2Y,GAA8B,IAAtBa,EAAsB,uDAAJ,GAC5C,OAAO5Y,KAAKoY,MAAL,kBAA8BL,EAAQ,CAC3Cc,OAAQD,EAAgBC,W,wCAWVd,GAA8B,IAAtBa,EAAsB,uDAAJ,GAC1C,OAAO5Y,KAAKoY,MAAL,yBAAqCL,EAAQ,CAClDc,OAAQD,EAAgBC,SACvBP,MAAK,SAACG,GACP,OAAO4E,GAA0B5E,EAAK5W,e,8CAWlBkW,GAA8B,IAAtBa,EAAsB,uDAAJ,GAChD,OAAO5Y,KAAKoY,MAAL,gBAA4BL,EAAQ,CACzCc,OAAQD,EAAgBC,SACvBP,MAAK,SAACG,GACP,OAAOU,GAA0BV,W,gCAnDbZ,I,05BC2MX0H,G,WAxNb,WAAYjV,GAAK,Y,4FAAA,SAKftK,KAAKwf,cAAgB,GACrBxf,KAAKyf,QAAQnV,GAGb2J,aAAY,WACV,EAAKyL,KAAK,UACT,KACH1f,KAAK2f,WAAa,G,+DAaIC,EAAQ7H,GAC9B,IAAI8H,EAAS,GAAH,OAAMD,EAAN,YAAgB7H,EAAO+H,SAGjC,OAFAD,GAAU9H,EAAOgI,KAAP,WAAkBhI,EAAOgI,MAAS,IAC5CF,GAAU9H,EAAO1S,GAAP,WAAgB0S,EAAO1S,IAAO,IAC1BW,W,iCAQRsE,GAAK,WACPtK,KAAKggB,WAAahgB,KAAKggB,UAAUC,aAAejgB,KAAKggB,UAAUE,QACjElgB,KAAKggB,UAAUG,QAIjBngB,KAAKggB,UAAY,IAAII,UAAU9V,GAE3BtK,KAAKqgB,aACPrgB,KAAKsgB,cAActgB,KAAKqgB,aAGtBrgB,KAAKugB,aACPvgB,KAAKwgB,QAAQxgB,KAAKugB,aAGpB,GAAIvgB,KAAKwf,eAAexc,SAAQ,SAAC/D,GAC/B,EAAKwhB,UAAUxhB,EAAE8Y,OAAQ9Y,EAAEyhB,GAAIzhB,EAAE0hB,SAAS,MAI5C3gB,KAAKggB,UAAUY,QAAU,WACvB9jB,OAAO+jB,aAAa,EAAKC,kBAEzB,EAAKA,iBAAmBhkB,OAAOikB,YAAW,kBAAM,EAAKtB,QAAQnV,KAAM,Q,0BAWnEyN,EAAQ2I,EAAIC,GACd,IAAMd,EAASN,EAAmByB,iBAAiB,MAAOjJ,GAC1D/X,KAAK0f,KAAKG,GACV7f,KAAKihB,OAAOlJ,EAAQ2I,EAAIC,K,2BAQrBO,GAAS,WACNxB,EAAO,WACX,EAAKM,UAAUN,KAAKwB,IAGlBlhB,KAAKggB,UAAUC,aAAeG,UAAUe,WAC1CnhB,KAAKggB,UAAUoB,iBAAiB,OAAQ1B,GAExCA,M,oCASUvhB,GAKZ6B,KAAKqgB,YAAcliB,EACnB6B,KAAK0f,KAAL,qBAAwBvhB,M,8BAQlB+d,GAAa,WAKnBlc,KAAKugB,YAAcrE,EACnBlc,KAAK0f,KAAL,eAAkBxD,EAAYhX,KAAK,OACnClF,KAAKwf,cAAcxc,SAAQ,SAAC/D,GAC1B,EAAKlB,IAAIkB,EAAE8Y,OAAQ9Y,EAAEyhB,GAAIzhB,EAAE0hB,c,6BAYxB5I,EAAQ2I,EAAIC,GACjB,IAAMU,EAAY,SAAChP,GACjB,IAAMoG,EAAO6I,KAAKC,MAAMlP,EAAEoG,MACtBnQ,EAASyP,EAAO+H,QACpBxX,GAAUyP,EAAOgI,KAAP,WAAkBhI,EAAOgI,MAAS,GAG1CtH,EAAKnQ,SAAWA,GACdyP,EAAO1S,IAAM0S,EAAO1S,KAAOoT,EAAK+I,kBAElCd,EAAGjI,IAWP,OAPAzY,KAAKggB,UAAUoB,iBAAiB,UAAWC,GAEvCV,IACF3gB,KAAKggB,UAAUoB,iBAAiB,QAAST,GACzC3gB,KAAKggB,UAAUoB,iBAAiB,QAAST,IAGpC,CAAEc,YAAaJ,EAAWK,UAAWf,K,gCAWpC5I,EAAQ2I,EAAIC,EAASgB,GAAO,MACD3hB,KAAKihB,OAAOlJ,EAAQ2I,EAAIC,GAAnDc,EAD4B,EAC5BA,YAAaC,EADe,EACfA,UACf7B,EAASN,EAAmByB,iBAAiB,GAAIjJ,GAElD4J,GACH3hB,KAAKwf,cAActd,KAAK,CAAE6V,SAAQ2I,KAAIC,UAASc,cAAaC,cAGzD1hB,KAAK2f,WAAWE,KACnB7f,KAAK0f,KAAL,cAAiBG,IACjB7f,KAAK0f,KAAL,cAAiBG,IACjB7f,KAAK2f,WAAWE,IAAU,K,kCAUlBvX,EAAQoY,GAAI,WACtB1gB,KAAKwf,cACFre,QAAO,SAAClC,GACP,OAAOA,EAAE8Y,OAAO+H,UAAYxX,KAAYoY,GAAMzhB,EAAEyhB,KAAOA,MAExD1d,SAAQ,YAAgC,IAA7Bye,EAA6B,EAA7BA,YAAaC,EAAgB,EAAhBA,UACvB,EAAK1B,UAAU4B,oBAAoB,UAAWH,GAC1CC,IACF,EAAK1B,UAAU4B,oBAAoB,QAASF,GAC5C,EAAK1B,UAAU4B,oBAAoB,QAASF,OAIlD1hB,KAAKwf,cAAgBxf,KAAKwf,cAAcre,QACtC,SAAClC,GAAD,OAAOA,EAAE8Y,OAAO+H,UAAYxX,GAAWoY,GAAMzhB,EAAEyhB,KAAOA,KAKtDpY,GACAtI,KAAK2f,WAAWrX,KACftI,KAAKwf,cAAcle,MAAK,SAACrC,GAAD,OAAOA,EAAE8Y,OAAO+H,UAAYxX,OAErDtI,KAAK0f,KAAL,cAAiBpX,IACjBtI,KAAK2f,WAAWrX,IAAU,Q,kCCnNnBuZ,GAAgB,SAACxjB,EAAMyjB,GAAP,OAC3BzjB,IAASyjB,EAAMC,UAAY,aAAe,IAQ/BC,GAAoB,SAACtH,EAAGuH,GAAoC,IAAjCC,EAAiC,wDAEjEC,EAAY,CAAC,SAAU,UAAW,YAClCC,EAAO1H,EAAE2H,SAAWF,EAAU/f,QAAQsY,EAAE4H,QAAU,EAClDC,EAAON,EAAEI,SAAWF,EAAU/f,QAAQ6f,EAAEK,QAAU,EAExD,GAAIF,GAAQG,EAAM,CAChB,GAAIH,IAASG,EACX,OAAOH,GAAQ,EAAI,EAGrB,GAAI1H,EAAE4H,QAAUL,EAAEK,MAEhB,OAAOH,EAAU/f,QAAQsY,EAAE4H,OAASH,EAAU/f,QAAQ6f,EAAEK,OAI5D,IAAIE,EAAY,KACZC,EAAY,KACVrU,EAAMD,KAAKC,MAUjB,OARI8T,GACFM,EAAY,IAAIrU,KAAKuM,EAAEgI,kBAAoBhI,EAAEnG,MAAMJ,UAAY/F,EAC/DqU,EAAY,IAAItU,KAAK8T,EAAES,kBAAoBT,EAAE1N,MAAMJ,UAAY/F,IAE/DoU,EAAY,IAAIrU,KAAKuM,EAAEnG,MAAMJ,UAAY/F,EACzCqU,EAAY,IAAItU,KAAK8T,EAAE1N,MAAMJ,UAAY/F,GAGpCoU,EAAYC,GAORE,GAAgB,SAACC,GAC5B,GAAKA,EAoBL,OAjBAA,EAAQ9G,SAAS9Y,SAAQ,SAAC6f,GAExBA,EAAQC,qBAAuBD,EAAQ1G,YACnC0G,EAAQxG,gBAEVwG,EAAQE,uBAAyBF,EAAQxG,eAEvCwG,EAAQlG,eAEVkG,EAAQ1G,aAAe0G,EAAQlG,aAC3BkG,EAAQxG,gBAEVwG,EAAQxG,eAAiBwG,EAAQlG,kBAKhCiG,G,sQCvDF,IAAMI,GAAc,CACzBC,IAAK,MACLC,YAAa,cACbnB,UAAW,aAkiBEoB,G,WApgBb,aAA0B,IAAd/jB,EAAc,uDAAJ,GAAI,WACxB,IAAIgkB,EAAQ,KAGVA,EADqB,iBAAZhkB,EACDA,EAEAA,EAAQkL,IAGdlL,EAAQmI,SACV6b,EAAQ,GAAH,OAAMA,EAAN,gBAAmBhkB,EAAQmI,SAIlCvH,KAAKqjB,qBAAuB,KAG5BrjB,KAAKsjB,uBAAyB,KAG9BtjB,KAAKujB,gBAAkB,GAGvBvjB,KAAKwjB,WAAa,GAGlBxjB,KAAKyjB,OAASrkB,EAAQqkB,QAAU,GAGhCzjB,KAAK0jB,KAAO,IAAInE,GAAmB6D,GACnCpjB,KAAK0jB,KAAKpD,cAAclhB,EAAQukB,YAAc,aAE1CvkB,EAAQwkB,MACV5jB,KAAK0jB,KAAKlD,QAAQphB,EAAQwkB,M,yDAapB9D,EAAS+D,EAAWC,GAAwB,IAAfnC,EAAe,wDACpD3hB,KAAK0jB,KAAKjD,UAAU,CAAEX,WAAW+D,EAAWC,EAASnC,K,kCAW3C7B,GAA0B,IAAjBiE,EAAiB,uDAAR,GAAIrD,EAAI,uCACpC1gB,KAAK0jB,KAAKM,YAAV,UACKlE,GADL,OACe+B,GAAcmB,GAAYjB,UAAWiB,KADpD,OACmEe,GACjErD,GAEF1gB,KAAK0jB,KAAKM,YAAV,UACKlE,GADL,OACe+B,GACXmB,GAAYE,YACZF,KAHJ,OAIMe,GACJrD,K,uCAYauD,GAAyC,IAA9B/B,EAA8B,wDAClDgC,EAAatmB,OAAOua,KAAK8L,GAAWvjB,KAAI,SAACyjB,GAAD,OAAOF,EAAUE,MAC/DD,EAAWzW,MAAK,SAACiN,EAAGuH,GAAJ,OAAUD,GAAkBtH,EAAGuH,EAAGC,MAElD,IAAIkC,EAAS,IAAIjW,KACjBiW,EAAOC,WAAWD,EAAOE,aAAetkB,KAAKujB,iBAC7Ca,EAASA,EAAOjQ,UAEhB,IAAIoQ,EAAO,IAAIpW,KACfoW,EAAKF,WAAWE,EAAKD,aAAetkB,KAAKujB,iBACzCgB,EAAOA,EAAKpQ,UAMZ,IAJA,IAAMqQ,EAAiB,GACjBC,EAAoB,GACtBC,EAAoB,KAEfxnB,EAAIgnB,EAAWziB,OAAS,EAAGvE,GAAK,EAAGA,GAAK,EAAG,CAClD,IAAMM,EAAI0mB,EAAWhnB,GACfkB,EAAI,IAAI+P,KAAK3Q,EAAE+W,MAAMJ,UAGvB/V,EAAImmB,GAAQnmB,EAAIgmB,IAGF,aAAZ5mB,EAAE8kB,SAC2C,IAA3CmC,EAAkBriB,QAAQ5E,EAAEmnB,UAC9BF,EAAkBviB,KAAK1E,EAAEmnB,UAEzBnnB,EAAE8kB,MAAQ,UAOZoC,GACAlnB,EAAEonB,GAAG,KAAOF,EAAkBE,GAAG,IACjCpb,KAAKqb,IAAIzmB,EAAIsmB,EAAkBnQ,MAAQ,KACvC/W,EAAEsnB,KAAKrnB,OAASinB,EAAkBI,KAAKrnB,OAEvCD,EAAE8kB,MAAQ,UAGR,qCAAqCpQ,KAAK1U,EAAE8kB,SAC9C9kB,EAAEgV,WAAY,IAGhBkS,EAAoBlnB,GACF+W,KAAOnW,EACzBomB,EAAehjB,QAAQhE,IAI3B,OAAOgnB,I,0CAUWzI,GAAoD,WAAzCmG,EAAyC,wDAAXb,EAAW,uCACtEvkB,OAAO+jB,aAAa7gB,KAAKsjB,wBACzBtjB,KAAK+kB,wBACL/kB,KAAKqjB,qBAAuBtH,EAC5B,IAAM+D,EAAU/D,EAAY,aAAH,OAAgBA,GAAc,KACjDiJ,EAAkB,GACxBhlB,KAAKygB,UACHX,GACA,SAACrH,GACC,GAAIA,EAAKnQ,SAAWwX,EAAS,CAC3B,IAAM8C,EAAUnK,EAAKmK,SAAW,GAC1BqC,EAAQ,IAAI9W,KAAKyU,EAAQsC,WAAW/Q,UAAYhG,KAAKC,MAC3DwU,EAAQuC,SAAWF,EACnBD,EAAgBpC,EAAQwC,SAAWxC,EAEnC9lB,OAAO+jB,aAAa,EAAKyC,wBACzB,EAAKA,uBAAyBxmB,OAAOikB,YAAW,WAC9C,IAAMmD,EAAa,EAAKmB,iBACtBL,EACA9C,GAEFb,EAAU6C,KACT,SAGP,WACE7C,EAAU,S,4CASMX,GAChB1gB,KAAKqjB,uBACPrjB,KAAKgkB,YAAL,oBAA8BhkB,KAAKqjB,sBAAwB,GAAI3C,GAC/D1gB,KAAKqjB,qBAAuB,Q,2CASXhC,GACnBrhB,KAAKygB,UAAL,UAAkBzgB,KAAKyjB,OAAvB,eAA2C,SAAChL,GAC1C4I,EAAU5I,EAAKmK,c,6CAQIlC,GACrB1gB,KAAKgkB,YAAL,UAAoBhkB,KAAKyjB,OAAzB,cAA6C,GAAI/C,K,iCAUxC4E,EAAKjnB,GAAM,WACd0Z,EAAS,CACb+H,QAAS,UAAF,OAAY+B,GAAcxjB,EAAM2kB,KACvCjD,KAAMuF,GAGR,OAAO,IAAI3jB,SAAQ,SAACC,EAAS8W,GAC3B,EAAKgL,KAAK3lB,IAAIga,GAAQ,SAACU,GACjBA,EAAKmK,QACPhhB,EAAQ6W,EAAKmK,SAEblK,Y,kCAaIra,EAAMulB,GAAM,WAChB9H,EAAW,GACb8H,GACF5jB,KAAK0jB,KAAKlD,QAAQoD,GAEpB,IAAM7L,EAAS,CACb+H,QAAS,UAAF,OAAY+B,GAAcxjB,EAAM2kB,MAGzC,OADAlmB,OAAO+jB,aAAa7gB,KAAKulB,sBAClB,IAAI5jB,SAAQ,SAACC,EAAS8W,GAC3B,EAAKgL,KAAK3lB,IAAIga,GAAQ,SAACU,GACjBA,EAAKmK,SACP9G,EAAS5Z,KAAKuW,EAAKmK,SACnB9lB,OAAO+jB,aAAa,EAAK0E,sBAEzB,EAAKA,qBAAuBzoB,OAAOikB,YAAW,WAC5Cnf,EAAQka,KACP,KAEHpD,EAAOD,EAAKmK,iB,wCAcFvkB,EAAMulB,EAAMvC,GAC5BrhB,KAAKwlB,sBACD5B,GACF5jB,KAAK0jB,KAAKlD,QAAQoD,GAEpB5jB,KAAKygB,UAAL,iBAAyBoB,GAAcxjB,EAAM2kB,MAAgB,SAACvK,GACxDA,EAAKmK,SACPvB,EAAU5I,EAAKmK,c,0CASDlC,GAClB5jB,OAAO+jB,aAAa7gB,KAAKulB,sBACzBvlB,KAAKgkB,YAAY,UAAW,GAAItD,K,0CAQdW,GAAW,WAC7BrhB,KAAKygB,UAAU,eAAe,SAAChI,GAC7B,IAAMgN,EAAYhN,EAAKmK,QAEvB,GAAI6C,EAAW,KACLC,EAAQD,EAAU9lB,WAAlB+lB,IAEe,YAAnBD,EAAU3kB,KACZ,EAAK0iB,WAAWkC,GAAOD,SAEhB,EAAKjC,WAAWkC,GAGzBrE,EACEzjB,OAAOua,KAAK,EAAKqL,YAAY9iB,KAAI,SAACjC,GAAD,OAAS,EAAK+kB,WAAW/kB,a,4CAU5CiiB,GACpB1gB,KAAKgkB,YAAY,cAAe,GAAItD,K,0CASlBriB,EAAMgjB,GACxBrhB,KAAK2lB,sBAAsBtE,GAC3BrhB,KAAKygB,UAAL,oBAA4BoB,GAAcxjB,EAAM2kB,KAAgB3B,K,4CAO5CX,GACpB1gB,KAAKgkB,YAAL,aAA+B,GAAItD,K,+CASZriB,EAAMgjB,GAC7BrhB,KAAK4lB,6BACL5lB,KAAKygB,UAAL,0BACqBoB,GAAcxjB,EAAM2kB,KACvC3B,K,iDAQuBX,GACzB1gB,KAAKgkB,YAAY,mBAAoB,GAAItD,K,wCAUzBrb,EAAIhH,GAAM,WACpB0Z,EAAS,CACb+H,QAAS,kBAAF,OAAoB+B,GAAcxjB,EAAM2kB,IAAxC,YAAwD3d,IAGjE,OAAO,IAAI1D,SAAQ,SAACC,GAClB,EAAK8hB,KAAK3lB,IAAIga,GAAQ,SAACU,GACjBA,EAAKmK,SACPhhB,EAAQ6W,EAAKmK,iB,0CAaDiD,EAAKxnB,GAAM,WACvBynB,EAAWD,EAAInlB,KAAI,SAAC2E,GACxB,OAAO,EAAK0gB,kBAAkB1gB,EAAIhH,MAEpC,OAAOsD,QAAQqkB,IAAIF,K,8CASGzgB,EAAIhH,GAE1B2B,KAAKimB,0BAA0B5gB,GAC/BrF,KAAKygB,UAAL,yBACoBoB,GAAcxjB,EAAM2kB,IADxC,YACwD3d,IACtD,SAACoT,GAEC1Q,QAAQme,IAAI,4BAA6BzN,MAE3C,SAACpO,GAECtC,QAAQme,IAAI,kCAAmC7b,Q,gDAW3BhF,EAAIqb,GAC5B1gB,KAAKgkB,YAAY,kBAAjB,WAAwC3e,GAAMqb,K,sCAShCrb,GAAI,WACZ0S,EAAS,CACb+H,QAAS,gBAAF,OAAkBza,IAE3B,OAAO,IAAI1D,SAAQ,SAACC,EAAS8W,GAC3B,EAAKgL,KAAK3lB,IACRga,GACA,SAACU,GAEC7W,EAAQ+gB,GAAclK,EAAKmK,SAAWnK,EAAKmK,QAAQ,QAErD,SAACvY,GACCqO,EAAOrO,W,uCAYEwb,GAAK,WACdC,EAAWD,EAAInlB,KAAI,SAAC2E,GACxB,OAAO,EAAK8gB,gBAAgB9gB,MAE9B,OAAO1D,QAAQqkB,IAAIF,K,4CASCzgB,EAAIgc,GACxBvkB,OAAO+jB,aAAa7gB,KAAKomB,6BACzBpmB,KAAKqmB,wBAAwBhhB,GAE7BrF,KAAKygB,UAAL,uBACkBpb,IAChB,SAACoT,GAEC4I,EAAUsB,GAAclK,EAAKmK,SAAWnK,EAAKmK,QAAQ,QAEvD,SAACvY,GAECtC,QAAQme,IAAI,+BAAgC7b,Q,8CAW1BhF,EAAIqb,GAC1B1gB,KAAKgkB,YAAL,0BAAqC3e,GAAMqb,K,2CAOxBW,GACnBrhB,KAAKsmB,yBACLtmB,KAAKygB,UAAU,cAAeY,K,+CAO9BrhB,KAAKgkB,YAAY,oB,03ECxhBd,IA2hBQuC,GApYY,SAACpQ,GAAD,oB,mOAAA,6HAON/W,GAAS,WACxB,sDAAuBA,GADC,IAUpBonB,EAPFC,EAIErnB,EAJFqnB,uBACAC,EAGEtnB,EAHFsnB,kBACAC,EAEEvnB,EAFFunB,WACAhM,EACEvb,EADFub,SAGEiM,EAAyB,EAE7B,IAAKxnB,EAAQynB,IAAK,CAChB,IAAMC,EAAa,GACf1nB,EAAQkL,MACVwc,EAAWxc,IAAMlL,EAAQkL,KAEvBlL,EAAQmI,SACVuf,EAAWvf,OAASnI,EAAQmI,QAE9Bif,EAAa,IAAIlH,GAAYwH,GAE/BlpB,OAAOyB,iBAAiBW,KAAM,CAC5B+mB,gBAAiB,CACf5oB,WAC8BsC,IAA5BrB,EAAQ2nB,iBACJ3nB,EAAQ2nB,gBAEd5mB,UAAU,GAEZ6mB,aAAc,CACZ7oB,MAAOiB,EAAQ4nB,cAAgB,IAC/B7mB,UAAU,GAEZ8mB,kBAAmB,CACjB9oB,MAAOiB,EAAQ6nB,mBAAqB,UACpC9mB,UAAU,GAEZ+mB,cAAe,CACb/oB,MAAOiB,EAAQ8nB,gBAAiB,EAChC/mB,UAAU,GAEZymB,uBAAwB,CACtB7oB,IAAK,WACH,OAAO6oB,GAETxmB,IAAK,SAAC+mB,GACAA,IAA8BP,IAChCA,EAAyBO,EACrB,EAAKznB,SAEP,EAAK4P,WAKboX,kBAAmB,CACjB3oB,IAAK,WACH,OAAO2oB,GAETtmB,IAAK,SAACgnB,GACJV,EAAoBU,EACpB,EAAKC,kBAGTV,WAAY,CACV5oB,IAAK,WACH,OAAO4oB,GAETvmB,IAAK,SAACknB,GACJX,EAAaW,EACb,EAAKD,kBAGT1M,SAAU,CACR5c,IAAK,WACH,OAAO4c,GAETva,IAAK,SAACmnB,GACJ5M,EAAW4M,EACX,EAAKF,kBAGTZ,uBAAwB,CACtB1oB,IAAK,WACH,OAAO0oB,GAETrmB,IAAK,SAAConB,GACJf,EAAyBe,EACzB,EAAKH,kBAGTR,IAAK,CACH1oB,MAAOiB,EAAQynB,KAAOL,OAnGL,2BAwGlB9lB,GACH,0CAAWA,GAGPV,KAAKynB,OACPznB,KAAKyN,KAAOzN,KAAKynB,OACRznB,KAAKknB,gBAEdlnB,KAAKyN,KAAO,SAACiN,EAAGuH,GACd,OAAgB,OAAZvH,EAAEsE,OACCtE,EAAEsE,MAAQiD,EAAEjD,MADU,GACG,MAlHf,8BAwHrBhf,KAAKqnB,gBACL,4CACArnB,KAAK0nB,4BA1HgB,6BA8HrB1nB,KAAK2nB,UAAY,KACjB3nB,KAAK4nB,yBACL5nB,KAAK6nB,yBACL,6CAjIqB,sCAsIrB,IAAMC,EAAangB,KAAG4Z,MAAMzkB,OAAOirB,SAASC,OAAO/nB,eAEnDD,KAAKmB,OAvMW,SAAC2jB,EAAMmD,EAAOtN,EAAUuN,GAC5C,IAAMC,EAAa,GAEnB,KAAKrD,GAASmD,GAAUtN,GAAauN,GACnC,OAAO,KAGT,GAAIA,EAAW,CACb,IAAME,EACiB,iBAAdF,EAAyB,CAACA,GAAaA,EAGhDC,EAAWjmB,MAFQ,SAAC9D,GAAD,OACjBgqB,EAAcC,MAAK,SAACC,GAAD,OAAQ,IAAIrW,OAAOqW,EAAI,KAAKpW,KAAK9T,EAAEX,YAI1D,GAAIqnB,EAAM,CACR,IACMyD,GADkC,iBAATzD,EAAoBA,EAAKtc,MAAM,KAAOsc,GACpCpkB,KAAI,SAACvD,GAAD,OACnCA,EAAEoL,QAAQ,OAAQ,IAAIigB,iBAIxBL,EAAWjmB,MAFQ,SAAC/E,GAAD,OACjBorB,EAASF,MAAK,SAAClnB,GAAD,OAAYA,IAAWhE,EAAEM,KAAK+qB,oBAIhD,GAAIP,EAAO,CACT,IACMQ,GAD0B,iBAAVR,EAAqBA,EAAMzf,MAAM,KAAOyf,GACrCvnB,KAAI,SAACgoB,GAAD,OAAUC,SAASD,EAAM,OAKtDP,EAAWjmB,MAJS,SAACwmB,GACnB,IAAME,EAAUD,SAASD,EAAKrO,gBAAgB7R,MAAM,KAAK,GAAI,IAC7D,OAAOigB,EAAUJ,MAAK,SAAChjB,GAAD,OAAQA,IAAOujB,QAKzC,GAAIjO,EAAU,CACZ,IAAMkO,EAAmC,iBAAblO,EAAwB,CAACA,GAAYA,EAGjEwN,EAAWjmB,MAFY,SAAC9D,GAAD,OACrByqB,EAAaR,MAAK,SAACS,GAAD,OAAQ,IAAI7W,OAAO6W,EAAI,KAAK5W,KAAK9T,EAAEuc,gBAIzD,OAAKwN,EAAW1mB,OAIT,SAACrD,GACN,IAAK,IAAIlB,EAAI,EAAGA,EAAIirB,EAAW1mB,OAAQvE,GAAK,EAC1C,IAAKirB,EAAWjrB,GAAGkB,GACjB,OAAO,EAGX,OAAO,GATA,KA4JS2qB,CACZ/oB,KAAK0mB,mBAAqBoB,EAAU,kBACpC9nB,KAAK2mB,YAAcmB,EAAU,WAC7B9nB,KAAK2a,UAAYmN,EAAU,SAC3B9nB,KAAKymB,0BA5Ic,+CAiJjBzmB,KAAK4Y,iBACP5Y,KAAK4Y,gBAAgBoQ,UAlJF,+CAsJEC,GACvB,IAAMlR,EAAS/X,KAAKkpB,UAAU,CAC5B7jB,GAAI4jB,EACJ1U,KAAMgD,GAAiB,IAAIpJ,QAE7B,OAAOnO,KAAK6mB,IAAIsC,wBAAwBpR,KA3JnB,kCA8JK,IAAlBqR,EAAkB,uDAAJ,GAEhBC,EAA0D,KAAnCrpB,KAAK4mB,uBAAyB,GACrD0C,EAAatpB,KAAK6S,MAAQwW,EAC1Bjb,EAAMpO,KAAKkO,SAEbqb,GAAO,EASX,GANEvpB,KAAKwpB,OACLpb,EAAI+F,UACFnU,KAAKwpB,MAAMrV,UAA0C,IAA9BnU,KAAK4mB,yBAE9B2C,GAAO,IAGNvpB,KAAKwpB,QACLD,GACDvpB,KAAKwpB,MAAMrV,UAAY/F,EAAI+F,UAAYmV,EACvC,CACA,IAAME,EAAQ,IAAIrb,KAAKC,EAAI+F,UAAYmV,GACvCtpB,KAAKwpB,MAAQA,EAGf,IAAMzR,EAAS,SACVqR,GADO,IAEVK,MAAOlS,GAAiBnJ,GACxBsb,MAAOnS,GAAiBvX,KAAKwpB,OAC7BhS,KAAMP,GAAiB7I,GACvBkM,IAAK,EACLI,EAAG,EACHiP,GAAI,EACJC,GAAI,EACJC,GAAI,IAUN,OAAO9R,IAzMc,gDA4MG,WACxB/X,KAAK4nB,yBAEL5nB,KAAK8pB,qBACL9pB,KAAK+pB,eAAiBjtB,OAAOmX,aAAY,WACvC,EAAK6V,uBAC0B,IAA9B9pB,KAAK4mB,0BAlNa,+CAsNrBtS,cAActU,KAAK+pB,kBAtNE,2CAyNF,WACnB/pB,KAAK6nB,yBACL7nB,KAAK4Y,gBAAkB,IAAIoR,gBAC3BhqB,KAAK6mB,IACFoD,kBACCjqB,KAAKkpB,UAAU,CACbgB,SAAU,IAEZlqB,KAAK4Y,iBAENuR,OAAM,SAAC9f,GACN,GAAiB,eAAbA,EAAI5M,KAIR,MAAM4M,KAEPiO,MAAK,SAACxL,GAEDA,IACF,EAAKmG,QAAQmX,gBAAgBtd,GAC7B,EAAK+G,2BA9OU,mCAmPVJ,EAAO9J,GAAM,IAEtB7I,EAQE2S,EARF3S,KACArD,EAOEgW,EAPFhW,KACA4H,EAMEoO,EANFpO,GACAwW,EAKEpI,EALFoI,MACAsD,EAIE1L,EAJF0L,UACAH,EAGEvL,EAHFuL,MACAxM,EAEEiB,EAFFjB,UACAoM,EACEnL,EADFmL,yBAEI/H,EAAIrN,KAAKyG,IAAIzG,KAAKqH,MAAMlH,GAAQ,GAAI,IACpC0gB,EAAQrqB,KAAKiN,iBAAmB5H,EAChCilB,EAAWtqB,KAAKkN,oBAAsB7H,EACtC5G,EAAM,GAAH,OAAMoY,GAAN,OAAU/V,GAAV,OAAiBrD,GAAjB,OAAwBmhB,GAAxB,OAAmDI,GAAnD,OAA2DqL,GAA3D,OAAmEC,GAAnE,OAA8E9X,GAEvF,IAAKxS,KAAKoT,WAAW3U,GAAM,CACzB,IAAI8rB,EX/Ua,WAAoB,IAAnBzpB,EAAmB,uDAAZ,EAAG6I,EAAS,uCAC3C,IACE,IAAMyI,EAAUL,GAAajR,GAC7B,OAAOkQ,GAAqBoB,GAASzI,GACrC,MAAO0I,GACP,OAAO,GW0UUmY,CAAU1pB,EAAM+V,GACvB4T,EAA0BF,GAAU,EAE1C,GAAe,IAAXA,EAEF,OADAvqB,KAAKoT,WAAW3U,GAAO,KAChB,MAGL4rB,GAASC,KACXC,EAASE,EAA0BF,EAAS,EAAI,IAElD,IACMG,EAAcH,EAAS,EACvBI,EAAsB,EAATJ,EAEbxhB,EAAS5D,SAASC,cAAc,UAEtC2D,EAAOqE,MAAsB,EAAdsd,EAAkBE,EAAa,IAC9C7hB,EAAOsE,OAAuB,EAAdqd,EAAkBE,EAAa,IAC/C,IAsCIC,EAtCEpV,EAAM1M,EAAOwE,WAAW,MACxBud,EAAS/hB,EAAOqE,MAAQ,EAc9B,GAZIqd,GAAqC,OAAVzL,IAE7BvJ,EAAIsV,OACJtV,EAAIuV,YACJvV,EAAIC,IAAIoV,EAAQA,EAAQJ,EAAa,EAAG,EAAIlhB,KAAKC,IAAI,GACrDgM,EAAIE,UAAYrD,GAAc0M,EAAOxM,GACrCiD,EAAItU,OAAS,YACbsU,EAAIG,OACJH,EAAIwV,WAKJR,IACCJ,GAASrL,GAAShf,KAAKgnB,cAAgBxU,GACxC,CAEAiD,EAAIsV,OACJtV,EAAIyV,UAAY,OAChBzV,EAAI0V,aAAe,SACnB1V,EAAIO,KAAJ,eAAmBxM,KAAK+L,IACtB/C,EAAY,GAAK,GACjBhJ,KAAKyG,IAAIuC,EAAY,GAAK,GAAa,IAAT+X,IAFhC,wBAIA9U,EAAIE,UAAYrD,GAAc0M,EAAOxM,GAAW,GAEhDiD,EAAIK,YAAc9V,KAAKinB,kBACvBxR,EAAII,UAAY,IAChB,IAAMuV,EX7SY,SAAC7Y,EAAWC,GACtC,GAAIA,EACF,OAAO6Y,OAAOC,cAAc,KAE9B,GAAI/Y,EAAY,KAAS,CACvB,IAAMgZ,EAAU/hB,KAAK6L,MAAM9C,EAAY,MACvC,iBAAWgZ,EAAX,KAGF,GAAIhZ,EAAY,KAAO,CACrB,IAAMgZ,EAAU/hB,KAAK6L,MAAM9C,EAAY,KACvC,iBAAWgZ,EAAX,KAGF,OAAIhZ,EAAY,EACd,WAAWA,EAAX,KAGK,GW2RmBiZ,CAAaxM,EAAOxM,GACtCiD,EAAIQ,WAAWmV,EAAWN,EAASJ,EAxCtB,EAwC4CI,GACzDrV,EAAIS,SAASkV,EAAWN,EAASJ,EAzCpB,EAyC0CI,GACvDrV,EAAIwV,UAmCN,GA7BEJ,EADE7qB,KAAKknB,cACW5U,GAAc0M,EAAOxM,GAErBqJ,GAAS1J,GAAWrR,GAGxC2U,EAAIsV,QACAN,GAA2BJ,GAASC,KACtC7U,EAAII,UAAY,EAChBJ,EAAIK,YAAc,WAEpBL,EAAIE,UAAYkV,EAChBpV,EAAIuV,YACJvV,EAAIC,IAAIoV,EAAQA,EAAQP,EAAQ,EAAG,EAAI/gB,KAAKC,IAAI,GAChDgM,EAAIG,OAGF6U,GACAzqB,KAAKknB,eACK,OAAVlI,GAC6B,QAA7BJ,GAEAnJ,EAAIgW,YAAY,CAAC,EAAG,KAElBhB,GAA2BJ,GAASC,IACtC7U,EAAIM,SAENN,EAAIwV,UAGAV,EAAS,GAAI,CACf,IACMmB,EXrYW,SAACjW,EAAKkV,EAAYnV,EAAM9P,GACjD+P,EAAIO,KAAJ,eAAmBtQ,EAAnB,YAMA,IALA,IAAIimB,EAAUlW,EAAImW,YAAYpW,GAG1BtY,EAAI,EAEDyuB,EAAQve,MAAQud,EAAa,GAAKztB,EAHzB,IAKdwI,GAAY,GACZ+P,EAAIO,KAAJ,eAAmBtQ,EAAnB,wBACAimB,EAAUlW,EAAImW,YAAYpW,GAC1BtY,GAAK,EAEP,OAAOwI,EWuXkBmmB,CAAYpW,EAAKkV,EAAYltB,EAD7B+L,KAAK+L,IAAIgV,EAAQ,KAKhCvqB,KAAKknB,eACK,OAAVlI,GAC6B,QAA7BJ,IAEAnJ,EAAIsV,OACJtV,EAAI0V,aAAe,SACnB1V,EAAIyV,UAAY,SAChBzV,EAAIO,KAAJ,eAAmB0V,EAAW,EAA9B,YACAjW,EAAIK,YAAc+U,EAClBpV,EAAIQ,WAAWxY,EAAMqtB,EAAQA,GAC7BrV,EAAIwV,WAINxV,EAAIsV,OACJtV,EAAI0V,aAAe,SACnB1V,EAAIyV,UAAY,SAChBzV,EAAIE,UAAa3V,KAAKknB,cAElB,UADA/H,GXvac,WAAc,IAAbre,EAAa,uDAAN,EAClC,IACE,IAAMsR,EAAUL,GAAajR,GAC7B,OAAO+Q,GAAWO,GAClB,MAAOC,GACP,OAAO,GWkagByZ,CAAahrB,GAE9B2U,EAAIO,KAAJ,eAAmB0V,EAAnB,YACAjW,EAAIK,YAAc+U,EAClBpV,EAAIQ,WAAWxY,EAAMqtB,EAAQA,GAC7BrV,EAAIS,SAASzY,EAAMqtB,EAAQA,GAC3BrV,EAAIwV,UAGNjrB,KAAKoT,WAAW3U,GAAOsK,EAGzB,OAAO/I,KAAKoT,WAAW3U,OAhYF,GACX0X,I,8jHCuHD4V,G,wQA1Qb,aAA0B,MAAd3sB,EAAc,uDAAJ,GAAI,mBAGxB,oBACKA,KAIA4sB,YAAc,IAAIC,UAAY,CACjC3jB,OAAQ,IAAI4jB,UAAa,CAAErqB,SAAU,OAEvC,EAAKS,QAAQG,YAAY0pB,SAAS,EAAG,EAAKH,aAXlB,E,0CAmBrBtrB,GACEA,IAILA,EAAIiE,SAAS3E,KAAKgsB,aAClB,0CAAWtrB,M,kCAQPV,KAAKU,KACPV,KAAKU,IAAI0rB,YAAYpsB,KAAKgsB,aAE5B,kD,8BAQKhsB,KAAKU,MAGV,4CAKAV,KAAK+Q,aAAL,aACK/Q,KAAK+Q,cADV,CAEE/Q,KAAKU,IAAIgC,GAAG,cAAe1C,KAAKqsB,WAAW3tB,KAAKsB,OAChDA,KAAKU,IAAIgC,GAAG,UAAW1C,KAAKssB,UAAU5tB,KAAKsB,Y,kCAS7CA,KAAK8pB,qBACD9pB,KAAKkN,mBAAqBlN,KAAK2nB,WACjC3nB,KAAKusB,wB,iCASE5pB,GAAK,WACd,GAAK3C,KAAKW,eAAec,OAAzB,CADc,IAKPqV,EALO,GAKI9W,KAAK+W,wBAAwBpU,EAAIb,WAAY,GALjD,MAMRD,EAAW,GAEjB,GAAIiV,EAAS,CACX,IAAM0V,EAAO1V,EAAQhV,WAAa,IAAI2qB,SAAM3V,EAAQhV,YAAc,KAClED,EAASK,KAAK,IAAIwqB,KAAJ,IAAcxd,SAAUsd,GAAS1V,KAE3CjV,EAASJ,SAKXzB,KAAKkN,kBAAoBrL,EAAS,GAAG9D,IAAI,MAEzCiC,KAAK2nB,UAAY9lB,EAAS,GAAG9D,IAAI,qBACjCiC,KAAK2sB,yBAAyB3sB,KAAKkN,mBAAmBoL,MACpD,SAACsU,GACC,EAAKjsB,eAAeqC,SAAQ,SAACjB,GAAD,OAC1BA,EAAS,SAAK+U,GAAY8V,GAAgB,EAAMjqB,eAMxD3C,KAAKkN,kBAAoB,KACzBlN,KAAKgsB,YAAY/oB,YAAYsL,QAC7BvO,KAAKW,eAAeqC,SAAQ,SAACjB,GAAD,OAAcA,EAAS,KAAM,EAAMY,S,yCAWhDkqB,EAAgBC,EAAcjR,GAE/C,IAAMkR,EAAgB,WAAW7a,KAAK2J,GAAS,UAAYA,EACrDmR,EAAehtB,KAAKgsB,YAAY/oB,YAGtC,GAFA+pB,EAAaze,QAETse,EAAgB,CAClB,IAAM3d,EAAW,IAAI+d,cAAWJ,GAC1BK,EAAuB,IAAIR,KAAQxd,GACzCge,EAAqB1Z,SACnB,IAAI2Z,SAAM,CACRC,OAAQ,EACRC,MAAO,IAAIC,UAAO,CAChB/C,OAAQ,EACR3U,KAAM,IAAI2X,QAAK,CACb1R,MAAO,iBAKf,IAAM2R,EAAuB,IAAId,KAAQxd,GACzCse,EAAqBha,SACnB,IAAI2Z,SAAM,CACRC,OAAQ,EACRC,MAAO,IAAIC,UAAO,CAChB/C,OAAQ,EACR3U,KAAM,IAAI2X,QAAK,CACb1R,MAAO7b,KAAKknB,cAAgB,UAAY6F,SAKhDC,EAAaS,YAAY,CAACP,EAAsBM,IAGlD,IAAME,EAAW,IAAIhB,KAAQ,CAC3Bxd,SAAU4d,IAEZY,EAASla,SAAS,CAChB,IAAI2Z,SAAM,CACRC,OAAQ,EACRrX,OAAQ,IAAI4X,UAAO,CACjB9R,MAAO,UACPzO,MAAO,MAGX,IAAI+f,SAAM,CACRC,OAAQ,EACRrX,OAAQ,IAAI4X,UAAO,CACjB9R,MAAO7b,KAAKknB,cAAgB,UAAY6F,EACxC3f,MAAO,QAIb4f,EAAaY,WAAWF,K,+CASDzE,GAAQ,WAC/B,OAAO,8DAA+BA,GAAQ3Q,MAAK,SAACsU,GAalD,OARA,EAAKC,eAAiB,GACtBD,EAAa9Q,SAAS9Y,SAAQ,SAAC6f,GAC7B,EAAKgK,eAAe3qB,KAClB2rB,qBAAgBhL,EAAQ3G,YAAa,YAAa,iBAItD,EAAKqQ,sBACEK,O,4CAQW,WACpB5sB,KAAK6mB,IACFiH,oBACC9tB,KAAKkpB,UAAU,CACb7jB,GAAIrF,KAAK2nB,UACTpT,KAAMgD,GAAiB,IAAIpJ,SAG9BmK,MAAK,SAACrJ,GAAS,IACH8e,EAAoB9e,EAAvBjQ,EAAcZ,EAAS6Q,EAAT7Q,EAAGb,EAAM0R,EAAN1R,EACnBywB,EAAa,GACnBD,EAAU/qB,SAAQ,SAAC8hB,GACjBA,EAAK9hB,SAAQ,SAACirB,GACZD,EAAW9rB,KAAK,CAAC+rB,EAAMjjB,EAAGijB,EAAMhjB,UAIpC,EAAKijB,mBACH,EAAKrB,eACL,IAAIvP,cAAW0Q,GACfzwB,EAAI,IAAH,OAAOA,GAAM4U,GAAW/T,OAG5B+rB,OAAM,WACL,EAAK6B,YAAY/oB,YAAYsL,a,kCAWP,IAAlB6a,EAAkB,uDAAJ,GAChBpU,EAAMhV,KAAKU,IAAIiK,UAAUwjB,kBACzBvK,EAAO3O,kBAAOD,EAAKoZ,oBAASpZ,GAAO,IAAI9P,KAAK,KAC5CyE,EAAO3J,KAAKU,IAAIiK,UAAUiM,UAEhC,+DACKwS,GADL,IAEExF,OACA3kB,EAAG0K,EAAO,GAAK,EAAI,EACnBkN,EAAGlN,O,mCAKM8J,GACX,IAAM9J,EAAO3J,KAAKU,IAAIiK,UAAUiM,UAChC,yDAA0BnD,EAAO9J,K,4BAQ7BvG,GACJ,OAAO,IAAI2oB,EAAJ,SAAuB/rB,KAAKZ,SAAYgE,S,gCAvQvB2D,GAAMoP,K,i3EClB3B,IA+LQkY,GA5HU,SAAClY,GAAD,oB,mOAAA,kBAErB,aAA0B,MAAd/W,EAAc,uDAAJ,GAAI,mBACxB,oBAAWA,KACNkvB,MAAQlvB,EAAQkvB,MACrB,EAAKjwB,KAAOe,EAAQf,MAAQ2kB,GAAYE,YACxC,EAAKpW,aAAe,GACpB,EAAKyhB,gBAAkB,IAAO,GAC9B,EAAKlN,UAAY,EAAKA,UAAU3iB,KAAf,OACjB,EAAK8vB,gBAAkB,EAAKA,gBAAgB9vB,KAArB,OACvB,EAAKmoB,IAAMznB,EAAQynB,KAAO,IAAI1D,GAAU/jB,GACxC,EAAKoL,OAAS,IAAIC,KAIlB,EAAKgkB,cAAgBrvB,EAAQqvB,eAAiB,GAC9C,EAAKC,uBAAyBtvB,EAAQsvB,wBAA0B,GAChE,EAAKC,aAAoC,IAArB,EAAKF,cAfD,EAFL,wCAoBhB/tB,GACH,0CAAWA,GACXV,KAAK6mB,IAAI+H,oBAAoB5uB,KAAK3B,KAAM2B,KAAKqhB,WAC7CrhB,KAAK6mB,IAAIgI,yBAAyB7uB,KAAK3B,KAAM2B,KAAKwuB,mBAvB/B,kCA2BnBxuB,KAAK6mB,IAAIlB,sBAAsB3lB,KAAKqhB,WACpCrhB,KAAK6mB,IAAIjB,2BAA2B5lB,KAAKwuB,iBACzC,kDA7BmB,8BAgCbnwB,GACF2B,KAAK3B,OAASA,IAGlB2B,KAAK3B,KAAOA,EACZ2B,KAAK6mB,IAAI+H,oBAAoB5uB,KAAK3B,KAAM2B,KAAKqhB,WAC7CrhB,KAAK6mB,IAAIgI,yBAAyB7uB,KAAK3B,KAAM2B,KAAKwuB,oBAtC/B,gCAyCX/V,GACR,GAAKA,EAAKmK,QAAV,CAGA,IAAMkM,EAAO9uB,KAAKwK,OAAO+B,YAAYkM,EAAKmK,SAK1C,GAHAkM,EAAK1uB,IAAI,aAAc+N,KAAKC,MAAQqK,EAAKyM,WAGrC4J,EAAK/wB,IAAI,sBAAwB,EAAG,CACtC,GACEiC,KAAKsuB,OACLtuB,KAAK3B,OAAS2kB,GAAYE,aAC1B4L,EAAK/wB,IAAI,mBACT,CACA,IAAMkwB,EAAQ,IAAIxB,KAAMqC,EAAK/wB,IAAI,oBACjCkwB,EAAMc,UAAU,YAAa/uB,KAAKU,IAAIiK,UAAUC,iBAChDkkB,EAAKE,YAAYf,GAGnBjuB,KAAKivB,cACHH,EAAK/wB,IAAI,YACT+wB,EAAKI,iBACJJ,EAAK/wB,IAAI,aAhEK,sCAqEL0a,GACVA,EAAKmK,SACP5iB,KAAKmvB,4BAA4B,WAAY1W,EAAKmK,WAvEjC,oCA2EPvd,EAAI4J,EAAMmgB,GACtB,IAAMjtB,EAAMnC,KAAK8M,aAAauiB,WAAU,SAACjxB,GAAD,OAAOA,EAAEkxB,WAAajqB,KACtC8J,EAAkBF,EAAlCsgB,eAGFC,EAAa,SAAKvgB,GAAR,IAAc5J,KAAI8J,kBAC9BigB,GACFpvB,KAAK8M,aAAatL,QAAQguB,IACb,IAATrtB,GACFnC,KAAKiT,QAAQnG,aAAapL,OAAOS,EAAM,EAAG,KAG5CnC,KAAK8M,aAAa5K,KAAKstB,IACV,IAATrtB,GACFnC,KAAKiT,QAAQnG,aAAapL,OAAOS,EAAK,IAI1CnC,KAAK8pB,uBA7Fc,uCAgGJzkB,GACf,IAAK,IAAInI,EAAI,EAAGuyB,EAAMzvB,KAAK8M,aAAarL,OAAQvE,EAAIuyB,EAAKvyB,GAAK,EAC5D,GAAI8C,KAAK8M,aAAa5P,GAAGmI,KAAOA,EAAI,CAClCrF,KAAK8M,aAAapL,OAAOxE,EAAG,GAC5B,SApGe,kDAyGOwyB,EAAevxB,GACzC,IAAK,IAAIjB,EAAI,EAAGuyB,EAAMzvB,KAAK8M,aAAarL,OAAQvE,EAAIuyB,EAAKvyB,GAAK,EAC5D,GAAI8C,KAAK8M,aAAa5P,GAAGwyB,KAAmBvxB,EAAO,CACjD6B,KAAK2vB,iBAAiB3vB,KAAK8M,aAAa5P,GAAGmI,IAC3C,SA7Ge,2CAmHnBrF,KAAKiT,QAAQmX,gBAAgBpqB,KAAK8M,cAClC9M,KAAK6T,uBApHc,2CAwHnB,OAAO7T,KAAKuuB,oBAxHO,GACTpY,I,s/DCjDDyZ,G,0WALPxsB,GACJ,OAAO,IAAIwsB,EAAJ,SAAqB5vB,KAAKZ,SAAYgE,S,gCAPvB2D,GAAMoP,K,gyECsFjB8V,G,wQA3Fb,aAA0B,MAAd7sB,EAAc,uDAAJ,GAAI,mBACxB,cAAMA,IAGDywB,aAAezwB,EAAQywB,cAAgB,EAJpB,E,gEAcC/tB,GAAY,WACjCD,EAAW,GAEf,GAAI7B,KAAKU,IAAK,CACZ,IAAMwL,EAAQlM,KAAKU,IAAIsM,uBAAuBlL,GAC9CD,EAAW7B,KAAKU,IAAIovB,mBAAmB5jB,EAAO,CAC5C6jB,YAAa,SAAC5yB,GAAD,OAAOA,IAAM,EAAKmF,SAC/ButB,aAAc7vB,KAAK6vB,eAIvB,OAAOluB,QAAQC,QAAQ,CACrBC,WACAN,MAAOvB,KACP8B,iB,2BAQCpB,GAAK,WACR,0CAAWA,GAENV,KAAKU,MASVV,KAAKgwB,eAAiBhwB,KAAKU,IAAIgC,GAAG,eAAe,SAAC2P,GAC3C,EAAK1R,eAAec,QAIzB,EAAKwuB,2BAA2B5d,EAAEvQ,YAC/BwW,MAAK,SAAC9a,GAAD,OAAO,EAAK0yB,mBAAmB1yB,EAAEqE,SAAUrE,EAAE+D,MAAO/D,EAAEsE,eAC3DqoB,OAAM,kBAAM,EAAK+F,mBAAmB,GAAI,EAAM7d,EAAEvQ,qB,yCAYpCD,EAAUN,EAAOO,GAClC9B,KAAKW,eAAeqC,SAAQ,SAACzF,GAAD,OAAOA,EAAEsE,EAAUN,EAAOO,Q,kCAOtD,gDACI9B,KAAKgwB,gBACP7sB,kBAAQnD,KAAKgwB,kB,4BASX5sB,GACJ,OAAO,IAAI6oB,EAAJ,SAAqBjsB,KAAKZ,SAAYgE,S,gCA9FvBjE,G,gyEC0HXgxB,G,wQArHb,aAA0B,MAAd/wB,EAAc,uDAAJ,GAAI,mBACxB,cAAMA,IAGDwZ,gBAAkB,IAAIoR,gBAE3B,EAAKxf,OAAS,IAAIC,KANM,E,uDAcR4E,GAChB,IAAMsU,EAAa3jB,KAAKU,IAAIiK,UAAUC,gBAChCyD,EAAarO,KAAKU,IAAIiK,UAAU6L,gBAEtC,QAAIxW,KAAKsC,QAAQW,YAAYmtB,mBACpBpwB,KAAKsC,QACTW,YACAmtB,kBAAkB/gB,EAAOhB,EAAYsV,EAAY,CAChD0M,YAAa,mBACbC,aAActwB,KAAKsC,QAAQW,YAAYimB,YAAY7kB,W,iDAahCvC,GAAY,WACrC9B,KAAK4Y,gBAAgBoQ,QACrBhpB,KAAK4Y,gBAAkB,IAAIoR,gBAFU,IAG7BnR,EAAW7Y,KAAK4Y,gBAAhBC,OACR,OAAOT,MAAMpY,KAAKowB,kBAAkBtuB,GAAa,CAAE+W,WAChDP,MAAK,SAACiY,GAAD,OAAUA,EAAK/X,UACpBF,MAAK,SAACta,GAAD,OAAOA,EAAE6D,YACdyW,MAAK,SAACG,GAAD,MAAW,CACflX,MAAO,EACPO,aACAD,SAAU4W,EAAK/X,KAAI,SAAClD,GAAD,OAAO,EAAKgN,OAAO+B,YAAY/O,UAEnD2sB,OAAM,kBAELxoB,QAAQC,QAAQ,CACdC,SAAU,GACVC,aACAP,MAAO,S,2BASVb,GAAK,WACR,0CAAWA,GAENV,KAAKU,MASVV,KAAKgwB,eAAiBhwB,KAAKU,IAAIgC,GAAG,eAAe,SAAC2P,GAC3C,EAAK1R,eAAec,QAIzB,EAAKwuB,2BAA2B5d,EAAEvQ,YAAYwW,MAAK,SAACG,GAAD,OACjD,EAAKyX,mBAAmBzX,EAAK5W,SAAU4W,EAAKlX,MAAOkX,EAAK3W,qB,yCAa3CD,EAAUN,EAAOO,GAClC9B,KAAKW,eAAeqC,SAAQ,SAACzF,GAAD,OAAOA,EAAEsE,EAAUN,EAAOO,Q,kCAOtD,gDACI9B,KAAKgwB,gBACP7sB,kBAAQnD,KAAKgwB,kB,4BASX5sB,GACJ,OAAO,IAAI+sB,EAAJ,SAAkBnwB,KAAKZ,SAAYgE,S,gCArHvBjE,G,61GCiCFiF,GCjBiBd,EDiBlB,IAACc,G,ygDEWNiC,G,wQA5Bb,WAAYjH,GAAS,a,4FAAA,UACnB,cAAMA,IACDoE,OAAS,EAAKA,OAAO9E,KAAZ,OAFK,E,gDAMnB,+CACIsB,KAAKU,MACPV,KAAKU,IAAIgC,GAAG,aAAc1C,KAAKwD,QAC/BxD,KAAKU,IAAIgC,GAAG,YAAa1C,KAAKwD,QAC9BxD,KAAKU,IAAIgC,GAAG,OAAQ1C,KAAKwD,W,mCAKvBxD,KAAKU,MACPV,KAAKU,IAAI8L,IAAI,aAAcxM,KAAKwD,QAChCxD,KAAKU,IAAI8L,IAAI,YAAaxM,KAAKwD,QAC/BxD,KAAKU,IAAI8L,IAAI,OAAQxM,KAAKwD,SAE5B,mD,sCAIA,OAAOyE,GAAuBjI,KAAKU,U,gCAzBRqG,GAAMzD,I,qqECZnByD,GAAMypB,Q,+uBCJjB,IAAMha,GAAgB,SAAC9V,GAC5B,IAAM+vB,EAAS/vB,EAAIgwB,YAAYC,UACzBC,EAAS,GAAH,UAAOC,sBAAWJ,EAAO,KAAzB,GAAiCI,sBAAWJ,EAAO,MAF3B,EAGV/vB,EAAIsI,YAAtBoE,EAH4B,EAG5BA,MAAOC,EAHqB,EAGrBA,OACTyjB,EAAc1C,oBAASwC,GAAUxjB,EACjC2jB,EAAcC,qBAAUJ,GAAUvjB,EACxC,OAAO7D,KAAK+L,IAAIub,EAAaC,IAQlBE,GAAuB,SAACvwB,GACnC,IAAM+vB,EAAS/vB,EAAIgwB,YAAYC,UAC/B,MAAO,CACL,CAACF,EAAO,GAAG,GAAIA,EAAO,GAAG,IADpB,GAEDA,EAAO,IACX,CAACA,EAAO,GAAG,GAAIA,EAAO,GAAG,IAHpB,GAIDA,EAAO,M,gvGC6IAta,G,wQA7Jb,aAA0B,MAAd/W,EAAc,uDAAJ,GAAI,mBACxB,oBACKA,KAIA8xB,aAAe,EAAKA,aAAaxyB,KAAlB,OAEpB,EAAKyyB,eAAiB,EAAKA,eAAezyB,KAApB,OARE,E,qDAeVqK,GACd/I,KAAKiT,QAAQme,aAAaroB,EAAOqE,MAAQrE,EAAOsoB,e,2BAS7C3wB,GAAK,WACR,GAAKA,EAAL,CAIA,IAAMqI,EAASrI,EAAIsI,YACbmE,EAAYpE,EAAOqE,MAAQrE,EAAOsoB,YACxC3wB,EAAIgC,GAAG,SAAU1C,KAAKsxB,gBAAgB5yB,KAAKsB,KAAM+I,IAEjD,0CAAWrI,EAAK,CACd0M,MAAOrE,EAAOqE,MACdC,OAAQtE,EAAOsE,OACfF,YACAH,uBAAwB,SAACqC,GACvB,IAAMkiB,EAAaz0B,OAAO00B,kBAAoB,EADb,KAEd1nB,oBAASuF,GAFK,GAE1BoiB,EAF0B,KAErBC,EAFqB,OAGhB,EAAKhxB,IAAIyL,QAAQ,CAAEslB,MAAKC,QACzC,MAAO,CAJ0B,EAGzB1mB,EACIumB,EAJqB,EAGtBtmB,EACiBsmB,S,kCAShC,OAHIvxB,KAAKU,KACPV,KAAKU,IAAI8L,IAAI,SAAUxM,KAAKsxB,iBAE9B,kD,kCAQU/c,GACV,IAAMxL,EAAS/I,KAAKU,IAAIsI,YACxB,iDACEuL,EACA,CAACxL,EAAOqE,MAAOrE,EAAOsE,QACtBmJ,GAAcxW,KAAKU,MAClBV,KAAKU,IAAIixB,aAAe3xB,KAAKU,IAAIkxB,eAAiB5xB,KAAKU,IAAImxB,e,8BAY9D,IAAM9oB,EAAS/I,KAAKU,IAAIsI,YACxB,2CACE,CAACD,EAAOqE,MAAOrE,EAAOsE,QACtBrN,KAAKU,IAAIkW,UACTJ,GAAcxW,KAAKU,MAGrBV,KAAKU,IAAIgC,GAAG,UAAW1C,KAAKkxB,cAExBlxB,KAAK2S,eACP3S,KAAKU,IAAIgC,GAAG,YAAa1C,KAAKmxB,kB,6BAUhC,2CACInxB,KAAKU,MACPV,KAAKU,IAAI8L,IAAI,UAAWxM,KAAKkxB,cAC7BlxB,KAAKU,IAAI8L,IAAI,YAAaxM,KAAKmxB,mB,8CAYXrvB,EAAYgT,GAClC,IAAMzG,EAAamI,GAAcxW,KAAKU,KACtC,oEAAqCoB,EAAYuM,EAAYyG,K,qCAS7D9U,KAAK8T,gBAAgB9T,KAAKU,IAAIkW,a,qCASjBjU,GACb,GACE3C,KAAKU,IAAIixB,YACT3xB,KAAKU,IAAIkxB,cACT5xB,KAAKU,IAAImxB,cACR7xB,KAAK2S,cAEN3S,KAAKU,IAAIqD,eAAewB,MAAMyR,OAAS,WANzC,CADkB,IAUXF,EAVW,GAUA9W,KAAK+W,wBACrB8Z,sBAAW,CAACluB,EAAImvB,OAAOL,IAAK9uB,EAAImvB,OAAOJ,MACvC,GAZgB,MAeZrsB,EAAKyR,GAAWA,EAAQzR,GAC1BrF,KAAKiN,iBAAmB5H,IAC1BrF,KAAKU,IAAIqD,eAAewB,MAAMyR,OAASF,EAAU,UAAY,OAC7D9W,KAAKiN,eAAiB5H,EAEtBrF,KAAK6T,mBAAmB7T,KAAKkO,iB,gCAzJRnH,GAAM5H,I,qyECqGlBywB,G,wQA1Fb,aAA0B,MAAdxwB,EAAc,uDAAJ,GAAI,mBACxB,oBAAWA,KAGN2yB,OAAS,EAAKA,OAAOrzB,KAAZ,OAEd,EAAK4tB,UAAY,EAAKA,UAAU5tB,KAAf,OANO,E,0CAerBgC,EAAKsxB,GAGR,GAFA,0CAAWtxB,GAENV,KAAKU,IAAV,CAIAV,KAAKU,IAAIgC,GAAG,UAAW1C,KAAKiyB,WAC5BjyB,KAAKU,IAAIgC,GAAG,OAAQ1C,KAAK+xB,QACzB/xB,KAAKU,IAAIgC,GAAG,UAAW1C,KAAKssB,WATV,MAWQtsB,KAAKU,IAAIsI,YAA3BoE,EAXU,EAWVA,MAAOC,EAXG,EAWHA,OACfrN,KAAKiT,QAAQlK,OAAOqE,MAAQA,EAC5BpN,KAAKiT,QAAQlK,OAAOsE,OAASA,EAE7BrN,KAAKU,IAAIwxB,UAAU,gBAAiB,CAClCpxB,KAAM,SACNiI,OAAQ/I,KAAKiT,QAAQlK,OACrBmT,YAAa+U,GAAqBjxB,KAAKU,KAEvCgJ,SAAS,IAEX1J,KAAKU,IAAIiE,SACP,CACEU,GAAI,eACJvE,KAAM,SACNwH,OAAQ,gBACR6pB,MAAO,CACL,iBAAkB,EAClB,uBAAwB,IAG5BH,M,kCAQEhyB,KAAKU,MACPV,KAAKU,IAAI8L,IAAI,UAAWxM,KAAKiyB,WAC7BjyB,KAAKU,IAAI8L,IAAI,OAAQxM,KAAK+xB,QAC1B/xB,KAAKU,IAAI8L,IAAI,UAAWxM,KAAKssB,YAE/B,kD,+BASAtsB,KAAKU,IACFuC,UAAU,iBACVmvB,eAAenB,GAAqBjxB,KAAKU,MAHrC,MAImBV,KAAKU,IAAIsI,YAA3BoE,EAJD,EAICA,MAAOC,EAJR,EAIQA,OACfrN,KAAK6T,mBACH7T,KAAKkO,SACL,CAACd,EAAOC,GACRmJ,GAAcxW,KAAKU,Q,kCAUrBV,KAAK8pB,0B,gCAvFiB/iB,GAAMoP,K,mkHCP1BzZ,GAAU,CACd21B,OAAQ,CACNtG,c,wQCUF,aAA0B,MAAd3sB,EAAc,uDAAJ,GAAI,mBACxB,oBAAWA,KACNitB,WAAa,EAAKA,WAAW3tB,KAAhB,OAClB,EAAKqzB,OAAS,EAAKA,OAAOrzB,KAAZ,OACd,EAAK4tB,UAAY,EAAKA,UAAU5tB,KAAf,OACjB,EAAK4zB,mBAAqB,EAAKA,mBAAmB5zB,KAAxB,OALF,E,0CAcrBgC,EAAKsxB,GACR,GAAKtxB,EAAL,CAIA,0CAAWA,GALO,MAOQA,EAAIsI,YAAtBoE,EAPU,EAOVA,MAAOC,EAPG,EAOHA,OACfrN,KAAKiT,QAAQlK,OAAOqE,MAAQA,EAC5BpN,KAAKiT,QAAQlK,OAAOsE,OAASA,EAE7B,IAAM/E,EAAS,CACbxH,KAAM,SACNiI,OAAQ/I,KAAKiT,QAAQlK,OACrBmT,YAAa+U,GAAqBvwB,GAElCgJ,SAAS,EACTxC,YAAalH,KAAKT,YAGpBS,KAAKgyB,SAAWA,EAChBhyB,KAAKuB,MAAQ,CACX8D,GAAIrF,KAAKvB,IACTqC,KAAM,SACNwH,OAAQtI,KAAKvB,IACb8zB,OAAQ,CACN/kB,WAAYxN,KAAKN,QAAU,UAAY,QAEzCyyB,MAAO,CACL,iBAAkB,EAClB,uBAAwB,EACxB,oBAAqB,YAGzBzxB,EAAIwxB,UAAUlyB,KAAKvB,IAAK6J,GACxB5H,EAAIiE,SAAS3E,KAAKuB,MAAOvB,KAAKgyB,UAE9BhyB,KAAKwyB,UAAY,CAACxyB,KAAK0C,GAAG,iBAAkB1C,KAAKsyB,wB,kCAS7CtyB,KAAKU,MACPV,KAAKwyB,UAAUxvB,SAAQ,SAACyvB,GACtBtvB,kBAAQsvB,MAEVzyB,KAAKU,IAAI0rB,YAAYpsB,KAAKvB,KAC1BuB,KAAKU,IAAIgyB,aAAa1yB,KAAKvB,MAE7B,kD,8BAIKuB,KAAKU,MAGV,4CACAV,KAAKU,IAAIgC,GAAG,QAAS1C,KAAKqsB,YAC1BrsB,KAAKU,IAAIgC,GAAG,OAAQ1C,KAAK+xB,QACzB/xB,KAAKU,IAAIgC,GAAG,UAAW1C,KAAKssB,c,6BAIxBtsB,KAAKU,MACPV,KAAKU,IAAI8L,IAAI,QAASxM,KAAKR,SAC3BQ,KAAKU,IAAI8L,IAAI,OAAQxM,KAAK+xB,QAC1B/xB,KAAKU,IAAI8L,IAAI,UAAWxM,KAAKssB,YAE/B,6C,2CAIItsB,KAAKN,UAAYM,KAAKU,IAAIiyB,SAAS3yB,KAAKvB,KAC1CuB,KAAKU,IAAIiE,SAAS3E,KAAKuB,MAAOvB,KAAKgyB,UAC1BhyB,KAAKU,IAAIiyB,SAAS3yB,KAAKvB,MAChCuB,KAAKU,IAAI0rB,YAAYpsB,KAAKvB,O,+BAe5BuB,KAAKU,IAAIuC,UAAUjD,KAAKvB,KAAK2zB,eAAenB,GAAqBjxB,KAAKU,MAD/D,MAGmBV,KAAKU,IAAIsI,YAA3BoE,EAHD,EAGCA,MAAOC,EAHR,EAGQA,OAEfrN,KAAK6T,mBACH7T,KAAKkO,SACL,CAACd,EAAOC,GACRmJ,GAAcxW,KAAKU,Q,kCASrBV,KAAK8pB,qBACD9pB,KAAKkN,mBAAqBlN,KAAK2nB,WACjC3nB,KAAKusB,wB,iCASE5pB,GAAK,WACd,GAAK3C,KAAKW,eAAec,OAAzB,CADc,IAKPqV,EALO,GAKI9W,KAAK+W,wBACrB8Z,sBAAW,CAACluB,EAAImvB,OAAOL,IAAK9uB,EAAImvB,OAAOJ,MACvC,GAPY,MAUV5a,GAKF9W,KAAKkN,kBAAoB4J,EAAQzR,GAEjCrF,KAAK2nB,UAAY7Q,EAAQ0H,kBACzBxe,KAAK2sB,yBAAyB3sB,KAAKkN,mBAAmBoL,MACpD,SAACsa,GAKC,EAAK/F,eAAiB,GACtB+F,EAAoB9W,SAAS9Y,SAAQ,SAAC6f,GACpC,EAAKgK,eAAe3qB,KAAK2uB,sBAAWhO,EAAQ3G,iBAE9C,EAAKvb,eAAeqC,SAAQ,SAACjB,GAAD,OAC1BA,EAAS,SAAK+U,GAAY8b,GAAuB,EAAMjwB,WAK7D3C,KAAKkN,kBAAoB,KACzBlN,KAAKW,eAAeqC,SAAQ,SAACjB,GAAD,OAAcA,EAAS,KAAM,EAAMY,U,kCAWvC,IAAlBymB,EAAkB,uDAAJ,GAChBqH,EAASzwB,KAAKU,IAAIgwB,YAAYC,UAC9BkC,EAAYhC,sBAAWJ,EAAO,IAC9BqC,EAAYjC,sBAAWJ,EAAO,IAC9Bzb,EAAM,GAAH,UAAO6d,GAAP,GAAqBC,IACxBlP,EAAO3O,kBAAOD,EAAKoZ,oBAASpZ,GAAO,IAAI9P,KAAK,KAC5CyE,EAAO3J,KAAKU,IAAIkW,UAEtB,+DACKwS,GADL,IAEExF,OACA3kB,EAAG0K,EAAO,GAAK,EAAI,EACnBkN,EAAGlN,O,mCAKM8J,GACX,IAAM9J,EAAO3J,KAAKU,IAAIkW,UACtB,yDAA0BnD,EAAO9J,K,yCAWhBkjB,EAAgBC,EAAcjR,GAE/C9T,QAAQme,IAAI,uB,0CA4DMyB,GAAW,WAC7B3nB,KAAK6mB,IACFiH,oBAAoB,CACnBzoB,GAAIsiB,EACJpT,KAAMgD,GAAiB,IAAIpJ,QAgB5Bgc,OAAM,WACD,EAAKzpB,IAAIiyB,SAAS,yBACpB,EAAKjyB,IAAI0rB,YAAY,gC,gCAxSHrlB,GAAMoP,KDR9ByZ,YAAamD,IAEfC,GAAI,CACFhsB,OACA7H,MAAOmD,EACP6tB,SAAU8C,GACVxqB,YAAayqB,GACbnH,cAAeoH,GACfvD,YAAawD,GACbnH,YAAaoH,KAIF32B","file":"index.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"mobility-toolbox-js\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"mobility-toolbox-js\"] = factory();\n\telse\n\t\troot[\"mobility-toolbox-js\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 24);\n","module.exports = require(\"ol/proj\");","module.exports = require(\"ol/style\");","module.exports = require(\"ol/Observable\");","module.exports = require(\"ol/geom\");","module.exports = require(\"ol/extent\");","module.exports = require(\"query-string\");","module.exports = require(\"ol/layer\");","module.exports = require(\"ol/format/GeoJSON\");","module.exports = require(\"ol/Feature\");","module.exports = require(\"ol/Object\");","module.exports = require(\"ol/layer/Layer\");","module.exports = require(\"mapbox-gl\");","module.exports = require(\"ol/source/Source\");","module.exports = require(\"ol/source\");","module.exports = require(\"ol\");","module.exports = require(\"ol/geom/GeometryType\");","module.exports = require(\"ol/format\");","module.exports = require(\"ol/Map\");","module.exports = require(\"ol/control\");","module.exports = require(\"ol/layer/Group\");","module.exports = require(\"uuid\");","module.exports = require(\"ol/geom/Point\");","module.exports = require(\"ol/interaction\");","module.exports = require(\"ol/events/condition\");","import Observable from 'ol/Observable';\nimport { v4 as uuid } from 'uuid';\n\n/**\n * A class representing a layer to display on map.\n *\n * @example\n * const layer = new Layer({\n * name: 'myLayer',\n * });\n *\n * @classproperty {string} name - Name of the layer\n * @classproperty {string} key - Identifier of the layer. Must be unique.\n * @classproperty {boolean} isBaseLayer - Define if the layer is a base layer. Read-only.\n * @classproperty {boolean} isQueryable - Define if the layer can be queried. Read-only.\n * @classproperty {boolean} isReactSpatialLayer - Custom property for duck typing since `instanceof` is not working when the instance was created on different bundles. Read-only.\n * @classproperty {Layer[]} children - List of children.\n * @classproperty {String[]} copyrights - Array of copyrights.\n * @classproperty {boolean} visible - Define if the layer is visible or not.\n * @classproperty {Object} properties - Custom properties.\n * @classproperty {ol/Map~Map|mapboxgl.Map} map - The map where the layer is displayed.\n */\nexport default class Layer extends Observable {\n /**\n * Constructor\n *\n * @param {Object} options\n * @param {string} [options.name=uuid()] Layer name. Default use a generated uuid.\n * @param {string} [options.key=uuid().toLowerCase()] Layer key, will use options.name.toLowerCase() if not specified.\n * @param {string} [options.copyrights=undefined] Array of copyrights.\n * @param {Array<Layer>} [options.children=[]] Sublayers.\n * @param {Object} [options.properties={}] Application-specific layer properties.\n * @param {boolean} [options.visible=true] If true this layer is visible on the map.\n * @param {boolean} [options.isBaseLayer=false] If true this layer is a baseLayer.\n * @param {boolean} [options.isQueryable=true] If true feature information can be queried by the react-spatial LayerService. Default is true.\n */\n constructor(options) {\n super();\n this.defineProperties({ isQueryable: true, ...options });\n\n if (options.copyrights) {\n this.copyrights = options.copyrights;\n }\n\n // Add click callback\n const { onClick } = options;\n if (onClick) {\n this.onClick(onClick);\n }\n }\n\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const {\n name,\n key,\n children,\n visible,\n properties,\n isBaseLayer,\n isQueryable,\n } = options;\n const uid = uuid();\n const dfltName = name || uid;\n Object.defineProperties(this, {\n // options is used for clone function.\n options: {\n value: options,\n },\n name: {\n value: dfltName,\n },\n key: {\n value: key || dfltName.toLowerCase(),\n },\n isBaseLayer: {\n value: !!isBaseLayer,\n },\n isQueryable: {\n value: !!isQueryable,\n },\n // Custom property for duck typing since `instanceof` is not working\n // when the instance was created on different bundles.\n isReactSpatialLayer: {\n value: true,\n },\n children: {\n value: children || [],\n writable: true,\n },\n copyrights: {\n get: () => {\n return this.get('copyrights');\n },\n set: (newCopyrights) => {\n const arrValue = !Array.isArray(newCopyrights)\n ? [newCopyrights]\n : newCopyrights;\n return this.set('copyrights', arrValue);\n },\n },\n visible: {\n value: visible === undefined ? true : visible,\n writable: true,\n },\n properties: {\n value: { ...(properties || {}) },\n },\n map: {\n writable: true,\n },\n /**\n * Callback function when a user click on a vehicle.\n */\n clickCallbacks: {\n value: [],\n },\n });\n }\n\n /**\n * Initialize the layer with the map passed in parameters.\n *\n * @param {ol/Map~Map|mapboxgl.Map} map A map.\n */\n init(map) {\n this.terminate();\n /** @ignore */\n this.map = map;\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n // eslint-disable-next-line class-methods-use-this\n terminate() {}\n\n /**\n * Get a layer property.\n *\n * @param {string} name Property name.\n * @returns {property} Property\n */\n get(name) {\n return this.properties[name];\n }\n\n /**\n * Set a layer property.\n *\n * @param {string} name Property name.\n * @param {string} value Value.\n */\n set(name, value) {\n this.properties[name] = value;\n this.dispatchEvent({\n type: `change:${name}`,\n target: this,\n });\n }\n\n /**\n * Change the visibility of the layer\n *\n * @param {boolean} visible Defines the visibility of the layer\n * @param {boolean} [stopPropagationDown]\n * @param {boolean} [stopPropagationUp]\n * @param {boolean} [stopPropagationSiblings]\n */\n setVisible(\n visible,\n stopPropagationDown = false,\n stopPropagationUp = false,\n stopPropagationSiblings = false,\n ) {\n if (visible === this.visible) {\n return;\n }\n\n /** @ignore */\n this.visible = visible;\n\n this.dispatchEvent({\n type: 'change:visible',\n target: this,\n stopPropagationDown,\n stopPropagationUp,\n stopPropagationSiblings,\n });\n }\n\n /**\n * Returns an array with visible child layers\n *\n * @returns {Layer[]} Visible children\n */\n getVisibleChildren() {\n return this.children.filter((child) => child.visible);\n }\n\n /**\n * Checks whether the layer has child layers with visible set to True\n *\n * @returns {boolean} True if the layer has visible child layers\n */\n hasVisibleChildren() {\n return !!this.hasChildren(true);\n }\n\n /**\n * Checks whether the layer has any child layers with visible equal to the input parameter\n *\n * @param {boolean} visible The state to check the childlayers against\n * @returns {boolean} True if the layer has children with the given visibility\n */\n hasChildren(visible) {\n return !!this.children.find((child) => child.visible === visible);\n }\n\n /**\n * Add a child layer\n *\n * @param {Layer} layer Add a child layer\n */\n addChild(layer) {\n this.children.unshift(layer);\n this.dispatchEvent({\n type: `change:children`,\n target: this,\n });\n }\n\n /**\n * Removes a child layer by layer name\n *\n * @param {string} name Layer's name\n */\n removeChild(name) {\n for (let i = 0; i < this.children.length; i += 1) {\n if (this.children[i].name === name) {\n this.children.splice(i, 1);\n return;\n }\n }\n this.dispatchEvent({\n type: `change:children`,\n target: this,\n });\n }\n\n /**\n * Request feature information for a given coordinate.\n * This function must be implemented by inheriting layers.\n *\n * @returns {Promise<{layer: Layer, features: ol/Feature~Feature[0], coordinate: null}}>} An empty response.\n */\n getFeatureInfoAtCoordinate() {\n // This layer returns no feature info.\n // The function is implemented by inheriting layers.\n return Promise.resolve({\n layer: this,\n features: [],\n coordinate: null,\n });\n }\n\n /**\n * Listens to click events on the layer.\n * @param {function} callback Callback function, called with the clicked\n * features,\n * the layer instance and the click event.\n */\n onClick(callback) {\n if (typeof callback === 'function') {\n if (!this.clickCallbacks.includes(callback)) {\n this.clickCallbacks.push(callback);\n }\n } else {\n throw new Error('callback must be of type function.');\n }\n }\n\n /**\n * Unlistens to click events on the layer.\n * @param {function} callback Callback function, called with the clicked\n * features,\n * the layer instance and the click event.\n */\n unClick(callback) {\n if (typeof callback === 'function') {\n const idx = this.clickCallbacks.indexOf(callback);\n if (idx >= -1) {\n this.clickCallbacks.splice(idx, 1);\n }\n }\n }\n}\n","import { unByKey } from 'ol/Observable';\nimport Group from 'ol/layer/Group';\nimport LayerCommon from '../../common/layers/Layer';\n\n/**\n * A class representing a layer to display on an OpenLayers map.\n *\n * @example\n * import { Layer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new Layer({\n * olLayer: ...,\n * });\n *\n * @see <a href=\"/example/ol-map\">Map example</a>\n *\n * @extends {Layer}\n */\nclass Layer extends LayerCommon {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {ol/layer/Layer~Layer} options.olLayer The layer (required).\n * @param {string} [options.name=uuid()] Layer name. Default use a generated uuid.\n * @param {string} [options.key=uuid().toLowerCase()] Layer key, will use options.name.toLowerCase() if not specified.\n * @param {string} [options.copyright=undefined] Copyright-Statement.\n * @param {Array<Layer>} [options.children=[]] Sublayers.\n * @param {Object} [options.properties={}] Application-specific layer properties.\n * @param {boolean} [options.visible=true] If true this layer is the currently visible layer on the map.\n * @param {boolean} [options.isBaseLayer=false] If true this layer is a baseLayer.\n * @param {boolean} [options.isQueryable=true] If true feature information can be queried by the react-spatial LayerService. Default is true.\n */\n constructor(options) {\n super(options);\n\n if (this.olLayer) {\n this.olLayer.setVisible(this.visible);\n }\n }\n\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n super.defineProperties(options);\n Object.defineProperties(this, {\n olLayer: { value: options.olLayer, writable: true },\n olListenersKeys: {\n value: [],\n },\n });\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map || !this.olLayer) {\n return;\n }\n\n this.olListenersKeys.push(\n this.map.getLayers().on('remove', (evt) => {\n if (evt.element === this.olLayer) {\n this.terminate();\n }\n }),\n );\n\n // We set the copyright to the source used by the layer.\n if (this.copyrights) {\n const attributions = this.copyrights || [];\n if (this.olLayer instanceof Group) {\n this.olLayer\n .getLayers()\n .getArray()\n .forEach((layer) => {\n layer.getSource().setAttributions(attributions);\n });\n } else {\n this.olLayer.getSource().setAttributions(attributions);\n }\n }\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n unByKey(this.olListenersKeys);\n super.terminate();\n }\n\n /**\n * Change the visibility of the layer\n *\n * @param {boolean} visible Defines the visibility of the layer\n * @param {boolean} [stopPropagationDown]\n * @param {boolean} [stopPropagationUp]\n * @param {boolean} [stopPropagationSiblings]\n */\n setVisible(\n visible,\n stopPropagationDown = false,\n stopPropagationUp = false,\n stopPropagationSiblings = false,\n ) {\n if (visible === this.visible) {\n return;\n }\n\n super.setVisible(\n visible,\n stopPropagationDown,\n stopPropagationUp,\n stopPropagationSiblings,\n );\n\n if (this.olLayer) {\n this.olLayer.setVisible(this.visible);\n }\n }\n\n /**\n * Create a copy of the Layer.\n * @param {Object} newOptions Options to override\n * @returns {Layer} A Layer\n */\n clone(newOptions) {\n return new Layer({ ...this.options, ...newOptions });\n }\n}\nexport default Layer;\n","import BaseObject from 'ol/Object';\n\n/**\n * A class representing a control to display on map.\n *\n * @example\n * const control = new Control();\n *\n * @classproperty {ol/Map~Map|mapboxgl.Map} map - The map which the control refers to.\n * @classproperty {boolean} active - Active the control.\n * @classproperty {function} render - Render function called whenever the control needs to be rerendered.\n * @classproperty {HTMLElement} element - The HTML element used to render the control. Read only.\n * @classproperty {HTMLElement} target - The HTML element where to render the element property. Default is the map's element. Read only.\n */\nclass Control extends BaseObject {\n /**\n * Constructor\n *\n * @param {Object} [options] Control options.\n * @param {boolean} [options.active = true] Whether the control is active or not.\n * @param {HTMLElement} [options.element] The HTML element used to render the control.\n * @param {HTMLElement} [options.target] The HTML element where to render the element property. Default is the map's element.\n * @param {HTMLElement} [options.render] Render function called whenever the control needs to be rerendered.\n */\n constructor(options = {}) {\n super(options);\n this.defineProperties(options);\n\n const { active } = {\n active: options.active !== false,\n ...options,\n };\n\n /**\n * @ignore\n */\n this.active = active;\n }\n\n /**\n * Define control's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const { target, element, render } = {\n ...options,\n };\n\n Object.defineProperties(this, {\n active: {\n get: () => {\n return this.get('active');\n },\n set: (newActive) => {\n this.set('active', newActive);\n if (newActive) {\n this.activate();\n } else {\n this.deactivate();\n }\n this.render();\n },\n },\n map: {\n get: () => {\n return this.get('map');\n },\n set: (map) => {\n // Remove previous node.\n if (this.map && this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n\n // Clean listeners\n this.deactivate();\n\n this.set('map', map);\n\n if (this.map) {\n // Add new node\n const targett = this.target || this.map.getContainer();\n\n if (!this.element) {\n this.createDefaultElement();\n }\n\n if (this.element) {\n targett.appendChild(this.element);\n }\n\n // Add listeners\n if (this.active) {\n this.activate();\n }\n }\n this.render();\n },\n },\n target: {\n value: target,\n },\n element: {\n value: element,\n writable: true,\n },\n render: {\n /**\n * @ignore\n */\n value: render || this.render,\n writable: true,\n },\n });\n }\n\n /**\n * Add listeners then renders the control.\n * To be defined in inherited classes.\n */\n activate() {\n this.deactivate();\n }\n\n /**\n * Remove listeners added by activate() function then renders the control.\n * To be defined in inherited classes.\n */\n // eslint-disable-next-line class-methods-use-this\n deactivate() {}\n\n /**\n * The default render function. It renders content in the HTML element.\n * To be defined in inherited classes.\n */\n render() {}\n\n /**\n * The default element to display if this.element is not defined.\n * To be defined in inherited classes.\n * @private\n */\n // eslint-disable-next-line class-methods-use-this\n createDefaultElement() {}\n}\n\nexport default Control;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable class-methods-use-this */\n// eslint-disable-next-line max-classes-per-file\nimport Control from '../controls/Control';\n\n/**\n * Map interface.\n */\nexport class MapInterface {\n /**\n * Constructor.\n *\n * @param {Object} options Map options\n * @param {Array<Layer>} [options.layers] Custom layers of the map.\n * @param {Array<Control>} [options.controls] Custom controls of the map.\n */\n // eslint-disable-next-line no-unused-vars\n constructor(options = {}) {}\n\n /**\n * Returns the HTML element of the map.\n * @returns {HTMLElement}\n */\n getContainer() {}\n\n /**\n * Returns a list of mobility layers.\n * @returns {Layer[]}\n */\n getMobilityLayers() {}\n\n /**\n * Returns a list of mobility controls.\n * @returns {Control[]}\n */\n getMobilityControls() {}\n}\n\n/**\n * Mixin for MapInterface.\n * @ignore\n */\nconst MapMixin = (Base) =>\n class extends Base {\n constructor(options = {}) {\n super({ ...options, layers: [], controls: [] });\n this.mobilityLayers = [];\n this.mobilityControls = [];\n\n // Add controls\n (options.controls || []).forEach((control) => {\n this.addControl(control);\n });\n\n // Add layers\n (options.layers || []).forEach((layer) => {\n this.addLayer(layer);\n });\n }\n\n getMobilityLayers() {\n return this.mobilityLayers;\n }\n\n getMobilityControls() {\n return this.mobilityControls;\n }\n\n addMobilityControl(control) {\n this.mobilityControls.push(control);\n // eslint-disable-next-line no-param-reassign\n control.map = this;\n }\n\n removeMobilityControl(control) {\n // eslint-disable-next-line no-param-reassign\n control.map = null;\n this.mobilityControls = this.mobilityControls.filter(\n (c) => c !== control,\n );\n }\n\n /** Documentation in inherited classes */\n addControl(control, position) {\n if (control instanceof Control) {\n this.addMobilityControl(control);\n } else {\n super.addControl(control, position);\n }\n }\n\n /** Documentation in inherited classes */\n removeControl(control) {\n if (control instanceof Control) {\n this.removeMobilityControl(control);\n } else {\n super.removeControl(control);\n }\n }\n };\n\nexport default MapMixin;\n","/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\n\n/**\n * Copyright control interface.\n *\n */\nexport class CopyrightInterface {\n /**\n * Return an array of layer's copyright.\n *\n * @returns {String[]} A list of copyrights to render.\n */\n getCopyrights() {}\n}\n\n/**\n * Mixin for CopyrightInterface.\n *\n * @param {Class} Base A class to extend with {CopyrightInterface} functionnalities.\n * @return {Class} A class that implements <CopyrightInterface> class and extends Base;\n * @private\n */\nconst CopyrightMixin = (Base) =>\n class extends Base {\n render() {\n if (!this.element) {\n return;\n }\n this.element.innerHTML = this.active\n ? this.getCopyrights().join(' | ')\n : '';\n }\n\n createDefaultElement() {\n this.element = document.createElement('div');\n this.element.id = 'mbt-copyright';\n Object.assign(this.element.style, {\n position: 'absolute',\n bottom: 0,\n right: 0,\n fontSize: '.8rem',\n padding: '0 10px',\n });\n }\n };\n\nexport default CopyrightMixin;\n","/**\n * This function remove duplicates lower case string value of an array.\n * It removes also null, undefined or non string values.\n *\n * @param {array} array Array of values.\n * @ignore\n */\nconst removeDuplicate = (array) => {\n const arrWithoutEmptyValues = array.filter(\n (val) => val !== undefined && val !== null && val.trim && val.trim(),\n );\n const lowerCasesValues = arrWithoutEmptyValues.map((str) =>\n str.toLowerCase(),\n );\n const uniqueLowerCaseValues = [...new Set(lowerCasesValues)];\n const uniqueValues = uniqueLowerCaseValues.map((uniqueStr) => {\n return arrWithoutEmptyValues.find((str) => str.toLowerCase() === uniqueStr);\n });\n return uniqueValues;\n};\n\nexport default removeDuplicate;\n","import { inView } from 'ol/layer/Layer';\nimport Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/CopyrightMixin';\nimport removeDuplicate from '../../common/utils/removeDuplicate';\n\n/**\n * Display layer's copyrights.\n *\n * @example\n * import { Map, CopyrightControl } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * controls: [\n * new CopyrightControl()\n * ]\n * });\n *\n *\n * @see <a href=\"/example/ol-copyright\">Openlayers copyright example</a>\n *\n * @extends {Control}\n * @implements {CopyrightInterface}\n */\nclass CopyrightControl extends mixin(Control) {\n constructor(options) {\n super(options);\n this.onPostRender = this.onPostRender.bind(this);\n }\n\n getCopyrights() {\n if (!this.frameState) {\n return [];\n }\n let copyrights = [];\n\n // This code loop comes mainly from ol.\n this.frameState.layerStatesArray.forEach((layerState) => {\n const { layer } = layerState;\n if (\n inView(layerState, this.frameState.viewState) &&\n layer &&\n layer.getSource &&\n layer.getSource() &&\n layer.getSource().getAttributions()\n ) {\n copyrights = copyrights.concat(\n layer.getSource().getAttributions()(this.frameState),\n );\n }\n });\n return removeDuplicate(copyrights);\n }\n\n activate() {\n super.activate();\n if (this.map) {\n this.map.on('postrender', this.onPostRender);\n }\n }\n\n deactivate() {\n if (this.map) {\n this.map.un('postrender', this.onPostRender);\n }\n super.deactivate();\n }\n\n onPostRender(evt) {\n if (this.map && this.element) {\n /**\n * @ignore\n */\n this.frameState = evt.frameState;\n this.render();\n }\n }\n}\n\nexport default CopyrightControl;\n","import OLMap from 'ol/Map';\nimport { defaults as defaultControls } from 'ol/control';\nimport Layer from './layers/Layer';\nimport mixin from '../common/mixins/MapMixin';\nimport CopyrightControl from './controls/CopyrightControl';\n\n/**\n * An OpenLayers map for handling mobility layers and controls.\n *\n * @example\n * import { Map } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * view: new View({\n * center: [0, 0],\n * zoom: 1,\n * }),\n * });\n *\n * @see <a href=\"/example/ol-map\">Map example</a>\n *\n * @extends {ol/Map~Map}\n */\nclass Map extends mixin(OLMap) {\n /**\n * Constructor.\n *\n * @param {Object} options See [ol/Map~Map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html) options documentation.\n * @param {Array<Layer|ol/layer/Layer~Layer>} [options.layers] Array of layers.\n */\n constructor(options = {}) {\n super({\n controls: [\n ...defaultControls({ attribution: false }).getArray(),\n new CopyrightControl(),\n ],\n ...options,\n });\n }\n\n /**\n * Get the HTML element containing the map.\n *\n * @return {HTMLElement} The HTML element of the container.\n */\n getContainer() {\n return this.getTargetElement();\n }\n\n /**\n * Adds a layer to the map.\n * @param {Layer|ol/layer/Layer~Layer} layer The layer to add.\n */\n addLayer(layer) {\n if (layer instanceof Layer) {\n // layer is an mobility layer\n layer.init(this);\n this.mobilityLayers.push(layer);\n\n if (layer.olLayer) {\n super.addLayer(layer.olLayer);\n }\n\n this.dispatchEvent({\n type: 'change:mobilityLayers',\n target: this,\n });\n } else {\n // layer is an OpenLayer layer\n super.addLayer(layer);\n }\n }\n\n /**\n * Removes a given layer from the map.\n * @param {Layer|ol/layer/Layer~Layer} layer The layer to remove.\n */\n removeLayer(layer) {\n if (layer instanceof Layer) {\n layer.terminate();\n this.mobilityLayers = this.mobilityLayers.filter((l) => l !== layer);\n if (layer.olLayer) {\n super.removeLayer(layer);\n }\n } else {\n // layer is an OpenLayer layer\n super.removeLayer(layer);\n }\n }\n\n /**\n * Adds a given control to the map.\n * @param {Control|ol/control/Control~Control} control The control to add.\n */\n addControl(control) {\n super.addControl(control);\n }\n\n /**\n * Removes a given control to the map.\n * @param {Control|ol/control/Control~Control} control The control to remove.\n */\n removeControl(control) {\n super.removeControl(control);\n }\n}\n\nexport default Map;\n","import qs from 'query-string';\n\n/**\n * Return the styleUrl with apiKey parameters set.\n * @param {string} apiKey apiKey value for the mapbox request.\n * @param {string} apiKeyName parameter name for apiKey in the mapbox request.\n * @param {string} styleUrl mapbox styleUrl value.\n * @ignore\n */\nconst getMapboxStyleUrl = (apiKey, apiKeyName, styleUrl) => {\n if (apiKey === false) {\n return styleUrl;\n }\n const parsedStyle = qs.parseUrl(styleUrl);\n if (!apiKey && parsedStyle.query[apiKeyName]) {\n return styleUrl;\n }\n if (!apiKey) {\n // eslint-disable-next-line no-console\n console.warn(`No apiKey is defined for request to ${styleUrl}`);\n return null;\n }\n return qs.stringifyUrl({\n ...parsedStyle,\n query: {\n ...parsedStyle.query,\n [apiKeyName]: apiKey,\n },\n });\n};\n\nexport default getMapboxStyleUrl;\n","import removeDuplicate from './removeDuplicate';\n\n/**\n * Return the copyright a Mapbox map.\n * @param {mapboxgl.Map} map A Mapbox map\n * @ignore\n */\nconst getMapboxMapCopyrights = (map) => {\n if (!map || !map.style) {\n return [];\n }\n const { sourceCaches } = map.style;\n let copyrights = [];\n Object.values(sourceCaches).forEach((sourceCache) => {\n if (sourceCache.used) {\n const source = sourceCache.getSource();\n const attribution =\n source.attribution || (source.options && source.options.attribution);\n if (attribution) {\n copyrights = copyrights.concat(\n attribution.replace(/&copy;/g, '©').split(/(<a.*?<\\/a>)/),\n );\n }\n }\n });\n\n return removeDuplicate(copyrights);\n};\n\nexport default getMapboxMapCopyrights;\n","/* eslint-disable no-underscore-dangle */\nimport { toLonLat } from 'ol/proj';\nimport mapboxgl from 'mapbox-gl';\nimport Source from 'ol/source/Source';\nimport OLLayer from 'ol/layer/Layer';\nimport GeoJSON from 'ol/format/GeoJSON';\nimport Layer from './Layer';\nimport { getMapboxMapCopyrights, getMapboxStyleUrl } from '../../common/utils';\n\n/**\n * A class representing Mapboxlayer to display on BasicMap\n *\n * @example\n * import { MapboxLayer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new MapboxLayer({\n * url: 'https://maps.geops.io/styles/travic_v2/style.json',\n * apikey: 'yourApiKey',\n * });\n *\n * @extends {Layer}\n */\nexport default class MapboxLayer extends Layer {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {boolean} [options.preserveDrawingBuffer=false] If true able to export the canvas.\n * @param {number} [options.fadeDuration=300] Duration of the fade effect in ms.\n */\n constructor(options = {}) {\n const mbLayer = new OLLayer({\n source: new Source({}),\n render: (frameState) => {\n if (!this.mbMap) {\n // eslint-disable-next-line no-console\n console.warn(\"Mapbox map doesn't exist.\");\n return null;\n }\n let changed = false;\n const canvas = this.mbMap.getCanvas();\n const { viewState } = frameState;\n\n const visible = this.olLayer.getVisible();\n if (this.renderState.visible !== visible) {\n canvas.style.display = visible ? 'block' : 'none';\n this.renderState.visible = visible;\n // Needed since mapbox-gl 1.9.0.\n // Without you don't see others ol layers on top.\n canvas.style.position = 'absolute';\n }\n\n const opacity = this.olLayer.getOpacity();\n if (this.renderState.opacity !== opacity) {\n canvas.style.opacity = opacity;\n this.renderState.opacity = opacity;\n }\n\n // adjust view parameters in mapbox\n const { rotation } = viewState;\n if (this.renderState.rotation !== rotation) {\n this.mbMap.rotateTo((-(rotation || 0) * 180) / Math.PI, {\n animate: false,\n });\n changed = true;\n this.renderState.rotation = rotation;\n }\n\n if (\n this.renderState.zoom !== viewState.zoom ||\n this.renderState.center[0] !== viewState.center[0] ||\n this.renderState.center[1] !== viewState.center[1]\n ) {\n this.mbMap.jumpTo({\n center: toLonLat(viewState.center),\n zoom: viewState.zoom - 1,\n animate: false,\n });\n changed = true;\n this.renderState.zoom = viewState.zoom;\n this.renderState.center = viewState.center;\n }\n\n const size = this.map.getSize();\n if (\n this.renderState.size[0] !== size[0] ||\n this.renderState.size[1] !== size[1]\n ) {\n changed = true;\n this.renderState.size = size;\n }\n\n // cancel the scheduled update & trigger synchronous redraw\n // see https://github.com/mapbox/mapbox-gl-js/issues/7893#issue-408992184\n // NOTE: THIS MIGHT BREAK WHEN UPDATING MAPBOX\n if (\n this.mbMap &&\n this.mbMap.style &&\n this.mbMap.isStyleLoaded() &&\n changed\n ) {\n try {\n if (this.mbMap._frame) {\n this.mbMap._frame.cancel();\n this.mbMap._frame = null;\n }\n this.mbMap._render();\n } catch (err) {\n // ignore render errors because it's probably related to\n // a render during an update of the style.\n // eslint-disable-next-line no-console\n console.warn(err);\n }\n }\n\n return canvas;\n },\n });\n\n super({\n ...options,\n olLayer: mbLayer,\n });\n\n /**\n * Url of the mapbox style.\n * @type {string}\n * @private\n */\n this.styleUrl = options.url;\n\n /**\n * Api key for the url of the mapbox style.\n * If set to false, the apiKey is not required.\n * @type {string}\n * @private\n */\n this.apiKey = options.apiKey;\n\n /**\n * Name of the apiKey to set in the url request.\n * Default is 'key'.\n * @type {string}\n * @private\n */\n this.apiKeyName = options.apiKeyName || 'key';\n\n /**\n * @ignores\n */\n this.updateAttribution = this.updateAttribution.bind(this);\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map || this.mbMap) {\n return;\n }\n\n /**\n * The feature format.\n * @type {ol/format/GeoJSON}\n */\n this.format = new GeoJSON({\n featureProjection: this.map.getView().getProjection(),\n });\n\n this.loadMbMap();\n\n this.olListenersKeys.push(\n this.map.on('change:size', () => {\n try {\n if (this.mbMap) {\n this.mbMap.resize();\n }\n } catch (err) {\n // ignore render errors\n // eslint-disable-next-line no-console\n console.warn(err);\n }\n }),\n );\n }\n\n /**\n * Returns a style URL with apiKey & apiKeyName infos.\n */\n createStyleUrl() {\n return getMapboxStyleUrl(this.apiKey, this.apiKeyName, this.styleUrl);\n }\n\n /**\n * Create the mapbox map.\n * @private\n */\n loadMbMap() {\n this.olListenersKeys.push(\n this.map.on('change:target', () => {\n this.loadMbMap();\n }),\n );\n\n if (!this.map.getTargetElement()) {\n return;\n }\n\n if (!this.visible) {\n // On next change of visibility we load the map\n this.olListenersKeys.push(\n this.once('change:visible', () => {\n this.loadMbMap();\n }),\n );\n return;\n }\n\n // If the map hasn't been resized, the center could be [NaN,NaN].\n // We set default good value for the mapbox map, to avoid the app crashes.\n let [x, y] = this.map.getView().getCenter();\n if (!x || !y) {\n x = 0;\n y = 0;\n }\n\n const style = this.createStyleUrl();\n try {\n /**\n * A mapbox map\n * @type {mapboxgl.Map}\n */\n this.mbMap = new mapboxgl.Map({\n style,\n attributionControl: false,\n boxZoom: false,\n center: toLonLat([x, y]),\n container: this.map.getTargetElement(),\n interactive: false,\n fadeDuration:\n 'fadeDuration' in this.options ? this.options.fadeDuration : 300,\n // Needs to be true to able to export the canvas, but could lead to performance issue on mobile.\n preserveDrawingBuffer: this.options.preserveDrawingBuffer || false,\n });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn('Failed creating mapbox map: ', err);\n }\n\n // Options the last render run did happen. If something changes\n // we have to render again\n /** @ignore */\n this.renderState = {\n center: [x, y],\n zoom: null,\n rotation: null,\n visible: null,\n opacity: null,\n size: [0, 0],\n };\n\n this.mbMap.once('load', () => {\n /**\n * Is the map loaded.\n * @type {boolean}\n */\n this.loaded = true;\n\n this.copyrights =\n this.copyrights || getMapboxMapCopyrights(this.mbMap) || [];\n\n this.olLayer.getSource().setAttributions(this.copyrights);\n\n this.dispatchEvent({\n type: 'load',\n target: this,\n });\n });\n\n const mapboxCanvas = this.mbMap.getCanvas();\n if (mapboxCanvas) {\n if (this.options.tabIndex) {\n mapboxCanvas.setAttribute('tabindex', this.options.tabIndex);\n } else {\n // With a tabIndex='-1' the mouse events works but the map is not focused when we click on it\n // so we remove completely the tabIndex attribute.\n mapboxCanvas.removeAttribute('tabindex');\n }\n }\n\n this.mbMap.on('idle', this.updateAttribution);\n }\n\n updateAttribution(evt) {\n const newAttributions =\n this.copyrights || getMapboxMapCopyrights(evt.target) || [];\n if (this.copyrights.toString() !== newAttributions.toString()) {\n this.olLayer.getSource().setAttributions(newAttributions);\n }\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate Coordinate to request the information at.\n * @param {Object} options A [mapboxgl.Map#queryrenderedfeatures](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#queryrenderedfeatures) options parameter.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit. The original Mapbox feature is available as a property named 'mapboxFeature'.\n */\n getFeatureInfoAtCoordinate(coordinate, options) {\n // Ignore the getFeatureInfo until the mapbox map is loaded\n if (\n !options ||\n !this.format ||\n !this.mbMap ||\n !this.mbMap.isStyleLoaded()\n ) {\n return Promise.resolve({ coordinate, features: [], layer: this });\n }\n\n const pixel = coordinate && this.mbMap.project(toLonLat(coordinate));\n // At this point we get GeoJSON Mapbox feature, we transform it to an OpenLayers\n // feature to be consistent with other layers.\n const features = this.mbMap\n .queryRenderedFeatures(pixel, options)\n .map((feature) => {\n const olFeature = this.format.readFeature(feature);\n if (olFeature) {\n // We save the original mapbox feature to avoid losing informations\n // potentially needed for other functionnality like highlighting\n // (id, layer id, source, sourceLayer ...)\n olFeature.set('mapboxFeature', feature);\n }\n return olFeature;\n });\n\n return Promise.resolve({\n layer: this,\n features,\n coordinate,\n });\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n if (this.mbMap) {\n this.mbMap.off('idle', this.updateAttribution);\n // Some asynchrone repaints are triggered even if the mbMap has been removed,\n // to avoid display of errors we set an empty function.\n this.mbMap.triggerRepaint = () => {};\n this.mbMap.remove();\n this.mbMap = null;\n }\n this.loaded = false;\n super.terminate();\n }\n\n /**\n * Create a copy of the MapboxLayer.\n * @param {Object} newOptions Options to override\n * @returns {MapboxLayer} A MapboxLayer\n */\n clone(newOptions) {\n return new MapboxLayer({ ...this.options, ...newOptions });\n }\n}\n","import { Circle, Fill, Stroke, Style } from 'ol/style';\nimport { Vector as VectorSource } from 'ol/source';\nimport { Vector } from 'ol/layer';\nimport Layer from './Layer';\n\nconst defaultStyleFunction = (feature, resolution) => {\n const mot = feature.get('mot');\n const viaPointIdx = feature.get('viaPointIdx');\n const minResolution = feature.get('minResolution');\n const maxResolution = feature.get('maxResolution');\n const inRange = resolution <= minResolution && resolution > maxResolution;\n\n // Default style for via points\n const image =\n viaPointIdx !== undefined &&\n new Circle({\n radius: 6,\n fill: new Fill({\n color: [255, 0, 0, 1],\n }),\n stroke: new Stroke({\n color: [0, 0, 0, 1],\n width: 1,\n }),\n });\n\n if (inRange === false) {\n return [new Style({ image })];\n }\n\n // Default style for route lines\n const stroke =\n mot &&\n new Stroke({\n color: [255, 0, 0, 1],\n width: 3,\n lineDash: mot === 'foot' ? [1, 10] : undefined,\n });\n\n const style = new Style({\n stroke,\n image,\n });\n\n const blackBorder = new Style({\n stroke: new Stroke({\n color: [0, 0, 0, mot === 'foot' ? 0 : 1],\n width: 5,\n }),\n });\n return [blackBorder, style];\n};\n\n/**\n * A class use to display vector data.\n *\n * @extends {Layer}\n */\nclass RoutingLayer extends Layer {\n /**\n * Constructor.\n * @param {Object} [options]\n * @param {number} [options.style] Style to be used for routes, uses (ol/StyleLike) [https://openlayers.org/en/latest/apidoc/module-ol_style_Style.html#~StyleLike] instances\n */\n constructor(options = {}) {\n super(options);\n\n this.olLayer =\n options.olLayer ||\n new Vector({\n source: new VectorSource(),\n style: options.style || defaultStyleFunction,\n });\n }\n\n /**\n * Create a copy of the RoutingLayer.\n * @param {Object} newOptions Options to override\n * @returns {RoutingLayer} A RoutingLayer\n */\n clone(newOptions) {\n return new RoutingLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default RoutingLayer;\n","import { unByKey } from 'ol/Observable';\nimport GeomType from 'ol/geom/GeometryType';\n\n/**\n * Tracker. This class stores and allows to draw trajectories on a canvas.\n * @class\n * @param {Object} options\n * @private\n */\nexport default class Tracker {\n /**\n * @private\n */\n constructor(options) {\n const opts = {\n interpolate: true,\n ...options,\n };\n\n /**\n * Array of trajectories.\n * @type {Array<trajectory>}\n */\n this.trajectories = [];\n\n /**\n * Array of trajectories that are currently drawn.\n * @type {Array<key>}\n */\n this.renderedTrajectories = [];\n\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<key>}\n */\n this.interpolate = !!opts.interpolate;\n\n /**\n * Function to Convert coordinate to canvas pixel.\n * @type {function}\n */\n this.getPixelFromCoordinate = opts.getPixelFromCoordinate;\n\n /**\n * Id of the trajectory which is hovered.\n * @type {string}\n */\n this.hoverVehicleId = null;\n\n /**\n * Id of the trajectory which is selected.\n * @type {string}\n */\n this.selectedVehicleId = null;\n\n /**\n * Scale the vehicle icons with this value.\n * @type {number}\n */\n this.iconScale = opts.iconScale;\n\n // we draw directly on the canvas since openlayers is too slow.\n /**\n * HTML <canvas> element.\n * @type {Canvas}\n */\n this.canvas = opts.canvas || document.createElement('canvas');\n this.canvas.width = opts.width;\n this.canvas.height = opts.height;\n this.canvas.setAttribute(\n 'style',\n [\n 'position: absolute',\n 'top: 0',\n 'bottom: 0',\n 'width: 100%',\n 'height: 100%',\n 'pointer-events: none',\n 'visibility: visible',\n 'margin-top: inherit', // for scrolling behavior.\n ].join(';'),\n );\n /**\n * 2d drawing context on the canvas.\n * @type {CanvasRenderingContext2D}\n */\n this.canvasContext = this.canvas.getContext('2d');\n }\n\n /**\n * Set visibility of the canvas.\n * @param {boolean} visible The visibility of the layer\n */\n setVisible(visible) {\n if (this.canvas) {\n this.canvas.style.visibility = visible ? 'visible' : 'hidden';\n }\n }\n\n /**\n * Define the trajectories.\n * @param {array<ol/Feature~Feature>} trajectories\n */\n setTrajectories(trajectories = []) {\n if (this.sort) {\n trajectories.sort(this.sort);\n }\n\n this.trajectories = trajectories;\n }\n\n /**\n * Return the trajectories.\n * @returns {array<trajectory>} trajectories\n */\n getTrajectories() {\n return this.trajectories || [];\n }\n\n /**\n * Return rendered trajectories.\n * Use this to avoid race conditions while rendering.\n * @returns {array<trajectory>} trajectories\n */\n getRenderedTrajectories() {\n return this.renderedTrajectories;\n }\n\n /**\n * Clear the canvas.\n * @private\n */\n clear() {\n if (this.canvasContext) {\n this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n }\n\n /**\n * Set the filter for tracker features.\n * @param {function} filter Filter function.\n */\n setFilter(filter) {\n /**\n * Current filter function.\n * @type {function}\n */\n this.filter = filter;\n }\n\n /**\n * Set the sort for tracker features.\n * @param {function} sort Sort function.\n */\n setSort(sort) {\n /**\n * The sort function for tracker features.\n * @type {function}\n */\n this.sort = sort;\n }\n\n /**\n * Set the id of the trajectory which is hovered.\n * @param {string} id Id of a vehicle.\n * @private\n */\n setHoverVehicleId(id) {\n if (id !== this.hoverVehicleId) {\n this.hoverVehicleId = id;\n }\n }\n\n /**\n * Set the id of the trajectory which is selected.\n * @param {string} id Id of a vehicle.\n * @private\n */\n setSelectedVehicleId(id) {\n if (id !== this.selectedVehicleId) {\n this.selectedVehicleId = id;\n }\n }\n\n /**\n * set the scale of the vehicle icons.\n * @param {number} iconScale Scale value.\n */\n setIconScale(iconScale) {\n this.iconScale = iconScale;\n }\n\n /**\n * Set the tracker style.\n * @param {function} s OpenLayers style function.\n */\n setStyle(s) {\n /**\n * Style function.\n * @type {function}\n */\n this.style = s;\n }\n\n /**\n * Move the canvas.\n * @param {number} offsetX Offset X.\n * @param {number} offsetY Offset Y.\n * @private\n */\n moveCanvas(offsetX, offsetY) {\n const oldLeft = parseFloat(this.canvas.style.left);\n const oldTop = parseFloat(this.canvas.style.top);\n this.canvas.style.left = `${oldLeft - offsetX}px`;\n this.canvas.style.top = `${oldTop - offsetY}px`;\n }\n\n /**\n * Draw all the trajectories available to the canvas.\n * @param {Date} currTime The date to render.\n * @param {number[2]} size Size ([width, height]) of the canvas to render.\n * @param {number} resolution Which resolution of the map to render.\n * @param {boolean} noInterpolate If true trajectories are not interpolated but\n * drawn at the last known coordinate. Use this for performance optimization\n * during map navigation.\n * @private\n */\n renderTrajectories(\n currTime = Date.now(),\n size = [],\n resolution,\n noInterpolate = false,\n ) {\n this.clear();\n this.canvas.style.left = '0px';\n this.canvas.style.top = '0px';\n\n const [width, height] = size;\n if (\n width &&\n height &&\n (this.canvas.width !== width || this.canvas.height !== height)\n ) {\n [this.canvas.width, this.canvas.height] = [width, height];\n }\n /**\n * Current resolution.\n * @type {number}\n */\n this.currResolution = resolution || this.currResolution;\n let hoverVehicleImg;\n let hoverVehiclePx;\n let hoverVehicleWidth;\n let hoverVehicleHeight;\n let selectedVehicleImg;\n let selectedVehiclePx;\n let selectedVehicleWidth;\n let selectedVehicleHeight;\n\n this.renderedTrajectories = [];\n\n for (let i = (this.trajectories || []).length - 1; i >= 0; i -= 1) {\n const traj = this.trajectories[i];\n\n // We simplify the traj object\n const { geometry, timeIntervals, timeOffset } = traj;\n\n if (this.filter && !this.filter(traj, i, this.trajectories)) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n let coord = null;\n let rotation;\n\n if (traj.coordinate && (noInterpolate || !this.interpolate)) {\n coord = traj.coordinate;\n } else if (timeIntervals && timeIntervals.length > 1) {\n const now = currTime - (timeOffset || 0);\n let start;\n let end;\n let startFrac;\n let endFrac;\n let timeFrac;\n\n // Search th time interval.\n for (let j = 0; j < timeIntervals.length - 1; j += 1) {\n // Rotation only available in tralis layer.\n [start, startFrac, rotation] = timeIntervals[j];\n [end, endFrac] = timeIntervals[j + 1];\n\n if (start <= now && now <= end) {\n break;\n } else {\n start = null;\n end = null;\n }\n }\n // The geometry can also be a Point\n if (geometry.getType() === GeomType.POINT) {\n coord = geometry.getCoordinates();\n } else if (geometry.getType() === GeomType.LINE_STRING) {\n if (start && end) {\n // interpolate position inside the time interval.\n timeFrac = this.interpolate\n ? Math.min((now - start) / (end - start), 1)\n : 0;\n\n const geomFrac = this.interpolate\n ? timeFrac * (endFrac - startFrac) + startFrac\n : 0;\n\n coord = geometry.getCoordinateAt(geomFrac);\n\n // We set the rotation and the timeFraction of the trajectory (used by tralis).\n this.trajectories[i].rotation = rotation;\n this.trajectories[i].endFraction = timeFrac;\n\n // It happens that the now date was some ms before the first timeIntervals we have.\n } else if (now < timeIntervals[0][0]) {\n [[, , rotation]] = timeIntervals;\n timeFrac = 0;\n coord = geometry.getFirstCoordinate();\n } else if (now > timeIntervals[timeIntervals.length - 1][0]) {\n [, , rotation] = timeIntervals[timeIntervals.length - 1];\n timeFrac = 1;\n coord = geometry.getLastCoordinate();\n }\n } else {\n // eslint-disable-next-line no-console\n console.error(\n 'This geometry type is not supported. Only Point or LineString are. Current geometry: ',\n geometry,\n );\n }\n // We set the rotation and the timeFraction of the trajectory (used by tralis).\n // if rotation === null that seems there is no rotation available.\n this.trajectories[i].rotation = rotation;\n this.trajectories[i].endFraction = timeFrac || 0;\n }\n\n if (coord) {\n // We set the rotation of the trajectory (used by tralis).\n this.trajectories[i].coordinate = coord;\n const px = this.getPixelFromCoordinate(coord);\n\n if (!px) {\n // eslint-disable-next-line no-continue\n continue;\n }\n // Trajectory with pixel (i.e. within map extent) will be in renderedTrajectories.\n this.trajectories[i].rendered = true;\n this.renderedTrajectories.push(this.trajectories[i]);\n const vehicleImg = this.style(traj, this.currResolution);\n\n if (!vehicleImg) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n let imgWidth = vehicleImg.width;\n let imgHeight = vehicleImg.height;\n\n if (this.iconScale) {\n imgHeight = Math.floor(imgHeight * this.iconScale);\n imgWidth = Math.floor(imgWidth * this.iconScale);\n }\n\n if (\n this.hoverVehicleId !== traj.id &&\n this.selectedVehicleId !== traj.id\n ) {\n this.canvasContext.drawImage(\n vehicleImg,\n px[0] - imgWidth / 2,\n px[1] - imgHeight / 2,\n imgWidth,\n imgHeight,\n );\n }\n if (this.hoverVehicleId === traj.id) {\n // Store the canvas to draw it at the end\n hoverVehicleImg = vehicleImg;\n hoverVehiclePx = px;\n hoverVehicleWidth = imgWidth;\n hoverVehicleHeight = imgHeight;\n }\n\n if (this.selectedVehicleId === traj.id) {\n // Store the canvas to draw it at the end\n selectedVehicleImg = vehicleImg;\n selectedVehiclePx = px;\n selectedVehicleWidth = imgWidth;\n selectedVehicleHeight = imgHeight;\n }\n }\n }\n\n if (selectedVehicleImg) {\n this.canvasContext.drawImage(\n selectedVehicleImg,\n selectedVehiclePx[0] - selectedVehicleWidth / 2,\n selectedVehiclePx[1] - selectedVehicleHeight / 2,\n selectedVehicleWidth,\n selectedVehicleHeight,\n );\n }\n\n if (hoverVehicleImg) {\n this.canvasContext.drawImage(\n hoverVehicleImg,\n hoverVehiclePx[0] - hoverVehicleWidth / 2,\n hoverVehiclePx[1] - hoverVehicleHeight / 2,\n hoverVehicleWidth,\n hoverVehicleHeight,\n );\n }\n }\n\n /**\n * Clean the canvas and the events the tracker.\n * @private\n */\n destroy() {\n unByKey(this.olEventsKeys);\n this.renderedTrajectories = [];\n this.clear();\n }\n}\n","const trackerRadiusMapping = {\n 0: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 1: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 2: [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],\n 3: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 4: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 5: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 6: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 7: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 8: [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],\n 9: [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],\n};\n\n/**\n * @ignore\n */\nexport const types = [\n 'Tram',\n 'Subway / Metro / S-Bahn',\n 'Train',\n 'Bus',\n 'Ferry',\n 'Cable Car',\n 'Gondola',\n 'Funicular',\n 'Long distance bus',\n 'Rail', // New endpoint use Rail instead of Train.\n];\n\n/**\n * @ignore\n */\nexport const bgColors = [\n '#ffb400',\n '#ff5400',\n '#ff8080',\n '#ea0000',\n '#3000ff',\n '#ffb400',\n '#41a27b',\n '#00d237',\n '#b5b5b5',\n '#ff8080',\n];\n\n/**\n * @ignore\n */\nexport const textColors = [\n '#000000',\n '#ffffff',\n '#000000',\n '#ffffff',\n '#ffffff',\n '#000000',\n '#ffffff',\n '#000000',\n '#000000',\n '#000000',\n];\n\n/**\n * @ignore\n */\nexport const timeSteps = [\n 100000,\n 50000,\n 40000,\n 30000,\n 20000,\n 15000,\n 10000,\n 5000,\n 2000,\n 1000,\n 400,\n 300,\n 250,\n 180,\n 90,\n 60,\n 50,\n 50,\n 50,\n 50,\n 50,\n];\n\n/**\n * @ignore\n */\nconst getTypeIndex = (type) => {\n if (typeof type === 'string') {\n const matched = types.find((t) => new RegExp(type).test(t));\n return types.indexOf(matched);\n }\n return type;\n};\n\n/**\n * @ignore\n */\nexport const getRadius = (type = 0, zoom) => {\n try {\n const typeIdx = getTypeIndex(type);\n return trackerRadiusMapping[typeIdx][zoom];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getBgColor = (type = 0) => {\n try {\n const typeIdx = getTypeIndex(type);\n return bgColors[typeIdx];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getTextColor = (type = 0) => {\n try {\n const typeIdx = getTypeIndex(type);\n return textColors[typeIdx];\n } catch (e) {\n return 1;\n }\n};\n\n/**\n * @ignore\n */\nexport const getTextSize = (ctx, markerSize, text, fontSize) => {\n ctx.font = `bold ${fontSize}px Arial`;\n let newText = ctx.measureText(text);\n\n const maxiter = 25;\n let i = 0;\n\n while (newText.width > markerSize - 6 && i < maxiter) {\n // eslint-disable-next-line no-param-reassign\n fontSize -= 0.5;\n ctx.font = `bold ${fontSize}px arial, sans-serif`;\n newText = ctx.measureText(text);\n i += 1;\n }\n return fontSize;\n};\n\n/**\n * @ignore\n * @param {number} delayInMs Delay in milliseconds.\n * @param {boolean} cancelled true if the journey is cancelled.\n * @param {boolean} isDelayText true if the color is used for delay text of the symbol.\n */\nexport const getDelayColor = (delayInMs, cancelled, isDelayText) => {\n if (cancelled) {\n return isDelayText ? '#ff0000' : '#a0a0a0'; // red or gray\n }\n if (delayInMs >= 3600000) {\n return '#ed004c'; // pink { r: 237, g: 0, b: 76, s: '237,0,76' };\n }\n if (delayInMs >= 500000) {\n return '#e80000'; // red { r: 232, g: 0, b: 0, s: '232,0,0' };\n }\n if (delayInMs >= 300000) {\n return '#ff4a00'; // orange { r: 255, g: 74, b: 0, s: '255,74,0' };\n }\n if (delayInMs >= 180000) {\n return '#f7bf00'; // yellow { r: 247, g: 191, b: 0, s: '247,191,0' };\n }\n if (delayInMs === null) {\n return '#a0a0a0'; // grey { r: 160, g: 160, b: 160, s: '160,160,160' };\n }\n return '#00a00c'; // green { r: 0, g: 160, b: 12, s: '0,160,12' };\n};\n\n/**\n * @ignore\n */\nexport const getDelayText = (delayInMs, cancelled) => {\n if (cancelled) {\n return String.fromCodePoint(0x00d7);\n }\n if (delayInMs > 3600000) {\n const rounded = Math.round(delayInMs / 3600000);\n return `+${rounded}h`;\n }\n\n if (delayInMs > 59000) {\n const rounded = Math.round(delayInMs / 60000);\n return `+${rounded}m`;\n }\n\n if (delayInMs > 0) {\n return `+${delayInMs}s`;\n }\n\n return '';\n};\n","/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport { buffer, containsCoordinate } from 'ol/extent';\nimport { unByKey } from 'ol/Observable';\nimport Tracker from '../Tracker';\nimport { timeSteps } from '../trackerConfig';\n\n/**\n * TrackerLayerInterface.\n *\n * @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.\n * @classproperty {boolean} isHoverActive - Activate/deactivate pointer hover effect.\n * @classproperty {function} style - Style of the vehicle.\n * @classproperty {FilterFunction} filter - Time speed.\n * @classproperty {function} sort - Set the filter for tracker features.\n * @classproperty {boolean} useRequestAnimationFrame - If true, encapsulates the renderTrajectories calls in a requestAnimationFrame. Experimental.\n */\nexport class TrackerLayerInterface {\n /**\n * Initalize the Tracker.\n * @param {ol/Map~Map} map\n * @param {Object} options\n * @param {number} [options.width] Canvas's width.\n * @param {number} [options.height] Canvas's height.\n * @param {function} [options.getPixelFromCoordinate] Convert an EPSG:3857 coordinate to a canvas pixel (origin top-left).\n */\n // eslint-disable-next-line no-unused-vars\n init(map, options) {}\n\n /**\n * Destroy the Tracker.\n */\n terminate() {}\n\n /**\n * Start the clock.\n *\n * @param {Array<number>} size Map's size: [width, height].\n * @param {number} zoom Map's zoom level.\n * @param {number} resolution Map's resolution.\n */\n // eslint-disable-next-line no-unused-vars\n start(size, zoom, resolution) {}\n\n /**\n * Stop the time.\n * @private\n * @param {number} zoom\n */\n // eslint-disable-next-line no-unused-vars\n startUpdateTime(zoom) {}\n\n /**\n * Stop the clock.\n */\n stop() {}\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n *\n * @param {Date} time The date to render.\n * @param {number[2]} size Size of the canvas to render.\n * @param {number} resolution Map's resolution to render.\n * @param {boolean} [mustRender=true] If false bypass the rendering of vehicles.\n */\n // eslint-disable-next-line no-unused-vars\n setCurrTime(time, size, resolution, mustRender = true) {}\n\n /**\n * Get vehicle.\n * @param {function} filterFc A function use to filter results.\n */\n // eslint-disable-next-line no-unused-vars\n getVehicle(filterFc) {}\n\n /**\n * Returns the list of vehicles which are at the given coordinates.\n * Returns an empty array when no vehicle is located at the given\n * coordinates.\n *\n * @param {number[2]} coordinate A coordinate ([x,y]).\n * @param {number} [resolution=1] The resolution of the map.\n * @param {number} [nb=Infinity] nb The max number of vehicles to return.\n * @returns {Array<ol/Feature~Feature>} Array of vehicles.\n */\n // eslint-disable-next-line no-unused-vars\n getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {}\n\n /**\n * Get the duration before the next update depending on zoom level.\n * @private\n * @param {number} zoom\n */\n // eslint-disable-next-line no-unused-vars\n getRefreshTimeInMs(zoom) {}\n\n /**\n * Define a default style of the vehicle.s\n * Draw a blue circle with the id of the props parameter.\n *\n * @param {Object} props Properties\n * @private\n */\n // eslint-disable-next-line no-unused-vars\n defaultStyle(props) {}\n}\n\n/**\n * Mixin for TrackeLayerInterface.\n *\n * @param {Class} Base A class to extend with {TrackerLayerInterface} functionnalities.\n * @return {Class} A class that implements <TrackerLayerInterface> class and extends Base;\n * @private\n */\nconst TrackerLayerMixin = (Base) =>\n class extends Base {\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n const { isHoverActive, style, speed } = {\n isHoverActive: true,\n ...options,\n };\n let cuurSpeed = speed || 1;\n super.defineProperties(options);\n Object.defineProperties(this, {\n isTrackerLayer: { value: true },\n isHoverActive: {\n value: !!isHoverActive,\n writable: true,\n },\n style: {\n value: style || this.defaultStyle,\n },\n speed: {\n get: () => cuurSpeed,\n set: (newSpeed) => {\n cuurSpeed = newSpeed;\n this.start();\n },\n },\n filter: {\n get: () => this.tracker.filter,\n set: (filter) => {\n if (this.tracker) {\n this.tracker.setFilter(filter);\n }\n },\n },\n sort: {\n get: () => this.tracker.sort,\n set: (sort) => {\n if (this.sort) {\n this.tracker.setSort(sort);\n }\n },\n },\n\n /**\n * The tracker that renders the trajectories.\n */\n tracker: { value: null, writable: true },\n\n /**\n * Canvas cache object for trajectories drawn.\n */\n styleCache: { value: {} },\n\n /**\n * Time used to display the trajectories.\n */\n currTime: {\n value: new Date(),\n writable: true,\n },\n\n /**\n * Keep track of the last time used to render trajectories.\n * Useful when the speed increase.\n */\n lastUpdateTime: {\n value: new Date(),\n writable: true,\n },\n\n /**\n * Keep track of which trajectories are currently drawn.\n */\n renderedTrajectories: {\n get: () => this.tracker.renderedTrajectories,\n },\n\n /**\n * Id of the hovered vehicle.\n */\n hoverVehicleId: {\n get: () => {\n return this.tracker.hoverVehicleId;\n },\n set: (hoverVehicleId) => {\n this.tracker.hoverVehicleId = hoverVehicleId;\n },\n },\n\n /**\n * Id of the selected vehicle.\n */\n selectedVehicleId: {\n get: () => {\n return this.tracker.selectedVehicleId;\n },\n set: (selectedVehicleId) => {\n this.tracker.selectedVehicleId = selectedVehicleId;\n },\n },\n\n /**\n * If true, encapsulates the renderTrajectories calls in a requestAnimationFrame\n */\n useRequestAnimationFrame: {\n default: false,\n writable: true,\n },\n });\n }\n\n /**\n * Initalize the Tracker.\n * @param {ol/Map~Map} map\n * @param {Object} options\n * @param {Number} [options.width] Canvas's width.\n * @param {Number} [options.height] Canvas's height.\n * @param {function} [options.getPixelFromCoordinate] Convert an EPSG:3857 coordinate to a canvas pixel (origin top-left).\n */\n init(map, options) {\n super.init(map);\n this.tracker = new Tracker(options);\n this.tracker.setStyle((props, r) => this.style(props, r));\n\n if (this.visible) {\n this.start();\n }\n\n this.visibilityRef = this.on('change:visible', (evt) => {\n if (evt.target.visible) {\n this.start();\n } else {\n this.stop();\n }\n });\n }\n\n /**\n * Destroy the Tracker.\n */\n terminate() {\n this.stop();\n unByKey(this.visibilityRef);\n if (this.tracker) {\n this.tracker.destroy();\n this.tracker = null;\n }\n super.terminate();\n }\n\n /**\n * Start the clock.\n *\n * @param {Array<Number>} size Map's size: [width, height].\n * @param {Number} zoom Map's zoom level.\n * @param {Number} resolution Map's resolution.\n */\n start(size, zoom, resolution) {\n this.stop();\n this.tracker.setVisible(true);\n this.renderTrajectories(this.currTime, size, resolution);\n this.startUpdateTime(zoom);\n }\n\n /**\n * Start the time.\n * @private\n * @param {number} zoom\n */\n startUpdateTime(zoom) {\n this.stopUpdateTime();\n this.updateTimeInterval = setInterval(() => {\n const newTime =\n this.currTime.getTime() +\n (new Date() - this.lastUpdateTime) * this.speed;\n this.setCurrTime(newTime);\n }, this.getRefreshTimeInMs(zoom));\n }\n\n /**\n * Stop the clock.\n */\n stop() {\n this.stopUpdateTime();\n if (this.tracker) {\n this.tracker.setVisible(false);\n this.tracker.clear();\n }\n }\n\n /**\n * Stop the time.\n * @private\n */\n stopUpdateTime() {\n if (this.updateTimeInterval) {\n clearInterval(this.updateTimeInterval);\n }\n }\n\n /**\n * Render the trajectories requesting an animation frame and cancelling the previous one\n * @private\n */\n renderTrajectories(time, size, resolution) {\n if (this.requestId) {\n cancelAnimationFrame(this.requestId);\n }\n if (this.useRequestAnimationFrame) {\n this.requestId = requestAnimationFrame(() => {\n this.tracker.renderTrajectories(time, size, resolution);\n });\n } else {\n this.tracker.renderTrajectories(time, size, resolution);\n }\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n * @param {dateString | value} time\n * @param {Array<number>} size\n * @param {number} resolution\n * @param {boolean} [mustRender=true]\n */\n setCurrTime(time, size, resolution, mustRender = true) {\n const newTime = new Date(time);\n this.currTime = newTime;\n this.lastUpdateTime = new Date();\n if (mustRender) {\n this.renderTrajectories(this.currTime, size, resolution);\n }\n }\n\n /**\n * Get vehicle.\n * @param {function} filterFc A function use to filter results.\n * @returns {Array<Object>} Array of vehicle.\n */\n getVehicle(filterFc) {\n return this.tracker.getTrajectories().filter(filterFc);\n }\n\n /**\n * Returns an array of vehicles located at the given coordinates and resolution.\n *\n * @param {number[2]} coordinate A coordinate ([x,y]).\n * @param {number} [resolution=1] The resolution of the map.\n * @param {number} [nb=Infinity] The max number of vehicles to return.\n * @returns {Array<ol/Feature~Feature>} Array of vehicle.\n */\n getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {\n const ext = buffer([...coordinate, ...coordinate], 10 * resolution);\n const trajectories = this.tracker.getTrajectories();\n const vehicles = [];\n for (let i = 0; i < trajectories.length; i += 1) {\n if (\n trajectories[i].coordinate &&\n containsCoordinate(ext, trajectories[i].coordinate)\n ) {\n vehicles.push(trajectories[i]);\n }\n if (vehicles.length === nb) {\n break;\n }\n }\n\n return vehicles;\n }\n\n /**\n * Get the duration before the next update depending on zoom level.\n * @private\n * @param {number} zoom\n */\n getRefreshTimeInMs(zoom) {\n const roundedZoom = Math.round(zoom);\n const timeStep = timeSteps[roundedZoom] || 25;\n const nextTick = Math.max(25, timeStep / this.speed);\n return nextTick;\n }\n\n /**\n * Define a default style of the vehicle.s\n * Draw a blue circle with the id of the props parameter.\n *\n * @param {Object} props Properties\n * @private\n */\n defaultStyle(props) {\n const { id: text } = props;\n if (this.styleCache[text]) {\n return this.styleCache[text];\n }\n const canvas = document.createElement('canvas');\n canvas.width = 200;\n canvas.height = 15;\n const ctx = canvas.getContext('2d');\n ctx.arc(8, 8, 5, 0, 2 * Math.PI, false);\n ctx.fillStyle = '#8ED6FF';\n ctx.fill();\n ctx.lineWidth = 3;\n ctx.strokeStyle = 'black';\n ctx.stroke();\n ctx.font = 'bold 12px arial';\n ctx.strokeStyle = 'white';\n ctx.lineWidth = 3;\n ctx.strokeText(text, 20, 10);\n ctx.fillStyle = 'black';\n ctx.fillText(text, 20, 10);\n this.styleCache[text] = canvas;\n return this.styleCache[text];\n }\n };\n\nexport default TrackerLayerMixin;\n","import { Layer as OLLayer, Group } from 'ol/layer';\nimport { unByKey } from 'ol/Observable';\nimport Source from 'ol/source/Source';\nimport mixin from '../../common/mixins/TrackerLayerMixin';\nimport Layer from './Layer';\n\n/**\n * Responsible for loading tracker data.\n *\n * @extends {Layer}\n * @implements {TrackerLayerInterface}\n */\nclass TrackerLayer extends mixin(Layer) {\n /**\n * Constructor.\n *\n * @param {Object} options\n * @param {boolean} options.useDelayStyle Set the delay style.\n * @private\n */\n constructor(options = {}) {\n // We use a group to be able to add custom vector layer in extended class.\n // For example TrajservLayer use a vectorLayer to display the complete trajectory.\n super({\n ...options,\n });\n\n /**\n * Function to define when allowing the render of trajectories depending on the zoom level. Default the fundtion return true.\n * It's useful to avoid rendering the map when the map is animating or interacting\n * @type {function}\n */\n this.renderWhenZooming = options.renderWhenZooming || (() => true);\n\n this.olLayer =\n options.olLayer ||\n new Group({\n layers: [\n new OLLayer({\n source: new Source({}),\n render: (frameState) => {\n if (!this.tracker || !this.tracker.canvas) {\n return null;\n }\n const { zoom, center, resolution } = frameState.viewState;\n\n if (zoom !== this.renderState.zoom) {\n this.renderState.zoom = zoom;\n this.renderState.center = center;\n\n if (!this.renderWhenZooming(zoom)) {\n this.tracker.clear();\n return this.tracker.canvas;\n }\n\n this.renderTrajectories(\n this.currTime,\n frameState.size,\n resolution,\n true,\n );\n } else if (\n this.renderState.center[0] !== center[0] ||\n this.renderState.center[1] !== center[1]\n ) {\n const px = this.map.getPixelFromCoordinate(center);\n const oldPx = this.map.getPixelFromCoordinate(\n this.renderState.center,\n );\n this.tracker.moveCanvas(px[0] - oldPx[0], px[1] - oldPx[1]);\n this.renderState.center = center;\n }\n\n return this.tracker.canvas;\n },\n }),\n ],\n });\n\n // Options the last render run did happen. If something changes\n // we have to render again\n /** @ignore */\n this.renderState = {\n center: [0, 0],\n zoom: null,\n };\n\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<ol/events~EventsKey>}\n * @private\n */\n this.olEventsKeys = []; // Be careful to not override this value in child classe.\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map A OpenLayers map.\n * @private\n */\n init(map) {\n if (!map) {\n return;\n }\n\n super.init(map, {\n getPixelFromCoordinate: map.getPixelFromCoordinate.bind(map),\n });\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n * @param {dateString | value} time\n */\n setCurrTime(time) {\n const view = this.map.getView();\n super.setCurrTime(\n time,\n this.map.getSize(),\n view.getResolution(),\n !this.map.getView().getAnimating() &&\n !this.map.getView().getInteracting(),\n );\n }\n\n /**\n * Trackerlayer is started.\n * @private\n */\n start() {\n super.start(\n this.map.getSize(),\n this.currentZoom || this.map.getView().getZoom(),\n this.map.getView().getResolution(),\n );\n\n this.olEventsKeys = [\n this.map.on('moveend', () => {\n const z = this.map.getView().getZoom();\n\n if (z !== this.currentZoom) {\n /**\n * Current value of the zoom.\n * @type {number}\n */\n this.currentZoom = z;\n this.startUpdateTime(z);\n }\n }),\n this.map.on('pointermove', (evt) => {\n if (\n this.map.getView().getInteracting() ||\n this.map.getView().getAnimating() ||\n !this.isHoverActive\n ) {\n return;\n }\n const [vehicle] = this.getVehiclesAtCoordinate(evt.coordinate, 1);\n const id = vehicle && vehicle.id;\n if (this.hoverVehicleId !== id) {\n this.map.getTargetElement().style.cursor = vehicle\n ? 'pointer'\n : 'auto';\n this.hoverVehicleId = id;\n\n // We doesn´t wait the next render, we force it.\n this.renderTrajectories(this.currTime);\n }\n }),\n ];\n }\n\n /**\n * Stop current layer.\n * @private\n */\n stop() {\n super.stop();\n unByKey(this.olEventsKeys);\n this.olEventsKeys = [];\n }\n\n /**\n * Returns the vehicle which are at the given coordinates.\n * Returns null when no vehicle is located at the given coordinates.\n * @param {ol/coordinate~Coordinate} coordinate\n * @param {number} nb Number of vehicles to return;\n * @returns {Array<ol/Feature~Feature>} Vehicle feature.\n * @override\n */\n getVehiclesAtCoordinate(coordinate, nb) {\n const resolution = this.map.getView().getResolution();\n return super.getVehiclesAtCoordinate(coordinate, resolution, nb);\n }\n\n /**\n * Create a copy of the TrackerLayer.\n * @param {Object} newOptions Options to override\n * @returns {TrackerLayer} A TrackerLayer\n */\n clone(newOptions) {\n return new TrackerLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TrackerLayer;\n","/**\n * Get a Date object as UTC date string .\n * ex: 2019 09 01\n * @ignore\n */\nexport const getUTCDateString = (now = new Date()) => {\n let month = (now.getUTCMonth() + 1).toString();\n month = month.length === 1 ? `0${month}` : month;\n let day = now.getUTCDate().toString();\n day = day.length === 1 ? `0${day}` : day;\n\n return [now.getUTCFullYear(), month, day].join('');\n};\n\n/**\n * Get the UTC time string of Date object.\n * ex: 09:05:01.123\n * @ignore\n */\nexport const getUTCTimeString = (date) =>\n [\n date.getUTCHours(),\n date.getUTCMinutes(),\n `${date.getUTCSeconds()}.${date.getUTCMilliseconds()}`,\n ].join(':');\n\n/**\n * Returns a string representation of a number, with a zero if the number is lower than 10.\n * @ignore\n */\nexport const pad = (integer) => (integer < 10 ? `0${integer}` : integer);\n\n/**\n * Returns a 'hh:mm' string from a time in ms.\n * @param {Number} timeInMs Time in milliseconds.\n * @ignore\n */\nexport const getHoursAndMinutes = (timeInMs) => {\n if (!timeInMs || timeInMs <= 0) {\n return '';\n }\n const date = new Date(timeInMs);\n return `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n};\n\n/**\n * Returns a string representing a delay.\n * @param {Number} timeInMs Delay time in milliseconds.\n * @ignore\n */\nexport const getDelayString = (timeInMs) => {\n const h = Math.floor(timeInMs / 3600000);\n const m = Math.floor((timeInMs % 3600000) / 60000);\n const s = Math.floor(((timeInMs % 3600000) % 60000) / 1000);\n\n if (s === 0 && h === 0 && m === 0) {\n return '0';\n }\n if (s === 0 && h === 0) {\n return `${m}m`;\n }\n if (s === 0) {\n return `${h}h${m}m`;\n }\n if (m === 0 && h === 0) {\n return `${s}s`;\n }\n if (h === 0) {\n return `${m}m${s}s`;\n }\n return `${h}h${m}m${s}s`;\n};\n","import qs from 'query-string';\nimport BaseObject from 'ol/Object';\n\n/**\n * Common class to access to a geOps api.\n *\n * @example\n * import { API } from 'mobility-toolbox-js/api';\n *\n * const api = new API({\n * url: [yourUrl],\n * apiKey: [yourApiKey]\n * });\n *\n * @classproperty {string} url Url of the service.\n * @classproperty {string} apiKey Api key to access the service.\n */\nclass API extends BaseObject {\n constructor(options = {}) {\n super();\n /** @ignore */\n this.url = options.url;\n\n /** @ignore */\n this.apiKey = options.apiKey;\n }\n\n /**\n * Append the apiKey before sending the request.\n * @ignore\n */\n fetch(path = '', params = {}, config) {\n // Clean requets parameters, removing undefined and null values.\n const urlParams = { ...params, key: this.apiKey };\n const clone = { ...urlParams };\n Object.keys(urlParams).forEach(\n (key) =>\n (clone[key] === undefined || clone[key] === null) && delete clone[key],\n );\n if (!this.apiKey) {\n // eslint-disable-next-line no-console\n return Promise.reject(\n new Error(`No apiKey defined for request to ${this.url}`),\n );\n }\n return fetch(`${this.url}${path}?${qs.stringify(clone)}`, config).then(\n (response) => {\n try {\n return response.json().then((data) => {\n if (data.error) {\n throw new Error(data.error);\n }\n return data;\n });\n } catch (err) {\n return Promise.reject(new Error(err));\n }\n },\n );\n }\n}\n\nexport default API;\n","import API from '../../common/api/api';\n\n/**\n * Access to the [Stops service](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n *\n * @example\n * import { StopsAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new StopsAPI({\n * url: 'https://api.geops.io/stops/v1/',\n * apiKey: [yourApiKey]\n * });\n *\n */\nclass StopsAPI extends API {\n /**\n * Constructor\n *\n * @param {Object} options Options.\n * @param {string} [options.url='https://api.geops.io/stops/v1/'] Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n */\n constructor(options = {}) {\n super({ url: 'https://api.geops.io/stops/v1/', ...options });\n }\n\n /**\n * Search.\n *\n * @param {StopsSearchParams} params Request parameters. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<GeoJSONFeature[]>} An array of GeoJSON features with coordinates in [EPSG:4326](http://epsg.io/4326).\n */\n search(params, abortController = {}) {\n return this.fetch('', params, {\n signal: abortController.signal,\n }).then((featureCollection) => featureCollection.features);\n }\n}\n\nexport default StopsAPI;\n","import { LineString } from 'ol/geom';\n\n/**\n * Translate the response date object into a readable object.\n * @returns {array<Date>}\n * @ignore\n */\nconst translateDates = (dates = []) => {\n const newDates = [];\n\n for (let i = 0; i < dates.length; i += 1) {\n const { d: day, m: month, y: year } = dates[i];\n newDates.push({\n day,\n month,\n year,\n });\n }\n return newDates;\n};\n\n/**\n * Translate the trajstations response into a readable object.\n * @returns {Object} returns a readable object\n * @private\n */\nexport const translateTrajStationsResp = (data) => {\n const newData = { ...data };\n\n // MAke sure all property exists.\n ['a', 'f', 'tt'].forEach((prop) => {\n if (!newData[prop]) {\n newData[prop] = {};\n }\n });\n\n const {\n id,\n hs: destination,\n t: vehicleType,\n ln: longName,\n sn: shortName,\n wa: wheelchairAccessible,\n ba: bicyclesAllowed,\n rt: realTime,\n fid: feedsId,\n rid: routeIdentifier,\n c: bgColor,\n tc: datacolor,\n a: { n: operator, u: operatorUrl, tz: operatorTimeZone },\n f: { n: publisher, u: publisherUrl, tz: publisherTimeZone },\n tt: {\n n: dateNotOperatingDays,\n p: dateAdditionalOperatingDays,\n t: operatingPeriod,\n },\n sts: dataStations,\n } = newData;\n\n const notOperatingDays = translateDates(dateNotOperatingDays);\n const additionalOperatingDays = translateDates(dateAdditionalOperatingDays);\n const backgroundColor = bgColor && `#${bgColor}`;\n const color = datacolor && `#${datacolor}`;\n\n const stations = [];\n for (let i = 0; i < (dataStations || []).length; i += 1) {\n const {\n sid: stationId,\n n: stationName,\n p: coordinates,\n at: arrivalTime,\n dt: departureTime,\n ap: arrivalDate,\n dp: departureDate,\n ad: arrivalDelay,\n dd: departureDelay,\n dot: noDropOff,\n put: noPickUp,\n c: cancelled,\n wa: stWheelchairAccessible,\n } = dataStations[i];\n\n stations.push({\n stationId,\n stationName,\n coordinates,\n arrivalTime: arrivalTime !== -1 ? arrivalDate * 1000 : null,\n departureTime: departureTime !== -1 ? departureDate * 1000 : null,\n arrivalDelay,\n departureDelay,\n noDropOff: !!noDropOff,\n noPickUp: !!noPickUp,\n cancelled: !!cancelled,\n wheelchairAccessible: !!stWheelchairAccessible,\n });\n }\n\n return {\n id,\n destination,\n backgroundColor,\n color,\n vehicleType,\n routeIdentifier,\n longName,\n shortName,\n stations,\n wheelchairAccessible: !!wheelchairAccessible,\n bicyclesAllowed: !!bicyclesAllowed,\n realTime,\n feedsId,\n operatingInformations: {\n operatingPeriod,\n notOperatingDays,\n additionalOperatingDays,\n },\n operator,\n operatorUrl,\n operatorTimeZone,\n publisher,\n publisherUrl,\n publisherTimeZone,\n };\n};\n\n/**\n * Translate the trajectory_collection response into a js usable object.\n * @returns {Array} returns an array of trajectories.\n * @ignore\n */\nexport const translateTrajCollResponse = (features = []) => {\n const trajectories = [];\n for (let i = 0; i < features.length; i += 1) {\n const traj = features[i];\n const geometry = new LineString(traj.geometry.coordinates);\n const {\n ID: id,\n ProductIdentifier: type,\n PublishedLineName: name,\n RouteIdentifier: routeIdentifier,\n DirectionText: directionText,\n Operator: operator,\n OperatorURL: operatorUrl,\n Publisher: publisher,\n PublisherURL: publisherUrl,\n License: license,\n LicenseUrl: licenseUrl,\n LicenseNote: licenseNote,\n Color: color,\n JourneyIdentifier: journeyIdentifier,\n RealtimeAvailable: realtimeAvailable,\n OperatorProvidesRealtime: operatorProvidesRealtime,\n DayOfOperation: dayOfOperation,\n Delay: delay,\n TimeIntervals: timeIntervals,\n TextColor: textColor,\n Cancelled: cancelled,\n } = traj.properties;\n\n trajectories.push({\n id,\n type,\n name,\n routeIdentifier,\n directionText,\n operator,\n operatorUrl,\n publisher,\n publisherUrl,\n license,\n licenseUrl,\n licenseNote,\n journeyIdentifier,\n realtimeAvailable,\n operatorProvidesRealtime,\n dayOfOperation,\n delay,\n timeIntervals,\n color: color && `#${color}`,\n textColor: textColor && `#${textColor}`,\n geometry,\n cancelled,\n });\n }\n return trajectories;\n};\n\nexport default {\n translateTrajCollResponse,\n translateTrajStationsResp,\n};\n","import {\n translateTrajCollResponse,\n translateTrajStationsResp,\n} from './TrajservAPIUtils';\nimport API from '../../common/api/api';\n\n/**\n * Access to the [Realtime service](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/).\n *\n * @example\n * import { TrajservAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TrajservAPI({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey]\n * });\n *\n */\nclass TrajservAPI extends API {\n /**\n * Constructor\n *\n * @param {Object} options Options.\n * @param {string} [options.url='https://api.geops.io/tracker/v1'] Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n */\n constructor(options = {}) {\n super({ url: 'https://api.geops.io/tracker/v1', ...options });\n }\n\n /**\n * Fetch a trajectory by id.\n *\n * @param {GetTrajectoryByIdParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajectorybyid).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<TrajservTrajectory>} A trajectory.\n */\n fetchTrajectoryById(params, abortController = {}) {\n return this.fetch(`/trajectorybyid`, params, {\n signal: abortController.signal,\n });\n }\n\n /**\n * Fetch trajectories.\n *\n * @param {GetTrajectoriesParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajectory_collection).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<Trajectory[]>} A list of trajectories.\n */\n fetchTrajectories(params, abortController = {}) {\n return this.fetch(`/trajectory_collection`, params, {\n signal: abortController.signal,\n }).then((data) => {\n return translateTrajCollResponse(data.features);\n });\n }\n\n /**\n * Fetch stations informations about a trajectory.\n *\n * @param {GetTrajectoryStationsParams} params Request parameters. See [Realtime service documentation](https://developer.geops.io/apis/5dcbd5c9a256d90001cf1360/#/default/get_trajstations).\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<TrajectoryStation[]>} A list of stations.\n */\n fetchTrajectoryStations(params, abortController = {}) {\n return this.fetch(`/trajstations`, params, {\n signal: abortController.signal,\n }).then((data) => {\n return translateTrajStationsResp(data);\n });\n }\n}\n\nexport default TrajservAPI;\n","/**\n * Class use to facilitate connection to a WebSocket\n * @private\n */\nclass WebSocketConnector {\n constructor(url) {\n /**\n * Array of subscriptions.\n * @type {Array<subscription>}\n */\n this.subscriptions = [];\n this.connect(url);\n\n // keep websocket alive\n setInterval(() => {\n this.send('PING');\n }, 10000);\n this.subscribed = {};\n }\n\n /**\n * Get the websocket request string.\n * @param {string} method Request mehtod {GET, SUB}.\n * @param {Object} params Request parameters.\n * @param {string} params.channel Channel name\n * @param {string} [params.args] Request arguments\n * @param {Number} [params.id] Request identifier\n * @returns {string} request string\n * @private\n */\n static getRequestString(method, params) {\n let reqStr = `${method} ${params.channel}`;\n reqStr += params.args ? ` ${params.args}` : '';\n reqStr += params.id ? ` ${params.id}` : '';\n return reqStr.trim();\n }\n\n /**\n * (Re)connect the websocket.\n * @param {string} url url to connect to\n * @private\n */\n connect(url) {\n if (this.websocket && this.websocket.readyState !== this.websocket.CLOSED) {\n this.websocket.close();\n }\n\n /** @ignore */\n this.websocket = new WebSocket(url);\n\n if (this.currentProj) {\n this.setProjection(this.currentProj);\n }\n\n if (this.currentBbox) {\n this.setBbox(this.currentBbox);\n }\n\n [...this.subscriptions].forEach((s) => {\n this.subscribe(s.params, s.cb, s.errorCb, true);\n });\n\n // reconnect on close\n this.websocket.onclose = () => {\n window.clearTimeout(this.reconnectTimeout);\n /** @ignore */\n this.reconnectTimeout = window.setTimeout(() => this.connect(url), 100);\n };\n }\n\n /**\n * Sends a get request to the websocket.\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @private\n */\n get(params, cb, errorCb) {\n const reqStr = WebSocketConnector.getRequestString('GET', params);\n this.send(reqStr);\n this.listen(params, cb, errorCb);\n }\n\n /**\n * Sends a message to the websocket.\n * @param {message} message Message to send.\n * @private\n */\n send(message) {\n const send = () => {\n this.websocket.send(message);\n };\n\n if (this.websocket.readyState === WebSocket.CONNECTING) {\n this.websocket.addEventListener('open', send);\n } else {\n send();\n }\n }\n\n /**\n * Set the projection for websocket responses.\n * @param {string} value projection value to be set\n * @private\n */\n setProjection(value) {\n /**\n * The projection for websocket responses\n * @type {string}\n */\n this.currentProj = value;\n this.send(`PROJECTION ${value}`);\n }\n\n /**\n * Set the BBOX for websocket responses.\n * @param {Array<Array<number>>} coordinates array of coordinates\n * @private\n */\n setBbox(coordinates) {\n /**\n * The BBOX for websocket responses\n * @type {Array<Array<number>>}\n */\n this.currentBbox = coordinates;\n this.send(`BBOX ${coordinates.join(' ')}`);\n this.subscriptions.forEach((s) => {\n this.get(s.params, s.cb, s.errorCb);\n });\n }\n\n /**\n * Listen to websocket responses.\n * @private\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @returns {{onMessage: function, errorCb: function}} Object with onMessage and error callbacks\n */\n listen(params, cb, errorCb) {\n const onMessage = (e) => {\n const data = JSON.parse(e.data);\n let source = params.channel;\n source += params.args ? ` ${params.args}` : '';\n\n if (\n data.source === source &&\n (!params.id || params.id === data.client_reference)\n ) {\n cb(data);\n }\n };\n\n this.websocket.addEventListener('message', onMessage);\n\n if (errorCb) {\n this.websocket.addEventListener('error', errorCb);\n this.websocket.addEventListener('close', errorCb);\n }\n\n return { onMessageCb: onMessage, onErrorCb: errorCb };\n }\n\n /**\n * Subscribe to a given channel.\n * @private\n * @param {Object} params Parameters for the websocket get request\n * @param {function} cb callback on listen\n * @param {function} errorCb Callback on error\n * @param {boolean} quiet if subscribe should be quiet\n */\n subscribe(params, cb, errorCb, quiet) {\n const { onMessageCb, onErrorCb } = this.listen(params, cb, errorCb);\n const reqStr = WebSocketConnector.getRequestString('', params);\n\n if (!quiet) {\n this.subscriptions.push({ params, cb, errorCb, onMessageCb, onErrorCb });\n }\n\n if (!this.subscribed[reqStr]) {\n this.send(`GET ${reqStr}`);\n this.send(`SUB ${reqStr}`);\n this.subscribed[reqStr] = true;\n }\n }\n\n /**\n * Unsubscribe from a channel.\n * @param {string} source source to unsubscribe from\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n * @private\n */\n unsubscribe(source, cb) {\n this.subscriptions\n .filter((s) => {\n return s.params.channel === source && (!cb || s.cb === cb);\n })\n .forEach(({ onMessageCb, onErrorCb }) => {\n this.websocket.removeEventListener('message', onMessageCb);\n if (onErrorCb) {\n this.websocket.removeEventListener('error', onErrorCb);\n this.websocket.removeEventListener('close', onErrorCb);\n }\n });\n\n this.subscriptions = this.subscriptions.filter(\n (s) => s.params.channel !== source || (cb && s.cb !== cb),\n );\n\n // If there is no more subscriptions to this channel we DEL it.\n if (\n source &&\n this.subscribed[source] &&\n !this.subscriptions.find((s) => s.params.channel === source)\n ) {\n this.send(`DEL ${source}`);\n this.subscribed[source] = false;\n }\n }\n}\n\nexport default WebSocketConnector;\n","/**\n * Get the websocket channel suffix, depending on the current mode.\n * @param {String} mode Mode 'topographic' ou 'schematic'.\n * @private\n */\nexport const getModeSuffix = (mode, modes) =>\n mode === modes.SCHEMATIC ? '_schematic' : '';\n\n/**\n * Compare two given departures for sort alogithm,\n * @param {Object} a First departure.\n * @param {Object} b Second departure.\n * @private\n */\nexport const compareDepartures = (a, b, sortByMinArrivalTime = false) => {\n // First LEAVING and HIDDEN, then BOARDING and then sorted by time.\n const topStates = ['HIDDEN', 'LEAVING', 'BOARDING'];\n const aTop = a.has_fzo && topStates.indexOf(a.state) > -1;\n const bTop = b.has_fzo && topStates.indexOf(b.state) > -1;\n\n if (aTop || bTop) {\n if (aTop !== bTop) {\n return aTop ? -1 : 1;\n }\n\n if (a.state !== b.state) {\n // one is leaving\n return topStates.indexOf(a.state) - topStates.indexOf(b.state);\n }\n }\n\n let aDuration = null;\n let bDuration = null;\n const now = Date.now();\n\n if (sortByMinArrivalTime) {\n aDuration = new Date(a.min_arrival_time || a.time).getTime() - now;\n bDuration = new Date(b.min_arrival_time || b.time).getTime() - now;\n } else {\n aDuration = new Date(a.time).getTime() - now;\n bDuration = new Date(b.time).getTime() - now;\n }\n\n return aDuration - bDuration;\n};\n\n/**\n * Remove the delay from arrivalTime and departureTime\n * @private\n */\nexport const cleanStopTime = (content) => {\n if (!content) {\n return;\n }\n content.stations.forEach((station) => {\n // eslint-disable-next-line no-param-reassign\n station.arrivalTimeWithDelay = station.arrivalTime;\n if (station.departureTime) {\n // eslint-disable-next-line no-param-reassign\n station.departureTimeWithDelay = station.departureTime;\n }\n if (station.arrivalDelay) {\n // eslint-disable-next-line no-param-reassign\n station.arrivalTime -= station.arrivalDelay;\n if (station.departureTime) {\n // eslint-disable-next-line no-param-reassign\n station.departureTime -= station.arrivalDelay;\n }\n }\n });\n // eslint-disable-next-line consistent-return\n return content;\n};\n","import WebSocketConnector from './WebSocketConnector';\nimport {\n getModeSuffix,\n cleanStopTime,\n compareDepartures,\n} from './TralisAPIUtils';\n\n/**\n * Enum for Tralis modes.\n * @readonly\n * @typedef {string} TralisMode\n * @property {string} RAW \"raw\"\n * @property {string} SCHEMATIC \"schematic\"\n * @property {string} TOPOGRAPHIC \"topographic\"\n * @enum {TralisMode}\n */\nexport const TralisModes = {\n RAW: 'raw',\n TOPOGRAPHIC: 'topographic',\n SCHEMATIC: 'schematic',\n};\n\n/**\n * Access to Tralis service.\n *\n * @example\n * import { TralisAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TralisAPI({\n * url: \"yourUrl\",\n * apiKey: \"yourApiKey\"\n * });\n *\n * @example\n * import { TralisAPI } from 'mobility-toolbox-js/api';\n *\n * const api = new TralisAPI(\"yourUrl\");\n */\nclass TralisAPI {\n /**\n * Constructor\n *\n * @param {Object|string} options A string representing the url of the service or an object containing the url and the apiKey.\n * @param {string} options.url Service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n * @param {string} [options.prefix=''] Service prefix to specify tenant.\n * @param {string} [options.projection='epsg:3857'] The epsg code of the projection for features.\n * @param {number[4]} [options.bbox=[minX, minY, maxX, maxY] The bounding box to receive data from.\n */\n constructor(options = {}) {\n let wsUrl = null;\n\n if (typeof options === 'string') {\n wsUrl = options;\n } else {\n wsUrl = options.url;\n }\n\n if (options.apiKey) {\n wsUrl = `${wsUrl}?key=${options.apiKey}`;\n }\n\n /** @ignore */\n this.subscribedStationUic = null;\n\n /** @ignore */\n this.departureUpdateTimeout = null;\n\n /** @ignore */\n this.maxDepartureAge = 30;\n\n /** @ignore */\n this.extraGeoms = {};\n\n /** @ignore */\n this.prefix = options.prefix || '';\n\n /** @ignore */\n this.conn = new WebSocketConnector(wsUrl);\n this.conn.setProjection(options.projection || 'epsg:3857');\n\n if (options.bbox) {\n this.conn.setBbox(options.bbox);\n }\n }\n\n /**\n * Subscribe to a channel.\n *\n * @param {string} channel Name of the websocket channel to subscribe.\n * @param {function} onSuccess Callback when the subscription succeeds.\n * @param {function} onError Callback when the subscription fails.\n * @param {boolean} [quiet=false] If true avoid to store the subscription in the subscriptions list.\n * @private\n */\n subscribe(channel, onSuccess, onError, quiet = false) {\n this.conn.subscribe({ channel }, onSuccess, onError, quiet);\n }\n\n /**\n * Unsubscribe to a channel.\n *\n * @param {string} channel Name of the websocket channel to unsubscribe.\n * @param {string} [suffix=''] Suffix to add to the channel name.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n * @private\n */\n unsubscribe(channel, suffix = '', cb) {\n this.conn.unsubscribe(\n `${channel}${getModeSuffix(TralisModes.SCHEMATIC, TralisModes)}${suffix}`,\n cb,\n );\n this.conn.unsubscribe(\n `${channel}${getModeSuffix(\n TralisModes.TOPOGRAPHIC,\n TralisModes,\n )}${suffix}`,\n cb,\n );\n }\n\n /**\n * Filter departures and return an array.\n *\n * @param {Object} depObject The object containing departures by id.\n * @param {boolean} [sortByMinArrivalTime=false] If true sort departures by arrival time.\n * @returns {Array<departure>} Return departures array.\n * @private\n */\n filterDepartures(depObject, sortByMinArrivalTime = false) {\n const departures = Object.keys(depObject).map((k) => depObject[k]);\n departures.sort((a, b) => compareDepartures(a, b, sortByMinArrivalTime));\n\n let future = new Date();\n future.setMinutes(future.getMinutes() + this.maxDepartureAge);\n future = future.getTime();\n\n let past = new Date();\n past.setMinutes(past.getMinutes() - this.maxDepartureAge);\n past = past.getTime();\n\n const departureArray = [];\n const platformsBoarding = [];\n let previousDeparture = null;\n\n for (let i = departures.length - 1; i >= 0; i -= 1) {\n const d = departures[i];\n const t = new Date(d.time).getTime();\n\n // Only show departures within the next 30 minutes\n if (t > past && t < future) {\n // If 2 trains are boarding at the same platform,\n // remove the older one.\n if (d.state === 'BOARDING') {\n if (platformsBoarding.indexOf(d.platform) === -1) {\n platformsBoarding.push(d.platform);\n } else {\n d.state = 'HIDDEN';\n }\n }\n\n // If two trains with the same line number and destinatin\n // and a departure difference < 1 minute, hide the second one.\n if (\n previousDeparture &&\n d.to[0] === previousDeparture.to[0] &&\n Math.abs(t - previousDeparture.time) < 1000 &&\n d.line.name === previousDeparture.line.name\n ) {\n d.state = 'HIDDEN';\n }\n\n if (/(STOP_CANCELLED|JOURNEY_CANCELLED)/.test(d.state)) {\n d.cancelled = true;\n }\n\n previousDeparture = d;\n previousDeparture.time = t;\n departureArray.unshift(d);\n }\n }\n\n return departureArray;\n }\n\n /**\n * Subscribe to departures channel of a given station.\n *\n * @param {number} stationId UIC of the station.\n * @param {Boolean} sortByMinArrivalTime Sort by minimum arrival time\n * @param {function(departures:Departure[])} onMessage Function called on each message of the channel.\n */\n subscribeDepartures(stationId, sortByMinArrivalTime = false, onMessage) {\n window.clearTimeout(this.departureUpdateTimeout);\n this.unsubscribeDepartures();\n this.subscribedStationUic = stationId;\n const channel = stationId ? `timetable_${stationId}` : null;\n const departureObject = {};\n this.subscribe(\n channel,\n (data) => {\n if (data.source === channel) {\n const content = data.content || {};\n const tDiff = new Date(content.timestamp).getTime() - Date.now();\n content.timediff = tDiff;\n departureObject[content.call_id] = content;\n\n window.clearTimeout(this.departureUpdateTimeout);\n this.departureUpdateTimeout = window.setTimeout(() => {\n const departures = this.filterDepartures(\n departureObject,\n sortByMinArrivalTime,\n );\n onMessage(departures);\n }, 100);\n }\n },\n () => {\n onMessage([]);\n },\n );\n }\n\n /**\n * Unsubscribe from current departures channel.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDepartures(cb) {\n if (this.subscribedStationUic) {\n this.unsubscribe(`timetable_${this.subscribedStationUic}`, '', cb);\n this.subscribedStationUic = null;\n }\n }\n\n /**\n * Subscribe to the disruptions channel for tenant.\n *\n * @param {function} onMessage Function called on each message of the channel.\n */\n subscribeDisruptions(onMessage) {\n this.subscribe(`${this.prefix}newsticker`, (data) => {\n onMessage(data.content);\n });\n }\n\n /**\n * Unsubscribe disruptions.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDisruptions(cb) {\n this.unsubscribe(`${this.prefix}newsticker`, '', cb);\n }\n\n /**\n * Return a station with a given uic number and a mode.\n *\n * @param {number} uic UIC of the station.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<Station>} A station.\n */\n getStation(uic, mode) {\n const params = {\n channel: `station${getModeSuffix(mode, TralisModes)}`,\n args: uic,\n };\n\n return new Promise((resolve, reject) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n resolve(data.content);\n } else {\n reject();\n }\n });\n });\n }\n\n /**\n * Update the model's station list for a given mode and a bbox.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {number[4]} bbox The extent where to request.\n * @returns {Promise<Station[]>} An array of stations.\n */\n getStations(mode, bbox) {\n const stations = [];\n if (bbox) {\n this.conn.setBbox(bbox);\n }\n const params = {\n channel: `station${getModeSuffix(mode, TralisModes)}`,\n };\n window.clearTimeout(this.stationUpdateTimeout);\n return new Promise((resolve, reject) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n stations.push(data.content);\n window.clearTimeout(this.stationUpdateTimeout);\n /** @ignore */\n this.stationUpdateTimeout = window.setTimeout(() => {\n resolve(stations);\n }, 50);\n } else {\n reject(data.content);\n }\n });\n });\n }\n\n /**\n * Subscribe to stations channel.\n * One message pro station.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {number[4]} bbox The extent where to request.\n * @param {function(station: Station)} onMessage Function called on each message of the channel.\n */\n subscribeStations(mode, bbox, onMessage) {\n this.unsubscribeStations();\n if (bbox) {\n this.conn.setBbox(bbox);\n }\n this.subscribe(`station${getModeSuffix(mode, TralisModes)}`, (data) => {\n if (data.content) {\n onMessage(data.content);\n }\n });\n }\n\n /**\n * Unsubscribe to stations channel.\n * @param {function} cb The listener callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribe.\n */\n unsubscribeStations(cb) {\n window.clearTimeout(this.stationUpdateTimeout);\n this.unsubscribe('station', '', cb);\n }\n\n /**\n * Subscribe to extra_geoms channel.\n *\n * @param {function(extraGeoms: GeosJSONFeature[])} onMessage Function called on each message of the channel.\n */\n subscribeExtraGeoms(onMessage) {\n this.subscribe('extra_geoms', (data) => {\n const extraGeom = data.content;\n\n if (extraGeom) {\n const { ref } = extraGeom.properties;\n\n if (extraGeom.type === 'Feature') {\n this.extraGeoms[ref] = extraGeom;\n } else {\n delete this.extraGeoms[ref];\n }\n\n onMessage(\n Object.keys(this.extraGeoms).map((key) => this.extraGeoms[key]),\n );\n }\n });\n }\n\n /**\n * Unsubscribe to extra_geoms channel.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeExtraGeoms(cb) {\n this.unsubscribe('extra_geoms', '', cb);\n }\n\n /**\n * Subscribe to trajectory channel.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {function(trajectory: TralisTrajectory)} onMessage Function called on each message of the channel.\n */\n subscribeTrajectory(mode, onMessage) {\n this.unsubscribeTrajectory(onMessage);\n this.subscribe(`trajectory${getModeSuffix(mode, TralisModes)}`, onMessage);\n }\n\n /**\n * Unsubscribe to trajectory channels.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeTrajectory(cb) {\n this.unsubscribe(`trajectory`, '', cb);\n }\n\n /**\n * Subscribe to deleted_vhicles channel.\n *\n * @param {TralisMode} mode Tralis mode.\n * @param {function(response: { content: Vehicle })} onMessage Function called on each message of the channel.\n */\n subscribeDeletedVehicles(mode, onMessage) {\n this.unsubscribeDeletedVehicles();\n this.subscribe(\n `deleted_vehicles${getModeSuffix(mode, TralisModes)}`,\n onMessage,\n );\n }\n\n /**\n * Unsubscribe to deleted_vhicles channels.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeDeletedVehicles(cb) {\n this.unsubscribe('deleted_vehicles', '', cb);\n }\n\n /**\n * Get a full trajectory of a vehicule .\n *\n * @param {string} id A vehicle id.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<FullTrajectory>} Return a full trajectory.\n */\n getFullTrajectory(id, mode) {\n const params = {\n channel: `full_trajectory${getModeSuffix(mode, TralisModes)}_${id}`,\n };\n\n return new Promise((resolve) => {\n this.conn.get(params, (data) => {\n if (data.content) {\n resolve(data.content);\n }\n });\n });\n }\n\n /**\n * Get full trajectories of a vehicules .\n *\n * @param {string[]} ids List of vehicles ids.\n * @param {TralisMode} mode Tralis mode.\n * @returns {Promise<FullTrajectory[]>} Return an array of full trajectories.\n */\n getFullTrajectories(ids, mode) {\n const promises = ids.map((id) => {\n return this.getFullTrajectory(id, mode);\n });\n return Promise.all(promises);\n }\n\n /**\n * Subscribe to full_trajectory channel of a given vehicle.\n *\n * @param {string} id A vehicle id.\n * @param {TralisMode} mode Tralis mode.\n */\n subscribeFullTrajectory(id, mode) {\n // window.clearTimeout(this.fullTrajectoryUpdateTimeout);\n this.unsubscribeFullTrajectory(id);\n this.subscribe(\n `full_trajectory${getModeSuffix(mode, TralisModes)}_${id}`,\n (data) => {\n // eslint-disable-next-line no-console\n console.log('subscribe full_trajectory', data);\n },\n (err) => {\n // eslint-disable-next-line no-console\n console.log('subscribe full_trajectory error', err);\n },\n );\n }\n\n /**\n * Unsubscribe from full_trajectory channel\n *\n * @param {string} id A vehicle id.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeFullTrajectory(id, cb) {\n this.unsubscribe('full_trajectory', `_${id}`, cb);\n }\n\n /**\n * Get the list of stops for this vehicle.\n *\n * @param {string} id A vehicle id.\n * @returns {Promise<StopSequence>} Returns a stop sequence object.\n */\n getStopSequence(id) {\n const params = {\n channel: `stopsequence_${id}`,\n };\n return new Promise((resolve, reject) => {\n this.conn.get(\n params,\n (data) => {\n // Remove the delay from arrivalTime nnd departureTime\n resolve(cleanStopTime(data.content && data.content[0]));\n },\n (err) => {\n reject(err);\n },\n );\n });\n }\n\n /**\n * Get a list of stops for a list of vehicles.\n *\n * @param {string[]} ids List of vehicles ids.\n * @returns {Promise<StopSequence[]>} Return an array of stop sequences.\n */\n getStopSequences(ids) {\n const promises = ids.map((id) => {\n return this.getStopSequence(id);\n });\n return Promise.all(promises);\n }\n\n /**\n * Subscribe to stopsequence channel of a given vehicle.\n *\n * @param {string} id A vehicle id.\n * @param {function(stopSequence: StopSequence)} onMessage Function called on each message of the channel.\n */\n subscribeStopSequence(id, onMessage) {\n window.clearTimeout(this.fullTrajectoryUpdateTimeout);\n this.unsubscribeStopSequence(id);\n\n this.subscribe(\n `stopsequence_${id}`,\n (data) => {\n // Remove the delay from arrivalTime nad departureTime\n onMessage(cleanStopTime(data.content && data.content[0]));\n },\n (err) => {\n // eslint-disable-next-line no-console\n console.log('subscribe stopsequence error', err);\n },\n );\n }\n\n /**\n * Unsubscribe from stopsequence channel\n *\n * @param {string} id A vehicle id.\n * @param {function} cb Callback function to unsubscribe. If null all subscriptions for the channel will be unsubscribed.\n */\n unsubscribeStopSequence(id, cb) {\n this.unsubscribe(`stopsequence`, `_${id}`, cb);\n }\n\n /**\n * Subscribe to healthcheck channel.\n * @param {function} onMessage Callback when the subscribe to healthcheck channel succeeds.\n */\n subscribeHealthCheck(onMessage) {\n this.unsubscribeHealthCheck();\n this.subscribe('healthcheck', onMessage);\n }\n\n /**\n * Unsubscribe to healthcheck channel.\n */\n unsubscribeHealthCheck() {\n this.unsubscribe('healthcheck');\n }\n}\nexport default TralisAPI;\n","/* eslint-disable no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport qs from 'query-string';\nimport { getUTCDateString, getUTCTimeString } from '../timeUtils';\nimport {\n getRadius,\n getBgColor,\n getDelayColor,\n getDelayText,\n getTextColor,\n getTextSize,\n} from '../trackerConfig';\nimport { TrajservAPI } from '../../api';\n\n/**\n * TrajservLayerInterface.\n *\n * @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.\n * @classproperty {boolean} isHoverActive - Activate/deactivate pointer hover effect.\n * @classproperty {function} style - Style of the vehicle.\n * @classproperty {FilterFunction} filter - Time speed.\n * @classproperty {function} sort - Set the filter for tracker features.\n *\n * @extends {TrackerLayerInterface}\n */\nexport class TrajservLayerInterface {\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map|mapboxgl.Map} map A map.\n * @override\n */\n init(map) {}\n\n /**\n * Start to update trajectories and initialize the filter.\n * @override\n */\n start() {}\n\n /**\n * Stop to update trajectories.\n * @override\n */\n stop() {}\n\n /**\n * Set the tracker filter property using class properties.\n * @private\n */\n addTrackerFilters() {}\n\n /**\n * Abort http requests.\n *\n * @private\n */\n abortFetchTrajectories() {}\n\n /**\n * Fetch stations information with a trajectory id.\n * @param {number} trajId The id of the trajectory.\n * @private\n */\n updateTrajectoryStations(trajId) {}\n\n /**\n * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {}\n\n /**\n * Start the update of trajectories.\n * @private\n */\n startUpdateTrajectories() {}\n\n /**\n * Stop the update of trajectories.\n * @private\n */\n stopUpdateTrajectories() {}\n\n /**\n * Update the trajectories\n * @private\n */\n updateTrajectories() {}\n\n /**\n * Define the style of the vehicle.\n * Draw a colored circle depending on train delay.\n *\n * @param {Object} props Properties\n * @private\n */\n defaultStyle(props) {}\n}\n\nconst LINE_FILTER = 'publishedlinename';\nconst ROUTE_FILTER = 'tripnumber';\nconst OPERATOR_FILTER = 'operator';\n\n/**\n * Create a array of filter functions based on some parameters.\n * @param {string} line\n * @param {string} route\n * @param {string} operator\n * @param {string} regexLine\n * @private\n */\nconst createFilters = (line, route, operator, regexLine) => {\n const filterList = [];\n\n if (!line && !route && !operator && !regexLine) {\n return null;\n }\n\n if (regexLine) {\n const regexLineList =\n typeof regexLine === 'string' ? [regexLine] : regexLine;\n const lineFilter = (t) =>\n regexLineList.some((tr) => new RegExp(tr, 'i').test(t.name));\n filterList.push(lineFilter);\n }\n\n if (line) {\n const lineFiltersList = typeof line === 'string' ? line.split(',') : line;\n const lineList = lineFiltersList.map((l) =>\n l.replace(/\\s+/g, '').toUpperCase(),\n );\n const lineFilter = (l) =>\n lineList.some((filter) => filter === l.name.toUpperCase());\n filterList.push(lineFilter);\n }\n\n if (route) {\n const routes = typeof route === 'string' ? route.split(',') : route;\n const routeList = routes.map((item) => parseInt(item, 10));\n const routeFilter = (item) => {\n const routeId = parseInt(item.routeIdentifier.split('.')[0], 10);\n return routeList.some((id) => id === routeId);\n };\n filterList.push(routeFilter);\n }\n\n if (operator) {\n const operatorList = typeof operator === 'string' ? [operator] : operator;\n const operatorFilter = (t) =>\n operatorList.some((op) => new RegExp(op, 'i').test(t.operator));\n filterList.push(operatorFilter);\n }\n\n if (!filterList.length) {\n return null;\n }\n\n return (t) => {\n for (let i = 0; i < filterList.length; i += 1) {\n if (!filterList[i](t)) {\n return false;\n }\n }\n return true;\n };\n};\n\n/**\n * Mixin for TrajservLayerInterface.\n *\n * @param {TrackerLayer} TrackerLayer A {TrackerLayer} class to extend with {TrajservLayerInterface} functionnalities.\n * @return {Class} A class that implements {TrajservLayerInterface} class and extends Base;\n * @private\n */\nconst TrajservLayerMixin = (TrackerLayer) =>\n class extends TrackerLayer {\n /**\n * Define layer's properties.\n *\n * @ignore\n */\n defineProperties(options) {\n super.defineProperties(options);\n let {\n regexPublishedLineName,\n publishedLineName,\n tripNumber,\n operator,\n } = options;\n\n let requestIntervalSeconds = 3;\n let defaultApi;\n if (!options.api) {\n const apiOptions = {};\n if (options.url) {\n apiOptions.url = options.url;\n }\n if (options.apiKey) {\n apiOptions.apiKey = options.apiKey;\n }\n defaultApi = new TrajservAPI(apiOptions);\n }\n Object.defineProperties(this, {\n showVehicleTraj: {\n value:\n options.showVehicleTraj !== undefined\n ? options.showVehicleTraj\n : true,\n writable: true,\n },\n delayDisplay: {\n value: options.delayDisplay || 300000,\n writable: true,\n },\n delayOutlineColor: {\n value: options.delayOutlineColor || '#000000',\n writable: true,\n },\n useDelayStyle: {\n value: options.useDelayStyle || false,\n writable: true,\n },\n requestIntervalSeconds: {\n get: () => {\n return requestIntervalSeconds;\n },\n set: (newRequestIntervalSeconds) => {\n if (newRequestIntervalSeconds !== requestIntervalSeconds) {\n requestIntervalSeconds = newRequestIntervalSeconds;\n if (this.visible) {\n // stop() is call within the start.\n this.start();\n }\n }\n },\n },\n publishedLineName: {\n get: () => {\n return publishedLineName;\n },\n set: (newPublishedLineName) => {\n publishedLineName = newPublishedLineName;\n this.updateFilters();\n },\n },\n tripNumber: {\n get: () => {\n return tripNumber;\n },\n set: (newTripNumber) => {\n tripNumber = newTripNumber;\n this.updateFilters();\n },\n },\n operator: {\n get: () => {\n return operator;\n },\n set: (newOperator) => {\n operator = newOperator;\n this.updateFilters();\n },\n },\n regexPublishedLineName: {\n get: () => {\n return regexPublishedLineName;\n },\n set: (newRegex) => {\n regexPublishedLineName = newRegex;\n this.updateFilters();\n },\n },\n api: {\n value: options.api || defaultApi,\n },\n });\n }\n\n init(map) {\n super.init(map);\n\n // Sort the trajectories.\n if (this.sortFc) {\n this.sort = this.sortFc;\n } else if (this.useDelayStyle) {\n // Automatic sorting depending on delay, higher delay on top.\n this.sort = (a, b) => {\n if (a.delay === null) return 1;\n return a.delay < b.delay ? 1 : -1;\n };\n }\n }\n\n start() {\n this.updateFilters();\n super.start();\n this.startUpdateTrajectories();\n }\n\n stop() {\n this.journeyId = null;\n this.stopUpdateTrajectories();\n this.abortFetchTrajectories();\n super.stop();\n }\n\n updateFilters() {\n // Setting filters from the permalink if no values defined by the layer.\n const parameters = qs.parse(window.location.search.toLowerCase());\n // filter is the property in TrackerLayerMixin.\n this.filter = createFilters(\n this.publishedLineName || parameters[LINE_FILTER],\n this.tripNumber || parameters[ROUTE_FILTER],\n this.operator || parameters[OPERATOR_FILTER],\n this.regexPublishedLineName,\n );\n }\n\n abortFetchTrajectories() {\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n updateTrajectoryStations(trajId) {\n const params = this.getParams({\n id: trajId,\n time: getUTCTimeString(new Date()),\n });\n return this.api.fetchTrajectoryStations(params);\n }\n\n getParams(extraParams = {}) {\n // The 5 seconds more are used as a buffer if the request takes too long.\n const requestIntervalInMs = (this.requestIntervalSeconds + 5) * 1000;\n const intervalMs = this.speed * requestIntervalInMs;\n const now = this.currTime;\n\n let diff = true;\n\n if (\n this.later &&\n now.getTime() >\n this.later.getTime() - this.requestIntervalSeconds * 1000\n ) {\n diff = false;\n }\n if (\n !this.later ||\n !diff ||\n this.later.getTime() - now.getTime() > intervalMs\n ) {\n const later = new Date(now.getTime() + intervalMs);\n this.later = later;\n }\n\n const params = {\n ...extraParams,\n btime: getUTCTimeString(now),\n etime: getUTCTimeString(this.later),\n date: getUTCDateString(now),\n rid: 1,\n a: 1,\n cd: 1,\n nm: 1,\n fl: 1,\n // toff: this.currTime.getTime() / 1000,\n };\n\n // Allow to load only differences between the last request,\n // but currently the Tracker render method doesn't manage to render only diff.\n /* if (diff) {\n // Not working\n params.diff = this.lastRequestTime;\n } */\n return params;\n }\n\n startUpdateTrajectories() {\n this.stopUpdateTrajectories();\n\n this.updateTrajectories();\n this.updateInterval = window.setInterval(() => {\n this.updateTrajectories();\n }, this.requestIntervalSeconds * 1000);\n }\n\n stopUpdateTrajectories() {\n clearInterval(this.updateInterval);\n }\n\n updateTrajectories() {\n this.abortFetchTrajectories();\n this.abortController = new AbortController();\n this.api\n .fetchTrajectories(\n this.getParams({\n attr_det: 1,\n }),\n this.abortController,\n )\n .catch((err) => {\n if (err.name === 'AbortError') {\n // Ignore abort error\n return;\n }\n throw err;\n })\n .then((trajectories) => {\n // Don't set trajectories when the user has aborted the request.\n if (trajectories) {\n this.tracker.setTrajectories(trajectories);\n this.renderTrajectories();\n }\n });\n }\n\n defaultStyle(props, zoom) {\n const {\n type,\n name,\n id,\n color,\n textColor,\n delay,\n cancelled,\n operatorProvidesRealtime,\n } = props;\n const z = Math.min(Math.floor(zoom || 1), 16);\n const hover = this.hoverVehicleId === id;\n const selected = this.selectedVehicleId === id;\n const key = `${z}${type}${name}${operatorProvidesRealtime}${delay}${hover}${selected}${cancelled}`;\n\n if (!this.styleCache[key]) {\n let radius = getRadius(type, z);\n const isDisplayStrokeAndDelay = radius >= 7;\n\n if (radius === 0) {\n this.styleCache[key] = null;\n return null;\n }\n\n if (hover || selected) {\n radius = isDisplayStrokeAndDelay ? radius + 5 : 14;\n }\n const margin = 1;\n const radiusDelay = radius + 2;\n const markerSize = radius * 2;\n\n const canvas = document.createElement('canvas');\n // add space for delay information\n canvas.width = radiusDelay * 2 + margin * 2 + 100;\n canvas.height = radiusDelay * 2 + margin * 2 + 100;\n const ctx = canvas.getContext('2d');\n const origin = canvas.width / 2;\n\n if (isDisplayStrokeAndDelay && delay !== null) {\n // Draw circle delay background\n ctx.save();\n ctx.beginPath();\n ctx.arc(origin, origin, radiusDelay, 0, 2 * Math.PI, false);\n ctx.fillStyle = getDelayColor(delay, cancelled);\n ctx.filter = 'blur(1px)';\n ctx.fill();\n ctx.restore();\n }\n\n // Show delay if feature is hovered or if delay is above 5mins.\n if (\n isDisplayStrokeAndDelay &&\n (hover || delay >= this.delayDisplay || cancelled)\n ) {\n // Draw delay text\n ctx.save();\n ctx.textAlign = 'left';\n ctx.textBaseline = 'middle';\n ctx.font = `bold ${Math.max(\n cancelled ? 19 : 14,\n Math.min(cancelled ? 19 : 17, radius * 1.2),\n )}px arial, sans-serif`;\n ctx.fillStyle = getDelayColor(delay, cancelled, true);\n\n ctx.strokeStyle = this.delayOutlineColor;\n ctx.lineWidth = 1.5;\n const delayText = getDelayText(delay, cancelled);\n ctx.strokeText(delayText, origin + radiusDelay + margin, origin);\n ctx.fillText(delayText, origin + radiusDelay + margin, origin);\n ctx.restore();\n }\n\n // Draw colored circle with black border\n let circleFillColor;\n if (this.useDelayStyle) {\n circleFillColor = getDelayColor(delay, cancelled);\n } else {\n circleFillColor = color || getBgColor(type);\n }\n\n ctx.save();\n if (isDisplayStrokeAndDelay || hover || selected) {\n ctx.lineWidth = 1;\n ctx.strokeStyle = '#000000';\n }\n ctx.fillStyle = circleFillColor;\n ctx.beginPath();\n ctx.arc(origin, origin, radius, 0, 2 * Math.PI, false);\n ctx.fill();\n // Dashed outline if a provider provides realtime but we don't use it.\n if (\n isDisplayStrokeAndDelay &&\n this.useDelayStyle &&\n delay === null &&\n operatorProvidesRealtime === 'yes'\n ) {\n ctx.setLineDash([5, 3]);\n }\n if (isDisplayStrokeAndDelay || hover || selected) {\n ctx.stroke();\n }\n ctx.restore();\n\n // Draw text in the circle\n if (radius > 10) {\n const fontSize = Math.max(radius, 10);\n const textSize = getTextSize(ctx, markerSize, name, fontSize);\n\n // Draw a stroke to the text only if a provider provides realtime but we don't use it.\n if (\n this.useDelayStyle &&\n delay === null &&\n operatorProvidesRealtime === 'yes'\n ) {\n ctx.save();\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'center';\n ctx.font = `bold ${textSize + 2}px Arial`;\n ctx.strokeStyle = circleFillColor;\n ctx.strokeText(name, origin, origin);\n ctx.restore();\n }\n\n // Draw a text\n ctx.save();\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'center';\n ctx.fillStyle = !this.useDelayStyle\n ? textColor || getTextColor(type)\n : '#000000';\n ctx.font = `bold ${textSize}px Arial`;\n ctx.strokeStyle = circleFillColor;\n ctx.strokeText(name, origin, origin);\n ctx.fillText(name, origin, origin);\n ctx.restore();\n }\n\n this.styleCache[key] = canvas;\n }\n\n return this.styleCache[key];\n }\n };\n\nexport default TrajservLayerMixin;\n","import Feature from 'ol/Feature';\nimport { transform as transformCoords } from 'ol/proj';\nimport { buffer, getWidth } from 'ol/extent';\nimport { Point, MultiPoint, LineString } from 'ol/geom';\nimport { Style, Fill, Stroke, Circle } from 'ol/style';\nimport { Vector as VectorLayer } from 'ol/layer';\nimport { Vector as VectorSource } from 'ol/source';\nimport TrackerLayer from './TrackerLayer';\nimport { getUTCTimeString } from '../../common/timeUtils';\nimport { getBgColor } from '../../common/trackerConfig';\nimport mixin from '../../common/mixins/TrajservLayerMixin';\n\n/**\n * Responsible for loading and display data from a Trajserv service.\n *\n * @example\n * import { TrajservLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TrajservLayer({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/trajserv/TrajservAPI%20js~TrajservAPI%20html\">TrajservAPI</a>\n * @see <a href=\"/example/ol-tracker\">OL tracker example</a>\n *\n * @extends {TrackerLayer}\n * @implements {TrajservLayerInterface}\n */\nclass TrajservLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n // We use a group to be able to add custom vector layer in extended class.\n // For example TrajservLayer use a vectorLayer to display the complete trajectory.\n super({\n ...options,\n });\n\n /** @ignore */\n this.vectorLayer = new VectorLayer({\n source: new VectorSource({ features: [] }),\n });\n this.olLayer.getLayers().insertAt(0, this.vectorLayer);\n }\n\n /**\n * Initialize the layer.\n * @param {mapboxgl.Map} map the mapbox map.\n * @override\n */\n init(map) {\n if (!map) {\n return;\n }\n\n map.addLayer(this.vectorLayer);\n super.init(map);\n }\n\n /**\n * Terminate the layer.\n * @override\n */\n terminate() {\n if (this.map) {\n this.map.removeLayer(this.vectorLayer);\n }\n super.terminate();\n }\n\n /**\n * Start the layer.\n * @override\n */\n start() {\n if (!this.map) {\n return;\n }\n super.start();\n /**\n * Array of ol events key, returned by on() or once().\n * @type {Array<ol/events~EventsKey>}\n */\n this.olEventsKeys = [\n ...this.olEventsKeys,\n this.map.on('singleclick', this.onMapClick.bind(this)),\n this.map.on('moveend', this.onMoveEnd.bind(this)),\n ];\n }\n\n /**\n * Callback on 'moveend' event.\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n if (this.selectedVehicleId && this.journeyId) {\n this.highlightTrajectory();\n }\n }\n\n /**\n * Callback on 'singleclick' event.\n * @param {ol/MapEvent~MapEvent} evt\n * @private\n */\n onMapClick(evt) {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n const [vehicle] = this.getVehiclesAtCoordinate(evt.coordinate, 1);\n const features = [];\n\n if (vehicle) {\n const geom = vehicle.coordinate ? new Point(vehicle.coordinate) : null;\n features.push(new Feature({ geometry: geom, ...vehicle }));\n\n if (features.length) {\n /**\n * Id of the selected vehicle\n * @type {string}\n */\n this.selectedVehicleId = features[0].get('id');\n /** @ignore */\n this.journeyId = features[0].get('journeyIdentifier');\n this.updateTrajectoryStations(this.selectedVehicleId).then(\n (trajStations) => {\n this.clickCallbacks.forEach((callback) =>\n callback({ ...vehicle, ...trajStations }, this, evt),\n );\n },\n );\n }\n } else {\n this.selectedVehicleId = null;\n this.vectorLayer.getSource().clear();\n this.clickCallbacks.forEach((callback) => callback(null, this, evt));\n }\n }\n\n /**\n * Draw the trajectory as a line with points for each stop.\n * @param {Array} stationsCoords Array of station coordinates.\n * @param {LineString|MultiLineString} lineGeometry A LineString or a MultiLineString.\n * @param {string} color The color of the line.\n * @private\n */\n drawFullTrajectory(stationsCoords, lineGeometry, color) {\n // Don't allow white lines, use red instead.\n const vehiculeColor = /#ffffff/i.test(color) ? '#ff0000' : color;\n const vectorSource = this.vectorLayer.getSource();\n vectorSource.clear();\n\n if (stationsCoords) {\n const geometry = new MultiPoint(stationsCoords);\n const aboveStationsFeature = new Feature(geometry);\n aboveStationsFeature.setStyle(\n new Style({\n zIndex: 1,\n image: new Circle({\n radius: 5,\n fill: new Fill({\n color: '#000000',\n }),\n }),\n }),\n );\n const belowStationsFeature = new Feature(geometry);\n belowStationsFeature.setStyle(\n new Style({\n zIndex: 4,\n image: new Circle({\n radius: 4,\n fill: new Fill({\n color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n }),\n }),\n }),\n );\n vectorSource.addFeatures([aboveStationsFeature, belowStationsFeature]);\n }\n\n const lineFeat = new Feature({\n geometry: lineGeometry,\n });\n lineFeat.setStyle([\n new Style({\n zIndex: 2,\n stroke: new Stroke({\n color: '#000000',\n width: 6,\n }),\n }),\n new Style({\n zIndex: 3,\n stroke: new Stroke({\n color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n width: 4,\n }),\n }),\n ]);\n vectorSource.addFeature(lineFeat);\n }\n\n /**\n * Fetch stations information with a trajectory ID\n * @param {number} trajId The ID of the trajectory\n * @returns {Promise<TrajectoryStation[]>} A list of stations.\n * @private\n */\n updateTrajectoryStations(trajId) {\n return super.updateTrajectoryStations(trajId).then((trajStations) => {\n /**\n * Array of station coordinates.\n * @type {Array<ol/coordinate~Coordinate>}\n */\n this.stationsCoords = [];\n trajStations.stations.forEach((station) => {\n this.stationsCoords.push(\n transformCoords(station.coordinates, 'EPSG:4326', 'EPSG:3857'),\n );\n });\n\n this.highlightTrajectory();\n return trajStations;\n });\n }\n\n /**\n * Highlight the trajectory of journey.\n * @private\n */\n highlightTrajectory() {\n this.api\n .fetchTrajectoryById(\n this.getParams({\n id: this.journeyId,\n time: getUTCTimeString(new Date()),\n }),\n )\n .then((traj) => {\n const { p: multiLine, t, c } = traj;\n const lineCoords = [];\n multiLine.forEach((line) => {\n line.forEach((point) => {\n lineCoords.push([point.x, point.y]);\n });\n });\n\n this.drawFullTrajectory(\n this.stationsCoords,\n new LineString(lineCoords),\n c ? `#${c}` : getBgColor(t),\n );\n })\n .catch(() => {\n this.vectorLayer.getSource().clear();\n });\n }\n\n /**\n * @override\n * * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {\n const ext = this.map.getView().calculateExtent();\n const bbox = buffer(ext, getWidth(ext) / 10).join(',');\n const zoom = this.map.getView().getZoom();\n\n return super.getParams({\n ...extraParams,\n bbox,\n s: zoom < 10 ? 1 : 0,\n z: zoom,\n });\n }\n\n /** @ignore */\n defaultStyle(props) {\n const zoom = this.map.getView().getZoom();\n return super.defaultStyle(props, zoom);\n }\n\n /**\n * Create a copy of the TrajservLayer.\n * @param {Object} newOptions Options to override\n * @returns {TrajservLayer} A TrajservLayer\n */\n clone(newOptions) {\n return new TrajservLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TrajservLayer;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport GeoJSON from 'ol/format/GeoJSON';\nimport Point from 'ol/geom/Point';\nimport { TralisAPI, TralisModes } from '../../api';\n\n/**\n * TralisLayerInterface.\n */\nexport class TralisLayerInterface {\n /*\n * Constructor\n\n * @param {Object} options Layer options.\n * @param {string} options.url Tralis service url.\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).\n * @param {boolean} [options.debug=false] Display additional debug informations.\n * @param {TralisMode} [options.mode=TralisMode.TOPOGRAPHIC] - Mode.\n * @param {number} [options.dfltIconScale=0.6] - Scale of vehicle icons.\n * @param {number} [options.dfltIconHighlightScale=0.8] - Scale of vehicle icons when they are highlighted.\n */\n constructor(options = {}) {}\n\n /**\n * Subscribe to the Tralis service.\n *\n * @param {ol/Map~Map} map\n */\n init(map) {}\n\n /**\n * Unsubscribe to the Tralis service.\n */\n terminate() {}\n\n /**\n * Change the mode.\n *\n * @param {TralisMode} mode Tralis mode\n */\n setMode(mode) {}\n\n /**\n * Add a feature to the tracker.\n * @param {number} id The feature id\n * @param {Trajectory} traj Properties of the trajectory.\n * @param {boolean} [addOnTop=false] If true, the trajectory is added on top of\n * the trajectory object. This affects the draw order. If addOnTop is\n * true, the trajectory is drawn first and appears on bottom.\n * @private\n */\n addTrajectory(id, traj, addOnTop = false) {}\n\n /**\n * Remove a trajectory with a given id.\n * @param {number} id The trajectory id\n * @private\n */\n removeTrajectory(id) {}\n\n /**\n * Remove a trajectory by attribute.\n * @param {string} attributeName Name of the attribute.\n * @param {*} value Attribute value.\n * @private\n */\n removeTrajectoryByAttribute(attributeName, value) {}\n}\n\n/**\n * Mixin for TralisLayerInterface.\n *\n * @param {TrackerLayer} TrackerLayer A {TrackerLayer} class to extend with {TrajservLayerInterface} functionnalities.\n * @return {Class} A class that implements {TralisLayerInterface} class and extends Base;\n * @private\n */\nconst TralisLayerMixin = (TrackerLayer) =>\n class extends TrackerLayer {\n constructor(options = {}) {\n super({ ...options });\n this.debug = options.debug;\n this.mode = options.mode || TralisModes.TOPOGRAPHIC;\n this.trajectories = [];\n this.refreshTimeInMs = 1000 / 30;\n this.onMessage = this.onMessage.bind(this);\n this.onDeleteMessage = this.onDeleteMessage.bind(this);\n this.api = options.api || new TralisAPI(options);\n this.format = new GeoJSON();\n\n // These scales depends from the size specifed in the svgs.\n // For some reason the size must be specified in the svg (../img/lines) for firefox.\n this.dfltIconScale = options.dfltIconScale || 0.6;\n this.dfltIconHighlightScale = options.dfltIconHighlightScale || 0.8;\n this.minIconScale = this.dfltIconScale * 0.75;\n }\n\n init(map) {\n super.init(map);\n this.api.subscribeTrajectory(this.mode, this.onMessage);\n this.api.subscribeDeletedVehicles(this.mode, this.onDeleteMessage);\n }\n\n terminate() {\n this.api.unsubscribeTrajectory(this.onMessage);\n this.api.unsubscribeDeletedVehicles(this.onDeleteMessage);\n super.terminate();\n }\n\n setMode(mode) {\n if (this.mode === mode) {\n return;\n }\n this.mode = mode;\n this.api.subscribeTrajectory(this.mode, this.onMessage);\n this.api.subscribeDeletedVehicles(this.mode, this.onDeleteMessage);\n }\n\n onMessage(data) {\n if (!data.content) {\n return;\n }\n const feat = this.format.readFeature(data.content);\n\n feat.set('timeOffset', Date.now() - data.timestamp);\n\n // ignore old events [SBAHNM-97]\n if (feat.get('time_since_update') >= 0) {\n if (\n this.debug &&\n this.mode === TralisModes.TOPOGRAPHIC &&\n feat.get('raw_coordinates')\n ) {\n const point = new Point(feat.get('raw_coordinates'));\n point.transform('EPSG:4326', this.map.getView().getProjection());\n feat.setGeometry(point);\n }\n\n this.addTrajectory(\n feat.get('train_id'),\n feat.getProperties(),\n !feat.get('line'),\n );\n }\n }\n\n onDeleteMessage(data) {\n if (data.content) {\n this.removeTrajectoryByAttribute('train_id', data.content);\n }\n }\n\n addTrajectory(id, traj, addOnTop) {\n const idx = this.trajectories.findIndex((t) => t.train_id === id);\n const { time_intervals: timeIntervals } = traj;\n\n // Properties needed to display the vehicle.\n const trajectory = { ...traj, id, timeIntervals };\n if (addOnTop) {\n this.trajectories.unshift(trajectory);\n if (idx !== -1) {\n this.tracker.trajectories.splice(idx + 1, 1);\n }\n } else {\n this.trajectories.push(trajectory);\n if (idx !== -1) {\n this.tracker.trajectories.splice(idx, 1);\n }\n }\n\n this.updateTrajectories();\n }\n\n removeTrajectory(id) {\n for (let i = 0, len = this.trajectories.length; i < len; i += 1) {\n if (this.trajectories[i].id === id) {\n this.trajectories.splice(i, 1);\n break;\n }\n }\n }\n\n removeTrajectoryByAttribute(attributeName, value) {\n for (let i = 0, len = this.trajectories.length; i < len; i += 1) {\n if (this.trajectories[i][attributeName] === value) {\n this.removeTrajectory(this.trajectories[i].id);\n break;\n }\n }\n }\n\n updateTrajectories() {\n this.tracker.setTrajectories(this.trajectories);\n this.renderTrajectories();\n }\n\n getRefreshTimeInMs() {\n return this.refreshTimeInMs;\n }\n };\n\nexport default TralisLayerMixin;\n","import TrackerLayer from './TrackerLayer';\nimport mixin from '../../common/mixins/TralisLayerMixin';\n\n/**\n * Responsible for loading and display data from a Tralis service.\n *\n * @example\n * import { TralisLayer } from 'mobility-toolbox-js/ol';\n *\n * const layer = new TralisLayer({\n * url: [yourUrl],\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html\">TralisAPI</a>\n *\n * @extends {TrackerLayer}\n * @implements {TralisLayerInterface}\n */\nclass TralisLayer extends mixin(TrackerLayer) {\n /**\n * Create a copy of the TralisLayer.\n * @param {Object} newOptions Options to override\n * @returns {TralisLayer} A TralisLayer\n */\n clone(newOptions) {\n return new TralisLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default TralisLayer;\n","import { unByKey } from 'ol/Observable';\nimport Layer from './Layer';\n\n/**\n * A class use to display vector data.\n *\n * @extends {Layer}\n */\nclass VectorLayer extends Layer {\n /**\n * Constructor.\n *\n * @param {Object} [options]\n * @param {number} [options.hitTolerance=5] Pixel value of the click hitTolerance of clicks.\n */\n constructor(options = {}) {\n super(options);\n\n /** @ignore */\n this.hitTolerance = options.hitTolerance || 5;\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate the coordinate to request the information at.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit.\n * eslint-disable-next-line class-methods-use-this\n */\n getFeatureInfoAtCoordinate(coordinate) {\n let features = [];\n\n if (this.map) {\n const pixel = this.map.getPixelFromCoordinate(coordinate);\n features = this.map.getFeaturesAtPixel(pixel, {\n layerFilter: (l) => l === this.olLayer,\n hitTolerance: this.hitTolerance,\n });\n }\n\n return Promise.resolve({\n features,\n layer: this,\n coordinate,\n });\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map\n */\n init(map) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n /**\n * ol click events key, returned by map.on('singleclick')\n * @type {ol/events~EventsKey}\n * @private\n */\n this.singleClickRef = this.map.on('singleclick', (e) => {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n this.getFeatureInfoAtCoordinate(e.coordinate)\n .then((d) => this.callClickCallbacks(d.features, d.layer, d.coordinate))\n .catch(() => this.callClickCallbacks([], this, e.coordinate));\n });\n }\n\n /**\n * Call click callbacks with given parameters.\n * This is done in a separate function for being able to modify the response.\n * @param {Array<ol/Feature~Feature>} features\n * @param {ol/layer/Layer~Layer} layer\n * @param {ol/coordinate~Coordinate} coordinate\n * @private\n */\n callClickCallbacks(features, layer, coordinate) {\n this.clickCallbacks.forEach((c) => c(features, layer, coordinate));\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n super.terminate();\n if (this.singleClickRef) {\n unByKey(this.singleClickRef);\n }\n }\n\n /**\n * Create a copy of the VectorLayer.\n * @param {Object} newOptions Options to override\n * @returns {VectorLayer} A VectorLayer\n */\n clone(newOptions) {\n return new VectorLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default VectorLayer;\n","import GeoJSON from 'ol/format/GeoJSON';\nimport { unByKey } from 'ol/Observable';\nimport Layer from './Layer';\n\n/**\n * Class use to display a WMS layer.\n *\n * @extends {Layer}\n */\nclass WMSLayer extends Layer {\n /**\n * @inheritdoc\n */\n constructor(options = {}) {\n super(options);\n\n /** @ignore */\n this.abortController = new AbortController();\n /** @ignore */\n this.format = new GeoJSON();\n }\n\n /**\n * Get features infos' Url.\n * @param {ol/coordinate~Coordinate} coord\n * @returns {ol/layer/Layer~Layer}\n */\n getFeatureInfoUrl(coord) {\n const projection = this.map.getView().getProjection();\n const resolution = this.map.getView().getResolution();\n\n if (this.olLayer.getSource().getFeatureInfoUrl) {\n return this.olLayer\n .getSource()\n .getFeatureInfoUrl(coord, resolution, projection, {\n info_format: 'application/json',\n query_layers: this.olLayer.getSource().getParams().layers,\n });\n }\n return false;\n }\n\n /**\n * Request feature information for a given coordinate.\n * @param {ol/coordinate~Coordinate} coordinate to request the information at.\n * @returns {Promise<Object>} Promise with features, layer and coordinate\n * or null if no feature was hit.\n * eslint-disable-next-line class-methods-use-this\n */\n getFeatureInfoAtCoordinate(coordinate) {\n this.abortController.abort();\n this.abortController = new AbortController();\n const { signal } = this.abortController;\n return fetch(this.getFeatureInfoUrl(coordinate), { signal })\n .then((resp) => resp.json())\n .then((r) => r.features)\n .then((data) => ({\n layer: this,\n coordinate,\n features: data.map((d) => this.format.readFeature(d)),\n }))\n .catch(() =>\n // resolve an empty feature array something fails\n Promise.resolve({\n features: [],\n coordinate,\n layer: this,\n }),\n );\n }\n\n /**\n * Initialize the layer and listen to feature clicks.\n * @param {ol/Map~Map} map An OpenLayers map.\n */\n init(map) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n /**\n * ol click events key, returned by map.on('singleclick')\n * @private\n * @type {ol/events~EventsKey}\n */\n this.singleClickRef = this.map.on('singleclick', (e) => {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n this.getFeatureInfoAtCoordinate(e.coordinate).then((data) =>\n this.callClickCallbacks(data.features, data.layer, data.coordinate),\n );\n });\n }\n\n /**\n * Call click callbacks with given parameters.\n * This is done in a separate function for being able to modify the response.\n * @param {Array<ol/Feature~Feature>} features\n * @param {ol/layer/Layer~Layer} layer\n * @param {ol/coordinate~Coordinate} coordinate\n * @private\n */\n callClickCallbacks(features, layer, coordinate) {\n this.clickCallbacks.forEach((c) => c(features, layer, coordinate));\n }\n\n /**\n * Terminate what was initialized in init function. Remove layer, events...\n */\n terminate() {\n super.terminate();\n if (this.singleClickRef) {\n unByKey(this.singleClickRef);\n }\n }\n\n /**\n * Create a copy of the WMSLayer.\n * @param {Object} newOptions Options to override\n * @returns {WMSLayer} A WMSLayer\n */\n clone(newOptions) {\n return new WMSLayer({ ...this.options, ...newOptions });\n }\n}\n\nexport default WMSLayer;\n","/* eslint-disable no-empty-function */\n/* eslint-disable no-useless-constructor */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport StopsAPI from '../../api/stops/StopsAPI';\n\n/**\n * Search control interface.\n *\n * @classproperty {StopsSearchParams} apiParams - Default request parameters used by the search method. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n */\nexport class SearchInterface {\n /**\n * Constructor.\n *\n * @param {Object} options Map options\n * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/). See StopsAPI.\n * @param {string} [options.url='https://api.geops.io/tracker/v1'] Stops service url. See StopsAPI.\n * @param {string} [options.placeholder='Search for a stop...'] Input field placeholder.\n * @param {StopsSearchParams} [options.apiParams={ limit: 20 }] Request parameters. See [Stops service documentation](https://developer.geops.io/apis/5dcbd702a256d90001cf1361/).\n */\n // eslint-disable-next-line no-unused-vars\n constructor(options = {}) {}\n\n /**\n * Launch a search.\n *\n * @param {String} query The query to search for.\n * @param {AbortController} abortController Abort controller used to cancel the request.\n * @returns {Promise<GeoJSONFeature[]>} An array of GeoJSON features with coordinates in [EPSG:4326](http://epsg.io/4326).\n */\n // eslint-disable-next-line no-unused-vars\n search(query, abortController) {}\n}\n\n/**\n * Mixin for SearchInterface.\n *\n * @param {Class} Base A class to extend with {SearchInterface} functionnalities.\n * @return {Class} A class that implements <SearchInterface> class and extends Base;\n * @private\n */\nconst SearchMixin = (Base) =>\n class extends Base {\n constructor(options = {}) {\n super(options);\n const { apiParams, apiKey, url } = options;\n\n this.apiParams = { limit: 20, ...(apiParams || {}) };\n this.placeholder = options.placeholder || 'Search for a stop...';\n\n const apiOptions = { apiKey };\n if (url) {\n apiOptions.url = url;\n }\n this.api = new StopsAPI(apiOptions);\n }\n\n render(suggestions = []) {\n if (!this.suggestionsElt) {\n return;\n }\n\n this.suggestionsElt.style.display = suggestions.length ? 'block' : 'none';\n\n this.suggestionsElt.innerHTML = '';\n\n suggestions.forEach((suggestion) => {\n const { properties } = suggestion;\n const suggElt = document.createElement('div');\n suggElt.innerHTML = properties.name;\n suggElt.onclick = () => {\n this.onSuggestionClick(suggestion);\n };\n Object.assign(suggElt.style, {\n padding: '5px 12px',\n });\n this.suggestionsElt.appendChild(suggElt);\n });\n }\n\n createDefaultElement() {\n /**\n * Define a default element.\n */\n this.element = document.createElement('div');\n this.element.id = 'mbt-search';\n Object.assign(this.element.style, {\n position: 'absolute',\n top: 0,\n left: '50px',\n margin: '10px',\n display: 'flex',\n flexDirection: 'column',\n width: '320px',\n });\n\n // Create input element\n this.inputElt = document.createElement('input');\n this.inputElt.type = 'text';\n this.inputElt.placeholder = this.placeholder;\n this.inputElt.autoComplete = 'off';\n this.inputElt.onkeyup = (evt) => {\n this.search(evt.target.value);\n };\n Object.assign(this.inputElt.style, {\n padding: '10px 30px 10px 10px',\n });\n this.element.appendChild(this.inputElt);\n\n // Create suggestions list element\n this.suggestionsElt = document.createElement('div');\n Object.assign(this.suggestionsElt.style, {\n backgroundColor: 'white',\n overflowY: 'auto',\n cursor: 'pointer',\n });\n this.element.appendChild(this.suggestionsElt);\n\n this.clearElt = document.createElement('div');\n Object.assign(this.clearElt.style, {\n display: 'none',\n position: 'absolute',\n right: '0',\n padding: '10px',\n fontSize: '200%',\n cursor: 'pointer',\n });\n this.clearElt.innerHTML = '×';\n this.clearElt.onclick = () => this.clear();\n this.element.appendChild(this.clearElt);\n }\n\n search(q, abortController) {\n if (q !== undefined || q !== null) {\n this.apiParams.q = q;\n }\n\n if (this.clearElt) {\n this.clearElt.style.display = 'block';\n }\n\n return this.api\n .search(this.apiParams, abortController)\n .then((data) => {\n this.render(data);\n })\n .catch(() => {\n this.render();\n });\n }\n\n /**\n * To be defined in inherited class\n */\n // eslint-disable-next-line no-unused-vars\n onSuggestionClick(suggestion) {}\n\n /**\n * Clear the search field and close the control.\n */\n clear() {\n if (!this.suggestionsElt) {\n return;\n }\n\n this.inputElt.value = '';\n this.suggestionsElt.innerHTML = '';\n this.clearElt.style.display = 'none';\n }\n };\n\nexport default SearchMixin;\n","import { fromLonLat } from 'ol/proj';\nimport Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/SearchMixin';\n\n/**\n * Search stations.\n *\n * @example\n * import { Map, StopFinderControl } from 'mobility-toolbox-js/ol';\n *\n * const map = new Map({\n * target: 'map',\n * controls: [\n * new StopFinderControl({\n * apiKey: [yourApiKey]\n * })\n * ]\n * });\n *\n *\n * @see <a href=\"/example/ol-search\">Openlayers search example</a>\n *\n * @extends {Control}\n * @implements {SearchInterface}\n */\nclass StopFinderControl extends mixin(Control) {\n /**\n * @private\n */\n onSuggestionClick({ geometry }) {\n const coord = fromLonLat(geometry.coordinates);\n this.map.getView().setCenter(coord);\n }\n}\n\nexport default StopFinderControl;\n","import Control from '../../common/controls/Control';\nimport mixin from '../../common/mixins/CopyrightMixin';\nimport { getMapboxMapCopyrights } from '../../common/utils';\n\n/**\n * Display layer's copyrights.\n *\n * @example\n * import { Map, CopyrightControl } from 'mobility-toolbox-js/mapbox';\n *\n * const map = new Map({\n * container: 'map',\n * style: `https://maps.geops.io/styles/travic_v2/style.json?key=${window.apiKey}`,\n * controls: [\n * new CopyrightControl()\n * ]\n * });\n *\n *\n * @see <a href=\"/example/mb-copyright\">Mapbox copyright example</a>\n *\n * @extends {Control}\n * @implements {CopyrightInterface}\n */\nclass CopyrightControl extends mixin(Control) {\n constructor(options) {\n super(options);\n this.render = this.render.bind(this);\n }\n\n activate() {\n super.activate();\n if (this.map) {\n this.map.on('sourcedata', this.render);\n this.map.on('styledata', this.render);\n this.map.on('idle', this.render);\n }\n }\n\n deactivate() {\n if (this.map) {\n this.map.off('sourcedata', this.render);\n this.map.off('styledata', this.render);\n this.map.off('idle', this.render);\n }\n super.deactivate();\n }\n\n getCopyrights() {\n return getMapboxMapCopyrights(this.map);\n }\n}\n\nexport default CopyrightControl;\n","import { Map as MBMap } from 'mapbox-gl';\nimport Layer from '../common/layers/Layer';\nimport mixin from '../common/mixins/MapMixin';\nimport CopyrightControl from './controls/CopyrightControl';\nimport getMapboxStyleUrl from '../common/utils/getMapboxStyleUrl';\n\n/**\n * An Mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map) for handling mobility layers and controls.\n *\n * @extends {mapboxgl.Map}\n * @implements {MapInterface}\n */\nclass Map extends mixin(MBMap) {\n /**\n * Constructor.\n */\n constructor(options) {\n const { style } = options;\n const apiKey = options.apiKey || false;\n const apiKeyName = options.apiKeyName || 'key';\n let newStyle = options.style;\n if (typeof style === 'string') {\n newStyle = getMapboxStyleUrl(apiKey, apiKeyName, style);\n }\n super({\n attributionControl: false,\n controls: [new CopyrightControl()],\n ...options,\n style: newStyle,\n });\n }\n\n /**\n * Adds a layer to the map.\n * @param {Layer|mapboxgl.Layer} layer The layer to add.\n * @param {number} beforeId See [mapbox-gl-js doc](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer)\n */\n addLayer(layer, beforeId) {\n if (layer instanceof Layer) {\n this.mobilityLayers.push(layer);\n this.fire('change:mobilityLayers');\n\n if (this.isStyleLoaded()) {\n layer.init(this, beforeId);\n } else {\n this.on('load', () => {\n layer.init(this, beforeId);\n });\n }\n } else {\n super.addLayer(layer, beforeId);\n }\n }\n\n /**\n * Removes a given layer from the map.\n * @param {Layer|number} layer The layer to remove.\n * If it's a mapbox-layer, pass the id instead..\n */\n removeLayer(layer) {\n if (layer instanceof Layer) {\n layer.terminate();\n this.mobilityLayers = this.mobilityLayers.filter((l) => l !== layer);\n } else {\n super.removeLayer(layer);\n }\n }\n\n /**\n * Adds a given control to the map.\n * @param {Control|mapboxgl.IControl} control The control to add.\n * @param {mapboxgl.position} position Position of the control. Only if control parameter is an <mapboxgl.IControl>.\n */\n addControl(control, position) {\n super.addControl(control, position);\n }\n\n /**\n * Removes a given control to the map.\n * @param {Control|mapboxgl.IControl} control The control to remove.\n */\n removeControl(control) {\n super.removeControl(control);\n }\n}\n\nexport default Map;\n","import { fromLonLat } from 'ol/proj';\nimport { getWidth, getHeight } from 'ol/extent';\n\n/**\n * Get the current resolution of a Mapbox map.\n * @param {mapboxgl.Map} map A map object.\n * @private\n */\nexport const getResolution = (map) => {\n const bounds = map.getBounds().toArray();\n const extent = [...fromLonLat(bounds[0]), ...fromLonLat(bounds[1])];\n const { width, height } = map.getCanvas();\n const xResolution = getWidth(extent) / width;\n const yResolution = getHeight(extent) / height;\n return Math.max(xResolution, yResolution);\n};\n\n/**\n * Get the canvas source coordinates of the current map's extent.\n * @param {mapboxgl.Map} map A map object.\n * @private\n */\nexport const getSourceCoordinates = (map) => {\n const bounds = map.getBounds().toArray();\n return [\n [bounds[0][0], bounds[1][1]],\n [...bounds[1]],\n [bounds[1][0], bounds[0][1]],\n [...bounds[0]],\n ];\n};\n\nexport default {\n getResolution,\n getSourceCoordinates,\n};\n","import { toLonLat, fromLonLat } from 'ol/proj';\nimport Layer from '../../common/layers/Layer';\nimport mixin from '../../common/mixins/TrackerLayerMixin';\nimport { getResolution } from '../utils';\n\n/**\n * Responsible for loading tracker data.\n *\n * @extends {Layer}\n * @implements {TrackerLayerInterface}\n */\nclass TrackerLayer extends mixin(Layer) {\n constructor(options = {}) {\n super({\n ...options,\n });\n\n /** @ignores */\n this.onMapZoomEnd = this.onMapZoomEnd.bind(this);\n /** @ignores */\n this.onMapMouseMove = this.onMapMouseMove.bind(this);\n }\n\n /**\n * Update the icon scale if the window (and probably the canvas) is resized.\n * @private\n */\n updateIconScale(canvas) {\n this.tracker.setIconScale(canvas.width / canvas.clientWidth);\n }\n\n /**\n * Initialize the layer.\n *\n * @param {mapboxgl.Map} map A [mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map/).\n * @override\n */\n init(map) {\n if (!map) {\n return;\n }\n\n const canvas = map.getCanvas();\n const iconScale = canvas.width / canvas.clientWidth;\n map.on('resize', this.updateIconScale.bind(this, canvas));\n\n super.init(map, {\n width: canvas.width,\n height: canvas.height,\n iconScale,\n getPixelFromCoordinate: (coord) => {\n const pixelRatio = window.devicePixelRatio || 1;\n const [lng, lat] = toLonLat(coord);\n const { x, y } = this.map.project({ lng, lat });\n return [x * pixelRatio, y * pixelRatio];\n },\n });\n }\n\n terminate() {\n if (this.map) {\n this.map.off('resize', this.updateIconScale);\n }\n return super.terminate();\n }\n\n /**\n * Set the current time, it triggers a rendering of the trajectories.\n *\n * @param {Date} time The current time.\n */\n setCurrTime(time) {\n const canvas = this.map.getCanvas();\n super.setCurrTime(\n time,\n [canvas.width, canvas.height],\n getResolution(this.map),\n !this.map.isMoving() && !this.map.isRotating() && !this.map.isZooming(),\n );\n }\n\n /**\n * Start updating vehicles position.\n *\n * @listens {mapboxgl.map.event:zoomend} Listen to zoom end event.\n * @listens {mapboxgl.map.event:mousemove} Listen to mousemove end.\n * @override\n */\n start() {\n const canvas = this.map.getCanvas();\n super.start(\n [canvas.width, canvas.height],\n this.map.getZoom(),\n getResolution(this.map),\n );\n\n this.map.on('zoomend', this.onMapZoomEnd);\n\n if (this.isHoverActive) {\n this.map.on('mousemove', this.onMapMouseMove);\n }\n }\n\n /**\n * Stop updating vehicles position, and unlisten events.\n *\n * @override\n */\n stop() {\n super.stop();\n if (this.map) {\n this.map.off('zoomend', this.onMapZoomEnd);\n this.map.off('mousemove', this.onMapMouseMove);\n }\n }\n\n /**\n * Returns an array of vehicles located at the given coordinate.\n *\n * @param {Array<number>} coordinate\n * @param {number} nb Number of vehicles to return;\n * @returns {Array<ol/Feature~Feature>} Array of vehicle.\n * @override\n */\n getVehiclesAtCoordinate(coordinate, nb) {\n const resolution = getResolution(this.map);\n return super.getVehiclesAtCoordinate(coordinate, resolution, nb);\n }\n\n /**\n * On zoomend we adjust the time interval of the update of vehicles positions.\n *\n * @private\n */\n onMapZoomEnd() {\n this.startUpdateTime(this.map.getZoom());\n }\n\n /**\n * On mousemove, we detect if a vehicle is heovered then updates the cursor's style.\n *\n * @param {mapboxgl.MapMouseEvent} evt Map's mousemove event.\n * @private\n */\n onMapMouseMove(evt) {\n if (\n this.map.isMoving() ||\n this.map.isRotating() ||\n this.map.isZooming() ||\n !this.isHoverActive\n ) {\n this.map.getContainer().style.cursor = 'auto';\n return;\n }\n const [vehicle] = this.getVehiclesAtCoordinate(\n fromLonLat([evt.lngLat.lng, evt.lngLat.lat]),\n 1,\n );\n\n const id = vehicle && vehicle.id;\n if (this.hoverVehicleId !== id) {\n this.map.getContainer().style.cursor = vehicle ? 'pointer' : 'auto';\n this.hoverVehicleId = id;\n // We doesn´t wait the next render, we force it.\n this.renderTrajectories(this.currTime);\n }\n }\n}\n\nexport default TrackerLayer;\n","import TrackerLayer from './TrackerLayer';\nimport { getSourceCoordinates, getResolution } from '../utils';\nimport mixin from '../../common/mixins/TralisLayerMixin';\n\n/**\n * Responsible for loading and display data from a Tralis service.\n *\n * @example\n * import { TralisLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TralisLayer({\n * url: [yourUrl],\n * apiKey: [yourApiKey],\n * });\n *\n *\n * @see <a href=\"/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html\">TralisAPI</a>\n *\n * @extends {TrackerLayer}\n * @implements {TralisLayerInterface}\n */\nclass TralisLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n super({ ...options });\n\n /** @ignore */\n this.onMove = this.onMove.bind(this);\n /** @ignore */\n this.onMoveEnd = this.onMoveEnd.bind(this);\n }\n\n /**\n * Add listeners from the Mapbox Map.\n *\n * @param {mapboxgl.Map} map\n * @param {string} beforeId See [mapboxgl.Map#addLayer](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer) beforeId documentation.\n */\n init(map, beforeId) {\n super.init(map);\n\n if (!this.map) {\n return;\n }\n\n this.map.on('zoomend', this.onZoomEnd);\n this.map.on('move', this.onMove);\n this.map.on('moveend', this.onMoveEnd);\n\n const { width, height } = this.map.getCanvas();\n this.tracker.canvas.width = width;\n this.tracker.canvas.height = height;\n\n this.map.addSource('canvas-source', {\n type: 'canvas',\n canvas: this.tracker.canvas,\n coordinates: getSourceCoordinates(this.map),\n // Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.\n animate: true,\n });\n this.map.addLayer(\n {\n id: 'canvas-layer',\n type: 'raster',\n source: 'canvas-source',\n paint: {\n 'raster-opacity': 1,\n 'raster-fade-duration': 0,\n },\n },\n beforeId,\n );\n }\n\n /**\n * Remove listeners from the Mapbox Map.\n */\n terminate() {\n if (this.map) {\n this.map.off('zoomend', this.onZoomEnd);\n this.map.off('move', this.onMove);\n this.map.off('moveend', this.onMoveEnd);\n }\n super.terminate();\n }\n\n /**\n * Callback on 'move' event.\n *\n * @private\n */\n onMove() {\n this.map\n .getSource('canvas-source')\n .setCoordinates(getSourceCoordinates(this.map));\n const { width, height } = this.map.getCanvas();\n this.renderTrajectories(\n this.currTime,\n [width, height],\n getResolution(this.map),\n );\n }\n\n /**\n * Callback on 'moveend' event.\n *\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n }\n}\n\nexport default TralisLayer;\n","import Map from './ol/Map';\nimport {\n Layer as olLayer,\n WMSLayer as olWMSLayer,\n MapboxLayer as olMapboxLayer,\n TrajservLayer as olTrajservLayer,\n TralisLayer as olTralisLayer,\n VectorLayer as olVectorLayer,\n} from './ol';\nimport {\n TrajservLayer as mbTrajservLayer,\n TralisLayer as mbTralisLayer,\n} from './mapbox';\n\nconst exports = {\n mapbox: {\n TrajservLayer: mbTrajservLayer,\n TralisLayer: mbTralisLayer,\n },\n ol: {\n Map,\n Layer: olLayer,\n WMSLayer: olWMSLayer,\n MapboxLayer: olMapboxLayer,\n TrajservLayer: olTrajservLayer,\n TralisLayer: olTralisLayer,\n VectorLayer: olVectorLayer,\n },\n};\n\nexport default exports;\n","import { fromLonLat } from 'ol/proj';\nimport { buffer, getWidth } from 'ol/extent';\nimport { unByKey } from 'ol/Observable';\nimport TrackerLayer from './TrackerLayer';\nimport mixin from '../../common/mixins/TrajservLayerMixin';\nimport { getUTCTimeString } from '../../common/timeUtils';\nimport { getSourceCoordinates, getResolution } from '../utils';\n\n/**\n * Responsible for loading and display data from a Trajserv service.\n *\n * @example\n * import { TrajservLayer } from 'mobility-toolbox-js/mapbox';\n *\n * const layer = new TrajservLayer({\n * url: 'https://api.geops.io/tracker/v1',\n * apiKey: [yourApiKey],\n * });\n *\n * @see <a href=\"/api/class/src/api/trajserv/TrajservAPI%20js~TrajservAPI%20html\">TrajservAPI</a>\n * @see <a href=\"/example/mapbox-tracker\">Mapbox tracker example</a>\n *\n * @extends {TrackerLayer}\n * @implements {TrajservLayerInterface}\n */\nclass TrajservLayer extends mixin(TrackerLayer) {\n constructor(options = {}) {\n super({ ...options });\n this.onMapClick = this.onMapClick.bind(this);\n this.onMove = this.onMove.bind(this);\n this.onMoveEnd = this.onMoveEnd.bind(this);\n this.onVisibilityChange = this.onVisibilityChange.bind(this);\n }\n\n /**\n * Add the mapbox layer and source to the map.\n *\n * @param {mapboxgl.Map} map A Mapbox map.\n * @param {String} beforeId See [mapboxgl.Map#addLayer](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer) documentation.\n */\n init(map, beforeId) {\n if (!map) {\n return;\n }\n\n super.init(map);\n\n const { width, height } = map.getCanvas();\n this.tracker.canvas.width = width;\n this.tracker.canvas.height = height;\n\n const source = {\n type: 'canvas',\n canvas: this.tracker.canvas,\n coordinates: getSourceCoordinates(map),\n // Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.\n animate: true,\n attribution: this.copyrights,\n };\n\n this.beforeId = beforeId;\n this.layer = {\n id: this.key,\n type: 'raster',\n source: this.key,\n layout: {\n visibility: this.visible ? 'visible' : 'none',\n },\n paint: {\n 'raster-opacity': 1,\n 'raster-fade-duration': 0,\n 'raster-resampling': 'nearest', // important otherwise it looks blurry\n },\n };\n map.addSource(this.key, source);\n map.addLayer(this.layer, this.beforeId);\n\n this.listeners = [this.on('change:visible', this.onVisibilityChange)];\n }\n\n /**\n * Remove the mapbox layer and the mapbox source.\n *\n * @override\n */\n terminate() {\n if (this.map) {\n this.listeners.forEach((listener) => {\n unByKey(listener);\n });\n this.map.removeLayer(this.key);\n this.map.removeSource(this.key);\n }\n super.terminate();\n }\n\n start() {\n if (!this.map) {\n return;\n }\n super.start();\n this.map.on('click', this.onMapClick);\n this.map.on('move', this.onMove);\n this.map.on('moveend', this.onMoveEnd);\n }\n\n stop() {\n if (this.map) {\n this.map.off('click', this.onClick);\n this.map.off('move', this.onMove);\n this.map.off('moveend', this.onMoveEnd);\n }\n super.stop();\n }\n\n onVisibilityChange() {\n if (this.visible && !this.map.getLayer(this.key)) {\n this.map.addLayer(this.layer, this.beforeId);\n } else if (this.map.getLayer(this.key)) {\n this.map.removeLayer(this.key);\n }\n // We can't use setLayoutProperty it triggers an error probably a bug in mapbox\n // this.map.setLayoutProperty(\n // this.key,\n // 'visibilty',\n // this.visible ? 'visible' : 'none',\n // );\n }\n\n /**\n * Callback on 'move' event.\n * @private\n */\n onMove() {\n this.map.getSource(this.key).setCoordinates(getSourceCoordinates(this.map));\n\n const { width, height } = this.map.getCanvas();\n\n this.renderTrajectories(\n this.currTime,\n [width, height],\n getResolution(this.map),\n );\n }\n\n /**\n * Callback on 'moveend' event.\n * @private\n */\n onMoveEnd() {\n this.updateTrajectories();\n if (this.selectedVehicleId && this.journeyId) {\n this.highlightTrajectory();\n }\n }\n\n /**\n * Callback on 'mouseclick' event.\n * @param {mapboxgl.MapMouseEvent} evt\n * @private\n */\n onMapClick(evt) {\n if (!this.clickCallbacks.length) {\n return;\n }\n\n const [vehicle] = this.getVehiclesAtCoordinate(\n fromLonLat([evt.lngLat.lng, evt.lngLat.lat]),\n 1,\n );\n\n if (vehicle) {\n /**\n * Id of the selected vehicle\n * @type {string}\n */\n this.selectedVehicleId = vehicle.id;\n /** @ignore */\n this.journeyId = vehicle.journeyIdentifier;\n this.updateTrajectoryStations(this.selectedVehicleId).then(\n (vehicleWithStations) => {\n /**\n * Array of station coordinates.\n * @type {Array<Array<number>>} Array of coordinates.\n */\n this.stationsCoords = [];\n vehicleWithStations.stations.forEach((station) => {\n this.stationsCoords.push(fromLonLat(station.coordinates));\n });\n this.clickCallbacks.forEach((callback) =>\n callback({ ...vehicle, ...vehicleWithStations }, this, evt),\n );\n },\n );\n } else {\n this.selectedVehicleId = null;\n this.clickCallbacks.forEach((callback) => callback(null, this, evt));\n }\n }\n\n /**\n * @override\n * * Returns the URL parameters.\n * @param {Object} extraParams Extra parameters\n * @returns {Object}\n * @private\n */\n getParams(extraParams = {}) {\n const bounds = this.map.getBounds().toArray();\n const southWest = fromLonLat(bounds[0]);\n const northEast = fromLonLat(bounds[1]);\n const ext = [...southWest, ...northEast];\n const bbox = buffer(ext, getWidth(ext) / 10).join(',');\n const zoom = this.map.getZoom();\n\n return super.getParams({\n ...extraParams,\n bbox,\n s: zoom < 10 ? 1 : 0,\n z: zoom,\n });\n }\n\n /** @ignore */\n defaultStyle(props) {\n const zoom = this.map.getZoom();\n return super.defaultStyle(props, zoom);\n }\n\n /**\n * Draw the trajectory as a line with points for each stop.\n * @param {Array} stationsCoords Array of station coordinates.\n * @param {ol/geom/LineString~LineString|ol/geom/MultiLineString~MultiLineString} lineGeometry A LineString or a MultiLineString.\n * @param {string} color The color of the line.\n * @private\n */\n // eslint-disable-next-line no-unused-vars,class-methods-use-this\n drawFullTrajectory(stationsCoords, lineGeometry, color) {\n // eslint-disable-next-line no-console\n console.log('to be implemented');\n // Don't allow white lines, use red instead.\n // const vehiculeColor = /#ffffff/i.test(color) ? '#ff0000' : color;\n // const vectorSource = this.olLayer.getSource();\n // vectorSource.clear();\n // if (stationsCoords) {\n // const geometry = new MultiPoint(stationsCoords);\n // const aboveStationsFeature = new Feature(geometry);\n // aboveStationsFeature.setStyle(\n // new Style({\n // zIndex: 1,\n // image: new Circle({\n // radius: 5,\n // fill: new Fill({\n // color: '#000000',\n // }),\n // }),\n // }),\n // );\n // const belowStationsFeature = new Feature(geometry);\n // belowStationsFeature.setStyle(\n // new Style({\n // zIndex: 4,\n // image: new Circle({\n // radius: 4,\n // fill: new Fill({\n // color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n // }),\n // }),\n // }),\n // );\n // vectorSource.addFeatures([aboveStationsFeature, belowStationsFeature]);\n // }\n // const lineFeat = new Feature({\n // geometry: lineGeometry,\n // });\n // lineFeat.setStyle([\n // new Style({\n // zIndex: 2,\n // stroke: new Stroke({\n // color: '#000000',\n // width: 6,\n // }),\n // }),\n // new Style({\n // zIndex: 3,\n // stroke: new Stroke({\n // color: this.useDelayStyle ? '#a0a0a0' : vehiculeColor,\n // width: 4,\n // }),\n // }),\n // ]);\n // vectorSource.addFeature(lineFeat);\n }\n\n /**\n * Highlight the trajectory of journey.\n * @param {String} journeyId The id of the journey.\n * @private\n */\n highlightTrajectory(journeyId) {\n this.api\n .fetchTrajectoryById({\n id: journeyId,\n time: getUTCTimeString(new Date()),\n })\n // .then((traj) => {\n // const { p: multiLine, t, c } = traj;\n // const lineCoords = [];\n // multiLine.forEach((line) => {\n // line.forEach((point) => {\n // lineCoords.push([point.x, point.y]);\n // });\n // });\n // this.drawFullTrajectory(\n // this.stationsCoords,\n // new LineString(lineCoords),\n // c ? `#${c}` : getBgColor(t),\n // );\n // })\n .catch(() => {\n if (this.map.getLayer('highlight-trajectory')) {\n this.map.removeLayer('highlight-trajectory');\n }\n });\n }\n}\n\nexport default TrajservLayer;\n"],"sourceRoot":""}