@wemap/routers 12.7.2 → 12.7.3
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/dist/index.js +19 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +19 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/remote/RemoteRouterManager.spec.ts +178 -0
- package/src/remote/RemoteRouterManager.ts +20 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/model/RouterRequest.ts","../src/graph/Edge.ts","../src/graph/GraphProjection.ts","../src/graph/Vertex.ts","../src/graph/Graph.ts","../src/Utils.ts","../src/model/TransitMode.ts","../src/model/Step.ts","../src/graph/GraphRoute.ts","../src/model/StepsBuilder.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../../../node_modules/ua-parser-js/src/ua-parser.js","../../utils/dist/index.mjs","../src/graph/GraphRouterOptionsBuilder.ts","../src/graph/GraphRouterEngine.ts","../src/graph/GraphRouter.ts","../src/graph/NoRouteFoundError.ts","../src/wemap-osm/OsmGraphUtils.ts","../src/remote/RemoteRouter.ts","../src/StatusCode.ts","../src/RoutingError.ts","../src/remote/RemoteRouterUtils.ts","../src/remote/cityway/CitywayRemoteRouter.ts","../src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts","../src/remote/idfm/IdfmRemoteRouter.ts","../src/remote/osrm/OsrmRemoteRouter.ts","../src/remote/otp/OtpRemoteRouter.ts","../src/remote/wemap-multi/WemapMultiRemoteRouter.ts","../src/remote/RemoteRouterManager.ts","../src/wemap-multi/WemapMultiRouter.ts","../src/wemap-multi/CustomGraphMap.ts","../src/wemap-multi/CustomGraphMapTester.ts","../src/ItineraryInfoManager.ts","../helpers/InstructionManager.ts"],"sourcesContent":["import { Coordinates } from \"@wemap/geo\"\n\nimport { TravelMode, TravelModePreference } from \"./TravelMode\"\n\nexport type RouterRequest = {\n origin: Coordinates,\n destination: Coordinates,\n travelMode: TravelMode,\n travelModePreference?: TravelModePreference,\n provideItineraryAlternatives?: boolean,\n waypoints?: Coordinates[],\n optimizeWaypoints?: boolean,\n itineraryModifiers?: {\n avoidStairs?: boolean,\n avoidEscalators?: boolean,\n avoidElevator?: boolean,\n avoidMovingWalkway?: boolean,\n avoidTicketRestrictedAreas?: boolean\n }\n output?: {\n distanceAndDurationOnly?: boolean\n }\n}\n\nexport function routerRequestToJson(routerRequest: RouterRequest) {\n const { origin, destination, waypoints, ...rest } = routerRequest;\n return {\n origin: origin.toJson(),\n destination: destination.toJson(),\n ...(waypoints && { waypoints: waypoints.map(w => w.toJson()) }),\n ...rest\n }\n}","import { Level, type Level_t } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nexport type EdgeProperties = {\n \n name?: string;\n externalId?: string | number;\n\n isOneway?: boolean;\n areStairs?: boolean;\n isElevator?: boolean;\n areEscalators?: boolean;\n isMovingWalkway?: boolean;\n needTicket?: boolean;\n incline?: 'up' | 'down';\n}\n\n/**\n * An Edge is a segment composed of two Vertex\n * An edge is mostly issued from an OsmWay, but this is not always the case.\n * For example, edges created by mapmatching.\n */\nexport default class Edge {\n\n static currentUniqueId = 0;\n public readonly id = Edge.currentUniqueId++;\n\n public readonly level: Level_t;\n\n /** Edge bearing from vertex1 to vertex2 */\n public readonly bearing: number;\n public readonly length: number;\n\n constructor(\n public vertex1: Vertex,\n public vertex2: Vertex,\n public properties: EdgeProperties = {}\n ) {\n this.level = Level.union(vertex1.coords.level, vertex2.coords.level)\n this.length = this.vertex1.distanceTo(this.vertex2);\n this.bearing = this.vertex1.bearingTo(this.vertex2);\n }\n\n static getEdgeByVertices(\n edges: Edge[],\n vertex1: Vertex,\n vertex2: Vertex\n ) {\n return edges.find(edge => vertex1 === edge.vertex1 && vertex2 === edge.vertex2\n || vertex2 === edge.vertex1 && vertex1 === edge.vertex2\n );\n }\n\n reverseProperties() {\n const { properties } = this;\n if (properties.incline) {\n properties.incline = properties.incline === 'up' ? 'down' : 'up';\n }\n if (properties.isOneway) {\n properties.isOneway = false;\n }\n }\n}\n","import { Coordinates, UserPosition } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\n\nclass GraphProjection<U extends Coordinates | UserPosition = Coordinates> {\n constructor(\n public readonly origin: U,\n public readonly distanceFromNearestElement: number,\n public readonly coords: U,\n public readonly nearestElement: Vertex | Edge\n ) { }\n}\n\nexport default GraphProjection;\n","import { Coordinates } from '@wemap/geo';\n\nimport { GraphVertexJson } from '../types.js';\n\nexport type VertexProperties = {\n\n name?: string;\n externalId?: string | number;\n\n isGate?: boolean;\n isSubwayEntrance?: boolean;\n subwayEntranceRef?: string;\n}\n\nexport default class Vertex {\n\n public id = -1;\n\n constructor(public coords: Coordinates, public properties: VertexProperties = {}) { }\n\n distanceTo(other: Vertex) {\n return this.coords.distanceTo(other.coords);\n }\n\n bearingTo(other: Vertex) {\n return this.coords.bearingTo(other.coords);\n }\n\n toJson(): GraphVertexJson {\n return {\n id: this.id,\n coords: this.coords.toCompressedJson(),\n ...(Object.keys(this.properties).length > 0 && { properties: this.properties })\n }\n }\n\n static fromJson(json: GraphVertexJson) {\n const v = new Vertex(\n Coordinates.fromCompressedJson(json.coords),\n json.properties\n );\n v.id = json.id;\n return v;\n }\n}\n","import { diffAngleLines } from '@wemap/maths';\nimport { BoundingBox, Coordinates, Level, UserPosition, Level_t, Constants as GeoConstants } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport GraphProjection from './GraphProjection.js';\nimport Vertex from './Vertex.js';\nimport { type CompressedGeoGraphJson, type GeoGraphJson } from '../types.js';\nimport { type GraphProjectionOptions } from './GraphProjectionOptions.js';\n\n\nclass Graph {\n\n /**\n * exitVertices are vertices that have at least one indoor edge and one outdoor edge\n * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]\n * This vertices are used to cover the projection case:\n * - if projection origin is null, an exit vertex can be used\n * - if projection origin is not null, the intersection level with an exit vertex can be used\n */\n public readonly exitVertices: Set<Vertex>;\n\n constructor(public readonly vertices: Vertex[], public readonly edges: Edge[]) {\n const nullVertices = edges.filter(e => e.level === null).map(e => [e.vertex1, e.vertex2]).flat();\n const levelVertices = edges.filter(e => e.level !== null).map(e => [e.vertex1, e.vertex2]).flat();\n this.exitVertices = new Set(nullVertices.filter(v1 => levelVertices.includes(v1)));\n }\n\n getEdgeByVertices(vertex1: Vertex, vertex2: Vertex) {\n return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);\n }\n\n getVertexByCoords(coords: Coordinates) {\n return Graph.getVertexByCoords(this.vertices, coords);\n }\n\n static getVertexByCoords(vertices: Vertex[], coords: Coordinates) {\n return vertices.find(vertex => vertex.coords.equals(coords));\n }\n\n getVertexByName(name: string) {\n return this.vertices.find(vertex => vertex.properties.name === name);\n }\n\n getEdgeByName(name: string) {\n return this.edges.find(edge => edge.properties.name === name);\n }\n\n getBoundingBox(extendedMeasure?: number) {\n if (!this.vertices.length) {\n return null;\n }\n const boundingBox = BoundingBox.fromCoordinates(this.vertices.map(vertex => vertex.coords)) as BoundingBox;\n if (extendedMeasure) {\n boundingBox.extendsWithMeasure(extendedMeasure);\n }\n return boundingBox;\n }\n\n getProjection<U extends (Coordinates | UserPosition)>(\n origin: U,\n options: GraphProjectionOptions = {}\n ): GraphProjection<U> | null {\n\n const useMaxDistance = 'maxDistance' in options;\n const maxDistance = options.maxDistance!\n\n const useMaxBearingAngle = 'maxBearingAngle' in options;\n if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null)) return null;\n const maxBearingAngle = options.maxBearingAngle!;\n\n const useAcceptEdgeFn = 'acceptEdgeFn' in options;\n\n const useMultiLevelSegments = !('useMultiLevelSegments' in options) || options.useMultiLevelSegments;\n\n let bestProjection: GraphProjection | null = null;\n\n this.edges.forEach(edge => {\n\n if (useAcceptEdgeFn && !options.acceptEdgeFn!(edge)) return;\n if (!useMultiLevelSegments && Level.isRange(edge.level)) return;\n if (!Level.intersect(edge.level, origin.level)) return;\n\n if (useMaxBearingAngle) {\n // Do not try to project if angle is greater than the threshold\n if (diffAngleLines(edge.bearing, (origin as UserPosition).bearing!) > maxBearingAngle) return;\n }\n\n const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);\n if (!segmentProjection) return;\n const distanceToSegment = segmentProjection.distanceTo(origin);\n\n if (useMaxDistance && distanceToSegment > maxDistance) return;\n\n if (distanceToSegment < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToSegment, segmentProjection, edge);\n }\n });\n\n // if mapmatching bearing is enabled do not use vertices matching\n if (useMaxBearingAngle) {\n return bestProjection;\n }\n\n this.vertices.forEach(vertex => {\n let vertexCoords = vertex.coords;\n\n // Specific case of io nodes that have a non-null level but can be matched to a null origin level\n if (this.exitVertices.has(vertex) && origin.level === null) {\n vertexCoords = vertex.coords.clone();\n vertexCoords.level = null;\n }\n\n if (!useMultiLevelSegments && Level.isRange(vertexCoords.level)) return;\n if (!Level.intersect(vertexCoords.level, origin.level)) return;\n\n const distanceToVertex = vertexCoords.distanceTo(origin);\n\n // If distance below epsilon consider it as best projection\n if (distanceToVertex < GeoConstants.EPS_MM) {\n bestProjection = new GraphProjection(origin, 0, vertexCoords, vertex);\n return;\n }\n\n if (useMaxDistance && distanceToVertex > maxDistance) return;\n\n if (distanceToVertex < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToVertex, vertexCoords, vertex);\n }\n });\n\n return bestProjection;\n }\n\n\n toJson(): GeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.toJson()),\n edges: this.edges.map(edge => ({\n id: edge.id,\n vertex1Idx: this.vertices.indexOf(edge.vertex1),\n vertex2Idx: this.vertices.indexOf(edge.vertex2),\n ...(Object.keys(edge.properties).length > 0 && { properties: edge.properties })\n }))\n };\n }\n\n static fromJson(json: GeoGraphJson) {\n\n const vertices = json.vertices.map(vertex => Vertex.fromJson(vertex));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge.vertex1Idx],\n vertices[jsonEdge.vertex2Idx],\n jsonEdge.properties\n ));\n\n return new Graph(vertices, edges);\n }\n\n /** @deprecated */\n toCompressedJson(): CompressedGeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.coords.toCompressedJson()),\n verticesIds: this.vertices.map(vertex => vertex.id),\n edges: this.edges.map(edge => {\n const vertex1Idx = this.vertices.indexOf(edge.vertex1);\n const vertex2Idx = this.vertices.indexOf(edge.vertex2);\n const edgeExtras = edge.properties;\n if (Object.keys(edgeExtras).length > 0) {\n return [vertex1Idx, vertex2Idx, edgeExtras];\n }\n return [vertex1Idx, vertex2Idx];\n })\n };\n }\n\n /** @deprecated */\n static fromCompressedJson(json: CompressedGeoGraphJson) {\n const vertices = json.vertices.map(vertex => new Vertex(Coordinates.fromCompressedJson(vertex)));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge[0]],\n vertices[jsonEdge[1]],\n jsonEdge.length > 2 ? jsonEdge[2] : {}\n ));\n\n return new Graph(vertices, edges);\n }\n\n\n static fromCoordinatesSegments(segments: Coordinates[][]) {\n\n const vertices: Vertex[] = [];\n const edges: Edge[] = [];\n\n const getOrCreateVertex = (coords: Coordinates) => {\n const vertex = vertices.find(otherVertex => otherVertex.coords.equals(coords));\n if (vertex) {\n return vertex;\n }\n const newVertex = new Vertex(coords);\n vertices.push(newVertex);\n return newVertex;\n };\n\n for (const segment of segments) {\n\n let previousVertex = null;\n for (const coords of segment) {\n const currentVertex = getOrCreateVertex(coords);\n\n if (previousVertex) {\n edges.push(new Edge(currentVertex, previousVertex));\n }\n\n previousVertex = currentVertex;\n }\n }\n\n return new Graph(vertices, edges);\n }\n\n /**\n * Create edges From MultiLevel Itinerary for a given level\n * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)\n */\n getEdgesAtLevel(targetLevel: Level_t, useMultiLevelEdges = true) {\n return this.edges.filter(\n ({ level }) => useMultiLevelEdges\n ? Level.intersect(targetLevel, level)\n : Level.contains(targetLevel, level)\n );\n }\n\n\n toDetailedString() {\n let output\n = '--- Network ---\\n'\n + `Vertices: ${this.vertices.length}\\n`\n + `Edges: ${this.edges.length}\\n`\n + '---\\n'\n + 'Vertices\\n';\n this.vertices.forEach(vertex => {\n output += vertex.id;\n const vertexProps = vertex.properties;\n if (Object.keys(vertexProps).length !== 0) { output += ` ${vertexProps}` }\n });\n output += '---\\n'\n + 'Edges\\n';\n this.edges.forEach(edge => {\n output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;\n const edgeProps = edge.properties;\n if (Object.keys(edgeProps).length !== 0) { output += ` ${edgeProps}` }\n });\n output += '---';\n return output;\n }\n}\n\nexport default Graph;\n","/**\n * Get route duration\n * @param {Number} speed in km/h\n * @returns {Number} duration in seconds\n */\nexport function getDurationFromLength(length: number, speed = 5) {\n return length / (speed * 1000 / 3600);\n}\n","export type TransitMode = 'AIRPLANE' | 'BOAT' | 'BIKE' | 'BUS' | 'CAR' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'MOTO' | 'TRAIN' | 'TAXI' |\n 'TRAM' | 'WALK' | 'MULTI' | 'UNKNOWN';\n\nexport type PublicTransport = 'AIRPLANE' | 'BOAT' | 'BUS' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'TRAIN' | 'TRAM';\n\nexport function isTransitModePublicTransport(routingMode: TransitMode): routingMode is PublicTransport {\n return [\n 'AIRPLANE', 'BOAT', 'BUS', 'FERRY',\n 'FUNICULAR', 'METRO', 'TRAIN', 'TRAM'\n ].includes(routingMode);\n}\n","import { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\n\nimport { LevelChange } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\n\nexport type Step = {\n\n firstStep: boolean;\n lastStep: boolean;\n number: number;\n\n angle: number;\n previousBearing: number;\n nextBearing: number;\n distance: number;\n duration: number;\n\n readonly coords: Coordinates;\n readonly name: string | null;\n readonly levelChange: LevelChange | null;\n readonly extras: StepExtra | null;\n}\n\nexport type StepJson = {\n firstStep?: boolean,\n lastStep?: boolean\n number: number,\n coords: CoordinatesCompressedJson,\n name?: string,\n angle: number,\n previousBearing: number,\n nextBearing: number,\n distance: number,\n duration: number\n levelChange?: LevelChange\n extras?: StepExtra,\n};\n\nexport type MinStepInfo = {\n coords: Coordinates,\n name?: string,\n levelChange?: LevelChange\n extras?: StepExtra,\n distance?: number,\n duration?: number\n};\n\nexport function stepToJson(step: Step): StepJson {\n return {\n ...(step.firstStep && { firstStep: true }),\n ...(step.lastStep && { lastStep: true }),\n number: step.number,\n coords: step.coords.toCompressedJson(),\n ...(step.name !== null && { name: step.name }),\n angle: Number(step.angle.toFixed(2)),\n previousBearing: Number(step.previousBearing.toFixed(2)),\n nextBearing: Number(step.nextBearing.toFixed(2)),\n distance: Number(step.distance.toFixed(1)),\n duration: Number(step.duration.toFixed(1)),\n ...(step.levelChange !== null && { levelChange: step.levelChange }),\n ...(step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }),\n };\n}\n\nexport function jsonToStep(json: StepJson): Step {\n return Object.assign({}, json, {\n coords: Coordinates.fromCompressedJson(json.coords),\n firstStep: Boolean(json.firstStep),\n lastStep: Boolean(json.lastStep),\n name: json.name || null,\n levelChange: json.levelChange || null,\n extras: json.extras || null\n });\n}\n\nexport function stepEquals(step1: Step, step2: Step) {\n return step1.coords.equals(step2.coords)\n && Math.abs(step1.angle - step2.angle) <= 0.005\n && Math.abs(step1.distance - step2.distance) <= 0.05\n && Math.abs(step1.duration - step2.duration) <= 0.05\n && step1.firstStep === step2.firstStep\n && step1.lastStep === step2.lastStep\n && step1.levelChange?.difference === step2.levelChange?.difference\n && step1.levelChange?.direction === step2.levelChange?.direction\n && step1.levelChange?.type === step2.levelChange?.type\n && step1.name === step2.name\n && Math.abs(step1.nextBearing - step2.nextBearing) <= 0.005\n && step1.number === step2.number\n && Math.abs(step1.previousBearing - step2.previousBearing) <= 0.005\n}\n","import { Coordinates } from '@wemap/geo';\n\nimport Graph from \"./Graph.js\";\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\nimport { getDurationFromLength } from '../Utils.js';\n\n\n/**\n * GraphRoute is an oriented graph\n */\nclass GraphRoute extends Graph {\n constructor(\n public start: Coordinates,\n public end: Coordinates,\n public vertices: Vertex[],\n public edges: Edge[],\n public edgesWeights: number[]\n ) {\n super(vertices, edges);\n }\n\n // /!\\ Does not clone vertices\n // /!\\ Create new Edges but does not deep clone properties\n // /!\\ Does not revert edge oneway property\n reverse() {\n const vertices = this.vertices.slice().reverse();\n const edges = this.edges.slice().reverse();\n const edgesWeights = this.edgesWeights.slice().reverse();\n edges.map(oldEdge => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));\n return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);\n }\n\n static fromCoordinates(start: Coordinates, end: Coordinates, coordinates: Coordinates[]) {\n const graph = Graph.fromCoordinatesSegments([coordinates]);\n const edgesWeights = graph.edges.map(e => getDurationFromLength(e.length));\n return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);\n }\n\n get hasRoute() { return Boolean(this.edges.length) }\n}\n\nexport default GraphRoute;\n","import { Coordinates, Level } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { diffAngle, deg2rad } from '@wemap/maths';\n\nimport { type LevelChange, type LevelChangeType } from './LevelChange.js';\nimport { type Step, type MinStepInfo } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport default class StepsBuilder {\n\n private start: Coordinates | null = null;\n private end: Coordinates | null = null;\n private pathCoords: Coordinates[] | null = null;\n private stepsInfo: MinStepInfo[] = [];\n\n setStart(start: Coordinates) {\n this.start = start;\n return this;\n }\n\n setEnd(end: Coordinates) {\n this.end = end;\n return this;\n }\n\n setPathCoords(pathCoords: Coordinates[]) {\n this.pathCoords = pathCoords;\n return this;\n }\n\n setStepsInfo(stepsInfo: MinStepInfo[]) {\n this.stepsInfo = stepsInfo;\n return this;\n }\n\n addStepInfo(stepInfo: MinStepInfo) {\n this.stepsInfo.push(stepInfo);\n return this;\n }\n\n setGraphRoute(graphRoute: GraphRoute) {\n\n const stepsInfo: MinStepInfo[] = [];\n\n const { start, end } = graphRoute;\n\n if (!graphRoute.hasRoute) { return this; }\n\n let currentStep: MinStepInfo | null = null;\n let previousBearing = start.bearingTo(graphRoute.vertices[0].coords);\n\n for (let i = 0; i < graphRoute.vertices.length - 1; i++) {\n\n const isFirstStep = i === 0;\n\n const vertex = graphRoute.vertices[i];\n const currentCoords = vertex.coords;\n const nextVertex = graphRoute.vertices[i + 1];\n const nextCoords = nextVertex.coords;\n\n const edge = graphRoute.edges[i];\n\n const nextBearing = vertex.bearingTo(nextVertex);\n const angle = diffAngle(previousBearing, nextBearing + Math.PI);\n\n const previousStep = stepsInfo.length ? stepsInfo[stepsInfo.length - 1] : null;\n\n const { isSubwayEntrance, isGate, subwayEntranceRef } = vertex.properties;\n const { isElevator, areEscalators, areStairs, isMovingWalkway, incline } = edge.properties;\n\n let levelChangeType: LevelChangeType | null = null;\n if (isElevator) {\n levelChangeType = 'elevator';\n } else if (areEscalators) {\n levelChangeType = 'escalator';\n } else if (areStairs) {\n levelChangeType = 'stairs';\n } else if (isMovingWalkway) {\n levelChangeType = 'moving walkway';\n }\n\n // Handle stairs/elevators/escalators/moving walkway without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n if (\n (areStairs || isElevator)\n && incline\n && !previousStep?.levelChange\n ) {\n forceLevelChange = incline;\n }\n\n const previousEdge = i > 0 ? graphRoute.edges[i - 1] : null;\n const previousEdgeProperties = previousEdge?.properties || {};\n const forceEndOfLevelChange = Boolean(\n previousEdgeProperties.incline && previousEdgeProperties.areStairs\n && (!incline || !areStairs)\n );\n const createNewStep = vertex.properties.isSubwayEntrance;\n\n const stepName = edge.properties.name || null;\n const duration = graphRoute.edgesWeights[i];\n const stepExtras = {\n ...(isSubwayEntrance && { isSubwayEntrance }),\n ...(subwayEntranceRef && { subwayEntranceRef }),\n ...(isGate && { isGate })\n };\n\n let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;\n\n const splitByLevel = Level.isRange(edge.level) && !Level.isRange(currentCoords.level) || forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || createNewStep;\n\n // New step creation\n if (isFirstStep || splitStepCondition) {\n\n let levelChange: LevelChange | undefined;\n\n if (splitByLevel) {\n const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;\n let direction: 'up' | 'down' = difference > 0 ? 'up' : 'down';\n if (forceLevelChange) {\n direction = forceLevelChange;\n }\n levelChange = {\n difference, direction, ...(levelChangeType && { type: levelChangeType })\n };\n }\n\n currentStep = {\n coords: currentCoords,\n ...(stepName && { name: stepName }),\n extras: stepExtras,\n levelChange,\n distance: 0,\n duration: 0\n };\n\n stepsInfo.push(currentStep);\n }\n\n currentStep!.distance! += currentCoords.distanceTo(nextCoords);\n currentStep!.duration! += duration;\n\n previousBearing = nextBearing;\n }\n\n const lastCoords = graphRoute.vertices[graphRoute.vertices.length - 1].coords;\n\n // Create a last step if end is not on the graph\n if (!Coordinates.equals(lastCoords, end)) {\n stepsInfo.push({ coords: lastCoords });\n }\n\n this.setStart(start);\n this.setEnd(end);\n this.setPathCoords(graphRoute.vertices.map(v => v.coords));\n this.setStepsInfo(stepsInfo);\n\n return this;\n }\n\n build(): Step[] {\n\n const { pathCoords, start, end } = this;\n\n if (!pathCoords) {\n Logger.warn(`StepsBuilder: Missing \"pathCoords\" property to build steps`);\n return [];\n }\n\n if (!start) {\n Logger.warn(`StepsBuilder: Missing \"from\" property to build steps`);\n return [];\n }\n\n if (!end) {\n Logger.warn(`StepsBuilder: Missing \"to\" property to build steps`);\n return [];\n }\n\n if (this.stepsInfo.length === 0) {\n // If there is no steps info, steps coordinates are calculated using our steps calculation algorithm above.\n this.setGraphRoute(GraphRoute.fromCoordinates(start, end, pathCoords));\n }\n\n const { stepsInfo } = this;\n\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = pathCoords.findIndex(coords => coords.equals(stepInfo.coords));\n if (coordsId === -1) {\n throw new Error('Cannot find step coordinates in itinerary coordinates.');\n }\n\n const coordsBeforeStep = coordsId === 0 ? start : pathCoords[coordsId - 1];\n const coordsAfterStep = coordsId === pathCoords.length - 1\n ? end\n : pathCoords[coordsId + 1];\n\n const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);\n const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);\n\n let distance = 0;\n const coordsToStopCalculation = stepId !== stepsInfo.length - 1\n ? stepsInfo[stepId + 1].coords\n : pathCoords[pathCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!pathCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += pathCoords[currentCoordsId].distanceTo(pathCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === pathCoords.length - 1) {\n distance += pathCoords[currentCoordsId].distanceTo(end);\n }\n\n return {\n coords: stepInfo.coords,\n name: stepInfo.name || null,\n number: stepId + 1,\n previousBearing,\n nextBearing,\n angle: diffAngle(previousBearing, nextBearing + Math.PI),\n firstStep: stepId === 0,\n lastStep: stepId === stepsInfo.length - 1,\n distance, // stepInfo.distance is overwritten\n duration: stepInfo.duration || getDurationFromLength(distance),\n levelChange: stepInfo.levelChange || null,\n extras: stepInfo.extras || null\n }\n });\n }\n\n}\n","import {\n Coordinates, CoordinatesCompressedJson, Level, Utils as GeoUtils\n} from '@wemap/geo';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { TransitMode, isTransitModePublicTransport } from './TransitMode.js';\n\nimport { jsonToStep, Step, stepEquals, StepJson, stepToJson } from './Step.js'\nimport StepsBuilder from './StepsBuilder.js';\n\nexport type Destination = {\n name: string | null,\n coords: Coordinates\n};\n\nexport type DestinationConstructor = {\n name?: string,\n coords: Coordinates\n};\n\nexport type DestinationJson = {\n name?: string,\n coords: CoordinatesCompressedJson\n};\n\nexport type TransportInfo = {\n name: string,\n routeColor?: string,\n routeTextColor?: string,\n directionName?: string\n}\n\ntype LegCommon = {\n transitMode: TransitMode,\n startTime?: number,\n endTime?: number,\n transportInfo?: TransportInfo,\n}\n\ntype LegConstructor =\n {\n start: DestinationConstructor,\n end: DestinationConstructor,\n coords: Coordinates[],\n steps?: Step[],\n duration?: number\n }\n & LegCommon;\n\nexport type LegJson = {\n start: DestinationJson,\n end: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\n distance: number,\n duration: number\n} & LegCommon;\n\nexport default class Leg {\n\n start: Destination;\n end: Destination;\n coords: Coordinates[];\n distance: number;\n transitMode: TransitMode;\n\n duration: number;\n startTime: number | null;\n endTime: number | null;\n\n steps: Step[];\n transportInfo: TransportInfo | null;\n\n constructor({\n start, end, coords, transitMode, duration,\n startTime, endTime, transportInfo, steps\n }: LegConstructor) {\n this.start = {\n name: start.name || null,\n coords: start.coords\n };\n this.end = {\n name: end.name || null,\n coords: end.coords\n };\n this.coords = coords;\n this.transitMode = transitMode;\n this.distance = GeoUtils.calcDistance(coords)\n this.duration = typeof duration === 'number' ? duration : getDurationFromLength(this.distance);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n this.transportInfo = transportInfo || null;\n this.steps = Array.isArray(steps)\n ? steps\n : new StepsBuilder().setStart(start.coords).setEnd(end.coords).setPathCoords(coords).build();\n }\n\n isPublicTransport() {\n return isTransitModePublicTransport(this.transitMode);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.transitMode === obj2.transitMode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.start.name === obj2.start.name\n && obj1.start.coords.equals(obj2.start.coords)\n && obj1.end.name === obj2.end.name\n && obj1.end.coords.equals(obj2.end.coords)\n && obj1.coords.length === obj2.coords.length\n && (\n obj1.steps === obj2.steps\n || obj1.steps?.length === obj2.steps?.length\n );\n\n if (!intermediate) {\n return false;\n }\n\n let i;\n for (i = 0; i < obj1.coords.length; i++) {\n if (!obj1.coords[i].equals(obj2.coords[i])) {\n return false;\n }\n }\n for (i = 0; i < obj1.steps.length; i++) {\n if (!stepEquals(obj1.steps[i], obj2.steps[i])) {\n return false;\n }\n }\n\n if (obj1.transportInfo !== obj2.transportInfo) {\n if (obj1.transportInfo === null || obj2.transportInfo === null) {\n return false;\n }\n if (\n obj1.transportInfo.name !== obj2.transportInfo.name\n || obj1.transportInfo.routeColor !== obj2.transportInfo.routeColor\n || obj1.transportInfo.routeTextColor !== obj2.transportInfo.routeTextColor\n || obj1.transportInfo.directionName !== obj2.transportInfo.directionName\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Leg) {\n return Leg.equals(this, obj);\n }\n\n toJson(): LegJson {\n return {\n transitMode: this.transitMode,\n start: {\n coords: this.start.coords.toCompressedJson(),\n ...(this.start.name && { name: this.start.name }),\n },\n end: {\n coords: this.end.coords.toCompressedJson(),\n ...(this.end.name && { name: this.end.name }),\n },\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n coords: this.coords.map(coords => coords.toCompressedJson()),\n steps: this.steps.map(stepToJson),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime }),\n ...(this.transportInfo !== null && { transportInfo: this.transportInfo }),\n };\n }\n\n static fromJson(json: LegJson) {\n const leg = new Leg(Object.assign({}, json, {\n start: {\n coords: Coordinates.fromCompressedJson(json.start.coords),\n name: json.start.name || null\n },\n end: {\n coords: Coordinates.fromCompressedJson(json.end.coords),\n name: json.end.name || null\n },\n coords: json.coords.map(Coordinates.fromCompressedJson),\n steps: json.steps?.map(jsonToStep) || null,\n }));\n\n return leg;\n }\n\n static fromGraphRoute(\n graphRoute: GraphRoute,\n transitMode: TransitMode = 'WALK'\n ) {\n return new Leg({\n start: { coords: graphRoute.start },\n end: { coords: graphRoute.end },\n coords: graphRoute.vertices.map(vertex => vertex.coords),\n duration: graphRoute.edgesWeights.reduce((acc, weight) => acc + weight, 0),\n transitMode,\n steps: new StepsBuilder().setGraphRoute(graphRoute).build()\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n this.start.coords.level = Level.multiplyBy(this.start.coords.level, levelFactor);\n this.end.coords.level = Level.multiplyBy(this.end.coords.level, levelFactor);\n for (const coords of this.coords) {\n coords.level = Level.multiplyBy(coords.level, levelFactor);\n }\n this.steps.forEach(step => {\n step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);\n });\n }\n}\n","import { Feature, FeatureCollection, MultiLineString, Point } from 'geojson';\nimport { Coordinates, Level, Utils as GeoUtils, CoordinatesJson, Level_t } from '@wemap/geo';\nimport { diffAngle, Point2_t, Vector3_t } from '@wemap/maths';\n\nimport Graph from '../graph/Graph.js';\nimport Leg, { type LegJson } from './Leg.js';\nimport { isTransitModePublicTransport, type TransitMode } from './TransitMode.js';\nimport { Step } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport StepsBuilder from './StepsBuilder.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\n\nexport type ItineraryCommon = {\n startTime?: number,\n endTime?: number\n};\n\nexport type ItineraryJson = {\n transitMode: TransitMode,\n origin: CoordinatesJson,\n destination: CoordinatesJson,\n distance: number,\n duration: number,\n legs: LegJson[]\n} & ItineraryCommon;\n\n\nexport type ItineraryConstructor = {\n origin: Coordinates,\n destination: Coordinates,\n duration?: number\n legs: Leg[],\n} & ItineraryCommon;\n\n/**\n * Main attributes are:\n * nodes: the ordered list of Node\n * edges: the ordered list of Edge\n * start: the start point (Coordinates)\n * end: the end point (Coordinates)\n * length: the route length\n */\nexport default class Itinerary {\n\n origin: Coordinates;\n destination: Coordinates;\n duration: number;\n readonly legs: Leg[];\n\n private _transitMode: TransitMode | null = null;\n startTime: number | null;\n endTime: number | null;\n\n private _coords: Coordinates[] | null = null;\n private _distance: number | null = null;\n\n constructor({\n origin, destination, duration, legs, startTime, endTime\n }: ItineraryConstructor) {\n this.origin = origin;\n this.destination = destination;\n this.legs = legs;\n this.duration = typeof duration === 'number'\n ? duration\n : this.legs.reduce((dur, leg) => dur + leg.duration, 0);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n\n this.updateStepsFromLegs();\n }\n\n set coords(_) {\n throw new Error('Itinerary.coords cannot be set. They are calculated from Itinerary.legs.');\n }\n\n public get coords() {\n if (!this._coords) {\n this._coords = this.legs.map(leg => leg.coords)\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n }\n return this._coords;\n }\n\n set steps(_) {\n throw new Error('Itinerary.step cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get steps(): Step[] {\n return this.legs.map(leg => leg.steps).flat();\n }\n\n set transitMode(_) {\n throw new Error('Itinerary.mode cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get transitMode() {\n if (!this._transitMode) {\n let isPublicTransport = false;\n let isBicycle = false;\n let isDriving = false;\n\n this.legs.forEach((leg) => {\n isPublicTransport = isPublicTransport || isTransitModePublicTransport(leg.transitMode);\n isBicycle = isBicycle || leg.transitMode === 'BIKE';\n isDriving = isDriving || leg.transitMode === 'CAR';\n });\n\n if (isPublicTransport) {\n this._transitMode = 'MULTI';\n } else if (isDriving) {\n this._transitMode = 'CAR';\n } else if (isBicycle) {\n this._transitMode = 'BIKE';\n } else {\n this._transitMode = 'WALK';\n }\n }\n\n return this._transitMode;\n\n }\n\n set distance(_) {\n throw new Error('Itinerary.distance cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get distance() {\n if (this._distance === null) {\n this._distance = GeoUtils.calcDistance(this.coords);\n }\n return this._distance;\n\n // Does not work if legs does not intersect\n // return this.legs.reduce((dist, leg) => dist + leg.distance, 0);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static fromItineraries(...itineraries: Itinerary[]) {\n let duration = 0;\n const legs: Leg[] = [];\n\n itineraries.forEach(_itinerary => {\n duration += _itinerary.duration;\n legs.push(..._itinerary.legs);\n });\n\n return new Itinerary({\n origin: itineraries[0].origin,\n destination: itineraries[itineraries.length - 1].destination,\n duration,\n legs\n });\n }\n\n /**\n * Convert lat/lng/level? points to Itinerary\n */\n static fromOrderedPointsArray(\n points: (Point2_t | Vector3_t)[],\n start: (Point2_t | Vector3_t),\n end: (Point2_t | Vector3_t)) {\n\n const pointToCoordinates = (point: Point2_t | Vector3_t) =>\n new Coordinates(point[0], point[1], null, point[2]);\n\n return this.fromOrderedCoordinates(\n points.map(pointToCoordinates),\n pointToCoordinates(start),\n pointToCoordinates(end)\n );\n }\n\n /**\n * Convert ordered Coordinates to Itinerary\n */\n static fromOrderedCoordinates(\n coords: Coordinates[],\n origin: Coordinates,\n destination: Coordinates,\n transitMode: TransitMode = 'WALK'\n ) {\n\n const steps = new StepsBuilder().setPathCoords(coords).setStart(origin).setEnd(destination).build();\n\n const leg = new Leg({\n start: { coords: origin },\n end: { coords: destination },\n coords,\n transitMode,\n steps\n });\n\n return new Itinerary({ origin, destination, legs: [leg] });\n }\n\n\n static equals(obj1: Itinerary, obj2: Itinerary) {\n const intermediate = obj1.origin.equals(obj2.origin)\n && obj1.destination.equals(obj2.destination)\n && Math.abs(obj1.distance - obj2.distance) <= 0.05\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.legs.length === obj2.legs.length;\n\n if (!intermediate) {\n return false;\n }\n\n for (let i = 0; i < obj1.legs.length; i++) {\n if (!obj1.legs[i].equals(obj2.legs[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Itinerary) {\n return Itinerary.equals(this, obj);\n }\n\n toJson(): ItineraryJson {\n return {\n origin: this.origin.toJson(),\n destination: this.destination.toJson(),\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n transitMode: this.transitMode,\n legs: this.legs.map(leg => leg.toJson()),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime })\n };\n }\n\n static fromJson(json: ItineraryJson) {\n return new Itinerary({\n origin: Coordinates.fromJson(json.origin),\n destination: Coordinates.fromJson(json.destination),\n duration: json.duration,\n legs: json.legs.map(Leg.fromJson),\n startTime: json.startTime,\n endTime: json.endTime\n });\n }\n\n static fromGraphRoute(graphRoute: GraphRoute, transitMode: TransitMode = 'WALK') {\n const leg = Leg.fromGraphRoute(graphRoute, transitMode);\n return new Itinerary({\n origin: graphRoute.start,\n destination: graphRoute.end,\n duration: leg.duration,\n legs: [leg]\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n\n this.origin.level = Level.multiplyBy(this.origin.level, levelFactor);\n this.destination.level = Level.multiplyBy(this.destination.level, levelFactor);\n\n this.legs.forEach(leg => leg.multiplyLevel(levelFactor));\n\n // It is not necessary to multiply this._coords because \n // coords are not cloned between legs and itinerary\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n forceUnknownLevelTo0() {\n\n this.origin.level = this.origin.level || 0;\n this.destination.level = this.destination.level || 0;\n\n for (const leg of this.legs) {\n leg.start.coords.level = leg.start.coords.level || 0;\n leg.end.coords.level = leg.end.coords.level || 0;\n for (const coords of leg.coords) {\n coords.level = coords.level || 0;\n }\n if (leg.steps) {\n for (const step of leg.steps) {\n step.coords.level = step.coords.level || 0;\n }\n }\n }\n\n if (this._coords) {\n for (const coords of this._coords) {\n coords.level = coords.level || 0;\n }\n }\n }\n\n toGeoJson(): FeatureCollection {\n const transformToPoint = (point: Coordinates, name?: string, type?: string): Feature<Point> => ({\n type: \"Feature\",\n properties: { name, level: point.level, ...(type && { type }) },\n geometry: {\n type: 'Point',\n coordinates: [point.lng, point.lat]\n }\n });\n const transformToMultiLineStrings = (segments: Coordinates[][], level: Level_t): Feature<MultiLineString> => ({\n type: \"Feature\",\n properties: { level, name: level?.toString() },\n geometry: {\n type: 'MultiLineString',\n coordinates: segments.map(s => s.map(({ lat, lng }) => [lng, lat]))\n }\n });\n\n const levelsOfItinerary = [...new Set(this.coords.map(c => Level.toString(c.level)))].map(Level.fromString);\n const segmentsSplitted: [Level_t, Coordinates[][]][] = levelsOfItinerary.map(loi => [loi, GeoUtils.createSegmentsAtLevel(this.coords, loi, true)]);\n const multiLineStrings = segmentsSplitted.map(([loi, segments]) => transformToMultiLineStrings(segments, loi))\n const legsStarts = this.legs.map((leg, idx) => transformToPoint(leg.start.coords, `Leg ${idx} start`, 'leg-start'));\n const legsEnds = this.legs.map((leg, idx) => transformToPoint(leg.end.coords, `Leg ${idx} end`, 'leg-end'));\n const steps = this.steps.map(step => transformToPoint(step.coords, `Step ${step.number}`, 'step'))\n return {\n type: \"FeatureCollection\",\n features: [\n transformToPoint(this.origin, 'origin', 'origin'),\n transformToPoint(this.destination, 'destination', 'destination'),\n ...multiLineStrings,\n ...legsStarts,\n ...legsEnds,\n ...steps\n ]\n };\n }\n\n /**\n * Update steps info thanks to the coordinates of the whole itinerary.\n * This method will update:\n * - all steps number\n * - first/last steps\n * - previousBearing/nextBearing/angle of first and last step of each leg\n * - distance/duration of first and last step of each leg\n */\n updateStepsFromLegs() {\n\n const itineraryCoords = this.coords\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n const steps = this.legs.map(leg => leg.steps).flat();\n\n\n steps.map((step, stepId) => {\n const coordsId = itineraryCoords.findIndex(coords => coords.equals(step.coords));\n if (coordsId === -1) {\n throw new Error('Cannot find step coordinates in itinerary coordinates.');\n }\n\n const coordsBeforeStep = coordsId === 0 ? this.origin : itineraryCoords[coordsId - 1];\n const coordsAfterStep = coordsId === itineraryCoords.length - 1\n ? this.destination\n : itineraryCoords[coordsId + 1];\n\n step.previousBearing = coordsBeforeStep.bearingTo(step.coords);\n step.nextBearing = step.coords.bearingTo(coordsAfterStep);\n step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);\n\n const stepDistanceBefore = step.distance;\n step.distance = 0;\n const coordsToStopCalculation = stepId !== steps.length - 1\n ? steps[stepId + 1].coords\n : itineraryCoords[itineraryCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === itineraryCoords.length - 1) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(this.destination);\n }\n\n step.number = stepId + 1;\n step.firstStep = stepId === 0;\n step.lastStep = stepId === steps.length - 1;\n\n step.duration += getDurationFromLength(step.distance - stepDistanceBefore)\n });\n }\n}\n","/////////////////////////////////////////////////////////////////////////////////\n/* UAParser.js v1.0.35\n Copyright © 2012-2021 Faisal Salman <f@faisalman.com>\n MIT License *//*\n Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.\n Supports browser & node.js environment. \n Demo : https://faisalman.github.io/ua-parser-js\n Source : https://github.com/faisalman/ua-parser-js */\n/////////////////////////////////////////////////////////////////////////////////\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '1.0.35',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major',\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded',\n UA_MAX_LENGTH = 350;\n\n var AMAZON = 'Amazon',\n APPLE = 'Apple',\n ASUS = 'ASUS',\n BLACKBERRY = 'BlackBerry',\n BROWSER = 'Browser',\n CHROME = 'Chrome',\n EDGE = 'Edge',\n FIREFOX = 'Firefox',\n GOOGLE = 'Google',\n HUAWEI = 'Huawei',\n LG = 'LG',\n MICROSOFT = 'Microsoft',\n MOTOROLA = 'Motorola',\n OPERA = 'Opera',\n SAMSUNG = 'Samsung',\n SHARP = 'Sharp',\n SONY = 'Sony',\n VIERA = 'Viera',\n XIAOMI = 'Xiaomi',\n ZEBRA = 'Zebra',\n FACEBOOK = 'Facebook',\n CHROMIUM_OS = 'Chromium OS',\n MAC_OS = 'Mac OS';\n\n ///////////\n // Helper\n //////////\n\n var extend = function (regexes, extensions) {\n var mergedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n mergedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n mergedRegexes[i] = regexes[i];\n }\n }\n return mergedRegexes;\n },\n enumerize = function (arr) {\n var enums = {};\n for (var i=0; i<arr.length; i++) {\n enums[arr[i].toUpperCase()] = arr[i];\n }\n return enums;\n },\n has = function (str1, str2) {\n return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;\n },\n lowerize = function (str) {\n return str.toLowerCase();\n },\n majorize = function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g, EMPTY).split('.')[0] : undefined;\n },\n trim = function (str, len) {\n if (typeof(str) === STR_TYPE) {\n str = str.replace(/^\\s\\s*/, EMPTY);\n return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);\n }\n };\n\n ///////////////\n // Map helper\n //////////////\n\n var rgxMapper = function (ua, arrays) {\n\n var i = 0, j, k, p, q, matches, match;\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n if (!regex[j]) { break; }\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length === 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length === 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length === 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n },\n\n strMapper = function (str, map) {\n\n for (var i in map) {\n // check if current value is array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return str;\n };\n\n ///////////////\n // String map\n //////////////\n\n // Safari < 3.0\n var oldSafariMap = {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n },\n windowsVersionMap = {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n };\n\n //////////////\n // Regex map\n /////////////\n\n var regexes = {\n\n browser : [[\n\n /\\b(?:crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [VERSION, [NAME, 'Chrome']], [\n /edg(?:e|ios|a)?\\/([\\w\\.]+)/i // Microsoft Edge\n ], [VERSION, [NAME, 'Edge']], [\n\n // Presto based\n /(opera mini)\\/([-\\w\\.]+)/i, // Opera Mini\n /(opera [mobiletab]{3,6})\\b.+version\\/([-\\w\\.]+)/i, // Opera Mobi/Tablet\n /(opera)(?:.+version\\/|[\\/ ]+)([\\w\\.]+)/i // Opera\n ], [NAME, VERSION], [\n /opios[\\/ ]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [VERSION, [NAME, OPERA+' Mini']], [\n /\\bopr\\/([\\w\\.]+)/i // Opera Webkit\n ], [VERSION, [NAME, OPERA]], [\n\n // Mixed\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer)[\\/ ]?([\\w\\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer\n // Trident based\n /(avant |iemobile|slim)(?:browser)?[\\/ ]?([\\w\\.]*)/i, // Avant/IEMobile/SlimBrowser\n /(ba?idubrowser)[\\/ ]?([\\w\\.]+)/i, // Baidu Browser\n /(?:ms|\\()(ie) ([\\w\\.]+)/i, // Internet Explorer\n\n // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon\n /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\\/([-\\w\\.]+)/i,\n // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ\n /(heytap|ovi)browser\\/([\\d\\.]+)/i, // Heytap/Ovi\n /(weibo)__([\\d\\.]+)/i // Weibo\n ], [NAME, VERSION], [\n /(?:\\buc? ?browser|(?:juc.+)ucweb)[\\/ ]?([\\w\\.]+)/i // UCBrowser\n ], [VERSION, [NAME, 'UC'+BROWSER]], [\n /microm.+\\bqbcore\\/([\\w\\.]+)/i, // WeChat Desktop for Windows Built-in Browser\n /\\bqbcore\\/([\\w\\.]+).+microm/i\n ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [\n /micromessenger\\/([\\w\\.]+)/i // WeChat\n ], [VERSION, [NAME, 'WeChat']], [\n /konqueror\\/([\\w\\.]+)/i // Konqueror\n ], [VERSION, [NAME, 'Konqueror']], [\n /trident.+rv[: ]([\\w\\.]{1,9})\\b.+like gecko/i // IE11\n ], [VERSION, [NAME, 'IE']], [\n /ya(?:search)?browser\\/([\\w\\.]+)/i // Yandex\n ], [VERSION, [NAME, 'Yandex']], [\n /(avast|avg)\\/([\\w\\.]+)/i // Avast/AVG Secure Browser\n ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [\n /\\bfocus\\/([\\w\\.]+)/i // Firefox Focus\n ], [VERSION, [NAME, FIREFOX+' Focus']], [\n /\\bopt\\/([\\w\\.]+)/i // Opera Touch\n ], [VERSION, [NAME, OPERA+' Touch']], [\n /coc_coc\\w+\\/([\\w\\.]+)/i // Coc Coc Browser\n ], [VERSION, [NAME, 'Coc Coc']], [\n /dolfin\\/([\\w\\.]+)/i // Dolphin\n ], [VERSION, [NAME, 'Dolphin']], [\n /coast\\/([\\w\\.]+)/i // Opera Coast\n ], [VERSION, [NAME, OPERA+' Coast']], [\n /miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI '+BROWSER]], [\n /fxios\\/([-\\w\\.]+)/i // Firefox for iOS\n ], [VERSION, [NAME, FIREFOX]], [\n /\\bqihu|(qi?ho?o?|360)browser/i // 360\n ], [[NAME, '360 '+BROWSER]], [\n /(oculus|samsung|sailfish|huawei)browser\\/([\\w\\.]+)/i\n ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser\n /(comodo_dragon)\\/([\\w\\.]+)/i // Comodo Dragon\n ], [[NAME, /_/g, ' '], VERSION], [\n /(electron)\\/([\\w\\.]+) safari/i, // Electron-based App\n /(tesla)(?: qtcarbrowser|\\/(20\\d\\d\\.[-\\w\\.]+))/i, // Tesla\n /m?(qqbrowser|baiduboxapp|2345Explorer)[\\/ ]?([\\w\\.]+)/i // QQBrowser/Baidu App/2345 Browser\n ], [NAME, VERSION], [\n /(metasr)[\\/ ]?([\\w\\.]+)/i, // SouGouBrowser\n /(lbbrowser)/i, // LieBao Browser\n /\\[(linkedin)app\\]/i // LinkedIn App for iOS & Android\n ], [NAME], [\n\n // WebView\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i // Facebook App for iOS & Android\n ], [[NAME, FACEBOOK], VERSION], [\n /(kakao(?:talk|story))[\\/ ]([\\w\\.]+)/i, // Kakao App\n /(naver)\\(.*?(\\d+\\.[\\w\\.]+).*\\)/i, // Naver InApp\n /safari (line)\\/([\\w\\.]+)/i, // Line App for iOS\n /\\b(line)\\/([\\w\\.]+)\\/iab/i, // Line App for Android\n /(chromium|instagram)[\\/ ]([-\\w\\.]+)/i // Chromium/Instagram\n ], [NAME, VERSION], [\n /\\bgsa\\/([\\w\\.]+) .*safari\\//i // Google Search Appliance on iOS\n ], [VERSION, [NAME, 'GSA']], [\n /musical_ly(?:.+app_?version\\/|_)([\\w\\.]+)/i // TikTok\n ], [VERSION, [NAME, 'TikTok']], [\n\n /headlesschrome(?:\\/([\\w\\.]+)| )/i // Chrome Headless\n ], [VERSION, [NAME, CHROME+' Headless']], [\n\n / wv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, CHROME+' WebView'], VERSION], [\n\n /droid.+ version\\/([\\w\\.]+)\\b.+(?:mobile safari|safari)/i // Android Browser\n ], [VERSION, [NAME, 'Android '+BROWSER]], [\n\n /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\\/v?([\\w\\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /version\\/([\\w\\.\\,]+) .*mobile\\/\\w+ (safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n /version\\/([\\w(\\.|\\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n /webkit.+?(mobile ?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, strMapper, oldSafariMap]], [\n\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape\\d?)\\/([-\\w\\.]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /mobile vr; rv:([\\w\\.]+)\\).+firefox/i // Firefox Reality\n ], [VERSION, [NAME, FIREFOX+' Reality']], [\n /ekiohf.+(flow)\\/([\\w\\.]+)/i, // Flow\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\\/ ]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar\n /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\\/([-\\w\\.]+)$/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(firefox)\\/([\\w\\.]+)/i, // Other Firefox-based\n /(mozilla)\\/([\\w\\.]+) .+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\\. ]?browser)[-\\/ ]?v?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser\n /(links) \\(([\\w\\.]+)/i, // Links\n /panasonic;(viera)/i // Panasonic Viera\n ], [NAME, VERSION], [\n \n /(cobalt)\\/([\\w\\.]+)/i // Cobalt\n ], [NAME, [VERSION, /master.|lts./, \"\"]]\n ],\n\n cpu : [[\n\n /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\\)]/i // AMD64 (x64)\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i // IA32 (quicktime)\n ], [[ARCHITECTURE, lowerize]], [\n\n /((?:i[346]|x)86)[;\\)]/i // IA32 (x86)\n ], [[ARCHITECTURE, 'ia32']], [\n\n /\\b(aarch64|arm(v?8e?l?|_?64))\\b/i // ARM64\n ], [[ARCHITECTURE, 'arm64']], [\n\n /\\b(arm(?:v[67])?ht?n?[fl]p?)\\b/i // ARMHF\n ], [[ARCHITECTURE, 'armhf']], [\n\n // PocketPC mistakenly identified as PowerPC\n /windows (ce|mobile); ppc;/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((?:ppc|powerpc)(?:64)?)(?: mac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [\n\n /(sun4\\w)[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /((?:avr32|ia64(?=;))|68k(?=\\))|\\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\\b|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, lowerize]]\n ],\n\n device : [[\n\n //////////////////////////\n // MOBILES & TABLETS\n /////////////////////////\n\n // Samsung\n /\\b(sch-i[89]0\\d|shw-m380s|sm-[ptx]\\w{2,4}|gt-[pn]\\d{2,4}|sgh-t8[56]9|nexus 10)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [\n /\\b((?:s[cgp]h|gt|sm)-\\w+|sc[g-]?[\\d]+a?|galaxy nexus)/i,\n /samsung[- ]([-\\w]+)/i,\n /sec-(sgh\\w+)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [\n\n // Apple\n /(?:\\/|\\()(ip(?:hone|od)[\\w, ]*)(?:\\/|;)/i // iPod/iPhone\n ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [\n /\\((ipad);[-\\w\\),; ]+apple/i, // iPad\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/i,\n /\\b(ipad)\\d\\d?,\\d\\d?[;\\]].+ios/i\n ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [\n /(macintosh);/i\n ], [MODEL, [VENDOR, APPLE]], [\n\n // Sharp\n /\\b(sh-?[altvz]?\\d\\d[a-ekm]?)/i\n ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [\n\n // Huawei\n /\\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\\d{2})\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [\n /(?:huawei|honor)([-\\w ]+)[;\\)]/i,\n /\\b(nexus 6p|\\w{2,4}e?-[atu]?[ln][\\dx][012359c][adn]?)\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [\n\n // Xiaomi\n /\\b(poco[\\w ]+)(?: bui|\\))/i, // Xiaomi POCO\n /\\b; (\\w+) build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /\\b(hm[-_ ]?note?[_ ]?(?:\\d\\w)?) bui/i, // Xiaomi Hongmi\n /\\b(redmi[\\-_ ]?(?:note|k)?[\\w_ ]+)(?: bui|\\))/i, // Xiaomi Redmi\n /\\b(mi[-_ ]?(?:a\\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\\d?\\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\\))/i // Xiaomi Mi\n ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [\n /\\b(mi[-_ ]?(?:pad)(?:[\\w_ ]+))(?: bui|\\))/i // Mi Pad tablets\n ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [\n\n // OPPO\n /; (\\w+) bui.+ oppo/i,\n /\\b(cph[12]\\d{3}|p(?:af|c[al]|d\\w|e[ar])[mt]\\d0|x9007|a101op)\\b/i\n ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [\n\n // Vivo\n /vivo (\\w+)(?: bui|\\))/i,\n /\\b(v[12]\\d{3}\\w?[at])(?: bui|;)/i\n ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [\n\n // Realme\n /\\b(rmx[12]\\d{3})(?: bui|;|\\))/i\n ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\\b[\\w ]+build\\//i,\n /\\bmot(?:orola)?[- ](\\w*)/i,\n /((?:moto[\\w\\(\\) ]+|xt\\d{3,4}|nexus 6)(?= bui|\\)))/i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [\n /\\b(mz60\\d|xoom[2 ]{0,2}) build\\//i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [\n\n // LG\n /((?=lg)?[vl]k\\-?\\d{3}) bui| 3\\.[-\\w; ]{10}lg?-([06cv9]{3,4})/i\n ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [\n /(lm(?:-?f100[nv]?|-[\\w\\.]+)(?= bui|\\))|nexus [45])/i,\n /\\blg[-e;\\/ ]+((?!browser|netcast|android tv)\\w+)/i,\n /\\blg-?([\\d\\w]+) bui/i\n ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [\n\n // Lenovo\n /(ideatab[-\\w ]+)/i,\n /lenovo ?(s[56]000[-\\w]+|tab(?:[\\w ]+)|yt[-\\d\\w]{6}|tb[-\\d\\w]{6})/i\n ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [\n\n // Nokia\n /(?:maemo|nokia).*(n900|lumia \\d+)/i,\n /nokia[-_ ]?([-\\w\\.]*)/i\n ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [\n\n // Google\n /(pixel c)\\b/i // Google Pixel C\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [\n /droid.+; (pixel[\\daxl ]{0,6})(?: bui|\\))/i // Google Pixel\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [\n\n // Sony\n /droid.+ (a?\\d[0-2]{2}so|[c-g]\\d{4}|so[-gl]\\w+|xq-a\\w[4-7][12])(?= bui|\\).+chrome\\/(?![1-6]{0,1}\\d\\.))/i\n ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [\n /sony tablet [ps]/i,\n /\\b(?:sony)?sgp\\w+(?: bui|\\))/i\n ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [\n\n // OnePlus\n / (kb2005|in20[12]5|be20[12][59])\\b/i,\n /(?:one)?(?:plus)? (a\\d0\\d\\d)(?: b|\\))/i\n ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [\n\n // Amazon\n /(alexa)webm/i,\n /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i, // Kindle Fire without Silk / Echo Show\n /(kf[a-z]+)( bui|\\)).+silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [\n /((?:sd|kf)[0349hijorstuw]+)( bui|\\)).+silk\\//i // Fire Phone\n ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [\n\n // BlackBerry\n /(playbook);[-\\w\\),; ]+(rim)/i // BlackBerry PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n /\\b((?:bb[a-f]|st[hv])100-\\d)/i,\n /\\(bb10; (\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [\n\n // Asus\n /(?:\\b|asus_)(transfo[prime ]{4,10} \\w+|eeepc|slider \\w+|nexus 7|padfone|p00[cj])/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [\n / (z[bes]6[027][012][km][ls]|zenfone \\d\\w?)\\b/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [\n\n // HTC\n /(nexus 9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n /(htc)[-;_ ]{1,2}([\\w ]+(?=\\)| bui)|\\w+)/i, // HTC\n\n // ZTE\n /(zte)[- ]([\\w ]+?)(?: bui|\\/|\\))/i,\n /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\\.))|sony(?!-bra))[-_ ]?([-\\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n // Acer\n /droid.+; ([ab][1-7]-?[0178a]\\d\\d?)/i\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n // Meizu\n /droid.+; (m[1-5] note) bui/i,\n /\\bmz-([-\\w]{2,})/i\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [\n\n // MIXED\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\\w]*)/i,\n // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron\n /(hp) ([\\w ]+\\w)/i, // HP iPAQ\n /(asus)-?(\\w+)/i, // Asus\n /(microsoft); (lumia[\\w ]+)/i, // Microsoft Lumia\n /(lenovo)[-_ ]?([-\\w]+)/i, // Lenovo\n /(jolla)/i, // Jolla\n /(oppo) ?([\\w ]+) bui/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /(kobo)\\s(ereader|touch)/i, // Kobo\n /(archos) (gamepad2?)/i, // Archos\n /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(nook)[\\w ]+build\\/(\\w+)/i, // Nook\n /(dell) (strea[kpr\\d ]*[\\dko])/i, // Dell Streak\n /(le[- ]+pan)[- ]+(\\w{1,9}) bui/i, // Le Pan Tablets\n /(trinity)[- ]*(t\\d{3}) bui/i, // Trinity Tablets\n /(gigaset)[- ]+(q\\w{1,9}) bui/i, // Gigaset Tablets\n /(vodafone) ([\\w ]+)(?:\\)| bui)/i // Vodafone\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(surface duo)/i // Surface Duo\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [\n /droid [\\d\\.]+; (fp\\du?)(?: b|\\))/i // Fairphone\n ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [\n /(u304aa)/i // AT&T\n ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [\n /\\bsie-(\\w*)/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n /\\b(rct\\w+) b/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n /\\b(venue[\\d ]{2,7}) b/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n /\\b(q(?:mv|ta)\\w+) b/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n /\\b(?:barnes[& ]+noble |bn[rt])([\\w\\+ ]*) b/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [\n /\\b(tm\\d{3}\\w+) b/i\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n /\\b(k88) b/i // ZTE K Series Tablet\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [\n /\\b(nx\\d{3}j) b/i // ZTE Nubia\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n /\\b(gen\\d{3}) b.+49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n /\\b(zur\\d{3}) b/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n /\\b((zeki)?tb.*\\b) b/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n /\\b([yr]\\d{2}) b/i,\n /\\b(dragon[- ]+touch |dt)(\\w{5}) b/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n /\\b(ns-?\\w{0,9}) b/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n /\\b((nxa|next)-?\\w{0,9}) b/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n /\\b(xtreme\\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [\n /\\b(lvtel\\-)?(v1[12]) b/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n /\\b(ph-1) /i // Essential PH-1\n ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [\n /\\b(v(100md|700na|7011|917g).*\\b) b/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n /\\b(trio[-\\w\\. ]+) b/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n /\\btu_(1491) b/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n /(shield[\\w ]+) b/i // Nvidia Shield Tablets\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [\n /(sprint) (\\w+)/i // Sprint Phones\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [\n /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\\)/i // Zebra\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [\n /droid.+; (ec30|ps20|tc[2-8]\\d[kx])\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [\n\n ///////////////////\n // SMARTTVS\n ///////////////////\n\n /smart-tv.+(samsung)/i // Samsung\n ], [VENDOR, [TYPE, SMARTTV]], [\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [\n /(nux; netcast.+smarttv|lg (netcast\\.tv-201\\d|android tv))/i // LG SmartTV\n ], [[VENDOR, LG], [TYPE, SMARTTV]], [\n /(apple) ?tv/i // Apple TV\n ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [\n /crkey/i // Google Chromecast\n ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [\n /droid.+aft(\\w)( bui|\\))/i // Fire TV\n ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [\n /\\(dtv[\\);].+(aquos)/i,\n /(aquos-tv[\\w ]+)\\)/i // Sharp\n ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[\n /(bravia[\\w ]+)( bui|\\))/i // Sony\n ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [\n /(mitv-\\w{5}) bui/i // Xiaomi\n ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [\n /Hbbtv.*(technisat) (.*);/i // TechniSAT\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /\\b(roku)[\\dx]*[\\)\\/]((?:dvp-)?[\\d\\.]*)/i, // Roku\n /hbbtv\\/\\d+\\.\\d+\\.\\d+ +\\([\\w\\+ ]*; *([\\w\\d][^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [\n /\\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\\b/i // SmartTV from Unidentified Vendors\n ], [[TYPE, SMARTTV]], [\n\n ///////////////////\n // CONSOLES\n ///////////////////\n\n /(ouya)/i, // Ouya\n /(nintendo) ([wids3utch]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n /droid.+; (shield) bui/i // Nvidia\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [\n /(playstation [345portablevi]+)/i // Playstation\n ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [\n /\\b(xbox(?: one)?(?!; xbox))[\\); ]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [\n\n ///////////////////\n // WEARABLES\n ///////////////////\n\n /((pebble))app/i // Pebble\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /(watch)(?: ?os[,\\/]|\\d,\\d\\/)[\\d\\.]+/i // Apple Watch\n ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [\n /droid.+; (glass) \\d/i // Google Glass\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [\n /droid.+; (wt63?0{2,3})\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [\n /(quest( 2| pro)?)/i // Oculus Quest\n ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [\n\n ///////////////////\n // EMBEDDED\n ///////////////////\n\n /(tesla)(?: qtcarbrowser|\\/[-\\w\\.]+)/i // Tesla\n ], [VENDOR, [TYPE, EMBEDDED]], [\n /(aeobc)\\b/i // Echo Dot\n ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [\n\n ////////////////////\n // MIXED (GENERIC)\n ///////////////////\n\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors\n ], [MODEL, [TYPE, MOBILE]], [\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors\n ], [MODEL, [TYPE, TABLET]], [\n /\\b((tablet|tab)[;\\/]|focus\\/\\d(?!.+mobile))/i // Unidentifiable Tablet\n ], [[TYPE, TABLET]], [\n /(phone|mobile(?:[;\\/]| [ \\w\\/\\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile\n ], [[TYPE, MOBILE]], [\n /(android[-\\w\\. ]{0,9});.+buil/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n ],\n\n engine : [[\n\n /windows.+ edge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, EDGE+'HTML']], [\n\n /webkit\\/537\\.36.+chrome\\/(?!27)([\\w\\.]+)/i // Blink\n ], [VERSION, [NAME, 'Blink']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna\n /ekioh(flow)\\/([\\w\\.]+)/i, // Flow\n /(khtml|tasman|links)[\\/ ]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/ ]([23]\\.[\\d\\.]+)/i, // iCab\n /\\b(libweb)/i\n ], [NAME, VERSION], [\n\n /rv\\:([\\w\\.]{1,9})\\b.+(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows\n /microsoft (windows) (vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows) nt 6\\.2; (arm)/i, // Windows RT\n /(windows (?:phone(?: os)?|mobile))[\\/ ]?([\\d\\.\\w ]*)/i, // Windows Phone\n /(windows)[\\/ ]?([ntce\\d\\. ]+\\w)(?!.+xbox)/i\n ], [NAME, [VERSION, strMapper, windowsVersionMap]], [\n /(win(?=3|9|n)|win 9x )([nt\\d\\.]+)/i\n ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [\n\n // iOS/macOS\n /ip[honead]{2,4}\\b(?:.*os ([\\w]+) like mac|; opera)/i, // iOS\n /ios;fbsv\\/([\\d\\.]+)/i,\n /cfnetwork\\/.+darwin/i\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n /(mac os x) ?([\\w\\. ]*)/i,\n /(macintosh|mac_powerpc\\b)(?!.+haiku)/i // Mac OS\n ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [\n\n // Mobile OSes\n /droid ([\\w\\.]+)\\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS\n ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS\n /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\\/ ]?([\\w\\.]*)/i,\n /(blackberry)\\w*\\/([\\w\\.]*)/i, // Blackberry\n /(tizen|kaios)[\\/ ]([\\w\\.]+)/i, // Tizen/KaiOS\n /\\((series40);/i // Series 40\n ], [NAME, VERSION], [\n /\\(bb(10);/i // BlackBerry 10\n ], [VERSION, [NAME, BLACKBERRY]], [\n /(?:symbian ?os|symbos|s60(?=;)|series60)[-\\/ ]?([\\w\\.]*)/i // Symbian\n ], [VERSION, [NAME, 'Symbian']], [\n /mozilla\\/[\\d\\.]+ \\((?:mobile|tablet|tv|mobile; [\\w ]+); rv:.+ gecko\\/([\\w\\.]+)/i // Firefox OS\n ], [VERSION, [NAME, FIREFOX+' OS']], [\n /web0s;.+rt(tv)/i,\n /\\b(?:hp)?wos(?:browser)?\\/([\\w\\.]+)/i // WebOS\n ], [VERSION, [NAME, 'webOS']], [\n /watch(?: ?os[,\\/]|\\d,\\d\\/)([\\d\\.]+)/i // watchOS\n ], [VERSION, [NAME, 'watchOS']], [\n\n // Google Chromecast\n /crkey\\/([\\d\\.]+)/i // Google Chromecast\n ], [VERSION, [NAME, CHROME+'cast']], [\n /(cros) [\\w]+(?:\\)| ([\\w\\.]+)\\b)/i // Chromium OS\n ], [[NAME, CHROMIUM_OS], VERSION],[\n\n // Smart TVs\n /panasonic;(viera)/i, // Panasonic Viera\n /(netrange)mmh/i, // Netrange\n /(nettv)\\/(\\d+\\.[\\w\\.]+)/i, // NetTV\n\n // Console\n /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation\n /(xbox); +xbox ([^\\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)\n\n // Other\n /\\b(joli|palm)\\b ?(?:os)?\\/?([\\w\\.]*)/i, // Joli/Palm\n /(mint)[\\/\\(\\) ]?(\\w*)/i, // Mint\n /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux\n /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\\/ ]?(?!chrom|package)([-\\w\\.]*)/i,\n // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire\n /(hurd|linux) ?([\\w\\.]*)/i, // Hurd/Linux\n /(gnu) ?([\\w\\.]*)/i, // GNU\n /\\b([-frentopcghs]{0,5}bsd|dragonfly)[\\/ ]?(?!amd|[ix346]{1,2}86)([\\w\\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly\n /(haiku) (\\w+)/i // Haiku\n ], [NAME, VERSION], [\n /(sunos) ?([\\w\\.\\d]*)/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n /((?:open)?solaris)[-\\/ ]?([\\w\\.]*)/i, // Solaris\n /(aix) ((\\d)(?=\\.|\\)| )[\\w\\.])*/i, // AIX\n /\\b(beos|os\\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS\n /(unix) ?([\\w\\.]*)/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n /////////////////\n // Constructor\n ////////////////\n\n var UAParser = function (ua, extensions) {\n\n if (typeof ua === OBJ_TYPE) {\n extensions = ua;\n ua = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(ua, extensions).getResult();\n }\n\n var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined;\n var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY);\n var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined;\n var _rgxmap = extensions ? extend(regexes, extensions) : regexes;\n var _isSelfNav = _navigator && _navigator.userAgent == _ua;\n\n this.getBrowser = function () {\n var _browser = {};\n _browser[NAME] = undefined;\n _browser[VERSION] = undefined;\n rgxMapper.call(_browser, _ua, _rgxmap.browser);\n _browser[MAJOR] = majorize(_browser[VERSION]);\n // Brave-specific detection\n if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {\n _browser[NAME] = 'Brave';\n }\n return _browser;\n };\n this.getCPU = function () {\n var _cpu = {};\n _cpu[ARCHITECTURE] = undefined;\n rgxMapper.call(_cpu, _ua, _rgxmap.cpu);\n return _cpu;\n };\n this.getDevice = function () {\n var _device = {};\n _device[VENDOR] = undefined;\n _device[MODEL] = undefined;\n _device[TYPE] = undefined;\n rgxMapper.call(_device, _ua, _rgxmap.device);\n if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {\n _device[TYPE] = MOBILE;\n }\n // iPadOS-specific detection: identified as Mac, but has some iOS-only properties\n if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {\n _device[MODEL] = 'iPad';\n _device[TYPE] = TABLET;\n }\n return _device;\n };\n this.getEngine = function () {\n var _engine = {};\n _engine[NAME] = undefined;\n _engine[VERSION] = undefined;\n rgxMapper.call(_engine, _ua, _rgxmap.engine);\n return _engine;\n };\n this.getOS = function () {\n var _os = {};\n _os[NAME] = undefined;\n _os[VERSION] = undefined;\n rgxMapper.call(_os, _ua, _rgxmap.os);\n if (_isSelfNav && !_os[NAME] && _uach && _uach.platform != 'Unknown') {\n _os[NAME] = _uach.platform \n .replace(/chrome os/i, CHROMIUM_OS)\n .replace(/macos/i, MAC_OS); // backward compatibility\n }\n return _os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return _ua;\n };\n this.setUA = function (ua) {\n _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;\n return this;\n };\n this.setUA(_ua);\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);\n UAParser.CPU = enumerize([ARCHITECTURE]);\n UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);\n UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);\n\n ///////////\n // Export\n //////////\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (typeof window !== UNDEF_TYPE) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);\n if ($ && !$.ua) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (ua) {\n parser.setUA(ua);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\nimport UAParser from \"ua-parser-js\";\nconst Browser = {\n UNKNOWN: \"Unknown\",\n SAFARI: \"Safari\",\n FIREFOX: \"Firefox\",\n OPERA: \"Opera\",\n CHROME: \"Chrome\",\n IOS_WEBVIEW: \"iOS-webview\"\n};\nclass BrowserUtils {\n static getName() {\n if (!this._name) {\n if (typeof navigator === \"undefined\" || !navigator) {\n this._name = Browser.UNKNOWN;\n } else {\n const { userAgent } = navigator;\n if (userAgent.match(/Firefox/i)) {\n this._name = Browser.FIREFOX;\n } else if (userAgent.match(/(Opera|OPR)/i)) {\n this._name = Browser.OPERA;\n } else if (userAgent.match(/Chrome/i)) {\n this._name = Browser.CHROME;\n } else if (userAgent.match(/Safari/i)) {\n this._name = Browser.SAFARI;\n } else if (userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Version)/i)) {\n this._name = Browser.IOS_WEBVIEW;\n } else {\n this._name = Browser.UNKNOWN;\n }\n }\n }\n return this._name;\n }\n static get isMobile() {\n if (this._isMobile === null) {\n this._isMobile = false;\n if (typeof navigator !== \"undefined\" && navigator) {\n const userAgent = navigator.userAgent || navigator.vendor;\n if (userAgent && (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(userAgent.substr(0, 4)))) {\n this._isMobile = true;\n }\n }\n }\n return this._isMobile;\n }\n static clearCache() {\n this._name = null;\n this._isMobile = null;\n }\n}\n__publicField(BrowserUtils, \"_name\", null);\n__publicField(BrowserUtils, \"_isMobile\", null);\nconst QUALITATIVE_COLORS = [\n 4215763,\n 14529296,\n 11869460,\n 48895,\n 16468400,\n 45661,\n 13290186\n];\nfunction getQualitativeColor(number) {\n return QUALITATIVE_COLORS[number % QUALITATIVE_COLORS.length];\n}\nconst ColorUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n getQualitativeColor\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction getDeviceFromUserAgent() {\n const info = new UAParser().getResult();\n if (!info) {\n return null;\n }\n const res = {\n vendor: info.device.vendor,\n model: info.device.model\n };\n if (!res.vendor && !res.model && info.os.name === \"Mac OS\") {\n res.vendor = \"Apple\";\n res.model = \"Mac\";\n }\n return res;\n}\nconst UserAgentUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n getDeviceFromUserAgent\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction any(promises) {\n return new Promise((resolve, reject) => {\n let count = promises.length, resolved = false;\n const reasons = [];\n promises.forEach((p) => {\n Promise.resolve(p).then((value) => {\n resolved = true;\n count--;\n resolve(value);\n }, (reason) => {\n count--;\n reasons.push(reason);\n if (count === 0 && !resolved) {\n reject(new Error(reasons.join(\"\\n\")));\n }\n });\n });\n });\n}\nconst PromiseUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n any\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction generateString(strLength) {\n return Math.random().toString(36).substring(2, strLength + 2);\n}\nconst RandomUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n generateString\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction formatSO(value, ...xargs) {\n let str = value.toString();\n if (xargs.length) {\n const t = typeof xargs[0];\n const args = t === \"string\" || t === \"number\" ? xargs.slice() : xargs[0];\n for (const key in args) {\n str = str.replace(new RegExp(\"\\\\{\" + key + \"\\\\}\", \"gi\"), args[key]);\n }\n }\n return str;\n}\nconst StringUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n formatSO\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction preciseTime() {\n if (typeof window !== \"undefined\" && window.performance) {\n return window.performance.now();\n }\n const hrtime = process.hrtime();\n return Math.round(hrtime[0] * 1e3 + hrtime[1] / 1e6);\n}\nfunction unixTimestampToPreciseTime(timestamp) {\n return preciseTime() + timestamp - (/* @__PURE__ */ new Date()).getTime();\n}\nfunction preciseTimeToUnixTimestamp(_preciseTime) {\n return (/* @__PURE__ */ new Date()).getTime() + _preciseTime - preciseTime();\n}\nconst TimeUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n preciseTime,\n preciseTimeToUnixTimestamp,\n unixTimestampToPreciseTime\n}, Symbol.toStringTag, { value: \"Module\" }));\nexport {\n Browser,\n BrowserUtils,\n ColorUtils,\n PromiseUtils,\n RandomUtils,\n StringUtils,\n TimeUtils,\n UserAgentUtils\n};\n//# sourceMappingURL=index.mjs.map\n","import Edge from './Edge.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { GraphRouterOptionsJson, type GraphRouterOptions } from './GraphRouterOptions.js';\n\nexport default class GraphRouterOptionsBuilder {\n\n public avoidStairs = false;\n public avoidEscalators = false;\n public avoidElevators = false;\n public avoidMovingWalkway = false;\n public avoidTicketRestrictedAreas = false;\n\n public projectionMaxDistance?: number;\n\n static DEFAULT = new GraphRouterOptionsBuilder().build();\n static WITHOUT_STAIRS = new GraphRouterOptionsBuilder().setAvoidStairs(true).build();\n\n setAvoidStairs(avoidStairs: boolean) {\n this.avoidStairs = avoidStairs;\n return this;\n }\n\n setAvoidEscalators(avoidEscalators: boolean) {\n this.avoidEscalators = avoidEscalators;\n return this;\n }\n\n setAvoidElevators(avoidElevators: boolean) {\n this.avoidElevators = avoidElevators;\n return this;\n }\n\n setAvoidMovingWalkway(avoidMovingWalkway: boolean) {\n this.avoidMovingWalkway = avoidMovingWalkway;\n return this;\n }\n\n setAvoidTicketRestrictedAreas(avoidTicketRestrictedAreas: boolean) {\n this.avoidTicketRestrictedAreas = avoidTicketRestrictedAreas;\n return this;\n }\n\n static fromJson(options: GraphRouterOptionsJson) {\n const builder = new GraphRouterOptionsBuilder();\n Object.assign(builder, options);\n return builder.build();\n }\n\n build(): GraphRouterOptions {\n\n const weightEdgeFn = (edge: Edge) => {\n if (edge.properties.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.properties.areStairs) {\n duration *= 3;\n } else if (edge.properties.areEscalators) {\n duration *= 1.5;\n } else if (edge.properties.isMovingWalkway) {\n duration *= 0.8;\n }\n return duration;\n }\n\n const acceptEdgeFn = (edge: Edge) => {\n\n if (this.avoidStairs && edge.properties.areStairs) return false;\n if (this.avoidEscalators && edge.properties.areEscalators) return false;\n if (this.avoidElevators && edge.properties.isElevator) return false;\n if (this.avoidMovingWalkway && edge.properties.isMovingWalkway) return false;\n if (this.avoidTicketRestrictedAreas && edge.properties.needTicket) return false;\n\n return true;\n };\n\n return {\n input: {\n avoidStairs: this.avoidStairs,\n avoidEscalators: this.avoidEscalators,\n avoidElevators: this.avoidElevators,\n avoidMovingWalkway: this.avoidMovingWalkway,\n avoidTicketRestrictedAreas: this.avoidTicketRestrictedAreas,\n projectionMaxDistance: this.projectionMaxDistance\n },\n weightEdgeFn,\n acceptEdgeFn,\n projectionMaxDistance: this.projectionMaxDistance\n };\n }\n\n}\n","\nimport { ColorUtils } from '@wemap/utils';\nimport Edge from './Edge.js';\nimport Graph from './Graph.js';\nimport GraphRoute from './GraphRoute.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\nimport Vertex from './Vertex.js';\n\nexport class GraphRouterEngineResults {\n constructor(\n public prev: Array<Vertex | null>,\n public dist: number[],\n public source: Vertex,\n public targets: Vertex[],\n public edges: Edge[]\n ) { }\n\n routeVertices(to = this.targets[0], list: Vertex[] = []): Vertex[] {\n const last = this.prev[to.id];\n if (last === null) return this.source === to ? [...list, to] : [];\n return [...this.routeVertices(last, list), to];\n }\n\n weightedDistance(to = this.targets[0]) {\n const distance = this.dist[to.id];\n return distance === Number.MAX_VALUE ? null : distance;\n }\n\n route(to = this.targets[0]) {\n\n const path = this.routeVertices(to);\n\n const edges = [];\n const edgesWeights = [];\n for (let i = 1; i < path.length; i++) {\n const v1 = path[i - 1];\n const v2 = path[i];\n const graphEdge = Edge.getEdgeByVertices(this.edges, v1, v2)!;\n const clonedEdge = new Edge(v1, v2, Object.assign({}, graphEdge.properties));\n const isReversed = graphEdge.vertex1 === clonedEdge.vertex2;\n if (isReversed) {\n clonedEdge.reverseProperties();\n }\n edges.push(clonedEdge);\n edgesWeights.push(this.dist[v2.id] - this.dist[v1.id]);\n }\n return new GraphRoute(this.source.coords, to.coords, path, edges, edgesWeights);\n }\n\n toGeoJson(graph: Graph) {\n return {\n type: \"FeatureCollection\",\n features: [\n ...graph.vertices.map(v => {\n const prev = this.prev[v.id];\n const dist = this.dist[v.id];\n const isSource = v === this.source;\n const isTarget = this.targets.includes(v);\n const level = v.coords.level;\n return {\n type: \"Feature\",\n properties: {\n id: v.id,\n ...(prev && { prev: prev.id }),\n dist: dist === Number.MAX_VALUE ? 'infinity' : dist,\n ...(isSource && { name: 'source' }),\n ...(isTarget && { name: 'target' }),\n ...(level !== null && { level }),\n ...v.properties\n },\n geometry: {\n type: 'Point',\n coordinates: [v.coords.lng, v.coords.lat]\n }\n }\n }),\n ...graph.edges.map(e => {\n const level = e.level;\n return {\n type: \"Feature\",\n properties: {\n id: e.id,\n ...(level !== null && { level }),\n ...e.properties\n },\n geometry: {\n type: 'LineString',\n coordinates: [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat]\n ]\n }\n }\n })\n ]\n };\n }\n}\n\nexport default class GraphRouterEngine {\n\n disabledEdges: Set<Edge> = new Set();\n\n constructor(public readonly graph: Graph) {\n let vertexId = 0;\n graph.vertices.forEach(vertex => vertex.id = vertexId++);\n }\n\n calculateShortestPathToMultipleDestinationsByVertex(\n source: Vertex,\n targets: Vertex[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n\n const q = new Set(inputVertices);\n const dist = Array(q.size).fill(Number.MAX_VALUE);\n const prev = new Array<Vertex | null>(q.size).fill(null);\n const edges = inputEdges.filter(e => (options.acceptEdgeFn?.(e) ?? true) && !this.disabledEdges.has(e));\n const weightEdgeFn = options.weightEdgeFn || ((edge: Edge) => edge.length);\n\n const getVertexWithMinDistance = (vertices: Set<Vertex>): Vertex | null => {\n let minDistance = Number.MAX_VALUE;\n let vertex: Vertex | null = null;\n vertices.forEach(_vertex => {\n const distance = dist[_vertex.id];\n if (distance <= minDistance) {\n minDistance = distance;\n vertex = _vertex;\n }\n });\n return vertex;\n }\n\n\n const remainingNodesToFind = new Set(targets);\n\n dist[source.id] = 0;\n\n while (q.size > 0) {\n const u = getVertexWithMinDistance(q)!;\n q.delete(u);\n\n if (targets.includes(u)) {\n remainingNodesToFind.delete(u);\n if (remainingNodesToFind.size === 0) {\n break;\n }\n }\n\n edges\n .filter(edge => edge.vertex1 == u || !edge.properties.isOneway && edge.vertex2 == u)\n .forEach(edge => {\n const v = u === edge.vertex1 ? edge.vertex2 : edge.vertex1;\n const distance = weightEdgeFn(edge);\n const alt = dist[u.id] + distance;\n if (alt < dist[v.id]) {\n dist[v.id] = alt;\n prev[v.id] = u\n }\n });\n }\n\n return new GraphRouterEngineResults(prev, dist, source, targets, edges);\n }\n\n calculateShortestPathByVertex(\n source: Vertex,\n target: Vertex,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n return this.calculateShortestPathToMultipleDestinationsByVertex(source, [target], options, inputVertices, inputEdges);\n }\n\n // https://en.wikipedia.org/wiki/Component_(graph_theory)\n calculateComponents() {\n\n function shiftSet<T>(set: Set<T>): T {\n const firstValue = set.values().next().value as T;\n set.delete(firstValue);\n return firstValue;\n }\n\n const verticesToTest = new Set<Vertex>(this.graph.vertices);\n let components: Vertex[][] = [];\n\n while (verticesToTest.size > 0) {\n const vertexToTest = shiftSet(verticesToTest);\n const otherVertices = this.graph.vertices.filter(v => v.id !== vertexToTest.id);\n const result = this.calculateShortestPathToMultipleDestinationsByVertex(vertexToTest, otherVertices);\n const reachedVertices = otherVertices.filter(ov => result.weightedDistance(ov) !== null);\n\n components.push([vertexToTest, ...reachedVertices]);\n reachedVertices.forEach(rv => verticesToTest.delete(rv));\n }\n\n // As graph is ordered, fuse components with same vertices\n let hasChanged;\n do {\n hasChanged = false;\n for (let i = 0; i < components.length - 1; i++) {\n const component1 = components[i];\n for (let j = i + 1; j < components.length; j++) {\n const component2 = components[j];\n const componentsIntersect = component2.some(v => component1.includes(v));\n if (componentsIntersect) {\n component1.push(...component2);\n components = components.filter(component => component !== component2);\n hasChanged = true;\n }\n }\n }\n } while (hasChanged)\n\n return components.map(c => [... new Set(c)]);\n }\n\n toGeoJson() {\n const components = this.calculateComponents();\n const features = components.map((component, i) => {\n const edges = this.graph.edges.filter(edge => component.includes(edge.vertex1) && component.includes(edge.vertex2));\n return {\n \"type\": \"Feature\",\n \"geometry\": {\n \"type\": \"MultiLineString\",\n \"coordinates\":\n edges.map(e => [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat],\n ])\n },\n \"properties\": {\n \"stroke\": '#' + ColorUtils.getQualitativeColor(i).toString(16)\n }\n }\n });\n\n return {\n \"type\": \"FeatureCollection\",\n \"features\": features\n };\n }\n\n}\n","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\nimport Edge, { EdgeProperties } from './Edge.js';\nimport GraphRoute from './GraphRoute.js';\nimport GraphRouterEngine, { GraphRouterEngineResults } from './GraphRouterEngine.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\n\nexport class GraphRouterResults extends GraphRouterEngineResults {\n\n constructor(\n engineResults: GraphRouterEngineResults,\n public sourceProjection: [Coordinates, Vertex | null],\n public targetsProjections: [Coordinates, Vertex | null][]\n\n ) {\n super(engineResults.prev, engineResults.dist, engineResults.source, engineResults.targets, engineResults.edges);\n }\n\n static createEmpty(source: Coordinates, targets: Coordinates[]) {\n const length = targets.length;\n const engineResults = new GraphRouterEngineResults(\n new Array(length).fill(null),\n new Array(length).fill(Number.MAX_VALUE),\n new Vertex(source),\n targets.map(target => new Vertex(target)),\n []\n );\n const sourceProjection: [Coordinates, null] = [source, null];\n const targetsProjections: [Coordinates, null][] = targets.map(target => [target, null]);\n return new GraphRouterResults(engineResults, sourceProjection, targetsProjections);\n }\n\n routeVertices(to: Coordinates | Vertex = this.targetsProjections[0][0]): Vertex[] {\n\n if (to instanceof Vertex) {\n return super.routeVertices(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return [];\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return [];\n\n return super.routeVertices(toVertex);\n }\n\n weightedDistance(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.weightedDistance(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return null;\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return null;\n\n return super.weightedDistance(toVertex);\n }\n\n route(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.route(to);\n }\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return new GraphRoute(this.sourceProjection[0], to, [], [], []);\n\n const route = super.route(toVertex);\n route.start = this.sourceProjection[0];\n route.end = to;\n return route;\n }\n}\n\n\nclass GraphRouter extends GraphRouterEngine {\n\n calculateShortestPathToMultipleDestinations(\n source: Coordinates,\n targets: Coordinates[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n\n const createdVertices = new Set<Vertex>();\n const createdEdges = new Set<Edge>();\n const createdVerticesByOriginalEdges: [Edge, Vertex[]][] = []\n\n const projectionsOptions = {\n maxDistance: options.projectionMaxDistance,\n acceptEdgeFn: options.acceptEdgeFn\n };\n\n const getOrCreateVertex = (coords: Coordinates): Vertex | null => {\n const projection = this.graph.getProjection(coords, projectionsOptions);\n if (projection === null) return null;\n if (projection.nearestElement instanceof Vertex) {\n return projection.nearestElement;\n }\n if (projection.nearestElement instanceof Edge) {\n const edge = projection.nearestElement;\n const newVertex = new Vertex(projection.coords, {\n name: `proj on ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n });\n newVertex.id = this.graph.vertices.length + createdVertices.size;\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n };\n const newEdge1 = new Edge(edge.vertex1, newVertex, newEdgesOptions);\n const newEdge2 = new Edge(newVertex, edge.vertex2, newEdgesOptions);\n\n createdVertices.add(newVertex);\n createdEdges.add(newEdge1);\n createdEdges.add(newEdge2);\n\n const createdVerticesByOriginalEdge = createdVerticesByOriginalEdges.find(p => p[0] === edge)\n if (!createdVerticesByOriginalEdge) {\n createdVerticesByOriginalEdges.push([edge, [newVertex]])\n } else {\n createdVerticesByOriginalEdge[1].push(newVertex);\n }\n return newVertex;\n }\n\n return null; // Should never happens\n }\n\n const sourceVertex = getOrCreateVertex(source);\n if (!sourceVertex) return GraphRouterResults.createEmpty(source, targets);\n\n const targetsProjections: [Coordinates, Vertex | null][] = targets.map(target => [target, getOrCreateVertex(target)]);\n const targetsVertices = targetsProjections.map(([, vertex]) => vertex).filter(p => p !== null) as Vertex[];\n\n // In some specific cases, more than one vertex is created from an original edge.\n // And this vertices need to be connected together.\n createdVerticesByOriginalEdges.filter(pair => pair[1].length >= 2);\n createdVerticesByOriginalEdges.forEach(([edge, vertices]) => {\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n };\n for (let i = 0; i < vertices.length; i++) {\n const vertexA = vertices[i];\n const distVertexAVertex1 = vertexA.distanceTo(edge.vertex1)\n for (let j = i + 1; j < vertices.length; j++) {\n const vertexB = vertices[j];\n const distVertexBVertex1 = vertexB.distanceTo(edge.vertex1)\n const reverse = distVertexBVertex1 < distVertexAVertex1;\n const newEdge = !reverse\n ? new Edge(vertexA, vertexB, newEdgesOptions)\n : new Edge(vertexB, vertexA, newEdgesOptions);\n createdEdges.add(newEdge);\n }\n }\n })\n\n\n const engineResults = this.calculateShortestPathToMultipleDestinationsByVertex(\n sourceVertex, targetsVertices, options,\n [...this.graph.vertices, ...createdVertices],\n [...this.graph.edges, ...createdEdges],\n );\n\n return new GraphRouterResults(engineResults, [source, sourceVertex], targetsProjections);\n }\n\n calculateShortestPath(\n source: Coordinates,\n target: Coordinates,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n return this.calculateShortestPathToMultipleDestinations(source, [target], options);\n }\n\n\n // TODO: Verify if it works well with oneway edges\n getShortestTrip(waypoints: Coordinates[], options?: GraphRouterOptions, tspTempCoeff = 0.99) {\n type CustomPoint = salesman.Point & { coords: Coordinates };\n\n const points = waypoints.map(waypoint => {\n const point = new salesman.Point(0, 0) as CustomPoint;\n point.coords = waypoint;\n return point;\n });\n const graphRoutesCache: GraphRoute[] = [];\n const solution = salesman.solve(points, tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n const route = this.calculateShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n ).route();\n graphRoutesCache.push(route);\n if (!route.hasRoute) { return Number.MAX_VALUE }\n return route.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedRoutes = [];\n for (let i = 0; i < orderedPoints.length; i++) {\n const p = orderedPoints[i] as CustomPoint;\n const q = orderedPoints[(i + 1) % orderedPoints.length] as CustomPoint;\n let cachedRoute = graphRoutesCache.find(route => route.start === p.coords && route.end === q.coords || route.end === p.coords && route.start === q.coords);\n if (cachedRoute?.end === p.coords) {\n // Need to revert route due to salesman bijectivity\n cachedRoute = cachedRoute.reverse();\n }\n if (cachedRoute) {\n orderedRoutes.push(cachedRoute);\n }\n }\n\n if (orderedRoutes.some(route => !route.hasRoute)) return [];\n\n return orderedRoutes;\n }\n\n\n}\nexport default GraphRouter;\n","import { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nclass NoRouteFoundError extends Error {\n\n constructor(\n public start: Vertex | Coordinates,\n public end: Vertex | Coordinates | (Coordinates | Vertex)[],\n public details: string | null = null\n ) { super(); }\n\n get startStr() {\n if (this.start instanceof Vertex) {\n return `Vertex ${this.start.coords.toString()}`;\n }\n return this.start.toString();\n }\n\n get endStr() {\n if (this.end instanceof Vertex) {\n return `Vertex ${this.end.coords.toString()}`;\n }\n if (Array.isArray(this.end)) {\n return this.end.map(p => p instanceof Vertex ? p.coords.toString() : p.toString()).join(',');\n }\n return this.end.toString();\n }\n\n get message() {\n let message = `No route found from ${this.startStr} to ${this.endStr}.`;\n if (this.details) {\n message += ` Details: ${this.details}`;\n }\n return message;\n }\n}\n\nexport default NoRouteFoundError;\n","import { Coordinates, Level, Level_t } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport { default as Edge, type EdgeProperties } from '../graph/Edge.js';\nimport { default as Vertex, type VertexProperties } from '../graph/Vertex.js';\n\n\nexport default class OsmGraphUtils {\n\n static RESTRICTED_PEDESTRIANS_HIGHWAYS = ['motorway', 'motorway_link'];\n\n static DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n if (way.isArea) return false;\n if (way.tags.foot === 'yes') return true;\n if (['no', 'private'].includes(way.tags.access)) return false;\n\n const isElevatorArea = way.tags.highway === 'elevator' && way.isGeometryClosed\n return way.tags.highway && !OsmGraphUtils.RESTRICTED_PEDESTRIANS_HIGHWAYS.includes(way.tags.highway) && !isElevatorArea\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n };\n\n static parseNodeProperties(osmNode: OsmNode): VertexProperties {\n return {\n ...(osmNode.name && { name: osmNode.name }),\n ...(osmNode.id && { externalId: osmNode.id }),\n ...(osmNode.isGate && { isGate: osmNode.isGate }),\n ...(osmNode.isSubwayEntrance && { isSubwayEntrance: osmNode.isSubwayEntrance }),\n ...(osmNode.subwayEntranceRef && { subwayEntrsanceRef: osmNode.subwayEntranceRef })\n }\n }\n\n static parseWayProperties(osmWay: OsmWay): EdgeProperties {\n return {\n ...(osmWay.name && { name: osmWay.name }),\n ...(osmWay.id && { externalId: osmWay.id }),\n ...(osmWay.isOneway && { isOneway: osmWay.isOneway }),\n ...(osmWay.areStairs && { areStairs: osmWay.areStairs }),\n ...(osmWay.isElevator && { isElevator: osmWay.isElevator }),\n ...(osmWay.areEscalators && { areEscalators: osmWay.areEscalators }),\n ...(osmWay.isMovingWalkway && { isMovingWalkway: osmWay.isMovingWalkway }),\n ...(osmWay.needTicket && { needTicket: osmWay.needTicket }),\n ...(osmWay.incline && { incline: osmWay.incline })\n }\n }\n\n static createGraphFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = OsmGraphUtils.DEFAULT_WAY_SELECTOR,\n callbackVerticesMapping?: (mapping: [nodeId: number, vertex: Vertex][]) => void\n ) {\n\n const edges: Edge[] = [];\n const verticesMapping: [nodeId: number, vertex: Vertex][] = [];\n const elevatorVertices: [id: number, name: string | undefined, vertices: Vertex[]][] = [];\n\n // 1. Create a function to retrieve a vertex which has already been created and avoid duplicates\n const getOrCreateVertex = (osmNode: OsmNode, nodeLevel: Level_t) => {\n\n // Check if a vertex with same coordinates already exists\n let vertex: Vertex | null = verticesMapping\n .find(([nodeId, v]) => {\n if (nodeId !== osmNode.id) return false;\n if (Level.intersect(v.coords.level, nodeLevel)) return true;\n // Specific case of exits\n return v.coords.level === null || nodeLevel === null;\n })?.[1] || null;\n\n // If the vertex already exists, return it\n if (vertex) {\n // In the case where vertices are linked to edges with level change\n if (!Level.equals(vertex.coords.level, nodeLevel)) {\n vertex.coords.level = Level.intersection(vertex.coords.level, nodeLevel) || nodeLevel;\n }\n return vertex;\n }\n\n // If it does not exist, create it\n const newCoords = new Coordinates(osmNode.coords.lat, osmNode.coords.lng, null, nodeLevel)\n vertex = new Vertex(newCoords, this.parseNodeProperties(osmNode));\n\n verticesMapping.push([osmNode.id, vertex]);\n\n if (osmNode.isElevator) {\n let elevatorEntry = elevatorVertices.find(([id]) => osmNode.id === id);\n if (!elevatorEntry) {\n elevatorEntry = [osmNode.id, osmNode.name, []];\n elevatorVertices.push(elevatorEntry);\n }\n elevatorEntry[2].push(vertex);\n }\n\n return vertex;\n };\n\n // 2. Go through OSM ways to create edges and vertices\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n const edgeProperties = this.parseWayProperties(way);\n\n const processWayForLevel = (_level: Level_t) => {\n for (let i = 1; i < way.nodes.length; i++) {\n\n let firstVertex = getOrCreateVertex(way.nodes[i - 1], _level);\n let secondVertex = getOrCreateVertex(way.nodes[i], _level);\n\n if (way.isOnewayBackward) {\n const tmpVertex = secondVertex;\n secondVertex = firstVertex;\n firstVertex = tmpVertex;\n }\n\n const edge = new Edge(firstVertex, secondVertex, edgeProperties);\n edges.push(edge);\n }\n }\n\n processWayForLevel(way.level);\n if ('repeat_on' in way.tags) {\n way.tags.repeat_on.split(';').map(Level.fromString).forEach(processWayForLevel);\n }\n\n });\n\n // 3. Manage elevators without explicit navigation graph inside.\n // It creates a graph from entries to the center of the elevator shape.\n let fakeOsmNodeId = -1;\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n const entryVertices = way.nodes.map(node => verticesMapping.filter(([osmId]) => osmId === node.id).map(vm => vm[1])).flat();\n\n // Horrible method but works for macro-problems\n const elevatorCenter = way.nodes\n .reduce((acc, node) => [acc[0] + node.coords.lat, acc[1] + node.coords.lng], [0, 0])\n .map(val => val / way.nodes.length);\n const elevatorLevel = entryVertices.reduce((acc, v) => Level.union(acc, v.coords.level), null as Level_t);\n const elevatorCenterCoords = new Coordinates(elevatorCenter[0], elevatorCenter[1], null, elevatorLevel);\n\n const elevatorCenterFakeOsmNode = new OsmNode(fakeOsmNodeId--, elevatorCenterCoords, { highway: 'elevator' });\n\n entryVertices.forEach(entryVertex => {\n const vertexCenter = getOrCreateVertex(elevatorCenterFakeOsmNode, entryVertex.coords.level);\n edges.push(new Edge(vertexCenter, entryVertex, { externalId: way.id }));\n })\n });\n\n\n // 4. Link elevators vertices\n elevatorVertices.forEach(([id, name, verticesOfEachLevel]) => {\n const elevatorEdgeProps = { name, isElevator: true, externalId: id };\n // Link vertices of each level together\n for (let i = 0; i < verticesOfEachLevel.length; i++) {\n for (let j = i + 1; j < verticesOfEachLevel.length; j++) {\n edges.push(new Edge(verticesOfEachLevel[i], verticesOfEachLevel[j], elevatorEdgeProps));\n }\n }\n });\n\n callbackVerticesMapping?.(verticesMapping);\n\n return new Graph(verticesMapping.map(v => v[1]), edges);\n }\n\n}","import { RouterRequest } from '../model/RouterRequest.js';\nimport Itinerary from '../model/Itinerary.js';\n\nabstract class RemoteRouter {\n\n /**\n * Get the router name\n */\n abstract get rname(): string;\n\n abstract getItineraries(endpointUrl: string, routerRequest: RouterRequest): Promise<Itinerary[]>;\n\n}\n\nexport default RemoteRouter;\n","// https://developers.google.com/actions-center/reference/grpc-api/status_codes\nexport enum StatusCode {\n OK = 0,\n CANCELLED = 1,\n UNKNOWN = 2,\n INVALID_ARGUMENT = 3,\n NOT_FOUND = 5,\n UNIMPLEMENTED = 12,\n INTERNAL = 13,\n UNAVAILABLE = 14\n}","// Based on GRPC status code\n\nimport { StatusCode } from \"./StatusCode\";\nimport { TravelMode } from \"./model/TravelMode\";\n\n\nexport class RoutingError extends Error {\n\n public customMapName?: string | null;\n\n constructor(public code = StatusCode.UNKNOWN, message?: string) {\n super(message)\n }\n\n static notFound(details?: string) {\n return new RoutingError(StatusCode.NOT_FOUND, `Cannot found an itinerary. Details: ${details}`)\n }\n}\n\n\nexport class WemapMultiRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public mapName: string | null, message?: string) {\n super(code, message);\n this.mapName = mapName;\n }\n\n static notFound(mapName: string, details?: string) {\n return new WemapMultiRoutingError(StatusCode.NOT_FOUND, mapName, `Cannot found an itinerary in map ${mapName}. Details: ${details}`)\n }\n\n}\n\nexport class RemoteRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public routerName: string, message?: string) {\n super(code, message);\n this.routerName = routerName;\n }\n\n static notFound(routerName: string, details?: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Cannot found an itinerary with ${routerName}. Details: ${details}`)\n }\n\n static unreachableServer(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server ${routerName} is unreachable. URL: ${url}`)\n }\n\n static responseNotParsing(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server response ${routerName} cannot be parsed. URL: ${url}`)\n }\n\n static travelModeUnimplemented(routerName: string, travelMode: TravelMode) {\n return new RemoteRoutingError(StatusCode.UNIMPLEMENTED, routerName, `Travel mode \"${travelMode}\" is not implemented for ${routerName}`)\n }\n}","import { RoutingError } from \"../RoutingError\";\n\n/**\n * Create and return a date with a given timezone\n * timeZone - timezone name (e.g. 'Europe/Paris')\n */\nexport function dateWithTimeZone(\n year: number, month: number, day: number,\n hour: number, minute: number, second: number,\n timeZone = 'Europe/Paris'\n) {\n const date = new Date(Date.UTC(year, month, day, hour, minute, second));\n\n const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));\n const offset = utcDate.getTime() - tzDate.getTime();\n\n date.setTime(date.getTime() + offset);\n\n return date;\n}\n\nexport function isRoutingError(e: unknown): e is Error {\n return e instanceof RoutingError;\n}\n","import { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport { TransitMode, isTransitModePublicTransport } from '../../model/TransitMode.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype CitywayCoordinates = { Lat: number, Long: number };\ntype CitywayLeg = {\n TransportMode: string,\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Line: {\n Name: string,\n Number: string,\n Color: string,\n TextColor: string,\n },\n Destination: string,\n Distance: number,\n steps: {\n Step: {\n Geometry: string\n }[]\n },\n pathLinks: {\n PathLink: {\n Departure: {\n Site: {\n Name: string\n }\n },\n Distance: number,\n Geometry: string | 'Null'\n }[]\n }\n};\ntype CitywayJson = {\n StatusCode: number,\n Message: string,\n Data: {\n response: {\n trips: {\n Trip: {\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n sections: {\n Section: {\n Leg?: CitywayLeg,\n PTRide: CitywayLeg\n }[]\n }\n }[]\n }\n },\n PlanTripType?: string\n }[],\n};\n\n\n\nfunction jsonToCoordinates(json: CitywayCoordinates) {\n return new Coordinates(json.Lat, json.Long);\n}\n\nfunction jsonDateToTimestamp(jsonDate: string) {\n const [dateStr, timeStr] = jsonDate.split(' ');\n const [dayStr, monthStr, yearStr] = dateStr.split('/');\n const [hoursStr, minutesStr, secondsStr] = timeStr.split(':');\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr)\n ).getTime();\n}\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'Car');\ninputModeCorrespondance.set('WALK', 'Walk');\ninputModeCorrespondance.set('BIKE', 'Bike');\ninputModeCorrespondance.set('TRANSIT', 'PT');\n\n\n/**\n * List of all routing modes supported by the API\n */\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('WALK', 'WALK');\ntransitModeCorrespondance.set('BICYCLE', 'BIKE');\ntransitModeCorrespondance.set('TRAMWAY', 'TRAM');\ntransitModeCorrespondance.set('METRO', 'METRO');\ntransitModeCorrespondance.set('FUNICULAR', 'FUNICULAR');\ntransitModeCorrespondance.set('BUS', 'BUS');\ntransitModeCorrespondance.set('COACH', 'BUS');\ntransitModeCorrespondance.set('SCHOOL', 'BUS');\ntransitModeCorrespondance.set('BUS_PMR', 'BUS');\ntransitModeCorrespondance.set('MINIBUS', 'BUS');\ntransitModeCorrespondance.set('TROLLEY_BUS', 'BUS');\ntransitModeCorrespondance.set('TAXIBUS', 'BUS');\ntransitModeCorrespondance.set('SHUTTLE', 'BUS');\ntransitModeCorrespondance.set('TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('HST', 'TRAIN');\ntransitModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('AIR', 'AIRPLANE');\ntransitModeCorrespondance.set('FERRY', 'BOAT');\ntransitModeCorrespondance.set('TAXI', 'UNKNOWN');\ntransitModeCorrespondance.set('CAR_POOL', 'UNKNOWN');\ntransitModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');\ntransitModeCorrespondance.set('SCOOTER', 'MOTO');\n\n/**\n * List of all plan trip supported by the API\n * Routing mode UNKNOWN means that the itinerary will not be parsed by the router\n */\nconst planTripType = new Map();\nplanTripType.set(0, 'BUS');\nplanTripType.set(1, 'WALK');\nplanTripType.set(2, 'BIKE');\nplanTripType.set(3, 'CAR');\nplanTripType.set(4, 'UNKNOWN');\nplanTripType.set(5, 'UNKNOWN');\nplanTripType.set(6, 'UNKNOWN');\nplanTripType.set(7, 'UNKNOWN');\nplanTripType.set(8, 'UNKNOWN');\nplanTripType.set(9, 'UNKNOWN');\nplanTripType.set(10, 'UNKNOWN');\nplanTripType.set(11, 'UNKNOWN');\nplanTripType.set(12, 'UNKNOWN');\nplanTripType.set(13, 'UNKNOWN');\nplanTripType.set(14, 'UNKNOWN');\n\nfunction parseWKTGeometry(wktGeometry: string) {\n const tmpCoordsStr = wktGeometry.match(/LINESTRING ?\\((.*)\\)/i);\n const tmpCoordsPt = wktGeometry.match(/POINT ?\\((.*)\\)/i);\n\n if (tmpCoordsPt) {\n const [lng, lat] = tmpCoordsPt[1].split(' ');\n return [new Coordinates(Number(lat), Number(lng))];\n }\n\n return (tmpCoordsStr as RegExpMatchArray)[1].split(',').map(str => {\n const sp = str.trim().split(' ');\n return new Coordinates(Number(sp[1]), Number(sp[0]));\n });\n}\n\n/**\n * Singleton.\n */\nclass CitywayRemoteRouter extends RemoteRouter {\n\n get rname() { return 'cityway' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n\n const { origin, destination, travelMode, waypoints } = routerRequest;\n const citywayMode = inputModeCorrespondance.get(travelMode);\n if (!citywayMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `DepartureLatitude=${origin.latitude}&DepartureLongitude=${origin.longitude}`;\n const toPlace = `ArrivalLatitude=${destination.latitude}&ArrivalLongitude=${destination.longitude}`;\n const queryMode = `TripModes=${citywayMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n /**\n * Generate multi itineraries from Cityway JSON\n * @example https://preprod.api.lia2.cityway.fr/journeyplanner/api/opt/PlanTrips/json?DepartureLatitude=49.51509388236216&DepartureLongitude=0.09341749619366316&ArrivalLatitude=49.5067090188444&ArrivalLongitude=0.1694842115417831&DepartureType=COORDINATES&ArrivalType=COORDINATES\n */\n parseResponse(json: CitywayJson) {\n\n if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {\n throw RemoteRoutingError.notFound(this.rname, json.Message);\n }\n\n const itineraries = [];\n\n const allJsonTrips = json.Data.map(dataObj =>\n dataObj.response.trips.Trip.map(trip => ({\n ...trip,\n ...(dataObj.hasOwnProperty('PlanTripType') && { PlanTripType: dataObj.PlanTripType })\n }))\n ).flat();\n\n // eslint-disable-next-line no-labels\n itineraryLoop:\n for (const trip of allJsonTrips) {\n\n if (trip.hasOwnProperty('PlanTripType') && planTripType.get(trip.PlanTripType) === 'UNKNOWN') {\n continue;\n }\n\n const legs = []\n for (const jsonSection of trip.sections.Section) {\n\n const jsonLeg = jsonSection.Leg ? jsonSection.Leg : jsonSection.PTRide;\n\n const legMode = transitModeCorrespondance.get(jsonLeg.TransportMode)!;\n const legCoords: Coordinates[] = [];\n let legStart, legEnd;\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder();\n\n if (legMode === 'UNKNOWN') {\n // eslint-disable-next-line\n continue itineraryLoop;\n }\n\n if (legMode === 'WALK'\n || legMode === 'BIKE'\n || legMode === 'CAR') {\n\n legStart = {\n name: jsonLeg.Departure.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)\n };\n\n for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {\n let stepCoords;\n // jsonPathLink.Geometry is either a POINT or a LINESTRING\n // or it can also be 'Null' as string\n if (jsonPathLink.Geometry && jsonPathLink.Geometry !== 'Null') {\n stepCoords = parseWKTGeometry(jsonPathLink.Geometry);\n } else {\n stepCoords = [legStart.coords, legEnd.coords];\n }\n\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n\n stepsBuilder.addStepInfo({\n coords: stepCoords[0],\n distance: jsonPathLink.Distance,\n name: jsonPathLink.Departure.Site.Name\n });\n }\n\n // If it's last leg, create a last step because cityway doesn't use the end of itinerary as step\n if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {\n stepsBuilder.addStepInfo({\n coords: legCoords[legCoords.length - 1]\n });\n }\n\n } else if (isTransitModePublicTransport(legMode)) {\n\n legStart = {\n name: jsonLeg.Departure.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.StopPlace.Position)\n };\n\n let transportName = jsonLeg.Line.Number;\n if (legMode === 'TRAM' && transportName.toLowerCase().includes('tram')) {\n // In order to remove the \"TRAM \" prefix.\n transportName = transportName.substr(5);\n }\n\n transportInfo = {\n name: transportName,\n routeColor: jsonLeg.Line.Color,\n routeTextColor: jsonLeg.Line.TextColor,\n directionName: jsonLeg.Destination\n };\n\n for (const jsonStep of jsonLeg.steps.Step) {\n const stepCoords = parseWKTGeometry(jsonStep.Geometry);\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.Line.Name,\n distance: jsonLeg.Distance,\n });\n } else {\n Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);\n continue;\n }\n\n stepsBuilder.setStart(legStart.coords);\n stepsBuilder.setEnd(legEnd.coords);\n stepsBuilder.setPathCoords(legCoords);\n\n const leg = new Leg({\n transitMode: legMode,\n duration: this.parseDuration(jsonLeg.Duration),\n startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),\n endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),\n coords: legCoords,\n start: legStart,\n end: legEnd,\n transportInfo,\n steps: stepsBuilder.build()\n });\n\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: this.parseDuration(trip.Duration),\n startTime: jsonDateToTimestamp(trip.Departure.Time),\n origin: jsonToCoordinates(trip.Departure.Site.Position),\n endTime: jsonDateToTimestamp(trip.Arrival.Time),\n destination: jsonToCoordinates(trip.Arrival.Site.Position),\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n\n\n /**\n * @param {string} iso8601Duration\n * @see https://stackoverflow.com/a/29153059/2239938\n */\n parseDuration(iso8601Duration: string) {\n const iso8601DurationRegex = /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\n const matches = iso8601Duration.match(iso8601DurationRegex)!;\n\n // const sign = typeof matches[1] === 'undefined' ? '+' : '-',\n const years = typeof matches[2] === 'undefined' ? 0 : Number(matches[2]);\n const months = typeof matches[3] === 'undefined' ? 0 : Number(matches[3]);\n const weeks = typeof matches[4] === 'undefined' ? 0 : Number(matches[4]);\n const days = typeof matches[5] === 'undefined' ? 0 : Number(matches[5]);\n const hours = typeof matches[6] === 'undefined' ? 0 : Number(matches[6]);\n const minutes = typeof matches[7] === 'undefined' ? 0 : Number(matches[7]);\n const seconds = typeof matches[8] === 'undefined' ? 0 : Number(matches[8]);\n\n return seconds\n + minutes * 60\n + hours * 3600\n + days * 86400\n + weeks * (86400 * 7)\n + months * (86400 * 30)\n + years * (86400 * 365.25);\n }\n}\n\nexport default new CitywayRemoteRouter();","import { Coordinates, Level } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg from '../../model/Leg.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype DBJson = {\n segments: {\n fromLevel: number,\n toLevel: number,\n polyline: {\n lat: number,\n lon: number\n }[]\n }[]\n};\n\n/**\n * Singleton.\n */\nclass DeutscheBahnRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'deutsche-bahn' as const; }\n\n /**\n * @override\n */\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n let url = endpointUrl + '/route/v1/walking/';\n const waypoints = [routerRequest.origin, ...routerRequest.waypoints || [], routerRequest.destination];\n\n url += waypoints.map(waypoint => {\n if (waypoint.level !== null) {\n const altitude = Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;\n return waypoint.longitude + ',' + waypoint.latitude + ',' + altitude;\n }\n return waypoint.longitude + ',' + waypoint.latitude;\n }).join(';');\n\n url += '?geometries=geojson&overview=full&steps=true';\n\n return url;\n }\n\n parseResponse(json: DBJson, origin: Coordinates, destination: Coordinates) {\n\n if (!json.segments) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const legs = json.segments.map(segment => {\n const level = Level.union(segment.fromLevel, segment.toLevel);\n const coords = segment.polyline.map(({ lon, lat }) =>\n new Coordinates(lat, lon, null, level)\n );\n return new Leg({\n transitMode: 'WALK',\n coords,\n start: { coords: coords[0] },\n end: { coords: coords[coords.length - 1] },\n })\n });\n\n return [new Itinerary({ origin, destination, legs })];\n }\n}\n\nexport default new DeutscheBahnRemoteRouter();\n","/* eslint-disable max-statements */\nimport { Coordinates, Utils as GeoUtils } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type MinStepInfo } from '../../model/Step.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype IdfmCoordinates = { lat: number, lon: number };\ntype IdfmSection = {\n type: 'waiting' | 'transfer' | string,\n mode: string,\n departure_date_time: string,\n arrival_date_time: string,\n duration: number,\n geojson: {\n coordinates: [number, number][],\n properties: { length: number }[]\n },\n path: {\n name: string,\n length: number\n }[],\n display_informations: {\n code: string,\n color: string,\n text_color: string,\n direction: string,\n physical_mode: string\n },\n from: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n },\n to: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n }\n}\ntype IdfmJson = {\n journeys: {\n duration: number,\n departure_date_time: string,\n arrival_date_time: string,\n sections: IdfmSection[]\n }[],\n context: {\n timezone: string\n };\n error: {\n message?: string;\n }\n};\n\ntype IdfmIntermediateStep = {\n name: string,\n distance: number\n};\n\n/**\n * List of all modes supported by the API\n * http://doc.navitia.io/#physical-mode\n */\n\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('Air', 'AIRPLANE');\ntransitModeCorrespondance.set('Boat', 'BOAT');\ntransitModeCorrespondance.set('Bus', 'BUS');\ntransitModeCorrespondance.set('BusRapidTransit', 'BUS');\ntransitModeCorrespondance.set('Coach', 'BUS');\ntransitModeCorrespondance.set('Ferry', 'FERRY');\ntransitModeCorrespondance.set('Funicular', 'FUNICULAR');\ntransitModeCorrespondance.set('LocalTrain', 'TRAIN');\ntransitModeCorrespondance.set('LongDistanceTrain', 'TRAIN');\ntransitModeCorrespondance.set('Metro', 'METRO');\ntransitModeCorrespondance.set('Métro', 'METRO');\ntransitModeCorrespondance.set('RailShuttle', 'TRAIN');\ntransitModeCorrespondance.set('RapidTransit', 'BUS');\ntransitModeCorrespondance.set('Shuttle', 'BUS');\ntransitModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');\ntransitModeCorrespondance.set('Taxi', 'TAXI');\ntransitModeCorrespondance.set('Train', 'TRAIN');\ntransitModeCorrespondance.set('RER', 'TRAIN');\ntransitModeCorrespondance.set('Tramway', 'TRAM');\ntransitModeCorrespondance.set('walking', 'WALK');\ntransitModeCorrespondance.set('bike', 'BIKE');\n\n/**\n * List of transports modes\n */\nconst TRANSPORT_IDS = [\n 'physical_mode:Air',\n 'physical_mode:Boat',\n 'physical_mode:Bus',\n 'physical_mode:BusRapidTransit',\n 'physical_mode:Coach',\n 'physical_mode:Ferry',\n 'physical_mode:Funicular',\n 'physical_mode:LocalTrain',\n 'physical_mode:LongDistanceTrain',\n 'physical_mode:Metro',\n 'physical_mode:RailShuttle',\n 'physical_mode:RapidTransit',\n 'physical_mode:Shuttle',\n 'physical_mode:SuspendedCableCar',\n 'physical_mode:Taxi',\n 'physical_mode:Train',\n 'physical_mode:Tramway'\n];\n\nconst apiKey = 'qWHj6ax6DMttG8DX6tH9CQARaiTgQ1Di';\n\n\nfunction jsonToCoordinates(json: IdfmCoordinates) {\n return new Coordinates(Number(json.lat), Number(json.lon));\n}\n\nfunction last<T>(array: T[]) {\n return array[array.length - 1];\n}\n\n/**\n * stringDate (e.g. 20211117T104516)\n */\nfunction dateStringToTimestamp(stringDate: string, timeZone: string) {\n const yearStr = stringDate.substr(0, 4);\n const monthStr = stringDate.substr(4, 2);\n const dayStr = stringDate.substr(6, 2);\n const hoursStr = stringDate.substr(9, 2);\n const minutesStr = stringDate.substr(11, 2);\n const secondsStr = stringDate.substr(13, 2);\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr),\n timeZone\n ).getTime();\n}\n\n\n/**\n * Singleton.\n */\nclass IdfmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'idfm' as const; }\n\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url, {\n method: 'GET',\n headers: { apiKey }\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n\n const jsonResponse: IdfmJson = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n // When IDFM failed to calculate an itinerary (ie. start or end\n // point is far from network), it respond a 404 with an error message\n // or a 200 with an error message\n if (jsonResponse && jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error.message);\n }\n\n const itineraries = this.parseResponse(jsonResponse);\n\n const sameModeFound = itineraries.some((itinerary) => itinerary.transitMode === routerRequest.travelMode);\n\n if (!sameModeFound) {\n throw RemoteRoutingError.notFound(\n this.rname,\n 'Selected mode of transport was not found for this itinerary.'\n )\n }\n\n return itineraries;\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const url = new URL(endpointUrl);\n\n const coreParams = new URLSearchParams();\n coreParams.set('from', `${origin.longitude};${origin.latitude}`);\n coreParams.set('to', `${destination.longitude};${destination.latitude}`);\n\n if (routerRequest.itineraryModifiers?.avoidStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (travelMode) {\n case 'WALK':\n queryParams = this.getWalkingQuery();\n break;\n case 'BIKE':\n queryParams = this.getBikeQuery();\n break;\n case 'CAR':\n queryParams = this.getCarQuery();\n break;\n default:\n break;\n }\n\n [coreParams, queryParams].map(params => {\n for (const pair of params.entries()) {\n url.searchParams.append(pair[0], pair[1]);\n }\n });\n\n return url.toString();\n }\n\n getCarQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('first_section_mode[]', 'car');\n urlSearchParams.append('last_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'car');\n\n return urlSearchParams;\n }\n\n getWalkingQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'walking');\n\n return urlSearchParams;\n }\n\n getBikeQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'bike');\n urlSearchParams.append('last_section_mode[]', 'bike');\n\n return urlSearchParams;\n }\n\n\n getSectionCoords(section: IdfmSection) {\n const from = section.from.stop_point ? jsonToCoordinates(section.from.stop_point.coord) : jsonToCoordinates(section.from.address.coord);\n const to = section.to.stop_point ? jsonToCoordinates(section.to.stop_point.coord) : jsonToCoordinates(section.to.address.coord);\n\n return {\n from,\n to\n };\n }\n\n /**\n * Since the IDFM API does not provide coords for each step, we need to compute them\n * We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step\n * @param {Leg} leg\n */\n findStepsCoord(legCoords: Coordinates[], steps: IdfmIntermediateStep[]) {\n const coords = legCoords;\n\n const duplicatedCoords = [...coords];\n let previousStep = steps[0];\n let accumulatedIndex = 0;\n const outputSteps = [];\n\n for (const [idx, step] of steps.entries()) {\n let newCoords: Coordinates;\n\n let _idCoordsInLeg;\n\n if (idx === 0) {\n _idCoordsInLeg = 0;\n newCoords = coords[0];\n } else if (idx === steps.length - 1) {\n _idCoordsInLeg = coords.length - 1;\n newCoords = last(coords);\n } else if (duplicatedCoords.length === 1) {\n accumulatedIndex++;\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = duplicatedCoords[0];\n\n coords[_idCoordsInLeg] = newCoords;\n } else {\n const result = GeoUtils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);\n accumulatedIndex += result.length - 1;\n\n duplicatedCoords.splice(0, result.length - 1);\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = last(result);\n\n coords[_idCoordsInLeg] = newCoords;\n }\n\n outputSteps.push({\n ...step,\n coords: newCoords\n });\n\n previousStep = step;\n }\n\n return outputSteps;\n }\n\n parseResponse(json: IdfmJson) {\n\n if (!json || !json.journeys) {\n throw RemoteRoutingError.notFound(this.rname, json.error?.message);\n }\n\n const itineraries = [];\n\n const timeZone = json.context.timezone;\n\n for (const jsonItinerary of json.journeys) {\n\n const legs = [];\n\n for (const jsonSection of jsonItinerary.sections) {\n\n if (jsonSection.type === 'waiting' || jsonSection.type === 'transfer') {\n continue;\n }\n\n const { from: startSection, to: endSection } = this.getSectionCoords(jsonSection);\n\n // A section can have multiple same coordinates, we need to remove them\n let existingCoords: string[] = [];\n const legCoords = jsonSection.geojson.coordinates.reduce((acc, [lon, lat]) => {\n if (!existingCoords.includes(`${lon}-${lat}`)) {\n existingCoords = existingCoords.concat(`${lon}-${lat}`);\n acc.push(new Coordinates(lat, lon));\n }\n return acc;\n }, [] as Coordinates[]);\n\n const stepsBuilder = new StepsBuilder().setStart(startSection).setEnd(endSection).setPathCoords(legCoords);\n let transportInfo: TransportInfo | undefined;\n let transitMode = transitModeCorrespondance.get(jsonSection.mode) as TransitMode;\n\n if (jsonSection.path) {\n const idfmIntermediateSteps = [];\n for (const jsonPathLink of jsonSection.path) {\n idfmIntermediateSteps.push({\n name: jsonPathLink.name,\n distance: jsonPathLink.length,\n });\n }\n stepsBuilder.setStepsInfo(this.findStepsCoord(legCoords, idfmIntermediateSteps));\n }\n\n if (jsonSection.type === 'public_transport') {\n transportInfo = {\n name: jsonSection.display_informations.code,\n routeColor: jsonSection.display_informations.color,\n routeTextColor: jsonSection.display_informations.text_color,\n directionName: jsonSection.display_informations.direction\n };\n\n transitMode = transitModeCorrespondance.get(jsonSection.display_informations.physical_mode) as TransitMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n stepsBuilder.setStepsInfo([legStep]);\n }\n\n const leg = new Leg({\n transitMode,\n duration: jsonSection.duration,\n startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),\n start: {\n name: jsonSection.from.name,\n coords: startSection\n },\n end: {\n name: jsonSection.to.name,\n coords: endSection\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\n });\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: dateStringToTimestamp(jsonItinerary.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonItinerary.arrival_date_time, timeZone),\n origin: this.getSectionCoords(jsonItinerary.sections[0]).from,\n destination: this.getSectionCoords(last(jsonItinerary.sections)).to,\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new IdfmRemoteRouter();","/* eslint-disable max-statements */\n\nimport { Coordinates, Level } from '@wemap/geo';\nimport { rad2deg, positiveMod } from '@wemap/maths';\nimport { LineString, Position } from 'geojson';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype OsrmCoordinates = Position;\ntype OsrmModifier = 'sharp right' | 'sharp left' | 'slight right'\n | 'slight left' | 'right' | 'left' | 'u turn' | 'straight';\ntype OsrmManeuverType = 'depart' | 'turn' | 'arrive';\ntype OsrmStep = {\n geometry: LineString,\n distance: number,\n duration: number,\n name?: string,\n maneuver: {\n bearing_before: number,\n bearing_after: number,\n location: OsrmCoordinates,\n modifier: OsrmModifier,\n type: OsrmManeuverType\n }\n};\ntype OsrmJson = {\n code?: string,\n message?: string,\n routes?: {\n geometry: LineString,\n legs: {\n distance: number,\n duration: number,\n steps: OsrmStep[]\n }[],\n distance: number,\n duration: number,\n weight_name: string,\n weight: number\n }[],\n waypoints?: []\n};\n\ntype OsrmMode = 'driving' | 'walking' | 'bike' | 'pmr' | 'bike-safest' | 'bike-fastest';\n\nconst outputModeCorrespondance = new Map<TravelMode, TransitMode>();\noutputModeCorrespondance.set('CAR', 'CAR');\noutputModeCorrespondance.set('WALK', 'WALK');\noutputModeCorrespondance.set('BIKE', 'BIKE');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n get rname() { return 'osrm' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination, routerRequest.travelMode);\n }\n\n /**\n * @throws {TravelModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination } = routerRequest;\n\n const osrmMode = this.inputModeCorrespondance(routerRequest);\n const waypoints = [origin, ...routerRequest.waypoints || [], destination];\n\n let url = endpointUrl + '/route/v1/' + osrmMode + '/';\n url += waypoints.map(waypoint => [waypoint.longitude + ',' + waypoint.latitude]).join(';');\n url += '?geometries=geojson&overview=full&steps=true';\n routerRequest.provideItineraryAlternatives && (url += '&alternatives=true')\n return url;\n }\n\n inputModeCorrespondance = (routerRequest: RouterRequest): OsrmMode => {\n const { travelMode, travelModePreference: preference } = routerRequest;\n if (travelMode === 'WALK' && routerRequest.itineraryModifiers?.avoidStairs) return 'pmr';\n if (travelMode === 'WALK') return 'walking';\n if (travelMode === 'BIKE') {\n if (preference === 'FASTEST') return 'bike-fastest';\n if (preference === 'SAFEST') return 'bike-safest';\n if (preference === 'TOURISM') return 'bike-safest';\n return 'bike-safest';\n }\n if (travelMode === 'CAR') return 'driving';\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n coordinatesToJson({ lat, lng, level }: Coordinates): OsrmCoordinates {\n if (level === null) {\n return [lng, lat];\n }\n if (Level.isRange(level)) {\n return [lng, lat, level[0]];\n }\n return [lng, lat, level];\n }\n\n /**\n * @param {object} json\n * @returns {Coordinates}\n */\n jsonToCoordinates(json: OsrmCoordinates): Coordinates {\n const coords = new Coordinates(json[1], json[0]);\n if (json.length > 2) {\n coords.level = json[2] as number;\n }\n return coords;\n }\n\n getModifierFromAngle(_angle: number): OsrmModifier {\n\n const angle = positiveMod(rad2deg(_angle), 360);\n\n if (angle > 0 && angle < 60) {\n return 'sharp right';\n }\n if (angle >= 60 && angle < 140) {\n return 'right';\n }\n if (angle >= 140 && angle < 160) {\n return 'slight right';\n }\n if (angle >= 160 && angle <= 200) {\n return 'straight';\n }\n if (angle > 200 && angle <= 220) {\n return 'slight left';\n }\n if (angle > 220 && angle <= 300) {\n return 'left';\n }\n if (angle > 300 && angle < 360) {\n return 'sharp left';\n }\n return 'u turn';\n }\n\n noRouteFoundJson(message: object) {\n return {\n 'code': 'NoRoute',\n message\n };\n }\n\n /**\n * @deprecated\n */\n itineraryToOsrmJson(itinerary: Itinerary): OsrmJson {\n\n const lastLegId = itinerary.legs.length - 1;\n const itinerarySteps = itinerary.steps;\n\n const jsonLegs = itinerary.legs.map(({ distance, duration, coords }, idLeg) => {\n\n // Filter steps which are in leg\n const legSteps = itinerarySteps.filter(step =>\n coords.find(_coords => _coords.equals(step.coords))\n );\n\n const lastStepId = legSteps.length - 1;\n\n return {\n distance,\n duration: duration || 0,\n steps: legSteps.map((step, idStep, arr) => {\n\n let type: OsrmManeuverType = idStep === 0 && idLeg === 0 ? 'depart' : 'turn';\n type = idStep === lastStepId && idLeg === lastLegId ? 'arrive' : type;\n\n const stepCoordsIdx = coords.findIndex(p => p.equals(step.coords));\n const nextStepCoordsIdx = idStep === lastStepId\n ? stepCoordsIdx\n : coords.findIndex(p => p.equals(arr[idStep + 1].coords));\n\n const osrmStep: OsrmStep = {\n geometry: {\n type: 'LineString',\n coordinates: coords.slice(stepCoordsIdx, nextStepCoordsIdx + 1).map(this.coordinatesToJson)\n },\n distance: step.distance,\n duration: step.duration || 0,\n ...(step.name && { name: step.name }),\n maneuver: {\n bearing_before: rad2deg(step.previousBearing),\n bearing_after: rad2deg(step.nextBearing),\n location: this.coordinatesToJson(step.coords),\n modifier: this.getModifierFromAngle(step.angle),\n type\n },\n };\n return osrmStep;\n })\n };\n });\n\n return {\n 'code': 'Ok',\n 'routes': [\n {\n 'geometry': {\n 'type': 'LineString',\n 'coordinates': itinerary.coords.map(this.coordinatesToJson)\n },\n 'legs': jsonLegs,\n 'distance': itinerary.distance,\n 'duration': itinerary.duration,\n 'weight_name': 'routability',\n 'weight': 0\n }\n ],\n 'waypoints': []\n };\n }\n\n parseResponse(json: OsrmJson, origin: Coordinates, destination: Coordinates, travelMode: TravelMode) {\n\n const transitMode = outputModeCorrespondance.get(travelMode)!;\n\n const { routes: jsonRoutes } = json;\n if (!jsonRoutes) {\n throw RemoteRoutingError.notFound(this.rname, json.message);\n }\n\n return jsonRoutes.map(jsonItinerary => {\n\n const legs = jsonItinerary.legs.map((jsonLeg) => {\n const legCoords = jsonLeg.steps\n .map(step => step.geometry.coordinates.map(this.jsonToCoordinates))\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n\n const startCoords = legCoords[0];\n const endCoords = legCoords[legCoords.length - 1];\n\n const stepsBuilder = new StepsBuilder().setPathCoords(legCoords).setStart(startCoords).setEnd(endCoords);\n jsonLeg.steps?.forEach(({ maneuver, name, distance, duration }) => {\n\n const stepCoords = this.jsonToCoordinates(maneuver.location);\n\n // Sometimes, OSRM step does not have the same coordinates than a point in legCoords.\n // ex: first step of https://routing-orsm.getwemap.com/route/v1/walking/2.33222164147,48.87084765712;2.3320734,48.8730212?geometries=geojson&overview=full&steps=true\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(stepCoords));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('Osrm Parser: Cannot find step coords in leg coordinates');\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name,\n distance,\n duration\n });\n })\n\n return new Leg({\n transitMode,\n duration: jsonLeg.duration,\n coords: legCoords,\n start: {\n coords: startCoords\n },\n end: {\n coords: endCoords\n },\n steps: stepsBuilder.build()\n });\n });\n\n return new Itinerary({\n duration: jsonItinerary.duration,\n origin,\n destination,\n legs\n });\n });\n }\n}\n\nexport default new OsrmRemoteRouter();","import Polyline from '@mapbox/polyline';\n\nimport { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { type TransportInfo } from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype OtpCoordinates = { lat: number, lon: number };\ntype FromTo = OtpCoordinates & { name: string };\ntype FromToPT = FromTo & { stopId: string, stopCode: string };\n\ntype CommonLeg = {\n startTime: number,\n endTime: number,\n legGeometry: {\n points: string,\n length: number\n },\n duration: number,\n};\n\ntype LegWalk = CommonLeg & {\n mode: 'WALK',\n from: FromTo,\n to: FromTo,\n steps: (OtpCoordinates & {\n distance: number,\n streetName: string\n })[]\n}\n\ntype LegPT = CommonLeg & {\n mode: 'BUS' | 'TRAM',\n from: FromToPT,\n to: FromToPT,\n intermediateStops: FromToPT,\n routeShortName: 'string',\n routeColor?: 'string',\n routeTextColor?: 'string',\n headsign: 'string'\n}\n\ntype OtpJson = {\n plan: {\n from: FromTo,\n to: FromTo,\n itineraries: {\n duration: number,\n startTime: number,\n endTime: number,\n walkDistance: number,\n legs: (LegWalk | LegPT)[]\n }[]\n }\n}\n\nfunction isLegPT(leg: LegPT | LegWalk): leg is LegPT {\n return leg.mode === 'BUS' || leg.mode === 'TRAM';\n}\n\nfunction jsonToCoordinates(json: OtpCoordinates) {\n return new Coordinates(json.lat, json.lon);\n}\n\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'CAR');\ninputModeCorrespondance.set('WALK', 'WALK');\ninputModeCorrespondance.set('BIKE', 'BICYCLE');\ninputModeCorrespondance.set('TRANSIT', 'WALK,TRANSIT');\n\n/**\n * Singleton.\n */\nclass OtpRemoteRouter extends RemoteRouter {\n\n get rname() { return 'otp' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n const otpMode = inputModeCorrespondance.get(travelMode);\n if (!otpMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `fromPlace=${origin.latitude},${origin.longitude}`;\n const toPlace = `toPlace=${destination.latitude},${destination.longitude}`;\n const queryMode = `mode=${otpMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n\n /**\n * Generate multi itineraries from OTP JSON\n */\n parseResponse(json: OtpJson) {\n\n const { plan: jsonPlan } = json;\n if (!jsonPlan) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const itineraries = [];\n\n const itinerariesOrigin = jsonToCoordinates(jsonPlan.from);\n const itinerariesDestination = jsonToCoordinates(jsonPlan.to);\n\n for (const jsonItinerary of jsonPlan.itineraries) {\n\n const legs: Leg[] = [];\n\n for (const jsonLeg of jsonItinerary.legs) {\n\n const startCoordinates = jsonToCoordinates(jsonLeg.from);\n const endCoordinates = jsonToCoordinates(jsonLeg.to);\n\n const legCoords = Polyline.decode(jsonLeg.legGeometry.points)\n .map(([lat, lon]) => new Coordinates(lat, lon));\n\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder().setStart(startCoordinates).setEnd(endCoordinates).setPathCoords(legCoords);\n\n if (isLegPT(jsonLeg)) {\n\n transportInfo = {\n name: jsonLeg.routeShortName,\n routeColor: jsonLeg.routeColor,\n routeTextColor: jsonLeg.routeTextColor,\n directionName: jsonLeg.headsign\n };\n\n stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.headsign\n });\n\n } else {\n\n jsonLeg.steps.forEach(jsonStep => {\n // OTP step does not have the same coordinates than a point in legCoords.\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(jsonToCoordinates(jsonStep)));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('OTP Parser: Cannot find closest step');\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name: jsonStep.streetName\n });\n })\n }\n\n\n const leg = new Leg({\n transitMode: jsonLeg.mode,\n duration: jsonLeg.duration,\n startTime: jsonLeg.startTime,\n endTime: jsonLeg.endTime,\n start: {\n name: jsonLeg.from.name,\n coords: jsonToCoordinates(jsonLeg.from)\n },\n end: {\n name: jsonLeg.to.name,\n coords: jsonToCoordinates(jsonLeg.to)\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\n });\n\n legs.push(leg);\n\n }\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: jsonItinerary.startTime,\n endTime: jsonItinerary.endTime,\n origin: itinerariesOrigin,\n destination: itinerariesDestination,\n legs\n });\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new OtpRemoteRouter();\n","import { Coordinates } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\n\ntype WemapRouterRequest = Omit<RouterRequest, 'origin' | 'destination' | 'waypoints'> & {\n mapId?: number,\n origin: Coordinates | number | string\n destination: Coordinates | number | string\n waypoints?: (Coordinates | number | string)[]\n}\n\n/**\n * Singleton.\n */\nclass WemapMultiRemoteRouter extends RemoteRouter {\n\n get rname() { return 'wemap-multi' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: WemapRouterRequest) {\n const { origin, destination, waypoints } = routerRequest;\n const payload = {\n ...routerRequest,\n origin: origin instanceof Coordinates ? origin.toJson() : origin,\n destination: destination instanceof Coordinates ? destination.toJson() : destination,\n ...(waypoints && {waypoints: waypoints.map(w => w instanceof Coordinates ? w.toJson() : w)})\n };\n\n const res = await (fetch(endpointUrl, {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, endpointUrl);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, endpointUrl);\n });\n\n if (jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error)\n }\n\n return (jsonResponse.itineraries || []).map(Itinerary.fromJson) as Itinerary[];\n }\n\n}\n\nexport default new WemapMultiRemoteRouter();\n","import RemoteRouter from './RemoteRouter.js';\nimport CitywayRemoteRouter from './cityway/CitywayRemoteRouter.js';\nimport DeutscheBahnRemoteRouter from './deutsche-bahn/DeutscheBahnRemoteRouter.js';\nimport IdfmRemoteRouter from './idfm/IdfmRemoteRouter.js';\nimport OsrmRemoteRouter from './osrm/OsrmRemoteRouter.js';\nimport OtpRemoteRouter from './otp/OtpRemoteRouter.js';\nimport WemapMultiRemoteRouter from './wemap-multi/WemapMultiRemoteRouter.js';\nimport { RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../RoutingError.js';\n\nconst remoteRouters = [\n CitywayRemoteRouter,\n DeutscheBahnRemoteRouter,\n IdfmRemoteRouter,\n OsrmRemoteRouter,\n OtpRemoteRouter,\n WemapMultiRemoteRouter\n] as const;\n\nexport type RemoteRouterName = typeof remoteRouters[number]['rname'];\n\nexport type RoutingFallbackStrategy = { name: RemoteRouterName, endpointUrl: string }[];\n\n/**\n * Singleton\n */\nclass RemoteRouterManager {\n\n getRouterByName(name: RemoteRouterName): RemoteRouter {\n return remoteRouters.find(remoteRouter => remoteRouter.rname === name) as RemoteRouter;\n }\n\n async getItineraries(name: RemoteRouterName, endpointUrl: string, routerRequest: RouterRequest) {\n const router = this.getRouterByName(name);\n if (!router) {\n throw RemoteRoutingError.notFound(name, `Unknown \"${name}\" remote router`);\n }\n return router.getItineraries(endpointUrl, routerRequest);\n }\n\n async getItinerariesWithFallback(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy) {\n let itineraries;\n for (const { name, endpointUrl } of fallbackStrategy) {\n itineraries = await this.getItineraries(name, endpointUrl, routerRequest);\n if (itineraries.length) {\n return itineraries;\n }\n }\n\n const routersNames = fallbackStrategy.map(({ name }) => name).join(',');\n throw RemoteRoutingError.notFound(routersNames, `Could not find an itinerary with any of following servers: ${routersNames}`)\n }\n}\n\nexport default new RemoteRouterManager();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\n\nimport CustomGraphMap from './CustomGraphMap.js';\nimport RemoteRouterManager, { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';\nimport Itinerary from '../model/Itinerary.js';\nimport WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport GraphRouterOptionsBuilder from '../graph/GraphRouterOptionsBuilder.js';\nimport { type RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError, WemapMultiRoutingError } from '../RoutingError.js';\n\n\nclass WemapMultiRouter {\n\n maps: CustomGraphMap[] = [];\n\n get rname() {\n return 'wemap-multi';\n }\n\n addIOMap(customGraphMap: CustomGraphMap) {\n this.maps.push(customGraphMap);\n }\n\n removeIOMap(customGraphMap: CustomGraphMap) {\n this.maps = this.maps.filter(map => map !== customGraphMap);\n }\n\n removeAllMaps() {\n this.maps = [];\n }\n\n getMapByName(mapId: string) {\n return this.maps.find(map => map.name === mapId);\n }\n\n async getItineraries(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy = [], targetMaps = this.maps): Promise<Itinerary[]> {\n\n const { origin, destination } = routerRequest;\n\n /*\n * Here, we try to get the shortest path using io maps networks and a remote router server.\n */\n\n /**\n * ----- 1 -----\n * Parse function params\n * -------------\n */\n\n // Avoid cycles on remoteRouters\n fallbackStrategy = fallbackStrategy.filter(({ name }) => name !== WemapMultiRemoteRouter.rname) || [];\n\n /*\n * ----- 2 -----\n * Retrieve the IO maps to consider for this itinerary\n * -------------\n *\n * By default, all maps in this.maps are considered\n * If options.targetMaps is defined, only use this subset\n */\n // const ioMapsToTest = this.getIoMapsFromOptions(options);\n // TODO: map it with Wemap backend\n const ioMapsToTest = targetMaps;\n\n /*\n * If there is no local map to test, use remote router directly.\n * This should happen:\n * 1 - this.maps is empty\n * 2 - options.targetMaps is defined but empty\n * 3 - intersection of this.maps and options.targetMaps is empty\n */\n if (!ioMapsToTest.length) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n\n /**\n * ----- 3 -----\n * Run the IO Maps - Remote Routers logic\n * -------------\n *\n * For this purpose we have to consider 5 use cases\n *\n */\n\n let ioMapRoute: GraphRoute | null;\n let ioMapItinerary: Itinerary;\n\n // Find the first map where the \"origin\" is inside.\n const mapWithOrigin = ioMapsToTest.find(map => map.isPointInside(origin));\n\n\n // Create GraphRouterOptions from request\n const routerOptions = GraphRouterOptionsBuilder.fromJson(routerRequest.itineraryModifiers || {});\n\n /*\n * Case 1\n *\n * If \"origin\" and \"destination\" are in the same map, use the local router.\n */\n if (mapWithOrigin && mapWithOrigin.isPointInside(destination)) {\n\n ioMapRoute = mapWithOrigin.getRouteInsideMap(origin, destination, routerOptions);\n if (!ioMapRoute) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\")\n }\n\n return [Itinerary.fromGraphRoute(ioMapRoute)];\n }\n\n // Find the first map where the \"destination\" is inside.\n // Note: At this step, mapWithDestination is necessarily different from mapWithOrigin\n const mapWithDestination = ioMapsToTest.find(map => map.isPointInside(destination));\n\n\n let remoteRouterItineraries: Itinerary[];\n\n /*\n * Case 2\n *\n * If no io map have been found for \"origin\" and \"destination\", therefore use remote router.\n */\n if (!mapWithOrigin && !mapWithDestination) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n /**\n * Case 3\n *\n * If a map has been found for the \"origin\" but not for the \"destination\", so:\n * - A first itinerary (firstRoute) is calculated from \"origin\" to an \"entrypoint\"\n * of the IO map network using the wemap router.\n * - A second itinerary (secondRoute) is calculated from an \"entrypoint\" to the\n * \"destination\" using remote routers.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (mapWithOrigin && !mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `A map including the \"origin\" but the \"destination\" has been \n found (${mapWithOrigin.name}), however, no \"entrypoints\" have been found to go out`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" '\n + `to \"entrypoints\" using wemap router on local map \"${mapWithOrigin.name}\" and `\n + 'an itinerary from \"entrypoints\" to \"destination\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}), but failed. `\n + `Details: ${details}.`;\n\n ioMapRoute = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute.end,\n destination,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the the IO map itinerary with the remote router response (for each itinerary)\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)\n );\n }\n\n /*\n * Case 4\n *\n * If a map has been found for the \"destination\" but not for the \"origin\", so:\n * - A first itinerary (remoteRouterResponse) is calculated from \"origin\" to an \"entrypoint\"\n * of the IO map network using remote routers.\n * - A second itinerary (ioMapItinerary) is calculated from an \"entrypoint\" to the\n * \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (!mapWithOrigin && mapWithDestination) {\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `A map including the \"destination\" but the \"origin\" has been \n found (${mapWithDestination.name}), however, no \"entrypoints\" have been found to go in`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints\" '\n + `using remote routers (${fallbackStrategy.map(r => r.name).join(', ')}) and an `\n + 'itinerary from \"entrypoints\" to \"destination\" using wemap router on local map '\n + `\"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`\n\n /*\n * ioMapItinerary is computed before the remoteRouterResponse because it is less expensive to\n * calculate all the routes to entrypoints using local router than all the routes with the\n * remote router.\n */\n ioMapRoute = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin,\n destination: ioMapRoute.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the remote router response (for each itinerary) with the IO map itinerary\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)\n );\n }\n\n /**\n * Case 5\n *\n * If maps have been found for the \"origin\" and the \"destination\" but they are different, so:\n * - A first itinerary (ioMapItinerary1) is calculated from \"origin\" to an \"entrypoint\" of\n * the mapWithOrigin using the wemap router.\n * - A second itinerary (remoteRouterResponse) is calculated from an \"entrypoint\" of the\n * mapWithOrigin to an \"entrypoint\" of the destinationWithMap using remote routers.\n * - A third itinerary (ioMapItinerary2) is calculated from an \"entrypoint\" of the mapWithDestination\n * to the \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the three itineraries.\n */\n if (mapWithOrigin && mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go out of the origin map`\n );\n }\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go in the second map`\n );\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints1\" '\n + `using wemap router on local map \"${mapWithOrigin.name}\", an itinerary from `\n + '\"entrypoints1\" to \"entrypoints2\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}) and an itinerary from \"entrypoints2\" `\n + `to \"destination\" using wemap router on local map \"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`;\n\n\n const ioMapRoute1 = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute1) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const ioMapRoute2 = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute2) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute1.end,\n destination: ioMapRoute2.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n\n // Concat the IO map itinerary 2 with the remote router response (for each itinerary)\n // and the IO map itinerary 2\n return remoteRouterItineraries.map(remoteRouterItinerary =>\n Itinerary.fromItineraries(\n Itinerary.fromGraphRoute(ioMapRoute1),\n remoteRouterItinerary,\n Itinerary.fromGraphRoute(ioMapRoute2)\n )\n );\n\n }\n\n throw new Error('Should never happen');\n }\n\n}\n\nexport default WemapMultiRouter;\n","import pointInPolygon from '@turf/boolean-point-in-polygon';\nimport convexHullFn from '@turf/convex';\nimport { Position, MultiPolygon } from '@turf/helpers';\n\nimport { Coordinates, Level } from '@wemap/geo';\nimport { OsmNode, OsmParser } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRouter from '../graph/GraphRouter.js';\nimport { GraphRouterOptions } from '../graph/GraphRouterOptions.js';\nimport Vertex from '../graph/Vertex.js';\nimport OsmGraphUtils from '../wemap-osm/OsmGraphUtils.js';\n\n\nexport type ParsingErrors = {\n couldNotParseFile: boolean,\n routingIoNotFound: OsmNode[],\n routingBoundsNotFound: boolean\n}\n\nexport default class CustomGraphMap {\n\n name: string | null;\n graph: Graph;\n router: GraphRouter;\n bounds: MultiPolygon;\n entryPoints: Vertex[];\n\n constructor(\n graph: Graph,\n entryPoints: Vertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new GraphRouter(graph);\n\n // Entry points\n entryPoints.forEach(entryPoint => {\n if (!graph.vertices.includes(entryPoint)) {\n throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in graph \"${name}\"`);\n }\n });\n this.entryPoints = entryPoints;\n\n // Bounds\n if (bounds) {\n this.bounds = bounds;\n } else {\n const polygon = [graph.vertices.map(vertex => [vertex.coords.lng, vertex.coords.lat] as Position)];\n const convexHull = convexHullFn({ type: 'polygon', coordinates: polygon });\n if (!convexHull) {\n throw new Error(`Cannot calculate convexHull of graph \"${name}\"`);\n }\n this.bounds = {\n type: 'MultiPolygon',\n coordinates: [convexHull.geometry.coordinates]\n };\n }\n }\n\n static fromOsmXml(\n osmXmlString: string,\n name: string | null = null,\n callbackErrors?: (errors: ParsingErrors) => void\n ) {\n const errors: ParsingErrors = {\n couldNotParseFile: false,\n routingIoNotFound: [],\n routingBoundsNotFound: false\n };\n\n let osmModel;\n try {\n osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n } catch (e) {\n errors.couldNotParseFile = true;\n callbackErrors?.(errors);\n return;\n }\n let verticesMapping: [nodeId: number, vertex: Vertex][] = []\n const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel, OsmGraphUtils.DEFAULT_WAY_SELECTOR, vm => (verticesMapping = vm));\n\n const entryPointsOsmNodes = osmModel.nodes.filter(node => node.tags['wemap:routing-io']);\n const entryPointsToCheck = entryPointsOsmNodes.map(node => {\n const vertex = verticesMapping.find(v => v[0] === node.id)?.[1]\n if (!vertex) { errors.routingIoNotFound.push(node); }\n return vertex || null;\n });\n const entryPoints = entryPointsToCheck.filter(it => it !== null) as Vertex[];\n entryPoints.forEach(v => graph.exitVertices.add(v));\n\n const bounds: MultiPolygon = {\n type: 'MultiPolygon',\n coordinates: []\n };\n osmModel.ways\n .filter(({ tags }) => tags['wemap:routing-bounds'])\n .forEach(way => {\n bounds.coordinates.push([way.nodes.reduce((acc, node) => {\n acc.push([node.coords.lng, node.coords.lat]);\n return acc;\n }, [] as Position[])\n ]);\n });\n osmModel.relations\n .filter(rel => rel.tags['wemap:routing-bounds'] && rel.isMultipolygon())\n .forEach(rel => {\n const polygon = rel.getGeoJsonPolygon();\n polygon && bounds.coordinates.push(polygon.coordinates);\n });\n\n if (!bounds.coordinates.length) {\n errors.routingBoundsNotFound = true;\n }\n callbackErrors?.(errors);\n return new CustomGraphMap(graph, entryPoints, bounds, name);\n }\n\n isPointInside(coordinates: Coordinates) {\n return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);\n }\n\n /**\n * Get the list of entry points sorted by the lowest distance between:\n * start -> entry point -> end\n * (as the crow flies)\n *\n */\n getOrderedEntryPointsSortedByDistance(start: Coordinates, end: Coordinates) {\n const entryPointsCopy = [...this.entryPoints];\n const levelDiffFactor = 50; // in meters\n return entryPointsCopy.sort((ep1, ep2) => {\n\n const distance2D = Number(ep1.coords.distanceTo(start)) + ep1.coords.distanceTo(end)\n - (ep2.coords.distanceTo(start) + ep2.coords.distanceTo(end))\n\n const levelDiffEp1Start = Math.abs(Level.diff(start.level, ep1.coords.level) || 0);\n const levelDiffEp1End = Math.abs(Level.diff(end.level, ep1.coords.level) || 0);\n const levelDiffEp2Start = Math.abs(Level.diff(start.level, ep2.coords.level) || 0);\n const levelDiffEp2End = Math.abs(Level.diff(end.level, ep2.coords.level) || 0);\n const levelDiff = levelDiffEp1Start + levelDiffEp1End - (levelDiffEp2Start + levelDiffEp2End);\n\n return distance2D + levelDiff * levelDiffFactor;\n });\n }\n\n /**\n * Get the best itinerary from any entry point to an end coordinates.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the first entry point to the end coordinates.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.\n *\n * /!\\ start is only used to sort the entry points (step 1).\n *\n */\n getBestRouteFromEntryPointsToDestination(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(entryPoint.coords, end, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n\n /**\n * Get the best itinerary from start coordinates to any entry point.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the start coordinates to the first entry point.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.\n *\n * /!\\ end is only used to sort the entry points (step 1).\n *\n */\n getBestRouteFromOriginToEntryPoints(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(start, entryPoint.coords, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n getRouteInsideMap(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.calculateShortestPath(start, end, options).route();\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getShortestTrip(waypoints, options);\n }\n\n getRoutesMultipleDestinationsInsideMap(start: Coordinates, ends: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path for all the input destinations\n return this.router.calculateShortestPathToMultipleDestinations(start, ends, options);\n }\n\n}\n","\nimport { OsmNode } from '@wemap/osm';\n\nimport CustomGraphMap, { type ParsingErrors } from './CustomGraphMap.js';\nimport Vertex from '../graph/Vertex.js';\n\nexport type Report = {\n customGraphMap?: CustomGraphMap,\n errors: Error[],\n}\n\nexport type Error = CouldNotParseFileError\n | MultipleGraphComponentsError\n | RoutingBoundsNotFoundError\n | RoutingIoNotOnGraphError;\n\nexport type CouldNotParseFileError = {\n type: 'could-not-parse-file'\n}\n\nexport type MultipleGraphComponentsError = {\n type: 'multiple-graph-components',\n data: Vertex[][]\n}\n\nexport type RoutingBoundsNotFoundError = {\n type: 'routing-bounds-not-found'\n}\n\nexport type RoutingIoNotOnGraphError = {\n type: 'routing-io-not-on-graph',\n data: OsmNode[]\n}\n\nexport default class CustomGraphMapTester {\n\n static createReport(osmXmlString: string): Report {\n\n let customGraphMapErrors: ParsingErrors | undefined;\n const customGraphMap = CustomGraphMap.fromOsmXml(osmXmlString, null, e => (customGraphMapErrors = e));\n const errors: Error[] = [];\n\n if (customGraphMapErrors?.couldNotParseFile || !customGraphMap) {\n errors.push({\n type: 'could-not-parse-file'\n });\n return { errors };\n }\n\n const components = customGraphMap.router.calculateComponents();\n if (components.length > 1) {\n errors.push({\n type: 'multiple-graph-components',\n data: components\n });\n }\n if (customGraphMapErrors?.routingBoundsNotFound) {\n errors.push({\n type: 'routing-bounds-not-found'\n });\n }\n if (customGraphMapErrors?.routingIoNotFound?.length) {\n errors.push({\n type: 'routing-io-not-on-graph',\n data: customGraphMapErrors.routingIoNotFound\n });\n }\n\n return { customGraphMap, errors };\n }\n\n static reportToJson(report: Report) {\n return {\n graph: report.customGraphMap?.graph?.toCompressedJson(),\n errors: report.errors.map(error => {\n if (error.type === 'multiple-graph-components') {\n return { type: error.type, data: error.data.map(c => c.map(v => v.id)) };\n }\n if (error.type === 'routing-io-not-on-graph') {\n return { type: error.type, data: error.data.map(v => v.id) };\n }\n return { type: error.type };\n })\n }\n }\n\n}\n\n","import { Coordinates } from '@wemap/geo';\n\nimport Itinerary from './model/Itinerary.js';\nimport Leg from './model/Leg.js';\nimport { Step } from './model/Step.js';\nimport Graph from './graph/Graph.js';\nimport GraphProjection from './graph/GraphProjection.js';\nimport Vertex from './graph/Vertex.js';\nimport Edge from './graph/Edge.js';\n\nexport type ItineraryInfo<U extends Coordinates = Coordinates> = {\n nextStep: Step | null;\n previousStep: Step | null;\n projection: GraphProjection<U>;\n leg: Leg;\n traveledDistance: number;\n remainingDistance: number;\n traveledPercentage: number;\n remainingPercentage: number;\n};\n\nclass ItineraryInfoManager {\n\n _itinerary: Itinerary | null = null;\n _graph: Graph | null = null;\n\n _steps: Step[] = [];\n _coordsNextStep: (Step | null)[] = [];\n _coordsPreviousStep: (Step | null)[] = [];\n _coordsDistanceTraveled: number[] = [];\n _coordsLeg: Leg[] = [];\n\n constructor(itinerary: Itinerary | null = null) {\n this.itinerary = itinerary;\n }\n\n get itinerary() {\n return this._itinerary;\n }\n\n set itinerary(itinerary) {\n\n if (itinerary === null) {\n this._itinerary = null;\n return;\n }\n\n this._itinerary = itinerary;\n this._steps = itinerary.steps;\n this._graph = itinerary.toGraph();\n\n this._coordsNextStep = new Array(itinerary.coords.length);\n this._coordsPreviousStep = new Array(itinerary.coords.length);\n this._coordsDistanceTraveled = new Array(itinerary.coords.length);\n this._coordsLeg = new Array(itinerary.coords.length);\n\n let stepId = 0;\n let previousStep: Step | null = null;\n let nextStep: Step | null = this._steps[0];\n let distanceTraveled = 0;\n\n itinerary.coords.forEach((coords, idx, arr) => {\n if (idx !== 0) {\n distanceTraveled += arr[idx - 1].distanceTo(coords);\n }\n\n this._coordsNextStep[idx] = nextStep;\n this._coordsPreviousStep[idx] = previousStep;\n this._coordsDistanceTraveled[idx] = distanceTraveled;\n this._coordsLeg[idx] = itinerary.legs.find(leg => leg.coords.includes(coords)) as Leg;\n\n if (stepId < this._steps.length && this._steps[stepId].coords.equals(coords)) {\n previousStep = this._steps[stepId];\n nextStep = stepId === this._steps.length - 1 ? null : this._steps[stepId + 1];\n stepId++;\n }\n });\n }\n\n getInfo<U extends Coordinates = Coordinates>(position: U) {\n\n if (!this._itinerary || !this._graph) {\n return null;\n }\n\n const projection = this._graph.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof Vertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as Vertex).coords === coords\n );\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Node)');\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx];\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx],\n previousStep: this._coordsPreviousStep[idx],\n projection: projection,\n leg: this._coordsLeg[idx],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n } else if (projection.nearestElement instanceof Edge) {\n\n let firstNode = projection.nearestElement.vertex1.coords;\n let idx = this._itinerary.coords.findIndex(coords => firstNode === coords);\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Edge)');\n }\n\n // graphEdge is not necessarly ordered. We have to look for the first point\n if (idx === this._itinerary.coords.length - 1\n || this._itinerary.coords[idx + 1] !== projection.nearestElement.vertex2.coords\n ) {\n firstNode = projection.nearestElement.vertex2.coords;\n idx--;\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx]\n + projection.coords.distanceTo(firstNode);\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx + 1],\n previousStep: this._coordsPreviousStep[idx + 1],\n projection: projection,\n leg: this._coordsLeg[idx + 1],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n }\n\n return itineraryInfo;\n }\n\n}\n\nexport default ItineraryInfoManager;\n","import { Coordinates } from '@wemap/geo';\nimport { diffAngle, rad2deg, roundFactor } from '@wemap/maths';\nimport ItineraryInfoManager from '../src/ItineraryInfoManager.js';\nimport { Step } from '../src/model/Step.js';\n\nexport default class InstructionManager {\n\n static useProposals = false;\n\n static getTurnInfoFromAngle(_angle: number) {\n\n let direction, directionExtra;\n\n const directionAngle = rad2deg(diffAngle(_angle, Math.PI));\n const directionAngleAbs = Math.abs(directionAngle);\n if (directionAngleAbs <= 20) {\n direction = 'straight';\n } else {\n direction = directionAngle > 0 ? 'left' : 'right';\n if (directionAngleAbs < 55) {\n directionExtra = 'slight';\n } else if (directionAngleAbs > 120) {\n directionExtra = 'sharp';\n }\n }\n\n return { direction, directionExtra };\n }\n\n static getInfoFromStep(step: Step) {\n\n let type, direction, directionExtra, levelChange;\n\n if (step.levelChange) {\n type = 'level-change';\n levelChange = step.levelChange;\n } else {\n type = 'turn';\n const turnInfo = InstructionManager.getTurnInfoFromAngle(step.angle);\n direction = turnInfo.direction;\n directionExtra = turnInfo.directionExtra;\n }\n\n return {\n type,\n direction,\n directionExtra,\n levelChange,\n name: step.name,\n indoor: step.coords.level !== null\n };\n }\n\n // eslint-disable-next-line max-statements, complexity\n static getInstructionFromStep(step: Step) {\n\n const { direction, directionExtra } = InstructionManager.getTurnInfoFromAngle(step.angle);\n const isTurn = direction !== 'straight';\n\n if (step.lastStep) {\n if (isTurn && direction === 'left') {\n return 'Your destination is on your left';\n } else if (isTurn && direction === 'right') {\n return 'Your destination is on your right';\n }\n }\n\n let suffix = '';\n if (step.extras?.isGate) {\n suffix = ` on gate ${step.name}`;\n } else if (step.name) {\n suffix = ` on ${step.name}`;\n }\n\n if (step.levelChange) {\n if (step.levelChange.direction === 'up') {\n if (step.levelChange.type === 'stairs') {\n return 'Go up the stairs';\n }\n if (step.levelChange.type === 'escalator') {\n return 'Go up the escalator';\n }\n if (step.levelChange.type === 'elevator') {\n return 'Go up the elevator';\n }\n if (step.levelChange.type === 'moving walkway') {\n return 'Go up the moving walkway';\n }\n return 'Go up' + suffix;\n }\n if (step.levelChange.direction === 'down') {\n if (step.levelChange.type === 'stairs') {\n return 'Go down the stairs';\n }\n if (step.levelChange.type === 'escalator') {\n return 'Go down the escalator';\n }\n if (step.levelChange.type === 'elevator') {\n return 'Go down the elevator';\n }\n if (step.levelChange.type === 'moving walkway') {\n return 'Go down the moving walkway';\n }\n return 'Go down' + suffix;\n }\n if (step.extras?.subwayEntrance) {\n return `Take exit ${step.extras.subwayEntranceRef}`;\n }\n }\n\n if (isTurn) {\n if (direction === 'left') {\n if (directionExtra === 'slight') {\n return 'Turn slightly left' + suffix;\n }\n return 'Turn left' + suffix;\n }\n if (direction === 'right') {\n if (directionExtra === 'slight') {\n return 'Turn slightly right' + suffix;\n }\n return 'Turn right' + suffix;\n }\n }\n\n return 'Continue straight';\n }\n\n\n\n static getInstructionFromPosition(itineraryInfoManager: ItineraryInfoManager, position: Coordinates) {\n const itineraryInfo = itineraryInfoManager.getInfo(position);\n if (!itineraryInfo) {\n return null;\n }\n\n // If distance between itinerary and position is too far,\n // something went wrong. (mapmatching.maxDistance)\n if (this.useProposals && itineraryInfo.projection.distanceFromNearestElement > 15) {\n return 'It seems that we are a little bit lost, please start again the localization process';\n }\n\n const { nextStep } = itineraryInfo;\n if (!nextStep) {\n return 'You are arrived';\n }\n\n const distNextStep = position.distanceTo(nextStep.coords);\n const distRounded = roundFactor(distNextStep, 5);\n\n if (this.useProposals && distNextStep > 10) {\n return `Continue straight for ${distRounded}m`;\n }\n\n\n let instruction = InstructionManager.getInstructionFromStep(nextStep);\n\n const stepWithImportantInfo = itineraryInfoManager._steps.find(step => step.levelChange\n && step.number > nextStep.number\n && step.coords.distanceTo(nextStep.coords) < 10\n ) || null;\n\n if (stepWithImportantInfo && stepWithImportantInfo.levelChange) {\n const nextBearing = nextStep.coords.bearingTo(stepWithImportantInfo.coords);\n const { direction } = InstructionManager.getTurnInfoFromAngle(nextBearing - nextStep.previousBearing);\n instruction = direction === 'straight' ? 'Continue straight' : `Turn ${direction}`;\n const { direction: levelDirection, type: levelType } = stepWithImportantInfo.levelChange;\n instruction += ` and take the ${levelType} going ${levelDirection}`;\n }\n\n if (distNextStep >= 5) {\n instruction += ` in ${distRounded}m`;\n }\n\n return instruction;\n }\n\n}\n"],"names":["Level","Coordinates","BoundingBox","UserPosition","diffAngleLines","GeoConstants","deg2rad","diffAngle","GeoUtils","window","undefined","regexes","ua","module","exports","this","__defProp","__defNormalProp","__publicField","last","OsmNode","StatusCode","jsonToCoordinates","inputModeCorrespondance","transitModeCorrespondance","positiveMod","rad2deg","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","RemoteRouterManager","OsmParser","roundFactor"],"mappings":"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","x_google_ignoreList":[12]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/model/RouterRequest.ts","../src/graph/Edge.ts","../src/graph/GraphProjection.ts","../src/graph/Vertex.ts","../src/graph/Graph.ts","../src/Utils.ts","../src/model/TransitMode.ts","../src/model/Step.ts","../src/graph/GraphRoute.ts","../src/model/StepsBuilder.ts","../src/model/Leg.ts","../src/model/Itinerary.ts","../../../node_modules/ua-parser-js/src/ua-parser.js","../../utils/dist/index.mjs","../src/graph/GraphRouterOptionsBuilder.ts","../src/graph/GraphRouterEngine.ts","../src/graph/GraphRouter.ts","../src/graph/NoRouteFoundError.ts","../src/wemap-osm/OsmGraphUtils.ts","../src/remote/RemoteRouter.ts","../src/StatusCode.ts","../src/RoutingError.ts","../src/remote/RemoteRouterUtils.ts","../src/remote/cityway/CitywayRemoteRouter.ts","../src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.ts","../src/remote/idfm/IdfmRemoteRouter.ts","../src/remote/osrm/OsrmRemoteRouter.ts","../src/remote/otp/OtpRemoteRouter.ts","../src/remote/wemap-multi/WemapMultiRemoteRouter.ts","../src/remote/RemoteRouterManager.ts","../src/wemap-multi/WemapMultiRouter.ts","../src/wemap-multi/CustomGraphMap.ts","../src/wemap-multi/CustomGraphMapTester.ts","../src/ItineraryInfoManager.ts","../helpers/InstructionManager.ts"],"sourcesContent":["import { Coordinates } from \"@wemap/geo\"\n\nimport { TravelMode, TravelModePreference } from \"./TravelMode\"\n\nexport type RouterRequest = {\n origin: Coordinates,\n destination: Coordinates,\n travelMode: TravelMode,\n travelModePreference?: TravelModePreference,\n provideItineraryAlternatives?: boolean,\n waypoints?: Coordinates[],\n optimizeWaypoints?: boolean,\n itineraryModifiers?: {\n avoidStairs?: boolean,\n avoidEscalators?: boolean,\n avoidElevator?: boolean,\n avoidMovingWalkway?: boolean,\n avoidTicketRestrictedAreas?: boolean\n }\n output?: {\n distanceAndDurationOnly?: boolean\n }\n}\n\nexport function routerRequestToJson(routerRequest: RouterRequest) {\n const { origin, destination, waypoints, ...rest } = routerRequest;\n return {\n origin: origin.toJson(),\n destination: destination.toJson(),\n ...(waypoints && { waypoints: waypoints.map(w => w.toJson()) }),\n ...rest\n }\n}","import { Level, type Level_t } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nexport type EdgeProperties = {\n \n name?: string;\n externalId?: string | number;\n\n isOneway?: boolean;\n areStairs?: boolean;\n isElevator?: boolean;\n areEscalators?: boolean;\n isMovingWalkway?: boolean;\n needTicket?: boolean;\n incline?: 'up' | 'down';\n}\n\n/**\n * An Edge is a segment composed of two Vertex\n * An edge is mostly issued from an OsmWay, but this is not always the case.\n * For example, edges created by mapmatching.\n */\nexport default class Edge {\n\n static currentUniqueId = 0;\n public readonly id = Edge.currentUniqueId++;\n\n public readonly level: Level_t;\n\n /** Edge bearing from vertex1 to vertex2 */\n public readonly bearing: number;\n public readonly length: number;\n\n constructor(\n public vertex1: Vertex,\n public vertex2: Vertex,\n public properties: EdgeProperties = {}\n ) {\n this.level = Level.union(vertex1.coords.level, vertex2.coords.level)\n this.length = this.vertex1.distanceTo(this.vertex2);\n this.bearing = this.vertex1.bearingTo(this.vertex2);\n }\n\n static getEdgeByVertices(\n edges: Edge[],\n vertex1: Vertex,\n vertex2: Vertex\n ) {\n return edges.find(edge => vertex1 === edge.vertex1 && vertex2 === edge.vertex2\n || vertex2 === edge.vertex1 && vertex1 === edge.vertex2\n );\n }\n\n reverseProperties() {\n const { properties } = this;\n if (properties.incline) {\n properties.incline = properties.incline === 'up' ? 'down' : 'up';\n }\n if (properties.isOneway) {\n properties.isOneway = false;\n }\n }\n}\n","import { Coordinates, UserPosition } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\n\nclass GraphProjection<U extends Coordinates | UserPosition = Coordinates> {\n constructor(\n public readonly origin: U,\n public readonly distanceFromNearestElement: number,\n public readonly coords: U,\n public readonly nearestElement: Vertex | Edge\n ) { }\n}\n\nexport default GraphProjection;\n","import { Coordinates } from '@wemap/geo';\n\nimport { GraphVertexJson } from '../types.js';\n\nexport type VertexProperties = {\n\n name?: string;\n externalId?: string | number;\n\n isGate?: boolean;\n isSubwayEntrance?: boolean;\n subwayEntranceRef?: string;\n}\n\nexport default class Vertex {\n\n public id = -1;\n\n constructor(public coords: Coordinates, public properties: VertexProperties = {}) { }\n\n distanceTo(other: Vertex) {\n return this.coords.distanceTo(other.coords);\n }\n\n bearingTo(other: Vertex) {\n return this.coords.bearingTo(other.coords);\n }\n\n toJson(): GraphVertexJson {\n return {\n id: this.id,\n coords: this.coords.toCompressedJson(),\n ...(Object.keys(this.properties).length > 0 && { properties: this.properties })\n }\n }\n\n static fromJson(json: GraphVertexJson) {\n const v = new Vertex(\n Coordinates.fromCompressedJson(json.coords),\n json.properties\n );\n v.id = json.id;\n return v;\n }\n}\n","import { diffAngleLines } from '@wemap/maths';\nimport { BoundingBox, Coordinates, Level, UserPosition, Level_t, Constants as GeoConstants } from '@wemap/geo';\n\nimport Edge from './Edge.js';\nimport GraphProjection from './GraphProjection.js';\nimport Vertex from './Vertex.js';\nimport { type CompressedGeoGraphJson, type GeoGraphJson } from '../types.js';\nimport { type GraphProjectionOptions } from './GraphProjectionOptions.js';\n\n\nclass Graph {\n\n /**\n * exitVertices are vertices that have at least one indoor edge and one outdoor edge\n * They are stored because the Level model cannot handle an indoor and outdoor state like [null, 1] or [null, [1,2]]\n * This vertices are used to cover the projection case:\n * - if projection origin is null, an exit vertex can be used\n * - if projection origin is not null, the intersection level with an exit vertex can be used\n */\n public readonly exitVertices: Set<Vertex>;\n\n constructor(public readonly vertices: Vertex[], public readonly edges: Edge[]) {\n const nullVertices = edges.filter(e => e.level === null).map(e => [e.vertex1, e.vertex2]).flat();\n const levelVertices = edges.filter(e => e.level !== null).map(e => [e.vertex1, e.vertex2]).flat();\n this.exitVertices = new Set(nullVertices.filter(v1 => levelVertices.includes(v1)));\n }\n\n getEdgeByVertices(vertex1: Vertex, vertex2: Vertex) {\n return Edge.getEdgeByVertices(this.edges, vertex1, vertex2);\n }\n\n getVertexByCoords(coords: Coordinates) {\n return Graph.getVertexByCoords(this.vertices, coords);\n }\n\n static getVertexByCoords(vertices: Vertex[], coords: Coordinates) {\n return vertices.find(vertex => vertex.coords.equals(coords));\n }\n\n getVertexByName(name: string) {\n return this.vertices.find(vertex => vertex.properties.name === name);\n }\n\n getEdgeByName(name: string) {\n return this.edges.find(edge => edge.properties.name === name);\n }\n\n getBoundingBox(extendedMeasure?: number) {\n if (!this.vertices.length) {\n return null;\n }\n const boundingBox = BoundingBox.fromCoordinates(this.vertices.map(vertex => vertex.coords)) as BoundingBox;\n if (extendedMeasure) {\n boundingBox.extendsWithMeasure(extendedMeasure);\n }\n return boundingBox;\n }\n\n getProjection<U extends (Coordinates | UserPosition)>(\n origin: U,\n options: GraphProjectionOptions = {}\n ): GraphProjection<U> | null {\n\n const useMaxDistance = 'maxDistance' in options;\n const maxDistance = options.maxDistance!\n\n const useMaxBearingAngle = 'maxBearingAngle' in options;\n if (useMaxBearingAngle && (!(origin instanceof UserPosition) || origin.bearing === null)) return null;\n const maxBearingAngle = options.maxBearingAngle!;\n\n const useAcceptEdgeFn = 'acceptEdgeFn' in options;\n\n const useMultiLevelSegments = !('useMultiLevelSegments' in options) || options.useMultiLevelSegments;\n\n let bestProjection: GraphProjection | null = null;\n\n this.edges.forEach(edge => {\n\n if (useAcceptEdgeFn && !options.acceptEdgeFn!(edge)) return;\n if (!useMultiLevelSegments && Level.isRange(edge.level)) return;\n if (!Level.intersect(edge.level, origin.level)) return;\n\n if (useMaxBearingAngle) {\n // Do not try to project if angle is greater than the threshold\n if (diffAngleLines(edge.bearing, (origin as UserPosition).bearing!) > maxBearingAngle) return;\n }\n\n const segmentProjection = origin.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);\n if (!segmentProjection) return;\n const distanceToSegment = segmentProjection.distanceTo(origin);\n\n if (useMaxDistance && distanceToSegment > maxDistance) return;\n\n if (distanceToSegment < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToSegment, segmentProjection, edge);\n }\n });\n\n // if mapmatching bearing is enabled do not use vertices matching\n if (useMaxBearingAngle) {\n return bestProjection;\n }\n\n this.vertices.forEach(vertex => {\n let vertexCoords = vertex.coords;\n\n // Specific case of io nodes that have a non-null level but can be matched to a null origin level\n if (this.exitVertices.has(vertex) && origin.level === null) {\n vertexCoords = vertex.coords.clone();\n vertexCoords.level = null;\n }\n\n if (!useMultiLevelSegments && Level.isRange(vertexCoords.level)) return;\n if (!Level.intersect(vertexCoords.level, origin.level)) return;\n\n const distanceToVertex = vertexCoords.distanceTo(origin);\n\n // If distance below epsilon consider it as best projection\n if (distanceToVertex < GeoConstants.EPS_MM) {\n bestProjection = new GraphProjection(origin, 0, vertexCoords, vertex);\n return;\n }\n\n if (useMaxDistance && distanceToVertex > maxDistance) return;\n\n if (distanceToVertex < (bestProjection?.distanceFromNearestElement ?? Number.MAX_VALUE)) {\n bestProjection = new GraphProjection(origin, distanceToVertex, vertexCoords, vertex);\n }\n });\n\n return bestProjection;\n }\n\n\n toJson(): GeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.toJson()),\n edges: this.edges.map(edge => ({\n id: edge.id,\n vertex1Idx: this.vertices.indexOf(edge.vertex1),\n vertex2Idx: this.vertices.indexOf(edge.vertex2),\n ...(Object.keys(edge.properties).length > 0 && { properties: edge.properties })\n }))\n };\n }\n\n static fromJson(json: GeoGraphJson) {\n\n const vertices = json.vertices.map(vertex => Vertex.fromJson(vertex));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge.vertex1Idx],\n vertices[jsonEdge.vertex2Idx],\n jsonEdge.properties\n ));\n\n return new Graph(vertices, edges);\n }\n\n /** @deprecated */\n toCompressedJson(): CompressedGeoGraphJson {\n return {\n vertices: this.vertices.map(vertex => vertex.coords.toCompressedJson()),\n verticesIds: this.vertices.map(vertex => vertex.id),\n edges: this.edges.map(edge => {\n const vertex1Idx = this.vertices.indexOf(edge.vertex1);\n const vertex2Idx = this.vertices.indexOf(edge.vertex2);\n const edgeExtras = edge.properties;\n if (Object.keys(edgeExtras).length > 0) {\n return [vertex1Idx, vertex2Idx, edgeExtras];\n }\n return [vertex1Idx, vertex2Idx];\n })\n };\n }\n\n /** @deprecated */\n static fromCompressedJson(json: CompressedGeoGraphJson) {\n const vertices = json.vertices.map(vertex => new Vertex(Coordinates.fromCompressedJson(vertex)));\n const edges = json.edges.map(jsonEdge => new Edge(\n vertices[jsonEdge[0]],\n vertices[jsonEdge[1]],\n jsonEdge.length > 2 ? jsonEdge[2] : {}\n ));\n\n return new Graph(vertices, edges);\n }\n\n\n static fromCoordinatesSegments(segments: Coordinates[][]) {\n\n const vertices: Vertex[] = [];\n const edges: Edge[] = [];\n\n const getOrCreateVertex = (coords: Coordinates) => {\n const vertex = vertices.find(otherVertex => otherVertex.coords.equals(coords));\n if (vertex) {\n return vertex;\n }\n const newVertex = new Vertex(coords);\n vertices.push(newVertex);\n return newVertex;\n };\n\n for (const segment of segments) {\n\n let previousVertex = null;\n for (const coords of segment) {\n const currentVertex = getOrCreateVertex(coords);\n\n if (previousVertex) {\n edges.push(new Edge(currentVertex, previousVertex));\n }\n\n previousVertex = currentVertex;\n }\n }\n\n return new Graph(vertices, edges);\n }\n\n /**\n * Create edges From MultiLevel Itinerary for a given level\n * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)\n */\n getEdgesAtLevel(targetLevel: Level_t, useMultiLevelEdges = true) {\n return this.edges.filter(\n ({ level }) => useMultiLevelEdges\n ? Level.intersect(targetLevel, level)\n : Level.contains(targetLevel, level)\n );\n }\n\n\n toDetailedString() {\n let output\n = '--- Network ---\\n'\n + `Vertices: ${this.vertices.length}\\n`\n + `Edges: ${this.edges.length}\\n`\n + '---\\n'\n + 'Vertices\\n';\n this.vertices.forEach(vertex => {\n output += vertex.id;\n const vertexProps = vertex.properties;\n if (Object.keys(vertexProps).length !== 0) { output += ` ${vertexProps}` }\n });\n output += '---\\n'\n + 'Edges\\n';\n this.edges.forEach(edge => {\n output += `${edge.id} - [v1: ${edge.vertex1.id}, v2: ${edge.vertex2.id}]`;\n const edgeProps = edge.properties;\n if (Object.keys(edgeProps).length !== 0) { output += ` ${edgeProps}` }\n });\n output += '---';\n return output;\n }\n}\n\nexport default Graph;\n","/**\n * Get route duration\n * @param {Number} speed in km/h\n * @returns {Number} duration in seconds\n */\nexport function getDurationFromLength(length: number, speed = 5) {\n return length / (speed * 1000 / 3600);\n}\n","export type TransitMode = 'AIRPLANE' | 'BOAT' | 'BIKE' | 'BUS' | 'CAR' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'MOTO' | 'TRAIN' | 'TAXI' |\n 'TRAM' | 'WALK' | 'MULTI' | 'UNKNOWN';\n\nexport type PublicTransport = 'AIRPLANE' | 'BOAT' | 'BUS' |\n 'FERRY' | 'FUNICULAR' | 'METRO' | 'TRAIN' | 'TRAM';\n\nexport function isTransitModePublicTransport(routingMode: TransitMode): routingMode is PublicTransport {\n return [\n 'AIRPLANE', 'BOAT', 'BUS', 'FERRY',\n 'FUNICULAR', 'METRO', 'TRAIN', 'TRAM'\n ].includes(routingMode);\n}\n","import { Coordinates, CoordinatesCompressedJson } from '@wemap/geo';\n\nimport { LevelChange } from './LevelChange.js';\nimport { StepExtra } from './StepExtra.js';\n\nexport type Step = {\n\n firstStep: boolean;\n lastStep: boolean;\n number: number;\n\n angle: number;\n previousBearing: number;\n nextBearing: number;\n distance: number;\n duration: number;\n\n readonly coords: Coordinates;\n readonly name: string | null;\n readonly levelChange: LevelChange | null;\n readonly extras: StepExtra | null;\n}\n\nexport type StepJson = {\n firstStep?: boolean,\n lastStep?: boolean\n number: number,\n coords: CoordinatesCompressedJson,\n name?: string,\n angle: number,\n previousBearing: number,\n nextBearing: number,\n distance: number,\n duration: number\n levelChange?: LevelChange\n extras?: StepExtra,\n};\n\nexport type MinStepInfo = {\n coords: Coordinates,\n name?: string,\n levelChange?: LevelChange\n extras?: StepExtra,\n distance?: number,\n duration?: number\n};\n\nexport function stepToJson(step: Step): StepJson {\n return {\n ...(step.firstStep && { firstStep: true }),\n ...(step.lastStep && { lastStep: true }),\n number: step.number,\n coords: step.coords.toCompressedJson(),\n ...(step.name !== null && { name: step.name }),\n angle: Number(step.angle.toFixed(2)),\n previousBearing: Number(step.previousBearing.toFixed(2)),\n nextBearing: Number(step.nextBearing.toFixed(2)),\n distance: Number(step.distance.toFixed(1)),\n duration: Number(step.duration.toFixed(1)),\n ...(step.levelChange !== null && { levelChange: step.levelChange }),\n ...(step.extras && Object.keys(step.extras).length !== 0 && { extras: step.extras }),\n };\n}\n\nexport function jsonToStep(json: StepJson): Step {\n return Object.assign({}, json, {\n coords: Coordinates.fromCompressedJson(json.coords),\n firstStep: Boolean(json.firstStep),\n lastStep: Boolean(json.lastStep),\n name: json.name || null,\n levelChange: json.levelChange || null,\n extras: json.extras || null\n });\n}\n\nexport function stepEquals(step1: Step, step2: Step) {\n return step1.coords.equals(step2.coords)\n && Math.abs(step1.angle - step2.angle) <= 0.005\n && Math.abs(step1.distance - step2.distance) <= 0.05\n && Math.abs(step1.duration - step2.duration) <= 0.05\n && step1.firstStep === step2.firstStep\n && step1.lastStep === step2.lastStep\n && step1.levelChange?.difference === step2.levelChange?.difference\n && step1.levelChange?.direction === step2.levelChange?.direction\n && step1.levelChange?.type === step2.levelChange?.type\n && step1.name === step2.name\n && Math.abs(step1.nextBearing - step2.nextBearing) <= 0.005\n && step1.number === step2.number\n && Math.abs(step1.previousBearing - step2.previousBearing) <= 0.005\n}\n","import { Coordinates } from '@wemap/geo';\n\nimport Graph from \"./Graph.js\";\nimport Edge from './Edge.js';\nimport Vertex from './Vertex.js';\nimport { getDurationFromLength } from '../Utils.js';\n\n\n/**\n * GraphRoute is an oriented graph\n */\nclass GraphRoute extends Graph {\n constructor(\n public start: Coordinates,\n public end: Coordinates,\n public vertices: Vertex[],\n public edges: Edge[],\n public edgesWeights: number[]\n ) {\n super(vertices, edges);\n }\n\n // /!\\ Does not clone vertices\n // /!\\ Create new Edges but does not deep clone properties\n // /!\\ Does not revert edge oneway property\n reverse() {\n const vertices = this.vertices.slice().reverse();\n const edges = this.edges.slice().reverse();\n const edgesWeights = this.edgesWeights.slice().reverse();\n edges.map(oldEdge => new Edge(oldEdge.vertex2, oldEdge.vertex1, oldEdge.properties));\n return new GraphRoute(this.start, this.end, vertices, edges, edgesWeights);\n }\n\n static fromCoordinates(start: Coordinates, end: Coordinates, coordinates: Coordinates[]) {\n const graph = Graph.fromCoordinatesSegments([coordinates]);\n const edgesWeights = graph.edges.map(e => getDurationFromLength(e.length));\n return new GraphRoute(start, end, graph.vertices, graph.edges, edgesWeights);\n }\n\n get hasRoute() { return Boolean(this.edges.length) }\n}\n\nexport default GraphRoute;\n","import { Coordinates, Level } from '@wemap/geo';\nimport Logger from '@wemap/logger';\nimport { diffAngle, deg2rad } from '@wemap/maths';\n\nimport { type LevelChange, type LevelChangeType } from './LevelChange.js';\nimport { type Step, type MinStepInfo } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\nconst SKIP_STEP_ANGLE_MAX = deg2rad(20);\n\nexport default class StepsBuilder {\n\n private start: Coordinates | null = null;\n private end: Coordinates | null = null;\n private pathCoords: Coordinates[] | null = null;\n private stepsInfo: MinStepInfo[] = [];\n\n setStart(start: Coordinates) {\n this.start = start;\n return this;\n }\n\n setEnd(end: Coordinates) {\n this.end = end;\n return this;\n }\n\n setPathCoords(pathCoords: Coordinates[]) {\n this.pathCoords = pathCoords;\n return this;\n }\n\n setStepsInfo(stepsInfo: MinStepInfo[]) {\n this.stepsInfo = stepsInfo;\n return this;\n }\n\n addStepInfo(stepInfo: MinStepInfo) {\n this.stepsInfo.push(stepInfo);\n return this;\n }\n\n setGraphRoute(graphRoute: GraphRoute) {\n\n const stepsInfo: MinStepInfo[] = [];\n\n const { start, end } = graphRoute;\n\n if (!graphRoute.hasRoute) { return this; }\n\n let currentStep: MinStepInfo | null = null;\n let previousBearing = start.bearingTo(graphRoute.vertices[0].coords);\n\n for (let i = 0; i < graphRoute.vertices.length - 1; i++) {\n\n const isFirstStep = i === 0;\n\n const vertex = graphRoute.vertices[i];\n const currentCoords = vertex.coords;\n const nextVertex = graphRoute.vertices[i + 1];\n const nextCoords = nextVertex.coords;\n\n const edge = graphRoute.edges[i];\n\n const nextBearing = vertex.bearingTo(nextVertex);\n const angle = diffAngle(previousBearing, nextBearing + Math.PI);\n\n const previousStep = stepsInfo.length ? stepsInfo[stepsInfo.length - 1] : null;\n\n const { isSubwayEntrance, isGate, subwayEntranceRef } = vertex.properties;\n const { isElevator, areEscalators, areStairs, isMovingWalkway, incline } = edge.properties;\n\n let levelChangeType: LevelChangeType | null = null;\n if (isElevator) {\n levelChangeType = 'elevator';\n } else if (areEscalators) {\n levelChangeType = 'escalator';\n } else if (areStairs) {\n levelChangeType = 'stairs';\n } else if (isMovingWalkway) {\n levelChangeType = 'moving walkway';\n }\n\n // Handle stairs/elevators/escalators/moving walkway without change in level coordinates\n let forceLevelChange: 'up' | 'down' | undefined;\n if (\n (areStairs || isElevator)\n && incline\n && !previousStep?.levelChange\n ) {\n forceLevelChange = incline;\n }\n\n const previousEdge = i > 0 ? graphRoute.edges[i - 1] : null;\n const previousEdgeProperties = previousEdge?.properties || {};\n const forceEndOfLevelChange = Boolean(\n previousEdgeProperties.incline && previousEdgeProperties.areStairs\n && (!incline || !areStairs)\n );\n const createNewStep = vertex.properties.isSubwayEntrance;\n\n const stepName = edge.properties.name || null;\n const duration = graphRoute.edgesWeights[i];\n const stepExtras = {\n ...(isSubwayEntrance && { isSubwayEntrance }),\n ...(subwayEntranceRef && { subwayEntranceRef }),\n ...(isGate && { isGate })\n };\n\n let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;\n\n const splitByLevel = Level.isRange(edge.level) && !Level.isRange(currentCoords.level) || forceLevelChange;\n splitByAngle = splitByAngle && !(currentCoords.level && Level.isRange(currentCoords.level));\n\n\n const splitByEndOfLevelChange = previousStep?.levelChange && !Level.isRange(currentCoords.level)\n || forceEndOfLevelChange;\n\n const splitStepCondition = splitByAngle || splitByLevel || splitByEndOfLevelChange || createNewStep;\n\n // New step creation\n if (isFirstStep || splitStepCondition) {\n\n let levelChange: LevelChange | undefined;\n\n if (splitByLevel) {\n const difference = Level.diff(currentCoords.level, nextCoords.level) || 0;\n let direction: 'up' | 'down' = difference > 0 ? 'up' : 'down';\n if (forceLevelChange) {\n direction = forceLevelChange;\n }\n levelChange = {\n difference, direction, ...(levelChangeType && { type: levelChangeType })\n };\n }\n\n currentStep = {\n coords: currentCoords,\n ...(stepName && { name: stepName }),\n extras: stepExtras,\n levelChange,\n distance: 0,\n duration: 0\n };\n\n stepsInfo.push(currentStep);\n }\n\n currentStep!.distance! += currentCoords.distanceTo(nextCoords);\n currentStep!.duration! += duration;\n\n previousBearing = nextBearing;\n }\n\n const lastCoords = graphRoute.vertices[graphRoute.vertices.length - 1].coords;\n\n // Create a last step if end is not on the graph\n if (!Coordinates.equals(lastCoords, end)) {\n stepsInfo.push({ coords: lastCoords });\n }\n\n this.setStart(start);\n this.setEnd(end);\n this.setPathCoords(graphRoute.vertices.map(v => v.coords));\n this.setStepsInfo(stepsInfo);\n\n return this;\n }\n\n build(): Step[] {\n\n const { pathCoords, start, end } = this;\n\n if (!pathCoords) {\n Logger.warn(`StepsBuilder: Missing \"pathCoords\" property to build steps`);\n return [];\n }\n\n if (!start) {\n Logger.warn(`StepsBuilder: Missing \"from\" property to build steps`);\n return [];\n }\n\n if (!end) {\n Logger.warn(`StepsBuilder: Missing \"to\" property to build steps`);\n return [];\n }\n\n if (this.stepsInfo.length === 0) {\n // If there is no steps info, steps coordinates are calculated using our steps calculation algorithm above.\n this.setGraphRoute(GraphRoute.fromCoordinates(start, end, pathCoords));\n }\n\n const { stepsInfo } = this;\n\n return stepsInfo.map((stepInfo, stepId) => {\n const coordsId = pathCoords.findIndex(coords => coords.equals(stepInfo.coords));\n if (coordsId === -1) {\n throw new Error('Cannot find step coordinates in itinerary coordinates.');\n }\n\n const coordsBeforeStep = coordsId === 0 ? start : pathCoords[coordsId - 1];\n const coordsAfterStep = coordsId === pathCoords.length - 1\n ? end\n : pathCoords[coordsId + 1];\n\n const previousBearing = coordsBeforeStep.bearingTo(stepInfo.coords);\n const nextBearing = stepInfo.coords.bearingTo(coordsAfterStep);\n\n let distance = 0;\n const coordsToStopCalculation = stepId !== stepsInfo.length - 1\n ? stepsInfo[stepId + 1].coords\n : pathCoords[pathCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!pathCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n distance += pathCoords[currentCoordsId].distanceTo(pathCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === pathCoords.length - 1) {\n distance += pathCoords[currentCoordsId].distanceTo(end);\n }\n\n return {\n coords: stepInfo.coords,\n name: stepInfo.name || null,\n number: stepId + 1,\n previousBearing,\n nextBearing,\n angle: diffAngle(previousBearing, nextBearing + Math.PI),\n firstStep: stepId === 0,\n lastStep: stepId === stepsInfo.length - 1,\n distance, // stepInfo.distance is overwritten\n duration: stepInfo.duration || getDurationFromLength(distance),\n levelChange: stepInfo.levelChange || null,\n extras: stepInfo.extras || null\n }\n });\n }\n\n}\n","import {\n Coordinates, CoordinatesCompressedJson, Level, Utils as GeoUtils\n} from '@wemap/geo';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { TransitMode, isTransitModePublicTransport } from './TransitMode.js';\n\nimport { jsonToStep, Step, stepEquals, StepJson, stepToJson } from './Step.js'\nimport StepsBuilder from './StepsBuilder.js';\n\nexport type Destination = {\n name: string | null,\n coords: Coordinates\n};\n\nexport type DestinationConstructor = {\n name?: string,\n coords: Coordinates\n};\n\nexport type DestinationJson = {\n name?: string,\n coords: CoordinatesCompressedJson\n};\n\nexport type TransportInfo = {\n name: string,\n routeColor?: string,\n routeTextColor?: string,\n directionName?: string\n}\n\ntype LegCommon = {\n transitMode: TransitMode,\n startTime?: number,\n endTime?: number,\n transportInfo?: TransportInfo,\n}\n\ntype LegConstructor =\n {\n start: DestinationConstructor,\n end: DestinationConstructor,\n coords: Coordinates[],\n steps?: Step[],\n duration?: number\n }\n & LegCommon;\n\nexport type LegJson = {\n start: DestinationJson,\n end: DestinationJson,\n coords: CoordinatesCompressedJson[],\n steps: StepJson[],\n distance: number,\n duration: number\n} & LegCommon;\n\nexport default class Leg {\n\n start: Destination;\n end: Destination;\n coords: Coordinates[];\n distance: number;\n transitMode: TransitMode;\n\n duration: number;\n startTime: number | null;\n endTime: number | null;\n\n steps: Step[];\n transportInfo: TransportInfo | null;\n\n constructor({\n start, end, coords, transitMode, duration,\n startTime, endTime, transportInfo, steps\n }: LegConstructor) {\n this.start = {\n name: start.name || null,\n coords: start.coords\n };\n this.end = {\n name: end.name || null,\n coords: end.coords\n };\n this.coords = coords;\n this.transitMode = transitMode;\n this.distance = GeoUtils.calcDistance(coords)\n this.duration = typeof duration === 'number' ? duration : getDurationFromLength(this.distance);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n this.transportInfo = transportInfo || null;\n this.steps = Array.isArray(steps)\n ? steps\n : new StepsBuilder().setStart(start.coords).setEnd(end.coords).setPathCoords(coords).build();\n }\n\n isPublicTransport() {\n return isTransitModePublicTransport(this.transitMode);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static equals(obj1: Leg, obj2: Leg) {\n const intermediate = obj1.transitMode === obj2.transitMode\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.start.name === obj2.start.name\n && obj1.start.coords.equals(obj2.start.coords)\n && obj1.end.name === obj2.end.name\n && obj1.end.coords.equals(obj2.end.coords)\n && obj1.coords.length === obj2.coords.length\n && (\n obj1.steps === obj2.steps\n || obj1.steps?.length === obj2.steps?.length\n );\n\n if (!intermediate) {\n return false;\n }\n\n let i;\n for (i = 0; i < obj1.coords.length; i++) {\n if (!obj1.coords[i].equals(obj2.coords[i])) {\n return false;\n }\n }\n for (i = 0; i < obj1.steps.length; i++) {\n if (!stepEquals(obj1.steps[i], obj2.steps[i])) {\n return false;\n }\n }\n\n if (obj1.transportInfo !== obj2.transportInfo) {\n if (obj1.transportInfo === null || obj2.transportInfo === null) {\n return false;\n }\n if (\n obj1.transportInfo.name !== obj2.transportInfo.name\n || obj1.transportInfo.routeColor !== obj2.transportInfo.routeColor\n || obj1.transportInfo.routeTextColor !== obj2.transportInfo.routeTextColor\n || obj1.transportInfo.directionName !== obj2.transportInfo.directionName\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Leg) {\n return Leg.equals(this, obj);\n }\n\n toJson(): LegJson {\n return {\n transitMode: this.transitMode,\n start: {\n coords: this.start.coords.toCompressedJson(),\n ...(this.start.name && { name: this.start.name }),\n },\n end: {\n coords: this.end.coords.toCompressedJson(),\n ...(this.end.name && { name: this.end.name }),\n },\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n coords: this.coords.map(coords => coords.toCompressedJson()),\n steps: this.steps.map(stepToJson),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime }),\n ...(this.transportInfo !== null && { transportInfo: this.transportInfo }),\n };\n }\n\n static fromJson(json: LegJson) {\n const leg = new Leg(Object.assign({}, json, {\n start: {\n coords: Coordinates.fromCompressedJson(json.start.coords),\n name: json.start.name || null\n },\n end: {\n coords: Coordinates.fromCompressedJson(json.end.coords),\n name: json.end.name || null\n },\n coords: json.coords.map(Coordinates.fromCompressedJson),\n steps: json.steps?.map(jsonToStep) || null,\n }));\n\n return leg;\n }\n\n static fromGraphRoute(\n graphRoute: GraphRoute,\n transitMode: TransitMode = 'WALK'\n ) {\n return new Leg({\n start: { coords: graphRoute.start },\n end: { coords: graphRoute.end },\n coords: graphRoute.vertices.map(vertex => vertex.coords),\n duration: graphRoute.edgesWeights.reduce((acc, weight) => acc + weight, 0),\n transitMode,\n steps: new StepsBuilder().setGraphRoute(graphRoute).build()\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n this.start.coords.level = Level.multiplyBy(this.start.coords.level, levelFactor);\n this.end.coords.level = Level.multiplyBy(this.end.coords.level, levelFactor);\n for (const coords of this.coords) {\n coords.level = Level.multiplyBy(coords.level, levelFactor);\n }\n this.steps.forEach(step => {\n step.coords.level = Level.multiplyBy(step.coords.level, levelFactor);\n });\n }\n}\n","import { Feature, FeatureCollection, MultiLineString, Point } from 'geojson';\nimport { Coordinates, Level, Utils as GeoUtils, CoordinatesJson, Level_t } from '@wemap/geo';\nimport { diffAngle, Point2_t, Vector3_t } from '@wemap/maths';\n\nimport Graph from '../graph/Graph.js';\nimport Leg, { type LegJson } from './Leg.js';\nimport { isTransitModePublicTransport, type TransitMode } from './TransitMode.js';\nimport { Step } from './Step.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport StepsBuilder from './StepsBuilder.js';\nimport GraphRoute from '../graph/GraphRoute.js';\n\n\nexport type ItineraryCommon = {\n startTime?: number,\n endTime?: number\n};\n\nexport type ItineraryJson = {\n transitMode: TransitMode,\n origin: CoordinatesJson,\n destination: CoordinatesJson,\n distance: number,\n duration: number,\n legs: LegJson[]\n} & ItineraryCommon;\n\n\nexport type ItineraryConstructor = {\n origin: Coordinates,\n destination: Coordinates,\n duration?: number\n legs: Leg[],\n} & ItineraryCommon;\n\n/**\n * Main attributes are:\n * nodes: the ordered list of Node\n * edges: the ordered list of Edge\n * start: the start point (Coordinates)\n * end: the end point (Coordinates)\n * length: the route length\n */\nexport default class Itinerary {\n\n origin: Coordinates;\n destination: Coordinates;\n duration: number;\n readonly legs: Leg[];\n\n private _transitMode: TransitMode | null = null;\n startTime: number | null;\n endTime: number | null;\n\n private _coords: Coordinates[] | null = null;\n private _distance: number | null = null;\n\n constructor({\n origin, destination, duration, legs, startTime, endTime\n }: ItineraryConstructor) {\n this.origin = origin;\n this.destination = destination;\n this.legs = legs;\n this.duration = typeof duration === 'number'\n ? duration\n : this.legs.reduce((dur, leg) => dur + leg.duration, 0);\n this.startTime = typeof startTime === 'number' ? startTime : null;\n this.endTime = typeof endTime === 'number' ? endTime : null;\n\n this.updateStepsFromLegs();\n }\n\n set coords(_) {\n throw new Error('Itinerary.coords cannot be set. They are calculated from Itinerary.legs.');\n }\n\n public get coords() {\n if (!this._coords) {\n this._coords = this.legs.map(leg => leg.coords)\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n }\n return this._coords;\n }\n\n set steps(_) {\n throw new Error('Itinerary.step cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get steps(): Step[] {\n return this.legs.map(leg => leg.steps).flat();\n }\n\n set transitMode(_) {\n throw new Error('Itinerary.mode cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get transitMode() {\n if (!this._transitMode) {\n let isPublicTransport = false;\n let isBicycle = false;\n let isDriving = false;\n\n this.legs.forEach((leg) => {\n isPublicTransport = isPublicTransport || isTransitModePublicTransport(leg.transitMode);\n isBicycle = isBicycle || leg.transitMode === 'BIKE';\n isDriving = isDriving || leg.transitMode === 'CAR';\n });\n\n if (isPublicTransport) {\n this._transitMode = 'MULTI';\n } else if (isDriving) {\n this._transitMode = 'CAR';\n } else if (isBicycle) {\n this._transitMode = 'BIKE';\n } else {\n this._transitMode = 'WALK';\n }\n }\n\n return this._transitMode;\n\n }\n\n set distance(_) {\n throw new Error('Itinerary.distance cannot be set. They are calculated from Itinerary.legs.');\n }\n\n get distance() {\n if (this._distance === null) {\n this._distance = GeoUtils.calcDistance(this.coords);\n }\n return this._distance;\n\n // Does not work if legs does not intersect\n // return this.legs.reduce((dist, leg) => dist + leg.distance, 0);\n }\n\n toGraph() {\n return Graph.fromCoordinatesSegments([this.coords]);\n }\n\n static fromItineraries(...itineraries: Itinerary[]) {\n let duration = 0;\n const legs: Leg[] = [];\n\n itineraries.forEach(_itinerary => {\n duration += _itinerary.duration;\n legs.push(..._itinerary.legs);\n });\n\n return new Itinerary({\n origin: itineraries[0].origin,\n destination: itineraries[itineraries.length - 1].destination,\n duration,\n legs\n });\n }\n\n /**\n * Convert lat/lng/level? points to Itinerary\n */\n static fromOrderedPointsArray(\n points: (Point2_t | Vector3_t)[],\n start: (Point2_t | Vector3_t),\n end: (Point2_t | Vector3_t)) {\n\n const pointToCoordinates = (point: Point2_t | Vector3_t) =>\n new Coordinates(point[0], point[1], null, point[2]);\n\n return this.fromOrderedCoordinates(\n points.map(pointToCoordinates),\n pointToCoordinates(start),\n pointToCoordinates(end)\n );\n }\n\n /**\n * Convert ordered Coordinates to Itinerary\n */\n static fromOrderedCoordinates(\n coords: Coordinates[],\n origin: Coordinates,\n destination: Coordinates,\n transitMode: TransitMode = 'WALK'\n ) {\n\n const steps = new StepsBuilder().setPathCoords(coords).setStart(origin).setEnd(destination).build();\n\n const leg = new Leg({\n start: { coords: origin },\n end: { coords: destination },\n coords,\n transitMode,\n steps\n });\n\n return new Itinerary({ origin, destination, legs: [leg] });\n }\n\n\n static equals(obj1: Itinerary, obj2: Itinerary) {\n const intermediate = obj1.origin.equals(obj2.origin)\n && obj1.destination.equals(obj2.destination)\n && Math.abs(obj1.distance - obj2.distance) <= 0.05\n && Math.abs(obj1.duration - obj2.duration) <= 0.05\n && obj1.startTime === obj2.startTime\n && obj1.endTime === obj2.endTime\n && obj1.legs.length === obj2.legs.length;\n\n if (!intermediate) {\n return false;\n }\n\n for (let i = 0; i < obj1.legs.length; i++) {\n if (!obj1.legs[i].equals(obj2.legs[i])) {\n return false;\n }\n }\n\n return true;\n }\n\n equals(obj: Itinerary) {\n return Itinerary.equals(this, obj);\n }\n\n toJson(): ItineraryJson {\n return {\n origin: this.origin.toJson(),\n destination: this.destination.toJson(),\n distance: Number(this.distance.toFixed(1)),\n duration: Number(this.duration.toFixed(1)),\n transitMode: this.transitMode,\n legs: this.legs.map(leg => leg.toJson()),\n ...(this.startTime !== null && { startTime: this.startTime }),\n ...(this.endTime !== null && { endTime: this.endTime })\n };\n }\n\n static fromJson(json: ItineraryJson) {\n return new Itinerary({\n origin: Coordinates.fromJson(json.origin),\n destination: Coordinates.fromJson(json.destination),\n duration: json.duration,\n legs: json.legs.map(Leg.fromJson),\n startTime: json.startTime,\n endTime: json.endTime\n });\n }\n\n static fromGraphRoute(graphRoute: GraphRoute, transitMode: TransitMode = 'WALK') {\n const leg = Leg.fromGraphRoute(graphRoute, transitMode);\n return new Itinerary({\n origin: graphRoute.start,\n destination: graphRoute.end,\n duration: leg.duration,\n legs: [leg]\n });\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n multiplyLevel(levelFactor: number) {\n\n this.origin.level = Level.multiplyBy(this.origin.level, levelFactor);\n this.destination.level = Level.multiplyBy(this.destination.level, levelFactor);\n\n this.legs.forEach(leg => leg.multiplyLevel(levelFactor));\n\n // It is not necessary to multiply this._coords because \n // coords are not cloned between legs and itinerary\n }\n\n // TODO: Remove when possible...\n // Livemap specific\n forceUnknownLevelTo0() {\n\n this.origin.level = this.origin.level || 0;\n this.destination.level = this.destination.level || 0;\n\n for (const leg of this.legs) {\n leg.start.coords.level = leg.start.coords.level || 0;\n leg.end.coords.level = leg.end.coords.level || 0;\n for (const coords of leg.coords) {\n coords.level = coords.level || 0;\n }\n if (leg.steps) {\n for (const step of leg.steps) {\n step.coords.level = step.coords.level || 0;\n }\n }\n }\n\n if (this._coords) {\n for (const coords of this._coords) {\n coords.level = coords.level || 0;\n }\n }\n }\n\n toGeoJson(): FeatureCollection {\n const transformToPoint = (point: Coordinates, name?: string, type?: string): Feature<Point> => ({\n type: \"Feature\",\n properties: { name, level: point.level, ...(type && { type }) },\n geometry: {\n type: 'Point',\n coordinates: [point.lng, point.lat]\n }\n });\n const transformToMultiLineStrings = (segments: Coordinates[][], level: Level_t): Feature<MultiLineString> => ({\n type: \"Feature\",\n properties: { level, name: level?.toString() },\n geometry: {\n type: 'MultiLineString',\n coordinates: segments.map(s => s.map(({ lat, lng }) => [lng, lat]))\n }\n });\n\n const levelsOfItinerary = [...new Set(this.coords.map(c => Level.toString(c.level)))].map(Level.fromString);\n const segmentsSplitted: [Level_t, Coordinates[][]][] = levelsOfItinerary.map(loi => [loi, GeoUtils.createSegmentsAtLevel(this.coords, loi, true)]);\n const multiLineStrings = segmentsSplitted.map(([loi, segments]) => transformToMultiLineStrings(segments, loi))\n const legsStarts = this.legs.map((leg, idx) => transformToPoint(leg.start.coords, `Leg ${idx} start`, 'leg-start'));\n const legsEnds = this.legs.map((leg, idx) => transformToPoint(leg.end.coords, `Leg ${idx} end`, 'leg-end'));\n const steps = this.steps.map(step => transformToPoint(step.coords, `Step ${step.number}`, 'step'))\n return {\n type: \"FeatureCollection\",\n features: [\n transformToPoint(this.origin, 'origin', 'origin'),\n transformToPoint(this.destination, 'destination', 'destination'),\n ...multiLineStrings,\n ...legsStarts,\n ...legsEnds,\n ...steps\n ]\n };\n }\n\n /**\n * Update steps info thanks to the coordinates of the whole itinerary.\n * This method will update:\n * - all steps number\n * - first/last steps\n * - previousBearing/nextBearing/angle of first and last step of each leg\n * - distance/duration of first and last step of each leg\n */\n updateStepsFromLegs() {\n\n const itineraryCoords = this.coords\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n const steps = this.legs.map(leg => leg.steps).flat();\n\n\n steps.map((step, stepId) => {\n const coordsId = itineraryCoords.findIndex(coords => coords.equals(step.coords));\n if (coordsId === -1) {\n throw new Error('Cannot find step coordinates in itinerary coordinates.');\n }\n\n const coordsBeforeStep = coordsId === 0 ? this.origin : itineraryCoords[coordsId - 1];\n const coordsAfterStep = coordsId === itineraryCoords.length - 1\n ? this.destination\n : itineraryCoords[coordsId + 1];\n\n step.previousBearing = coordsBeforeStep.bearingTo(step.coords);\n step.nextBearing = step.coords.bearingTo(coordsAfterStep);\n step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);\n\n const stepDistanceBefore = step.distance;\n step.distance = 0;\n const coordsToStopCalculation = stepId !== steps.length - 1\n ? steps[stepId + 1].coords\n : itineraryCoords[itineraryCoords.length - 1];\n let currentCoordsId = coordsId;\n while (!itineraryCoords[currentCoordsId].equals(coordsToStopCalculation)) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(itineraryCoords[currentCoordsId + 1]);\n currentCoordsId++;\n }\n if (currentCoordsId === itineraryCoords.length - 1) {\n step.distance += itineraryCoords[currentCoordsId].distanceTo(this.destination);\n }\n\n step.number = stepId + 1;\n step.firstStep = stepId === 0;\n step.lastStep = stepId === steps.length - 1;\n\n step.duration += getDurationFromLength(step.distance - stepDistanceBefore)\n });\n }\n}\n","/////////////////////////////////////////////////////////////////////////////////\n/* UAParser.js v1.0.35\n Copyright © 2012-2021 Faisal Salman <f@faisalman.com>\n MIT License *//*\n Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.\n Supports browser & node.js environment. \n Demo : https://faisalman.github.io/ua-parser-js\n Source : https://github.com/faisalman/ua-parser-js */\n/////////////////////////////////////////////////////////////////////////////////\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '1.0.35',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major',\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded',\n UA_MAX_LENGTH = 350;\n\n var AMAZON = 'Amazon',\n APPLE = 'Apple',\n ASUS = 'ASUS',\n BLACKBERRY = 'BlackBerry',\n BROWSER = 'Browser',\n CHROME = 'Chrome',\n EDGE = 'Edge',\n FIREFOX = 'Firefox',\n GOOGLE = 'Google',\n HUAWEI = 'Huawei',\n LG = 'LG',\n MICROSOFT = 'Microsoft',\n MOTOROLA = 'Motorola',\n OPERA = 'Opera',\n SAMSUNG = 'Samsung',\n SHARP = 'Sharp',\n SONY = 'Sony',\n VIERA = 'Viera',\n XIAOMI = 'Xiaomi',\n ZEBRA = 'Zebra',\n FACEBOOK = 'Facebook',\n CHROMIUM_OS = 'Chromium OS',\n MAC_OS = 'Mac OS';\n\n ///////////\n // Helper\n //////////\n\n var extend = function (regexes, extensions) {\n var mergedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n mergedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n mergedRegexes[i] = regexes[i];\n }\n }\n return mergedRegexes;\n },\n enumerize = function (arr) {\n var enums = {};\n for (var i=0; i<arr.length; i++) {\n enums[arr[i].toUpperCase()] = arr[i];\n }\n return enums;\n },\n has = function (str1, str2) {\n return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;\n },\n lowerize = function (str) {\n return str.toLowerCase();\n },\n majorize = function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g, EMPTY).split('.')[0] : undefined;\n },\n trim = function (str, len) {\n if (typeof(str) === STR_TYPE) {\n str = str.replace(/^\\s\\s*/, EMPTY);\n return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);\n }\n };\n\n ///////////////\n // Map helper\n //////////////\n\n var rgxMapper = function (ua, arrays) {\n\n var i = 0, j, k, p, q, matches, match;\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n if (!regex[j]) { break; }\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length === 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length === 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length === 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n },\n\n strMapper = function (str, map) {\n\n for (var i in map) {\n // check if current value is array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return str;\n };\n\n ///////////////\n // String map\n //////////////\n\n // Safari < 3.0\n var oldSafariMap = {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n },\n windowsVersionMap = {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n };\n\n //////////////\n // Regex map\n /////////////\n\n var regexes = {\n\n browser : [[\n\n /\\b(?:crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [VERSION, [NAME, 'Chrome']], [\n /edg(?:e|ios|a)?\\/([\\w\\.]+)/i // Microsoft Edge\n ], [VERSION, [NAME, 'Edge']], [\n\n // Presto based\n /(opera mini)\\/([-\\w\\.]+)/i, // Opera Mini\n /(opera [mobiletab]{3,6})\\b.+version\\/([-\\w\\.]+)/i, // Opera Mobi/Tablet\n /(opera)(?:.+version\\/|[\\/ ]+)([\\w\\.]+)/i // Opera\n ], [NAME, VERSION], [\n /opios[\\/ ]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [VERSION, [NAME, OPERA+' Mini']], [\n /\\bopr\\/([\\w\\.]+)/i // Opera Webkit\n ], [VERSION, [NAME, OPERA]], [\n\n // Mixed\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer)[\\/ ]?([\\w\\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer\n // Trident based\n /(avant |iemobile|slim)(?:browser)?[\\/ ]?([\\w\\.]*)/i, // Avant/IEMobile/SlimBrowser\n /(ba?idubrowser)[\\/ ]?([\\w\\.]+)/i, // Baidu Browser\n /(?:ms|\\()(ie) ([\\w\\.]+)/i, // Internet Explorer\n\n // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon\n /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\\/([-\\w\\.]+)/i,\n // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ\n /(heytap|ovi)browser\\/([\\d\\.]+)/i, // Heytap/Ovi\n /(weibo)__([\\d\\.]+)/i // Weibo\n ], [NAME, VERSION], [\n /(?:\\buc? ?browser|(?:juc.+)ucweb)[\\/ ]?([\\w\\.]+)/i // UCBrowser\n ], [VERSION, [NAME, 'UC'+BROWSER]], [\n /microm.+\\bqbcore\\/([\\w\\.]+)/i, // WeChat Desktop for Windows Built-in Browser\n /\\bqbcore\\/([\\w\\.]+).+microm/i\n ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [\n /micromessenger\\/([\\w\\.]+)/i // WeChat\n ], [VERSION, [NAME, 'WeChat']], [\n /konqueror\\/([\\w\\.]+)/i // Konqueror\n ], [VERSION, [NAME, 'Konqueror']], [\n /trident.+rv[: ]([\\w\\.]{1,9})\\b.+like gecko/i // IE11\n ], [VERSION, [NAME, 'IE']], [\n /ya(?:search)?browser\\/([\\w\\.]+)/i // Yandex\n ], [VERSION, [NAME, 'Yandex']], [\n /(avast|avg)\\/([\\w\\.]+)/i // Avast/AVG Secure Browser\n ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [\n /\\bfocus\\/([\\w\\.]+)/i // Firefox Focus\n ], [VERSION, [NAME, FIREFOX+' Focus']], [\n /\\bopt\\/([\\w\\.]+)/i // Opera Touch\n ], [VERSION, [NAME, OPERA+' Touch']], [\n /coc_coc\\w+\\/([\\w\\.]+)/i // Coc Coc Browser\n ], [VERSION, [NAME, 'Coc Coc']], [\n /dolfin\\/([\\w\\.]+)/i // Dolphin\n ], [VERSION, [NAME, 'Dolphin']], [\n /coast\\/([\\w\\.]+)/i // Opera Coast\n ], [VERSION, [NAME, OPERA+' Coast']], [\n /miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI '+BROWSER]], [\n /fxios\\/([-\\w\\.]+)/i // Firefox for iOS\n ], [VERSION, [NAME, FIREFOX]], [\n /\\bqihu|(qi?ho?o?|360)browser/i // 360\n ], [[NAME, '360 '+BROWSER]], [\n /(oculus|samsung|sailfish|huawei)browser\\/([\\w\\.]+)/i\n ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser\n /(comodo_dragon)\\/([\\w\\.]+)/i // Comodo Dragon\n ], [[NAME, /_/g, ' '], VERSION], [\n /(electron)\\/([\\w\\.]+) safari/i, // Electron-based App\n /(tesla)(?: qtcarbrowser|\\/(20\\d\\d\\.[-\\w\\.]+))/i, // Tesla\n /m?(qqbrowser|baiduboxapp|2345Explorer)[\\/ ]?([\\w\\.]+)/i // QQBrowser/Baidu App/2345 Browser\n ], [NAME, VERSION], [\n /(metasr)[\\/ ]?([\\w\\.]+)/i, // SouGouBrowser\n /(lbbrowser)/i, // LieBao Browser\n /\\[(linkedin)app\\]/i // LinkedIn App for iOS & Android\n ], [NAME], [\n\n // WebView\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i // Facebook App for iOS & Android\n ], [[NAME, FACEBOOK], VERSION], [\n /(kakao(?:talk|story))[\\/ ]([\\w\\.]+)/i, // Kakao App\n /(naver)\\(.*?(\\d+\\.[\\w\\.]+).*\\)/i, // Naver InApp\n /safari (line)\\/([\\w\\.]+)/i, // Line App for iOS\n /\\b(line)\\/([\\w\\.]+)\\/iab/i, // Line App for Android\n /(chromium|instagram)[\\/ ]([-\\w\\.]+)/i // Chromium/Instagram\n ], [NAME, VERSION], [\n /\\bgsa\\/([\\w\\.]+) .*safari\\//i // Google Search Appliance on iOS\n ], [VERSION, [NAME, 'GSA']], [\n /musical_ly(?:.+app_?version\\/|_)([\\w\\.]+)/i // TikTok\n ], [VERSION, [NAME, 'TikTok']], [\n\n /headlesschrome(?:\\/([\\w\\.]+)| )/i // Chrome Headless\n ], [VERSION, [NAME, CHROME+' Headless']], [\n\n / wv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, CHROME+' WebView'], VERSION], [\n\n /droid.+ version\\/([\\w\\.]+)\\b.+(?:mobile safari|safari)/i // Android Browser\n ], [VERSION, [NAME, 'Android '+BROWSER]], [\n\n /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\\/v?([\\w\\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /version\\/([\\w\\.\\,]+) .*mobile\\/\\w+ (safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n /version\\/([\\w(\\.|\\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n /webkit.+?(mobile ?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, strMapper, oldSafariMap]], [\n\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape\\d?)\\/([-\\w\\.]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /mobile vr; rv:([\\w\\.]+)\\).+firefox/i // Firefox Reality\n ], [VERSION, [NAME, FIREFOX+' Reality']], [\n /ekiohf.+(flow)\\/([\\w\\.]+)/i, // Flow\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\\/ ]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar\n /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\\/([-\\w\\.]+)$/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(firefox)\\/([\\w\\.]+)/i, // Other Firefox-based\n /(mozilla)\\/([\\w\\.]+) .+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\\. ]?browser)[-\\/ ]?v?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser\n /(links) \\(([\\w\\.]+)/i, // Links\n /panasonic;(viera)/i // Panasonic Viera\n ], [NAME, VERSION], [\n \n /(cobalt)\\/([\\w\\.]+)/i // Cobalt\n ], [NAME, [VERSION, /master.|lts./, \"\"]]\n ],\n\n cpu : [[\n\n /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\\)]/i // AMD64 (x64)\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i // IA32 (quicktime)\n ], [[ARCHITECTURE, lowerize]], [\n\n /((?:i[346]|x)86)[;\\)]/i // IA32 (x86)\n ], [[ARCHITECTURE, 'ia32']], [\n\n /\\b(aarch64|arm(v?8e?l?|_?64))\\b/i // ARM64\n ], [[ARCHITECTURE, 'arm64']], [\n\n /\\b(arm(?:v[67])?ht?n?[fl]p?)\\b/i // ARMHF\n ], [[ARCHITECTURE, 'armhf']], [\n\n // PocketPC mistakenly identified as PowerPC\n /windows (ce|mobile); ppc;/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((?:ppc|powerpc)(?:64)?)(?: mac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [\n\n /(sun4\\w)[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /((?:avr32|ia64(?=;))|68k(?=\\))|\\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\\b|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, lowerize]]\n ],\n\n device : [[\n\n //////////////////////////\n // MOBILES & TABLETS\n /////////////////////////\n\n // Samsung\n /\\b(sch-i[89]0\\d|shw-m380s|sm-[ptx]\\w{2,4}|gt-[pn]\\d{2,4}|sgh-t8[56]9|nexus 10)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [\n /\\b((?:s[cgp]h|gt|sm)-\\w+|sc[g-]?[\\d]+a?|galaxy nexus)/i,\n /samsung[- ]([-\\w]+)/i,\n /sec-(sgh\\w+)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [\n\n // Apple\n /(?:\\/|\\()(ip(?:hone|od)[\\w, ]*)(?:\\/|;)/i // iPod/iPhone\n ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [\n /\\((ipad);[-\\w\\),; ]+apple/i, // iPad\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/i,\n /\\b(ipad)\\d\\d?,\\d\\d?[;\\]].+ios/i\n ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [\n /(macintosh);/i\n ], [MODEL, [VENDOR, APPLE]], [\n\n // Sharp\n /\\b(sh-?[altvz]?\\d\\d[a-ekm]?)/i\n ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [\n\n // Huawei\n /\\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\\d{2})\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [\n /(?:huawei|honor)([-\\w ]+)[;\\)]/i,\n /\\b(nexus 6p|\\w{2,4}e?-[atu]?[ln][\\dx][012359c][adn]?)\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [\n\n // Xiaomi\n /\\b(poco[\\w ]+)(?: bui|\\))/i, // Xiaomi POCO\n /\\b; (\\w+) build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /\\b(hm[-_ ]?note?[_ ]?(?:\\d\\w)?) bui/i, // Xiaomi Hongmi\n /\\b(redmi[\\-_ ]?(?:note|k)?[\\w_ ]+)(?: bui|\\))/i, // Xiaomi Redmi\n /\\b(mi[-_ ]?(?:a\\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\\d?\\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\\))/i // Xiaomi Mi\n ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [\n /\\b(mi[-_ ]?(?:pad)(?:[\\w_ ]+))(?: bui|\\))/i // Mi Pad tablets\n ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [\n\n // OPPO\n /; (\\w+) bui.+ oppo/i,\n /\\b(cph[12]\\d{3}|p(?:af|c[al]|d\\w|e[ar])[mt]\\d0|x9007|a101op)\\b/i\n ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [\n\n // Vivo\n /vivo (\\w+)(?: bui|\\))/i,\n /\\b(v[12]\\d{3}\\w?[at])(?: bui|;)/i\n ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [\n\n // Realme\n /\\b(rmx[12]\\d{3})(?: bui|;|\\))/i\n ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\\b[\\w ]+build\\//i,\n /\\bmot(?:orola)?[- ](\\w*)/i,\n /((?:moto[\\w\\(\\) ]+|xt\\d{3,4}|nexus 6)(?= bui|\\)))/i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [\n /\\b(mz60\\d|xoom[2 ]{0,2}) build\\//i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [\n\n // LG\n /((?=lg)?[vl]k\\-?\\d{3}) bui| 3\\.[-\\w; ]{10}lg?-([06cv9]{3,4})/i\n ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [\n /(lm(?:-?f100[nv]?|-[\\w\\.]+)(?= bui|\\))|nexus [45])/i,\n /\\blg[-e;\\/ ]+((?!browser|netcast|android tv)\\w+)/i,\n /\\blg-?([\\d\\w]+) bui/i\n ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [\n\n // Lenovo\n /(ideatab[-\\w ]+)/i,\n /lenovo ?(s[56]000[-\\w]+|tab(?:[\\w ]+)|yt[-\\d\\w]{6}|tb[-\\d\\w]{6})/i\n ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [\n\n // Nokia\n /(?:maemo|nokia).*(n900|lumia \\d+)/i,\n /nokia[-_ ]?([-\\w\\.]*)/i\n ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [\n\n // Google\n /(pixel c)\\b/i // Google Pixel C\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [\n /droid.+; (pixel[\\daxl ]{0,6})(?: bui|\\))/i // Google Pixel\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [\n\n // Sony\n /droid.+ (a?\\d[0-2]{2}so|[c-g]\\d{4}|so[-gl]\\w+|xq-a\\w[4-7][12])(?= bui|\\).+chrome\\/(?![1-6]{0,1}\\d\\.))/i\n ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [\n /sony tablet [ps]/i,\n /\\b(?:sony)?sgp\\w+(?: bui|\\))/i\n ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [\n\n // OnePlus\n / (kb2005|in20[12]5|be20[12][59])\\b/i,\n /(?:one)?(?:plus)? (a\\d0\\d\\d)(?: b|\\))/i\n ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [\n\n // Amazon\n /(alexa)webm/i,\n /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i, // Kindle Fire without Silk / Echo Show\n /(kf[a-z]+)( bui|\\)).+silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [\n /((?:sd|kf)[0349hijorstuw]+)( bui|\\)).+silk\\//i // Fire Phone\n ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [\n\n // BlackBerry\n /(playbook);[-\\w\\),; ]+(rim)/i // BlackBerry PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n /\\b((?:bb[a-f]|st[hv])100-\\d)/i,\n /\\(bb10; (\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [\n\n // Asus\n /(?:\\b|asus_)(transfo[prime ]{4,10} \\w+|eeepc|slider \\w+|nexus 7|padfone|p00[cj])/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [\n / (z[bes]6[027][012][km][ls]|zenfone \\d\\w?)\\b/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [\n\n // HTC\n /(nexus 9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n /(htc)[-;_ ]{1,2}([\\w ]+(?=\\)| bui)|\\w+)/i, // HTC\n\n // ZTE\n /(zte)[- ]([\\w ]+?)(?: bui|\\/|\\))/i,\n /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\\.))|sony(?!-bra))[-_ ]?([-\\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n // Acer\n /droid.+; ([ab][1-7]-?[0178a]\\d\\d?)/i\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n // Meizu\n /droid.+; (m[1-5] note) bui/i,\n /\\bmz-([-\\w]{2,})/i\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [\n\n // MIXED\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\\w]*)/i,\n // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron\n /(hp) ([\\w ]+\\w)/i, // HP iPAQ\n /(asus)-?(\\w+)/i, // Asus\n /(microsoft); (lumia[\\w ]+)/i, // Microsoft Lumia\n /(lenovo)[-_ ]?([-\\w]+)/i, // Lenovo\n /(jolla)/i, // Jolla\n /(oppo) ?([\\w ]+) bui/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /(kobo)\\s(ereader|touch)/i, // Kobo\n /(archos) (gamepad2?)/i, // Archos\n /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(nook)[\\w ]+build\\/(\\w+)/i, // Nook\n /(dell) (strea[kpr\\d ]*[\\dko])/i, // Dell Streak\n /(le[- ]+pan)[- ]+(\\w{1,9}) bui/i, // Le Pan Tablets\n /(trinity)[- ]*(t\\d{3}) bui/i, // Trinity Tablets\n /(gigaset)[- ]+(q\\w{1,9}) bui/i, // Gigaset Tablets\n /(vodafone) ([\\w ]+)(?:\\)| bui)/i // Vodafone\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(surface duo)/i // Surface Duo\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [\n /droid [\\d\\.]+; (fp\\du?)(?: b|\\))/i // Fairphone\n ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [\n /(u304aa)/i // AT&T\n ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [\n /\\bsie-(\\w*)/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n /\\b(rct\\w+) b/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n /\\b(venue[\\d ]{2,7}) b/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n /\\b(q(?:mv|ta)\\w+) b/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n /\\b(?:barnes[& ]+noble |bn[rt])([\\w\\+ ]*) b/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [\n /\\b(tm\\d{3}\\w+) b/i\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n /\\b(k88) b/i // ZTE K Series Tablet\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [\n /\\b(nx\\d{3}j) b/i // ZTE Nubia\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n /\\b(gen\\d{3}) b.+49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n /\\b(zur\\d{3}) b/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n /\\b((zeki)?tb.*\\b) b/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n /\\b([yr]\\d{2}) b/i,\n /\\b(dragon[- ]+touch |dt)(\\w{5}) b/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n /\\b(ns-?\\w{0,9}) b/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n /\\b((nxa|next)-?\\w{0,9}) b/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n /\\b(xtreme\\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [\n /\\b(lvtel\\-)?(v1[12]) b/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n /\\b(ph-1) /i // Essential PH-1\n ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [\n /\\b(v(100md|700na|7011|917g).*\\b) b/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n /\\b(trio[-\\w\\. ]+) b/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n /\\btu_(1491) b/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n /(shield[\\w ]+) b/i // Nvidia Shield Tablets\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [\n /(sprint) (\\w+)/i // Sprint Phones\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [\n /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\\)/i // Zebra\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [\n /droid.+; (ec30|ps20|tc[2-8]\\d[kx])\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [\n\n ///////////////////\n // SMARTTVS\n ///////////////////\n\n /smart-tv.+(samsung)/i // Samsung\n ], [VENDOR, [TYPE, SMARTTV]], [\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [\n /(nux; netcast.+smarttv|lg (netcast\\.tv-201\\d|android tv))/i // LG SmartTV\n ], [[VENDOR, LG], [TYPE, SMARTTV]], [\n /(apple) ?tv/i // Apple TV\n ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [\n /crkey/i // Google Chromecast\n ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [\n /droid.+aft(\\w)( bui|\\))/i // Fire TV\n ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [\n /\\(dtv[\\);].+(aquos)/i,\n /(aquos-tv[\\w ]+)\\)/i // Sharp\n ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[\n /(bravia[\\w ]+)( bui|\\))/i // Sony\n ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [\n /(mitv-\\w{5}) bui/i // Xiaomi\n ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [\n /Hbbtv.*(technisat) (.*);/i // TechniSAT\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /\\b(roku)[\\dx]*[\\)\\/]((?:dvp-)?[\\d\\.]*)/i, // Roku\n /hbbtv\\/\\d+\\.\\d+\\.\\d+ +\\([\\w\\+ ]*; *([\\w\\d][^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [\n /\\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\\b/i // SmartTV from Unidentified Vendors\n ], [[TYPE, SMARTTV]], [\n\n ///////////////////\n // CONSOLES\n ///////////////////\n\n /(ouya)/i, // Ouya\n /(nintendo) ([wids3utch]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n /droid.+; (shield) bui/i // Nvidia\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [\n /(playstation [345portablevi]+)/i // Playstation\n ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [\n /\\b(xbox(?: one)?(?!; xbox))[\\); ]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [\n\n ///////////////////\n // WEARABLES\n ///////////////////\n\n /((pebble))app/i // Pebble\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /(watch)(?: ?os[,\\/]|\\d,\\d\\/)[\\d\\.]+/i // Apple Watch\n ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [\n /droid.+; (glass) \\d/i // Google Glass\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [\n /droid.+; (wt63?0{2,3})\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [\n /(quest( 2| pro)?)/i // Oculus Quest\n ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [\n\n ///////////////////\n // EMBEDDED\n ///////////////////\n\n /(tesla)(?: qtcarbrowser|\\/[-\\w\\.]+)/i // Tesla\n ], [VENDOR, [TYPE, EMBEDDED]], [\n /(aeobc)\\b/i // Echo Dot\n ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [\n\n ////////////////////\n // MIXED (GENERIC)\n ///////////////////\n\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors\n ], [MODEL, [TYPE, MOBILE]], [\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors\n ], [MODEL, [TYPE, TABLET]], [\n /\\b((tablet|tab)[;\\/]|focus\\/\\d(?!.+mobile))/i // Unidentifiable Tablet\n ], [[TYPE, TABLET]], [\n /(phone|mobile(?:[;\\/]| [ \\w\\/\\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile\n ], [[TYPE, MOBILE]], [\n /(android[-\\w\\. ]{0,9});.+buil/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n ],\n\n engine : [[\n\n /windows.+ edge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, EDGE+'HTML']], [\n\n /webkit\\/537\\.36.+chrome\\/(?!27)([\\w\\.]+)/i // Blink\n ], [VERSION, [NAME, 'Blink']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna\n /ekioh(flow)\\/([\\w\\.]+)/i, // Flow\n /(khtml|tasman|links)[\\/ ]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/ ]([23]\\.[\\d\\.]+)/i, // iCab\n /\\b(libweb)/i\n ], [NAME, VERSION], [\n\n /rv\\:([\\w\\.]{1,9})\\b.+(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows\n /microsoft (windows) (vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows) nt 6\\.2; (arm)/i, // Windows RT\n /(windows (?:phone(?: os)?|mobile))[\\/ ]?([\\d\\.\\w ]*)/i, // Windows Phone\n /(windows)[\\/ ]?([ntce\\d\\. ]+\\w)(?!.+xbox)/i\n ], [NAME, [VERSION, strMapper, windowsVersionMap]], [\n /(win(?=3|9|n)|win 9x )([nt\\d\\.]+)/i\n ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [\n\n // iOS/macOS\n /ip[honead]{2,4}\\b(?:.*os ([\\w]+) like mac|; opera)/i, // iOS\n /ios;fbsv\\/([\\d\\.]+)/i,\n /cfnetwork\\/.+darwin/i\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n /(mac os x) ?([\\w\\. ]*)/i,\n /(macintosh|mac_powerpc\\b)(?!.+haiku)/i // Mac OS\n ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [\n\n // Mobile OSes\n /droid ([\\w\\.]+)\\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS\n ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS\n /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\\/ ]?([\\w\\.]*)/i,\n /(blackberry)\\w*\\/([\\w\\.]*)/i, // Blackberry\n /(tizen|kaios)[\\/ ]([\\w\\.]+)/i, // Tizen/KaiOS\n /\\((series40);/i // Series 40\n ], [NAME, VERSION], [\n /\\(bb(10);/i // BlackBerry 10\n ], [VERSION, [NAME, BLACKBERRY]], [\n /(?:symbian ?os|symbos|s60(?=;)|series60)[-\\/ ]?([\\w\\.]*)/i // Symbian\n ], [VERSION, [NAME, 'Symbian']], [\n /mozilla\\/[\\d\\.]+ \\((?:mobile|tablet|tv|mobile; [\\w ]+); rv:.+ gecko\\/([\\w\\.]+)/i // Firefox OS\n ], [VERSION, [NAME, FIREFOX+' OS']], [\n /web0s;.+rt(tv)/i,\n /\\b(?:hp)?wos(?:browser)?\\/([\\w\\.]+)/i // WebOS\n ], [VERSION, [NAME, 'webOS']], [\n /watch(?: ?os[,\\/]|\\d,\\d\\/)([\\d\\.]+)/i // watchOS\n ], [VERSION, [NAME, 'watchOS']], [\n\n // Google Chromecast\n /crkey\\/([\\d\\.]+)/i // Google Chromecast\n ], [VERSION, [NAME, CHROME+'cast']], [\n /(cros) [\\w]+(?:\\)| ([\\w\\.]+)\\b)/i // Chromium OS\n ], [[NAME, CHROMIUM_OS], VERSION],[\n\n // Smart TVs\n /panasonic;(viera)/i, // Panasonic Viera\n /(netrange)mmh/i, // Netrange\n /(nettv)\\/(\\d+\\.[\\w\\.]+)/i, // NetTV\n\n // Console\n /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation\n /(xbox); +xbox ([^\\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)\n\n // Other\n /\\b(joli|palm)\\b ?(?:os)?\\/?([\\w\\.]*)/i, // Joli/Palm\n /(mint)[\\/\\(\\) ]?(\\w*)/i, // Mint\n /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux\n /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\\/ ]?(?!chrom|package)([-\\w\\.]*)/i,\n // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire\n /(hurd|linux) ?([\\w\\.]*)/i, // Hurd/Linux\n /(gnu) ?([\\w\\.]*)/i, // GNU\n /\\b([-frentopcghs]{0,5}bsd|dragonfly)[\\/ ]?(?!amd|[ix346]{1,2}86)([\\w\\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly\n /(haiku) (\\w+)/i // Haiku\n ], [NAME, VERSION], [\n /(sunos) ?([\\w\\.\\d]*)/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n /((?:open)?solaris)[-\\/ ]?([\\w\\.]*)/i, // Solaris\n /(aix) ((\\d)(?=\\.|\\)| )[\\w\\.])*/i, // AIX\n /\\b(beos|os\\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS\n /(unix) ?([\\w\\.]*)/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n /////////////////\n // Constructor\n ////////////////\n\n var UAParser = function (ua, extensions) {\n\n if (typeof ua === OBJ_TYPE) {\n extensions = ua;\n ua = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(ua, extensions).getResult();\n }\n\n var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined;\n var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY);\n var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined;\n var _rgxmap = extensions ? extend(regexes, extensions) : regexes;\n var _isSelfNav = _navigator && _navigator.userAgent == _ua;\n\n this.getBrowser = function () {\n var _browser = {};\n _browser[NAME] = undefined;\n _browser[VERSION] = undefined;\n rgxMapper.call(_browser, _ua, _rgxmap.browser);\n _browser[MAJOR] = majorize(_browser[VERSION]);\n // Brave-specific detection\n if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {\n _browser[NAME] = 'Brave';\n }\n return _browser;\n };\n this.getCPU = function () {\n var _cpu = {};\n _cpu[ARCHITECTURE] = undefined;\n rgxMapper.call(_cpu, _ua, _rgxmap.cpu);\n return _cpu;\n };\n this.getDevice = function () {\n var _device = {};\n _device[VENDOR] = undefined;\n _device[MODEL] = undefined;\n _device[TYPE] = undefined;\n rgxMapper.call(_device, _ua, _rgxmap.device);\n if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {\n _device[TYPE] = MOBILE;\n }\n // iPadOS-specific detection: identified as Mac, but has some iOS-only properties\n if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {\n _device[MODEL] = 'iPad';\n _device[TYPE] = TABLET;\n }\n return _device;\n };\n this.getEngine = function () {\n var _engine = {};\n _engine[NAME] = undefined;\n _engine[VERSION] = undefined;\n rgxMapper.call(_engine, _ua, _rgxmap.engine);\n return _engine;\n };\n this.getOS = function () {\n var _os = {};\n _os[NAME] = undefined;\n _os[VERSION] = undefined;\n rgxMapper.call(_os, _ua, _rgxmap.os);\n if (_isSelfNav && !_os[NAME] && _uach && _uach.platform != 'Unknown') {\n _os[NAME] = _uach.platform \n .replace(/chrome os/i, CHROMIUM_OS)\n .replace(/macos/i, MAC_OS); // backward compatibility\n }\n return _os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return _ua;\n };\n this.setUA = function (ua) {\n _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;\n return this;\n };\n this.setUA(_ua);\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);\n UAParser.CPU = enumerize([ARCHITECTURE]);\n UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);\n UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);\n\n ///////////\n // Export\n //////////\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (typeof window !== UNDEF_TYPE) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);\n if ($ && !$.ua) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (ua) {\n parser.setUA(ua);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\nimport UAParser from \"ua-parser-js\";\nconst Browser = {\n UNKNOWN: \"Unknown\",\n SAFARI: \"Safari\",\n FIREFOX: \"Firefox\",\n OPERA: \"Opera\",\n CHROME: \"Chrome\",\n IOS_WEBVIEW: \"iOS-webview\"\n};\nclass BrowserUtils {\n static getName() {\n if (!this._name) {\n if (typeof navigator === \"undefined\" || !navigator) {\n this._name = Browser.UNKNOWN;\n } else {\n const { userAgent } = navigator;\n if (userAgent.match(/Firefox/i)) {\n this._name = Browser.FIREFOX;\n } else if (userAgent.match(/(Opera|OPR)/i)) {\n this._name = Browser.OPERA;\n } else if (userAgent.match(/Chrome/i)) {\n this._name = Browser.CHROME;\n } else if (userAgent.match(/Safari/i)) {\n this._name = Browser.SAFARI;\n } else if (userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Version)/i)) {\n this._name = Browser.IOS_WEBVIEW;\n } else {\n this._name = Browser.UNKNOWN;\n }\n }\n }\n return this._name;\n }\n static get isMobile() {\n if (this._isMobile === null) {\n this._isMobile = false;\n if (typeof navigator !== \"undefined\" && navigator) {\n const userAgent = navigator.userAgent || navigator.vendor;\n if (userAgent && (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(userAgent.substr(0, 4)))) {\n this._isMobile = true;\n }\n }\n }\n return this._isMobile;\n }\n static clearCache() {\n this._name = null;\n this._isMobile = null;\n }\n}\n__publicField(BrowserUtils, \"_name\", null);\n__publicField(BrowserUtils, \"_isMobile\", null);\nconst QUALITATIVE_COLORS = [\n 4215763,\n 14529296,\n 11869460,\n 48895,\n 16468400,\n 45661,\n 13290186\n];\nfunction getQualitativeColor(number) {\n return QUALITATIVE_COLORS[number % QUALITATIVE_COLORS.length];\n}\nconst ColorUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n getQualitativeColor\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction getDeviceFromUserAgent() {\n const info = new UAParser().getResult();\n if (!info) {\n return null;\n }\n const res = {\n vendor: info.device.vendor,\n model: info.device.model\n };\n if (!res.vendor && !res.model && info.os.name === \"Mac OS\") {\n res.vendor = \"Apple\";\n res.model = \"Mac\";\n }\n return res;\n}\nconst UserAgentUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n getDeviceFromUserAgent\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction any(promises) {\n return new Promise((resolve, reject) => {\n let count = promises.length, resolved = false;\n const reasons = [];\n promises.forEach((p) => {\n Promise.resolve(p).then((value) => {\n resolved = true;\n count--;\n resolve(value);\n }, (reason) => {\n count--;\n reasons.push(reason);\n if (count === 0 && !resolved) {\n reject(new Error(reasons.join(\"\\n\")));\n }\n });\n });\n });\n}\nconst PromiseUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n any\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction generateString(strLength) {\n return Math.random().toString(36).substring(2, strLength + 2);\n}\nconst RandomUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n generateString\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction formatSO(value, ...xargs) {\n let str = value.toString();\n if (xargs.length) {\n const t = typeof xargs[0];\n const args = t === \"string\" || t === \"number\" ? xargs.slice() : xargs[0];\n for (const key in args) {\n str = str.replace(new RegExp(\"\\\\{\" + key + \"\\\\}\", \"gi\"), args[key]);\n }\n }\n return str;\n}\nconst StringUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n formatSO\n}, Symbol.toStringTag, { value: \"Module\" }));\nfunction preciseTime() {\n if (typeof window !== \"undefined\" && window.performance) {\n return window.performance.now();\n }\n const hrtime = process.hrtime();\n return Math.round(hrtime[0] * 1e3 + hrtime[1] / 1e6);\n}\nfunction unixTimestampToPreciseTime(timestamp) {\n return preciseTime() + timestamp - (/* @__PURE__ */ new Date()).getTime();\n}\nfunction preciseTimeToUnixTimestamp(_preciseTime) {\n return (/* @__PURE__ */ new Date()).getTime() + _preciseTime - preciseTime();\n}\nconst TimeUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n preciseTime,\n preciseTimeToUnixTimestamp,\n unixTimestampToPreciseTime\n}, Symbol.toStringTag, { value: \"Module\" }));\nexport {\n Browser,\n BrowserUtils,\n ColorUtils,\n PromiseUtils,\n RandomUtils,\n StringUtils,\n TimeUtils,\n UserAgentUtils\n};\n//# sourceMappingURL=index.mjs.map\n","import Edge from './Edge.js';\nimport { getDurationFromLength } from '../Utils.js';\nimport { GraphRouterOptionsJson, type GraphRouterOptions } from './GraphRouterOptions.js';\n\nexport default class GraphRouterOptionsBuilder {\n\n public avoidStairs = false;\n public avoidEscalators = false;\n public avoidElevators = false;\n public avoidMovingWalkway = false;\n public avoidTicketRestrictedAreas = false;\n\n public projectionMaxDistance?: number;\n\n static DEFAULT = new GraphRouterOptionsBuilder().build();\n static WITHOUT_STAIRS = new GraphRouterOptionsBuilder().setAvoidStairs(true).build();\n\n setAvoidStairs(avoidStairs: boolean) {\n this.avoidStairs = avoidStairs;\n return this;\n }\n\n setAvoidEscalators(avoidEscalators: boolean) {\n this.avoidEscalators = avoidEscalators;\n return this;\n }\n\n setAvoidElevators(avoidElevators: boolean) {\n this.avoidElevators = avoidElevators;\n return this;\n }\n\n setAvoidMovingWalkway(avoidMovingWalkway: boolean) {\n this.avoidMovingWalkway = avoidMovingWalkway;\n return this;\n }\n\n setAvoidTicketRestrictedAreas(avoidTicketRestrictedAreas: boolean) {\n this.avoidTicketRestrictedAreas = avoidTicketRestrictedAreas;\n return this;\n }\n\n static fromJson(options: GraphRouterOptionsJson) {\n const builder = new GraphRouterOptionsBuilder();\n Object.assign(builder, options);\n return builder.build();\n }\n\n build(): GraphRouterOptions {\n\n const weightEdgeFn = (edge: Edge) => {\n if (edge.properties.isElevator) {\n return 90;\n }\n let duration = getDurationFromLength(edge.length, 4);\n if (edge.properties.areStairs) {\n duration *= 3;\n } else if (edge.properties.areEscalators) {\n duration *= 1.5;\n } else if (edge.properties.isMovingWalkway) {\n duration *= 0.8;\n }\n return duration;\n }\n\n const acceptEdgeFn = (edge: Edge) => {\n\n if (this.avoidStairs && edge.properties.areStairs) return false;\n if (this.avoidEscalators && edge.properties.areEscalators) return false;\n if (this.avoidElevators && edge.properties.isElevator) return false;\n if (this.avoidMovingWalkway && edge.properties.isMovingWalkway) return false;\n if (this.avoidTicketRestrictedAreas && edge.properties.needTicket) return false;\n\n return true;\n };\n\n return {\n input: {\n avoidStairs: this.avoidStairs,\n avoidEscalators: this.avoidEscalators,\n avoidElevators: this.avoidElevators,\n avoidMovingWalkway: this.avoidMovingWalkway,\n avoidTicketRestrictedAreas: this.avoidTicketRestrictedAreas,\n projectionMaxDistance: this.projectionMaxDistance\n },\n weightEdgeFn,\n acceptEdgeFn,\n projectionMaxDistance: this.projectionMaxDistance\n };\n }\n\n}\n","\nimport { ColorUtils } from '@wemap/utils';\nimport Edge from './Edge.js';\nimport Graph from './Graph.js';\nimport GraphRoute from './GraphRoute.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\nimport Vertex from './Vertex.js';\n\nexport class GraphRouterEngineResults {\n constructor(\n public prev: Array<Vertex | null>,\n public dist: number[],\n public source: Vertex,\n public targets: Vertex[],\n public edges: Edge[]\n ) { }\n\n routeVertices(to = this.targets[0], list: Vertex[] = []): Vertex[] {\n const last = this.prev[to.id];\n if (last === null) return this.source === to ? [...list, to] : [];\n return [...this.routeVertices(last, list), to];\n }\n\n weightedDistance(to = this.targets[0]) {\n const distance = this.dist[to.id];\n return distance === Number.MAX_VALUE ? null : distance;\n }\n\n route(to = this.targets[0]) {\n\n const path = this.routeVertices(to);\n\n const edges = [];\n const edgesWeights = [];\n for (let i = 1; i < path.length; i++) {\n const v1 = path[i - 1];\n const v2 = path[i];\n const graphEdge = Edge.getEdgeByVertices(this.edges, v1, v2)!;\n const clonedEdge = new Edge(v1, v2, Object.assign({}, graphEdge.properties));\n const isReversed = graphEdge.vertex1 === clonedEdge.vertex2;\n if (isReversed) {\n clonedEdge.reverseProperties();\n }\n edges.push(clonedEdge);\n edgesWeights.push(this.dist[v2.id] - this.dist[v1.id]);\n }\n return new GraphRoute(this.source.coords, to.coords, path, edges, edgesWeights);\n }\n\n toGeoJson(graph: Graph) {\n return {\n type: \"FeatureCollection\",\n features: [\n ...graph.vertices.map(v => {\n const prev = this.prev[v.id];\n const dist = this.dist[v.id];\n const isSource = v === this.source;\n const isTarget = this.targets.includes(v);\n const level = v.coords.level;\n return {\n type: \"Feature\",\n properties: {\n id: v.id,\n ...(prev && { prev: prev.id }),\n dist: dist === Number.MAX_VALUE ? 'infinity' : dist,\n ...(isSource && { name: 'source' }),\n ...(isTarget && { name: 'target' }),\n ...(level !== null && { level }),\n ...v.properties\n },\n geometry: {\n type: 'Point',\n coordinates: [v.coords.lng, v.coords.lat]\n }\n }\n }),\n ...graph.edges.map(e => {\n const level = e.level;\n return {\n type: \"Feature\",\n properties: {\n id: e.id,\n ...(level !== null && { level }),\n ...e.properties\n },\n geometry: {\n type: 'LineString',\n coordinates: [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat]\n ]\n }\n }\n })\n ]\n };\n }\n}\n\nexport default class GraphRouterEngine {\n\n disabledEdges: Set<Edge> = new Set();\n\n constructor(public readonly graph: Graph) {\n let vertexId = 0;\n graph.vertices.forEach(vertex => vertex.id = vertexId++);\n }\n\n calculateShortestPathToMultipleDestinationsByVertex(\n source: Vertex,\n targets: Vertex[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n\n const q = new Set(inputVertices);\n const dist = Array(q.size).fill(Number.MAX_VALUE);\n const prev = new Array<Vertex | null>(q.size).fill(null);\n const edges = inputEdges.filter(e => (options.acceptEdgeFn?.(e) ?? true) && !this.disabledEdges.has(e));\n const weightEdgeFn = options.weightEdgeFn || ((edge: Edge) => edge.length);\n\n const getVertexWithMinDistance = (vertices: Set<Vertex>): Vertex | null => {\n let minDistance = Number.MAX_VALUE;\n let vertex: Vertex | null = null;\n vertices.forEach(_vertex => {\n const distance = dist[_vertex.id];\n if (distance <= minDistance) {\n minDistance = distance;\n vertex = _vertex;\n }\n });\n return vertex;\n }\n\n\n const remainingNodesToFind = new Set(targets);\n\n dist[source.id] = 0;\n\n while (q.size > 0) {\n const u = getVertexWithMinDistance(q)!;\n q.delete(u);\n\n if (targets.includes(u)) {\n remainingNodesToFind.delete(u);\n if (remainingNodesToFind.size === 0) {\n break;\n }\n }\n\n edges\n .filter(edge => edge.vertex1 == u || !edge.properties.isOneway && edge.vertex2 == u)\n .forEach(edge => {\n const v = u === edge.vertex1 ? edge.vertex2 : edge.vertex1;\n const distance = weightEdgeFn(edge);\n const alt = dist[u.id] + distance;\n if (alt < dist[v.id]) {\n dist[v.id] = alt;\n prev[v.id] = u\n }\n });\n }\n\n return new GraphRouterEngineResults(prev, dist, source, targets, edges);\n }\n\n calculateShortestPathByVertex(\n source: Vertex,\n target: Vertex,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n inputVertices = this.graph.vertices,\n inputEdges = this.graph.edges\n ): GraphRouterEngineResults {\n return this.calculateShortestPathToMultipleDestinationsByVertex(source, [target], options, inputVertices, inputEdges);\n }\n\n // https://en.wikipedia.org/wiki/Component_(graph_theory)\n calculateComponents() {\n\n function shiftSet<T>(set: Set<T>): T {\n const firstValue = set.values().next().value as T;\n set.delete(firstValue);\n return firstValue;\n }\n\n const verticesToTest = new Set<Vertex>(this.graph.vertices);\n let components: Vertex[][] = [];\n\n while (verticesToTest.size > 0) {\n const vertexToTest = shiftSet(verticesToTest);\n const otherVertices = this.graph.vertices.filter(v => v.id !== vertexToTest.id);\n const result = this.calculateShortestPathToMultipleDestinationsByVertex(vertexToTest, otherVertices);\n const reachedVertices = otherVertices.filter(ov => result.weightedDistance(ov) !== null);\n\n components.push([vertexToTest, ...reachedVertices]);\n reachedVertices.forEach(rv => verticesToTest.delete(rv));\n }\n\n // As graph is ordered, fuse components with same vertices\n let hasChanged;\n do {\n hasChanged = false;\n for (let i = 0; i < components.length - 1; i++) {\n const component1 = components[i];\n for (let j = i + 1; j < components.length; j++) {\n const component2 = components[j];\n const componentsIntersect = component2.some(v => component1.includes(v));\n if (componentsIntersect) {\n component1.push(...component2);\n components = components.filter(component => component !== component2);\n hasChanged = true;\n }\n }\n }\n } while (hasChanged)\n\n return components.map(c => [... new Set(c)]);\n }\n\n toGeoJson() {\n const components = this.calculateComponents();\n const features = components.map((component, i) => {\n const edges = this.graph.edges.filter(edge => component.includes(edge.vertex1) && component.includes(edge.vertex2));\n return {\n \"type\": \"Feature\",\n \"geometry\": {\n \"type\": \"MultiLineString\",\n \"coordinates\":\n edges.map(e => [\n [e.vertex1.coords.lng, e.vertex1.coords.lat],\n [e.vertex2.coords.lng, e.vertex2.coords.lat],\n ])\n },\n \"properties\": {\n \"stroke\": '#' + ColorUtils.getQualitativeColor(i).toString(16)\n }\n }\n });\n\n return {\n \"type\": \"FeatureCollection\",\n \"features\": features\n };\n }\n\n}\n","import salesman from '@wemap/salesman.js';\n\nimport { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\nimport Edge, { EdgeProperties } from './Edge.js';\nimport GraphRoute from './GraphRoute.js';\nimport GraphRouterEngine, { GraphRouterEngineResults } from './GraphRouterEngine.js';\nimport { type GraphRouterOptions } from './GraphRouterOptions.js';\nimport GraphRouterOptionsBuilder from './GraphRouterOptionsBuilder.js';\n\nexport class GraphRouterResults extends GraphRouterEngineResults {\n\n constructor(\n engineResults: GraphRouterEngineResults,\n public sourceProjection: [Coordinates, Vertex | null],\n public targetsProjections: [Coordinates, Vertex | null][]\n\n ) {\n super(engineResults.prev, engineResults.dist, engineResults.source, engineResults.targets, engineResults.edges);\n }\n\n static createEmpty(source: Coordinates, targets: Coordinates[]) {\n const length = targets.length;\n const engineResults = new GraphRouterEngineResults(\n new Array(length).fill(null),\n new Array(length).fill(Number.MAX_VALUE),\n new Vertex(source),\n targets.map(target => new Vertex(target)),\n []\n );\n const sourceProjection: [Coordinates, null] = [source, null];\n const targetsProjections: [Coordinates, null][] = targets.map(target => [target, null]);\n return new GraphRouterResults(engineResults, sourceProjection, targetsProjections);\n }\n\n routeVertices(to: Coordinates | Vertex = this.targetsProjections[0][0]): Vertex[] {\n\n if (to instanceof Vertex) {\n return super.routeVertices(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return [];\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return [];\n\n return super.routeVertices(toVertex);\n }\n\n weightedDistance(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.weightedDistance(to);\n }\n\n const sourceVertex = this.sourceProjection[1];\n if (!sourceVertex) return null;\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return null;\n\n return super.weightedDistance(toVertex);\n }\n\n route(to: Coordinates | Vertex = this.targetsProjections[0][0]) {\n\n if (to instanceof Vertex) {\n return super.route(to);\n }\n\n const toVertex = this.targetsProjections.find(([coord]) => coord === to)?.[1];\n if (!toVertex) return new GraphRoute(this.sourceProjection[0], to, [], [], []);\n\n const route = super.route(toVertex);\n route.start = this.sourceProjection[0];\n route.end = to;\n return route;\n }\n}\n\n\nclass GraphRouter extends GraphRouterEngine {\n\n calculateShortestPathToMultipleDestinations(\n source: Coordinates,\n targets: Coordinates[],\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n\n const createdVertices = new Set<Vertex>();\n const createdEdges = new Set<Edge>();\n const createdVerticesByOriginalEdges: [Edge, Vertex[]][] = []\n\n const projectionsOptions = {\n maxDistance: options.projectionMaxDistance,\n acceptEdgeFn: options.acceptEdgeFn\n };\n\n const getOrCreateVertex = (coords: Coordinates): Vertex | null => {\n const projection = this.graph.getProjection(coords, projectionsOptions);\n if (projection === null) return null;\n if (projection.nearestElement instanceof Vertex) {\n return projection.nearestElement;\n }\n if (projection.nearestElement instanceof Edge) {\n const edge = projection.nearestElement;\n const newVertex = new Vertex(projection.coords, {\n name: `proj on ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n });\n newVertex.id = this.graph.vertices.length + createdVertices.size;\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n ...(typeof edge.properties.externalId !== 'undefined' && { externalId: edge.properties.externalId })\n };\n const newEdge1 = new Edge(edge.vertex1, newVertex, newEdgesOptions);\n const newEdge2 = new Edge(newVertex, edge.vertex2, newEdgesOptions);\n\n createdVertices.add(newVertex);\n createdEdges.add(newEdge1);\n createdEdges.add(newEdge2);\n\n const createdVerticesByOriginalEdge = createdVerticesByOriginalEdges.find(p => p[0] === edge)\n if (!createdVerticesByOriginalEdge) {\n createdVerticesByOriginalEdges.push([edge, [newVertex]])\n } else {\n createdVerticesByOriginalEdge[1].push(newVertex);\n }\n return newVertex;\n }\n\n return null; // Should never happens\n }\n\n const sourceVertex = getOrCreateVertex(source);\n if (!sourceVertex) return GraphRouterResults.createEmpty(source, targets);\n\n const targetsProjections: [Coordinates, Vertex | null][] = targets.map(target => [target, getOrCreateVertex(target)]);\n const targetsVertices = targetsProjections.map(([, vertex]) => vertex).filter(p => p !== null) as Vertex[];\n\n // In some specific cases, more than one vertex is created from an original edge.\n // And this vertices need to be connected together.\n createdVerticesByOriginalEdges.filter(pair => pair[1].length >= 2);\n createdVerticesByOriginalEdges.forEach(([edge, vertices]) => {\n const newEdgesOptions: EdgeProperties = {\n ...edge.properties,\n name: `splitted ${edge.properties.name || null} (tmp)`,\n };\n for (let i = 0; i < vertices.length; i++) {\n const vertexA = vertices[i];\n const distVertexAVertex1 = vertexA.distanceTo(edge.vertex1)\n for (let j = i + 1; j < vertices.length; j++) {\n const vertexB = vertices[j];\n const distVertexBVertex1 = vertexB.distanceTo(edge.vertex1)\n const reverse = distVertexBVertex1 < distVertexAVertex1;\n const newEdge = !reverse\n ? new Edge(vertexA, vertexB, newEdgesOptions)\n : new Edge(vertexB, vertexA, newEdgesOptions);\n createdEdges.add(newEdge);\n }\n }\n })\n\n\n const engineResults = this.calculateShortestPathToMultipleDestinationsByVertex(\n sourceVertex, targetsVertices, options,\n [...this.graph.vertices, ...createdVertices],\n [...this.graph.edges, ...createdEdges],\n );\n\n return new GraphRouterResults(engineResults, [source, sourceVertex], targetsProjections);\n }\n\n calculateShortestPath(\n source: Coordinates,\n target: Coordinates,\n options: GraphRouterOptions = GraphRouterOptionsBuilder.DEFAULT,\n ): GraphRouterResults {\n return this.calculateShortestPathToMultipleDestinations(source, [target], options);\n }\n\n\n // TODO: Verify if it works well with oneway edges\n getShortestTrip(waypoints: Coordinates[], options?: GraphRouterOptions, tspTempCoeff = 0.99) {\n type CustomPoint = salesman.Point & { coords: Coordinates };\n\n const points = waypoints.map(waypoint => {\n const point = new salesman.Point(0, 0) as CustomPoint;\n point.coords = waypoint;\n return point;\n });\n const graphRoutesCache: GraphRoute[] = [];\n const solution = salesman.solve(points, tspTempCoeff, undefined, (p: salesman.Point, q: salesman.Point) => {\n const route = this.calculateShortestPath(\n (p as CustomPoint).coords,\n (q as CustomPoint).coords,\n options\n ).route();\n graphRoutesCache.push(route);\n if (!route.hasRoute) { return Number.MAX_VALUE }\n return route.edgesWeights.reduce((acc, weight) => acc + weight, 0);\n });\n\n const orderedPoints = solution.map(i => points[i]);\n const orderedRoutes = [];\n for (let i = 0; i < orderedPoints.length; i++) {\n const p = orderedPoints[i] as CustomPoint;\n const q = orderedPoints[(i + 1) % orderedPoints.length] as CustomPoint;\n let cachedRoute = graphRoutesCache.find(route => route.start === p.coords && route.end === q.coords || route.end === p.coords && route.start === q.coords);\n if (cachedRoute?.end === p.coords) {\n // Need to revert route due to salesman bijectivity\n cachedRoute = cachedRoute.reverse();\n }\n if (cachedRoute) {\n orderedRoutes.push(cachedRoute);\n }\n }\n\n if (orderedRoutes.some(route => !route.hasRoute)) return [];\n\n return orderedRoutes;\n }\n\n\n}\nexport default GraphRouter;\n","import { Coordinates } from '@wemap/geo';\n\nimport Vertex from './Vertex.js';\n\nclass NoRouteFoundError extends Error {\n\n constructor(\n public start: Vertex | Coordinates,\n public end: Vertex | Coordinates | (Coordinates | Vertex)[],\n public details: string | null = null\n ) { super(); }\n\n get startStr() {\n if (this.start instanceof Vertex) {\n return `Vertex ${this.start.coords.toString()}`;\n }\n return this.start.toString();\n }\n\n get endStr() {\n if (this.end instanceof Vertex) {\n return `Vertex ${this.end.coords.toString()}`;\n }\n if (Array.isArray(this.end)) {\n return this.end.map(p => p instanceof Vertex ? p.coords.toString() : p.toString()).join(',');\n }\n return this.end.toString();\n }\n\n get message() {\n let message = `No route found from ${this.startStr} to ${this.endStr}.`;\n if (this.details) {\n message += ` Details: ${this.details}`;\n }\n return message;\n }\n}\n\nexport default NoRouteFoundError;\n","import { Coordinates, Level, Level_t } from '@wemap/geo';\nimport { OsmModel, OsmNode, OsmWay } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport { default as Edge, type EdgeProperties } from '../graph/Edge.js';\nimport { default as Vertex, type VertexProperties } from '../graph/Vertex.js';\n\n\nexport default class OsmGraphUtils {\n\n static RESTRICTED_PEDESTRIANS_HIGHWAYS = ['motorway', 'motorway_link'];\n\n static DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n if (way.isArea) return false;\n if (way.tags.foot === 'yes') return true;\n if (['no', 'private'].includes(way.tags.access)) return false;\n\n const isElevatorArea = way.tags.highway === 'elevator' && way.isGeometryClosed\n return way.tags.highway && !OsmGraphUtils.RESTRICTED_PEDESTRIANS_HIGHWAYS.includes(way.tags.highway) && !isElevatorArea\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n };\n\n static parseNodeProperties(osmNode: OsmNode): VertexProperties {\n return {\n ...(osmNode.name && { name: osmNode.name }),\n ...(osmNode.id && { externalId: osmNode.id }),\n ...(osmNode.isGate && { isGate: osmNode.isGate }),\n ...(osmNode.isSubwayEntrance && { isSubwayEntrance: osmNode.isSubwayEntrance }),\n ...(osmNode.subwayEntranceRef && { subwayEntrsanceRef: osmNode.subwayEntranceRef })\n }\n }\n\n static parseWayProperties(osmWay: OsmWay): EdgeProperties {\n return {\n ...(osmWay.name && { name: osmWay.name }),\n ...(osmWay.id && { externalId: osmWay.id }),\n ...(osmWay.isOneway && { isOneway: osmWay.isOneway }),\n ...(osmWay.areStairs && { areStairs: osmWay.areStairs }),\n ...(osmWay.isElevator && { isElevator: osmWay.isElevator }),\n ...(osmWay.areEscalators && { areEscalators: osmWay.areEscalators }),\n ...(osmWay.isMovingWalkway && { isMovingWalkway: osmWay.isMovingWalkway }),\n ...(osmWay.needTicket && { needTicket: osmWay.needTicket }),\n ...(osmWay.incline && { incline: osmWay.incline })\n }\n }\n\n static createGraphFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = OsmGraphUtils.DEFAULT_WAY_SELECTOR,\n callbackVerticesMapping?: (mapping: [nodeId: number, vertex: Vertex][]) => void\n ) {\n\n const edges: Edge[] = [];\n const verticesMapping: [nodeId: number, vertex: Vertex][] = [];\n const elevatorVertices: [id: number, name: string | undefined, vertices: Vertex[]][] = [];\n\n // 1. Create a function to retrieve a vertex which has already been created and avoid duplicates\n const getOrCreateVertex = (osmNode: OsmNode, nodeLevel: Level_t) => {\n\n // Check if a vertex with same coordinates already exists\n let vertex: Vertex | null = verticesMapping\n .find(([nodeId, v]) => {\n if (nodeId !== osmNode.id) return false;\n if (Level.intersect(v.coords.level, nodeLevel)) return true;\n // Specific case of exits\n return v.coords.level === null || nodeLevel === null;\n })?.[1] || null;\n\n // If the vertex already exists, return it\n if (vertex) {\n // In the case where vertices are linked to edges with level change\n if (!Level.equals(vertex.coords.level, nodeLevel)) {\n vertex.coords.level = Level.intersection(vertex.coords.level, nodeLevel) || nodeLevel;\n }\n return vertex;\n }\n\n // If it does not exist, create it\n const newCoords = new Coordinates(osmNode.coords.lat, osmNode.coords.lng, null, nodeLevel)\n vertex = new Vertex(newCoords, this.parseNodeProperties(osmNode));\n\n verticesMapping.push([osmNode.id, vertex]);\n\n if (osmNode.isElevator) {\n let elevatorEntry = elevatorVertices.find(([id]) => osmNode.id === id);\n if (!elevatorEntry) {\n elevatorEntry = [osmNode.id, osmNode.name, []];\n elevatorVertices.push(elevatorEntry);\n }\n elevatorEntry[2].push(vertex);\n }\n\n return vertex;\n };\n\n // 2. Go through OSM ways to create edges and vertices\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n const edgeProperties = this.parseWayProperties(way);\n\n const processWayForLevel = (_level: Level_t) => {\n for (let i = 1; i < way.nodes.length; i++) {\n\n let firstVertex = getOrCreateVertex(way.nodes[i - 1], _level);\n let secondVertex = getOrCreateVertex(way.nodes[i], _level);\n\n if (way.isOnewayBackward) {\n const tmpVertex = secondVertex;\n secondVertex = firstVertex;\n firstVertex = tmpVertex;\n }\n\n const edge = new Edge(firstVertex, secondVertex, edgeProperties);\n edges.push(edge);\n }\n }\n\n processWayForLevel(way.level);\n if ('repeat_on' in way.tags) {\n way.tags.repeat_on.split(';').map(Level.fromString).forEach(processWayForLevel);\n }\n\n });\n\n // 3. Manage elevators without explicit navigation graph inside.\n // It creates a graph from entries to the center of the elevator shape.\n let fakeOsmNodeId = -1;\n osmModel.ways\n .filter(way => way.isElevator)\n .forEach(way => {\n const entryVertices = way.nodes.map(node => verticesMapping.filter(([osmId]) => osmId === node.id).map(vm => vm[1])).flat();\n\n // Horrible method but works for macro-problems\n const elevatorCenter = way.nodes\n .reduce((acc, node) => [acc[0] + node.coords.lat, acc[1] + node.coords.lng], [0, 0])\n .map(val => val / way.nodes.length);\n const elevatorLevel = entryVertices.reduce((acc, v) => Level.union(acc, v.coords.level), null as Level_t);\n const elevatorCenterCoords = new Coordinates(elevatorCenter[0], elevatorCenter[1], null, elevatorLevel);\n\n const elevatorCenterFakeOsmNode = new OsmNode(fakeOsmNodeId--, elevatorCenterCoords, { highway: 'elevator' });\n\n entryVertices.forEach(entryVertex => {\n const vertexCenter = getOrCreateVertex(elevatorCenterFakeOsmNode, entryVertex.coords.level);\n edges.push(new Edge(vertexCenter, entryVertex, { externalId: way.id }));\n })\n });\n\n\n // 4. Link elevators vertices\n elevatorVertices.forEach(([id, name, verticesOfEachLevel]) => {\n const elevatorEdgeProps = { name, isElevator: true, externalId: id };\n // Link vertices of each level together\n for (let i = 0; i < verticesOfEachLevel.length; i++) {\n for (let j = i + 1; j < verticesOfEachLevel.length; j++) {\n edges.push(new Edge(verticesOfEachLevel[i], verticesOfEachLevel[j], elevatorEdgeProps));\n }\n }\n });\n\n callbackVerticesMapping?.(verticesMapping);\n\n return new Graph(verticesMapping.map(v => v[1]), edges);\n }\n\n}","import { RouterRequest } from '../model/RouterRequest.js';\nimport Itinerary from '../model/Itinerary.js';\n\nabstract class RemoteRouter {\n\n /**\n * Get the router name\n */\n abstract get rname(): string;\n\n abstract getItineraries(endpointUrl: string, routerRequest: RouterRequest): Promise<Itinerary[]>;\n\n}\n\nexport default RemoteRouter;\n","// https://developers.google.com/actions-center/reference/grpc-api/status_codes\nexport enum StatusCode {\n OK = 0,\n CANCELLED = 1,\n UNKNOWN = 2,\n INVALID_ARGUMENT = 3,\n NOT_FOUND = 5,\n UNIMPLEMENTED = 12,\n INTERNAL = 13,\n UNAVAILABLE = 14\n}","// Based on GRPC status code\n\nimport { StatusCode } from \"./StatusCode\";\nimport { TravelMode } from \"./model/TravelMode\";\n\n\nexport class RoutingError extends Error {\n\n public customMapName?: string | null;\n\n constructor(public code = StatusCode.UNKNOWN, message?: string) {\n super(message)\n }\n\n static notFound(details?: string) {\n return new RoutingError(StatusCode.NOT_FOUND, `Cannot found an itinerary. Details: ${details}`)\n }\n}\n\n\nexport class WemapMultiRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public mapName: string | null, message?: string) {\n super(code, message);\n this.mapName = mapName;\n }\n\n static notFound(mapName: string, details?: string) {\n return new WemapMultiRoutingError(StatusCode.NOT_FOUND, mapName, `Cannot found an itinerary in map ${mapName}. Details: ${details}`)\n }\n\n}\n\nexport class RemoteRoutingError extends RoutingError {\n \n constructor(public code = StatusCode.UNKNOWN, public routerName: string, message?: string) {\n super(code, message);\n this.routerName = routerName;\n }\n\n static notFound(routerName: string, details?: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Cannot found an itinerary with ${routerName}. Details: ${details}`)\n }\n\n static unreachableServer(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server ${routerName} is unreachable. URL: ${url}`)\n }\n\n static responseNotParsing(routerName: string, url: string) {\n return new RemoteRoutingError(StatusCode.NOT_FOUND, routerName, `Remote router server response ${routerName} cannot be parsed. URL: ${url}`)\n }\n\n static travelModeUnimplemented(routerName: string, travelMode: TravelMode) {\n return new RemoteRoutingError(StatusCode.UNIMPLEMENTED, routerName, `Travel mode \"${travelMode}\" is not implemented for ${routerName}`)\n }\n}","import { RoutingError } from \"../RoutingError\";\n\n/**\n * Create and return a date with a given timezone\n * timeZone - timezone name (e.g. 'Europe/Paris')\n */\nexport function dateWithTimeZone(\n year: number, month: number, day: number,\n hour: number, minute: number, second: number,\n timeZone = 'Europe/Paris'\n) {\n const date = new Date(Date.UTC(year, month, day, hour, minute, second));\n\n const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));\n const offset = utcDate.getTime() - tzDate.getTime();\n\n date.setTime(date.getTime() + offset);\n\n return date;\n}\n\nexport function isRoutingError(e: unknown): e is Error {\n return e instanceof RoutingError;\n}\n","import { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport { TransitMode, isTransitModePublicTransport } from '../../model/TransitMode.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype CitywayCoordinates = { Lat: number, Long: number };\ntype CitywayLeg = {\n TransportMode: string,\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Name: string,\n Position: CitywayCoordinates\n },\n StopPlace: {\n Name: string,\n Position: CitywayCoordinates\n }\n },\n Line: {\n Name: string,\n Number: string,\n Color: string,\n TextColor: string,\n },\n Destination: string,\n Distance: number,\n steps: {\n Step: {\n Geometry: string\n }[]\n },\n pathLinks: {\n PathLink: {\n Departure: {\n Site: {\n Name: string\n }\n },\n Distance: number,\n Geometry: string | 'Null'\n }[]\n }\n};\ntype CitywayJson = {\n StatusCode: number,\n Message: string,\n Data: {\n response: {\n trips: {\n Trip: {\n Duration: string,\n Departure: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n Arrival: {\n Time: string,\n Site: {\n Position: CitywayCoordinates\n }\n },\n sections: {\n Section: {\n Leg?: CitywayLeg,\n PTRide: CitywayLeg\n }[]\n }\n }[]\n }\n },\n PlanTripType?: string\n }[],\n};\n\n\n\nfunction jsonToCoordinates(json: CitywayCoordinates) {\n return new Coordinates(json.Lat, json.Long);\n}\n\nfunction jsonDateToTimestamp(jsonDate: string) {\n const [dateStr, timeStr] = jsonDate.split(' ');\n const [dayStr, monthStr, yearStr] = dateStr.split('/');\n const [hoursStr, minutesStr, secondsStr] = timeStr.split(':');\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr)\n ).getTime();\n}\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'Car');\ninputModeCorrespondance.set('WALK', 'Walk');\ninputModeCorrespondance.set('BIKE', 'Bike');\ninputModeCorrespondance.set('TRANSIT', 'PT');\n\n\n/**\n * List of all routing modes supported by the API\n */\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('WALK', 'WALK');\ntransitModeCorrespondance.set('BICYCLE', 'BIKE');\ntransitModeCorrespondance.set('TRAMWAY', 'TRAM');\ntransitModeCorrespondance.set('METRO', 'METRO');\ntransitModeCorrespondance.set('FUNICULAR', 'FUNICULAR');\ntransitModeCorrespondance.set('BUS', 'BUS');\ntransitModeCorrespondance.set('COACH', 'BUS');\ntransitModeCorrespondance.set('SCHOOL', 'BUS');\ntransitModeCorrespondance.set('BUS_PMR', 'BUS');\ntransitModeCorrespondance.set('MINIBUS', 'BUS');\ntransitModeCorrespondance.set('TROLLEY_BUS', 'BUS');\ntransitModeCorrespondance.set('TAXIBUS', 'BUS');\ntransitModeCorrespondance.set('SHUTTLE', 'BUS');\ntransitModeCorrespondance.set('TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('HST', 'TRAIN');\ntransitModeCorrespondance.set('LOCAL_TRAIN', 'TRAIN');\ntransitModeCorrespondance.set('AIR', 'AIRPLANE');\ntransitModeCorrespondance.set('FERRY', 'BOAT');\ntransitModeCorrespondance.set('TAXI', 'UNKNOWN');\ntransitModeCorrespondance.set('CAR_POOL', 'UNKNOWN');\ntransitModeCorrespondance.set('PRIVATE_VEHICLE', 'CAR');\ntransitModeCorrespondance.set('SCOOTER', 'MOTO');\n\n/**\n * List of all plan trip supported by the API\n * Routing mode UNKNOWN means that the itinerary will not be parsed by the router\n */\nconst planTripType = new Map();\nplanTripType.set(0, 'BUS');\nplanTripType.set(1, 'WALK');\nplanTripType.set(2, 'BIKE');\nplanTripType.set(3, 'CAR');\nplanTripType.set(4, 'UNKNOWN');\nplanTripType.set(5, 'UNKNOWN');\nplanTripType.set(6, 'UNKNOWN');\nplanTripType.set(7, 'UNKNOWN');\nplanTripType.set(8, 'UNKNOWN');\nplanTripType.set(9, 'UNKNOWN');\nplanTripType.set(10, 'UNKNOWN');\nplanTripType.set(11, 'UNKNOWN');\nplanTripType.set(12, 'UNKNOWN');\nplanTripType.set(13, 'UNKNOWN');\nplanTripType.set(14, 'UNKNOWN');\n\nfunction parseWKTGeometry(wktGeometry: string) {\n const tmpCoordsStr = wktGeometry.match(/LINESTRING ?\\((.*)\\)/i);\n const tmpCoordsPt = wktGeometry.match(/POINT ?\\((.*)\\)/i);\n\n if (tmpCoordsPt) {\n const [lng, lat] = tmpCoordsPt[1].split(' ');\n return [new Coordinates(Number(lat), Number(lng))];\n }\n\n return (tmpCoordsStr as RegExpMatchArray)[1].split(',').map(str => {\n const sp = str.trim().split(' ');\n return new Coordinates(Number(sp[1]), Number(sp[0]));\n });\n}\n\n/**\n * Singleton.\n */\nclass CitywayRemoteRouter extends RemoteRouter {\n\n get rname() { return 'cityway' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n\n const { origin, destination, travelMode, waypoints } = routerRequest;\n const citywayMode = inputModeCorrespondance.get(travelMode);\n if (!citywayMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `DepartureLatitude=${origin.latitude}&DepartureLongitude=${origin.longitude}`;\n const toPlace = `ArrivalLatitude=${destination.latitude}&ArrivalLongitude=${destination.longitude}`;\n const queryMode = `TripModes=${citywayMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n /**\n * Generate multi itineraries from Cityway JSON\n * @example https://preprod.api.lia2.cityway.fr/journeyplanner/api/opt/PlanTrips/json?DepartureLatitude=49.51509388236216&DepartureLongitude=0.09341749619366316&ArrivalLatitude=49.5067090188444&ArrivalLongitude=0.1694842115417831&DepartureType=COORDINATES&ArrivalType=COORDINATES\n */\n parseResponse(json: CitywayJson) {\n\n if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {\n throw RemoteRoutingError.notFound(this.rname, json.Message);\n }\n\n const itineraries = [];\n\n const allJsonTrips = json.Data.map(dataObj =>\n dataObj.response.trips.Trip.map(trip => ({\n ...trip,\n ...(dataObj.hasOwnProperty('PlanTripType') && { PlanTripType: dataObj.PlanTripType })\n }))\n ).flat();\n\n // eslint-disable-next-line no-labels\n itineraryLoop:\n for (const trip of allJsonTrips) {\n\n if (trip.hasOwnProperty('PlanTripType') && planTripType.get(trip.PlanTripType) === 'UNKNOWN') {\n continue;\n }\n\n const legs = []\n for (const jsonSection of trip.sections.Section) {\n\n const jsonLeg = jsonSection.Leg ? jsonSection.Leg : jsonSection.PTRide;\n\n const legMode = transitModeCorrespondance.get(jsonLeg.TransportMode)!;\n const legCoords: Coordinates[] = [];\n let legStart, legEnd;\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder();\n\n if (legMode === 'UNKNOWN') {\n // eslint-disable-next-line\n continue itineraryLoop;\n }\n\n if (legMode === 'WALK'\n || legMode === 'BIKE'\n || legMode === 'CAR') {\n\n legStart = {\n name: jsonLeg.Departure.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.Site.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)\n };\n\n for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {\n let stepCoords;\n // jsonPathLink.Geometry is either a POINT or a LINESTRING\n // or it can also be 'Null' as string\n if (jsonPathLink.Geometry && jsonPathLink.Geometry !== 'Null') {\n stepCoords = parseWKTGeometry(jsonPathLink.Geometry);\n } else {\n stepCoords = [legStart.coords, legEnd.coords];\n }\n\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n\n stepsBuilder.addStepInfo({\n coords: stepCoords[0],\n distance: jsonPathLink.Distance,\n name: jsonPathLink.Departure.Site.Name\n });\n }\n\n // If it's last leg, create a last step because cityway doesn't use the end of itinerary as step\n if (jsonSection === trip.sections.Section[trip.sections.Section.length - 1]) {\n stepsBuilder.addStepInfo({\n coords: legCoords[legCoords.length - 1]\n });\n }\n\n } else if (isTransitModePublicTransport(legMode)) {\n\n legStart = {\n name: jsonLeg.Departure.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)\n };\n legEnd = {\n name: jsonLeg.Arrival.StopPlace.Name,\n coords: jsonToCoordinates(jsonLeg.Arrival.StopPlace.Position)\n };\n\n let transportName = jsonLeg.Line.Number;\n if (legMode === 'TRAM' && transportName.toLowerCase().includes('tram')) {\n // In order to remove the \"TRAM \" prefix.\n transportName = transportName.substr(5);\n }\n\n transportInfo = {\n name: transportName,\n routeColor: jsonLeg.Line.Color,\n routeTextColor: jsonLeg.Line.TextColor,\n directionName: jsonLeg.Destination\n };\n\n for (const jsonStep of jsonLeg.steps.Step) {\n const stepCoords = parseWKTGeometry(jsonStep.Geometry);\n stepCoords.forEach((coords, idx) => {\n if (\n idx !== 0\n || legCoords.length === 0\n || !legCoords[legCoords.length - 1].equals(coords)\n ) {\n legCoords.push(coords);\n }\n });\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.Line.Name,\n distance: jsonLeg.Distance,\n });\n } else {\n Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);\n continue;\n }\n\n stepsBuilder.setStart(legStart.coords);\n stepsBuilder.setEnd(legEnd.coords);\n stepsBuilder.setPathCoords(legCoords);\n\n const leg = new Leg({\n transitMode: legMode,\n duration: this.parseDuration(jsonLeg.Duration),\n startTime: jsonDateToTimestamp(jsonLeg.Departure.Time),\n endTime: jsonDateToTimestamp(jsonLeg.Arrival.Time),\n coords: legCoords,\n start: legStart,\n end: legEnd,\n transportInfo,\n steps: stepsBuilder.build()\n });\n\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: this.parseDuration(trip.Duration),\n startTime: jsonDateToTimestamp(trip.Departure.Time),\n origin: jsonToCoordinates(trip.Departure.Site.Position),\n endTime: jsonDateToTimestamp(trip.Arrival.Time),\n destination: jsonToCoordinates(trip.Arrival.Site.Position),\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n\n\n /**\n * @param {string} iso8601Duration\n * @see https://stackoverflow.com/a/29153059/2239938\n */\n parseDuration(iso8601Duration: string) {\n const iso8601DurationRegex = /(-)?P(?:([.,\\d]+)Y)?(?:([.,\\d]+)M)?(?:([.,\\d]+)W)?(?:([.,\\d]+)D)?T(?:([.,\\d]+)H)?(?:([.,\\d]+)M)?(?:([.,\\d]+)S)?/;\n\n const matches = iso8601Duration.match(iso8601DurationRegex)!;\n\n // const sign = typeof matches[1] === 'undefined' ? '+' : '-',\n const years = typeof matches[2] === 'undefined' ? 0 : Number(matches[2]);\n const months = typeof matches[3] === 'undefined' ? 0 : Number(matches[3]);\n const weeks = typeof matches[4] === 'undefined' ? 0 : Number(matches[4]);\n const days = typeof matches[5] === 'undefined' ? 0 : Number(matches[5]);\n const hours = typeof matches[6] === 'undefined' ? 0 : Number(matches[6]);\n const minutes = typeof matches[7] === 'undefined' ? 0 : Number(matches[7]);\n const seconds = typeof matches[8] === 'undefined' ? 0 : Number(matches[8]);\n\n return seconds\n + minutes * 60\n + hours * 3600\n + days * 86400\n + weeks * (86400 * 7)\n + months * (86400 * 30)\n + years * (86400 * 365.25);\n }\n}\n\nexport default new CitywayRemoteRouter();","import { Coordinates, Level } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg from '../../model/Leg.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype DBJson = {\n segments: {\n fromLevel: number,\n toLevel: number,\n polyline: {\n lat: number,\n lon: number\n }[]\n }[]\n};\n\n/**\n * Singleton.\n */\nclass DeutscheBahnRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'deutsche-bahn' as const; }\n\n /**\n * @override\n */\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n let url = endpointUrl + '/route/v1/walking/';\n const waypoints = [routerRequest.origin, ...routerRequest.waypoints || [], routerRequest.destination];\n\n url += waypoints.map(waypoint => {\n if (waypoint.level !== null) {\n const altitude = Level.isRange(waypoint.level) ? waypoint.level[0] : waypoint.level;\n return waypoint.longitude + ',' + waypoint.latitude + ',' + altitude;\n }\n return waypoint.longitude + ',' + waypoint.latitude;\n }).join(';');\n\n url += '?geometries=geojson&overview=full&steps=true';\n\n return url;\n }\n\n parseResponse(json: DBJson, origin: Coordinates, destination: Coordinates) {\n\n if (!json.segments) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const legs = json.segments.map(segment => {\n const level = Level.union(segment.fromLevel, segment.toLevel);\n const coords = segment.polyline.map(({ lon, lat }) =>\n new Coordinates(lat, lon, null, level)\n );\n return new Leg({\n transitMode: 'WALK',\n coords,\n start: { coords: coords[0] },\n end: { coords: coords[coords.length - 1] },\n })\n });\n\n return [new Itinerary({ origin, destination, legs })];\n }\n}\n\nexport default new DeutscheBahnRemoteRouter();\n","/* eslint-disable max-statements */\nimport { Coordinates, Utils as GeoUtils } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { TransportInfo } from '../../model/Leg.js';\nimport { dateWithTimeZone } from '../RemoteRouterUtils.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type MinStepInfo } from '../../model/Step.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype IdfmCoordinates = { lat: number, lon: number };\ntype IdfmSection = {\n type: 'waiting' | 'transfer' | string,\n mode: string,\n departure_date_time: string,\n arrival_date_time: string,\n duration: number,\n geojson: {\n coordinates: [number, number][],\n properties: { length: number }[]\n },\n path: {\n name: string,\n length: number\n }[],\n display_informations: {\n code: string,\n color: string,\n text_color: string,\n direction: string,\n physical_mode: string\n },\n from: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n },\n to: {\n name: string,\n stop_point: { coord: IdfmCoordinates },\n address: { coord: IdfmCoordinates }\n }\n}\ntype IdfmJson = {\n journeys: {\n duration: number,\n departure_date_time: string,\n arrival_date_time: string,\n sections: IdfmSection[]\n }[],\n context: {\n timezone: string\n };\n error: {\n message?: string;\n }\n};\n\ntype IdfmIntermediateStep = {\n name: string,\n distance: number\n};\n\n/**\n * List of all modes supported by the API\n * http://doc.navitia.io/#physical-mode\n */\n\nconst transitModeCorrespondance = new Map<string, TransitMode>();\ntransitModeCorrespondance.set('Air', 'AIRPLANE');\ntransitModeCorrespondance.set('Boat', 'BOAT');\ntransitModeCorrespondance.set('Bus', 'BUS');\ntransitModeCorrespondance.set('BusRapidTransit', 'BUS');\ntransitModeCorrespondance.set('Coach', 'BUS');\ntransitModeCorrespondance.set('Ferry', 'FERRY');\ntransitModeCorrespondance.set('Funicular', 'FUNICULAR');\ntransitModeCorrespondance.set('LocalTrain', 'TRAIN');\ntransitModeCorrespondance.set('LongDistanceTrain', 'TRAIN');\ntransitModeCorrespondance.set('Metro', 'METRO');\ntransitModeCorrespondance.set('Métro', 'METRO');\ntransitModeCorrespondance.set('RailShuttle', 'TRAIN');\ntransitModeCorrespondance.set('RapidTransit', 'BUS');\ntransitModeCorrespondance.set('Shuttle', 'BUS');\ntransitModeCorrespondance.set('SuspendedCableCar', 'FUNICULAR');\ntransitModeCorrespondance.set('Taxi', 'TAXI');\ntransitModeCorrespondance.set('Train', 'TRAIN');\ntransitModeCorrespondance.set('RER', 'TRAIN');\ntransitModeCorrespondance.set('Tramway', 'TRAM');\ntransitModeCorrespondance.set('walking', 'WALK');\ntransitModeCorrespondance.set('bike', 'BIKE');\n\n/**\n * List of transports modes\n */\nconst TRANSPORT_IDS = [\n 'physical_mode:Air',\n 'physical_mode:Boat',\n 'physical_mode:Bus',\n 'physical_mode:BusRapidTransit',\n 'physical_mode:Coach',\n 'physical_mode:Ferry',\n 'physical_mode:Funicular',\n 'physical_mode:LocalTrain',\n 'physical_mode:LongDistanceTrain',\n 'physical_mode:Metro',\n 'physical_mode:RailShuttle',\n 'physical_mode:RapidTransit',\n 'physical_mode:Shuttle',\n 'physical_mode:SuspendedCableCar',\n 'physical_mode:Taxi',\n 'physical_mode:Train',\n 'physical_mode:Tramway'\n];\n\nconst apiKey = 'qWHj6ax6DMttG8DX6tH9CQARaiTgQ1Di';\n\n\nfunction jsonToCoordinates(json: IdfmCoordinates) {\n return new Coordinates(Number(json.lat), Number(json.lon));\n}\n\nfunction last<T>(array: T[]) {\n return array[array.length - 1];\n}\n\n/**\n * stringDate (e.g. 20211117T104516)\n */\nfunction dateStringToTimestamp(stringDate: string, timeZone: string) {\n const yearStr = stringDate.substr(0, 4);\n const monthStr = stringDate.substr(4, 2);\n const dayStr = stringDate.substr(6, 2);\n const hoursStr = stringDate.substr(9, 2);\n const minutesStr = stringDate.substr(11, 2);\n const secondsStr = stringDate.substr(13, 2);\n\n return dateWithTimeZone(\n Number(yearStr),\n Number(monthStr) - 1,\n Number(dayStr),\n Number(hoursStr),\n Number(minutesStr),\n Number(secondsStr),\n timeZone\n ).getTime();\n}\n\n\n/**\n * Singleton.\n */\nclass IdfmRemoteRouter extends RemoteRouter {\n\n /**\n * @override\n */\n get rname() { return 'idfm' as const; }\n\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url, {\n method: 'GET',\n headers: { apiKey }\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n\n const jsonResponse: IdfmJson = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n // When IDFM failed to calculate an itinerary (ie. start or end\n // point is far from network), it respond a 404 with an error message\n // or a 200 with an error message\n if (jsonResponse && jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error.message);\n }\n\n const itineraries = this.parseResponse(jsonResponse);\n\n const sameModeFound = itineraries.some((itinerary) => itinerary.transitMode === routerRequest.travelMode);\n\n if (!sameModeFound) {\n throw RemoteRoutingError.notFound(\n this.rname,\n 'Selected mode of transport was not found for this itinerary.'\n )\n }\n\n return itineraries;\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const url = new URL(endpointUrl);\n\n const coreParams = new URLSearchParams();\n coreParams.set('from', `${origin.longitude};${origin.latitude}`);\n coreParams.set('to', `${destination.longitude};${destination.latitude}`);\n\n if (routerRequest.itineraryModifiers?.avoidStairs) {\n coreParams.set('wheelchair', 'true')\n }\n\n let queryParams: URLSearchParams = new URLSearchParams();\n switch (travelMode) {\n case 'WALK':\n queryParams = this.getWalkingQuery();\n break;\n case 'BIKE':\n queryParams = this.getBikeQuery();\n break;\n case 'CAR':\n queryParams = this.getCarQuery();\n break;\n default:\n break;\n }\n\n [coreParams, queryParams].map(params => {\n for (const pair of params.entries()) {\n url.searchParams.append(pair[0], pair[1]);\n }\n });\n\n return url.toString();\n }\n\n getCarQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('first_section_mode[]', 'car');\n urlSearchParams.append('last_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'car');\n\n return urlSearchParams;\n }\n\n getWalkingQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'walking');\n urlSearchParams.append('last_section_mode[]', 'walking');\n\n return urlSearchParams;\n }\n\n getBikeQuery() {\n const urlSearchParams = new URLSearchParams();\n\n TRANSPORT_IDS.forEach((id) => {\n urlSearchParams.append('forbidden_uris[]', id);\n });\n\n urlSearchParams.append('first_section_mode[]', 'bike');\n urlSearchParams.append('last_section_mode[]', 'bike');\n\n return urlSearchParams;\n }\n\n\n getSectionCoords(section: IdfmSection) {\n const from = section.from.stop_point ? jsonToCoordinates(section.from.stop_point.coord) : jsonToCoordinates(section.from.address.coord);\n const to = section.to.stop_point ? jsonToCoordinates(section.to.stop_point.coord) : jsonToCoordinates(section.to.address.coord);\n\n return {\n from,\n to\n };\n }\n\n /**\n * Since the IDFM API does not provide coords for each step, we need to compute them\n * We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step\n * @param {Leg} leg\n */\n findStepsCoord(legCoords: Coordinates[], steps: IdfmIntermediateStep[]) {\n const coords = legCoords;\n\n const duplicatedCoords = [...coords];\n let previousStep = steps[0];\n let accumulatedIndex = 0;\n const outputSteps = [];\n\n for (const [idx, step] of steps.entries()) {\n let newCoords: Coordinates;\n\n let _idCoordsInLeg;\n\n if (idx === 0) {\n _idCoordsInLeg = 0;\n newCoords = coords[0];\n } else if (idx === steps.length - 1) {\n _idCoordsInLeg = coords.length - 1;\n newCoords = last(coords);\n } else if (duplicatedCoords.length === 1) {\n accumulatedIndex++;\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = duplicatedCoords[0];\n\n coords[_idCoordsInLeg] = newCoords;\n } else {\n const result = GeoUtils.trimRoute(duplicatedCoords, duplicatedCoords[0], previousStep.distance);\n accumulatedIndex += result.length - 1;\n\n duplicatedCoords.splice(0, result.length - 1);\n\n _idCoordsInLeg = accumulatedIndex;\n\n newCoords = last(result);\n\n coords[_idCoordsInLeg] = newCoords;\n }\n\n outputSteps.push({\n ...step,\n coords: newCoords\n });\n\n previousStep = step;\n }\n\n return outputSteps;\n }\n\n parseResponse(json: IdfmJson) {\n\n if (!json || !json.journeys) {\n throw RemoteRoutingError.notFound(this.rname, json.error?.message);\n }\n\n const itineraries = [];\n\n const timeZone = json.context.timezone;\n\n for (const jsonItinerary of json.journeys) {\n\n const legs = [];\n\n for (const jsonSection of jsonItinerary.sections) {\n\n if (jsonSection.type === 'waiting' || jsonSection.type === 'transfer') {\n continue;\n }\n\n const { from: startSection, to: endSection } = this.getSectionCoords(jsonSection);\n\n // A section can have multiple same coordinates, we need to remove them\n let existingCoords: string[] = [];\n const legCoords = jsonSection.geojson.coordinates.reduce((acc, [lon, lat]) => {\n if (!existingCoords.includes(`${lon}-${lat}`)) {\n existingCoords = existingCoords.concat(`${lon}-${lat}`);\n acc.push(new Coordinates(lat, lon));\n }\n return acc;\n }, [] as Coordinates[]);\n\n const stepsBuilder = new StepsBuilder().setStart(startSection).setEnd(endSection).setPathCoords(legCoords);\n let transportInfo: TransportInfo | undefined;\n let transitMode = transitModeCorrespondance.get(jsonSection.mode) as TransitMode;\n\n if (jsonSection.path) {\n const idfmIntermediateSteps = [];\n for (const jsonPathLink of jsonSection.path) {\n idfmIntermediateSteps.push({\n name: jsonPathLink.name,\n distance: jsonPathLink.length,\n });\n }\n stepsBuilder.setStepsInfo(this.findStepsCoord(legCoords, idfmIntermediateSteps));\n }\n\n if (jsonSection.type === 'public_transport') {\n transportInfo = {\n name: jsonSection.display_informations.code,\n routeColor: jsonSection.display_informations.color,\n routeTextColor: jsonSection.display_informations.text_color,\n directionName: jsonSection.display_informations.direction\n };\n\n transitMode = transitModeCorrespondance.get(jsonSection.display_informations.physical_mode) as TransitMode;\n\n const legStep: MinStepInfo = {\n coords: legCoords[0],\n name: transportInfo.directionName,\n distance: jsonSection.geojson.properties[0].length\n };\n stepsBuilder.setStepsInfo([legStep]);\n }\n\n const leg = new Leg({\n transitMode,\n duration: jsonSection.duration,\n startTime: dateStringToTimestamp(jsonSection.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonSection.arrival_date_time, timeZone),\n start: {\n name: jsonSection.from.name,\n coords: startSection\n },\n end: {\n name: jsonSection.to.name,\n coords: endSection\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\n });\n legs.push(leg);\n }\n\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: dateStringToTimestamp(jsonItinerary.departure_date_time, timeZone),\n endTime: dateStringToTimestamp(jsonItinerary.arrival_date_time, timeZone),\n origin: this.getSectionCoords(jsonItinerary.sections[0]).from,\n destination: this.getSectionCoords(last(jsonItinerary.sections)).to,\n legs\n });\n\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new IdfmRemoteRouter();","/* eslint-disable max-statements */\n\nimport { Coordinates, Level } from '@wemap/geo';\nimport { rad2deg, positiveMod } from '@wemap/maths';\nimport { LineString, Position } from 'geojson';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type TransitMode } from '../../model/TransitMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype OsrmCoordinates = Position;\ntype OsrmModifier = 'sharp right' | 'sharp left' | 'slight right'\n | 'slight left' | 'right' | 'left' | 'u turn' | 'straight';\ntype OsrmManeuverType = 'depart' | 'turn' | 'arrive';\ntype OsrmStep = {\n geometry: LineString,\n distance: number,\n duration: number,\n name?: string,\n maneuver: {\n bearing_before: number,\n bearing_after: number,\n location: OsrmCoordinates,\n modifier: OsrmModifier,\n type: OsrmManeuverType\n }\n};\ntype OsrmJson = {\n code?: string,\n message?: string,\n routes?: {\n geometry: LineString,\n legs: {\n distance: number,\n duration: number,\n steps: OsrmStep[]\n }[],\n distance: number,\n duration: number,\n weight_name: string,\n weight: number\n }[],\n waypoints?: []\n};\n\ntype OsrmMode = 'driving' | 'walking' | 'bike' | 'pmr' | 'bike-safest' | 'bike-fastest';\n\nconst outputModeCorrespondance = new Map<TravelMode, TransitMode>();\noutputModeCorrespondance.set('CAR', 'CAR');\noutputModeCorrespondance.set('WALK', 'WALK');\noutputModeCorrespondance.set('BIKE', 'BIKE');\n\n/**\n * Singleton.\n */\nclass OsrmRemoteRouter extends RemoteRouter {\n\n get rname() { return 'osrm' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n\n return this.parseResponse(jsonResponse, routerRequest.origin, routerRequest.destination, routerRequest.travelMode);\n }\n\n /**\n * @throws {TravelModeCorrespondanceNotFound}\n */\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination } = routerRequest;\n\n const osrmMode = this.inputModeCorrespondance(routerRequest);\n const waypoints = [origin, ...routerRequest.waypoints || [], destination];\n\n let url = endpointUrl + '/route/v1/' + osrmMode + '/';\n url += waypoints.map(waypoint => [waypoint.longitude + ',' + waypoint.latitude]).join(';');\n url += '?geometries=geojson&overview=full&steps=true';\n routerRequest.provideItineraryAlternatives && (url += '&alternatives=true')\n return url;\n }\n\n inputModeCorrespondance = (routerRequest: RouterRequest): OsrmMode => {\n const { travelMode, travelModePreference: preference } = routerRequest;\n if (travelMode === 'WALK' && routerRequest.itineraryModifiers?.avoidStairs) return 'pmr';\n if (travelMode === 'WALK') return 'walking';\n if (travelMode === 'BIKE') {\n if (preference === 'FASTEST') return 'bike-fastest';\n if (preference === 'SAFEST') return 'bike-safest';\n if (preference === 'TOURISM') return 'bike-safest';\n return 'bike-safest';\n }\n if (travelMode === 'CAR') return 'driving';\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n coordinatesToJson({ lat, lng, level }: Coordinates): OsrmCoordinates {\n if (level === null) {\n return [lng, lat];\n }\n if (Level.isRange(level)) {\n return [lng, lat, level[0]];\n }\n return [lng, lat, level];\n }\n\n /**\n * @param {object} json\n * @returns {Coordinates}\n */\n jsonToCoordinates(json: OsrmCoordinates): Coordinates {\n const coords = new Coordinates(json[1], json[0]);\n if (json.length > 2) {\n coords.level = json[2] as number;\n }\n return coords;\n }\n\n getModifierFromAngle(_angle: number): OsrmModifier {\n\n const angle = positiveMod(rad2deg(_angle), 360);\n\n if (angle > 0 && angle < 60) {\n return 'sharp right';\n }\n if (angle >= 60 && angle < 140) {\n return 'right';\n }\n if (angle >= 140 && angle < 160) {\n return 'slight right';\n }\n if (angle >= 160 && angle <= 200) {\n return 'straight';\n }\n if (angle > 200 && angle <= 220) {\n return 'slight left';\n }\n if (angle > 220 && angle <= 300) {\n return 'left';\n }\n if (angle > 300 && angle < 360) {\n return 'sharp left';\n }\n return 'u turn';\n }\n\n noRouteFoundJson(message: object) {\n return {\n 'code': 'NoRoute',\n message\n };\n }\n\n /**\n * @deprecated\n */\n itineraryToOsrmJson(itinerary: Itinerary): OsrmJson {\n\n const lastLegId = itinerary.legs.length - 1;\n const itinerarySteps = itinerary.steps;\n\n const jsonLegs = itinerary.legs.map(({ distance, duration, coords }, idLeg) => {\n\n // Filter steps which are in leg\n const legSteps = itinerarySteps.filter(step =>\n coords.find(_coords => _coords.equals(step.coords))\n );\n\n const lastStepId = legSteps.length - 1;\n\n return {\n distance,\n duration: duration || 0,\n steps: legSteps.map((step, idStep, arr) => {\n\n let type: OsrmManeuverType = idStep === 0 && idLeg === 0 ? 'depart' : 'turn';\n type = idStep === lastStepId && idLeg === lastLegId ? 'arrive' : type;\n\n const stepCoordsIdx = coords.findIndex(p => p.equals(step.coords));\n const nextStepCoordsIdx = idStep === lastStepId\n ? stepCoordsIdx\n : coords.findIndex(p => p.equals(arr[idStep + 1].coords));\n\n const osrmStep: OsrmStep = {\n geometry: {\n type: 'LineString',\n coordinates: coords.slice(stepCoordsIdx, nextStepCoordsIdx + 1).map(this.coordinatesToJson)\n },\n distance: step.distance,\n duration: step.duration || 0,\n ...(step.name && { name: step.name }),\n maneuver: {\n bearing_before: rad2deg(step.previousBearing),\n bearing_after: rad2deg(step.nextBearing),\n location: this.coordinatesToJson(step.coords),\n modifier: this.getModifierFromAngle(step.angle),\n type\n },\n };\n return osrmStep;\n })\n };\n });\n\n return {\n 'code': 'Ok',\n 'routes': [\n {\n 'geometry': {\n 'type': 'LineString',\n 'coordinates': itinerary.coords.map(this.coordinatesToJson)\n },\n 'legs': jsonLegs,\n 'distance': itinerary.distance,\n 'duration': itinerary.duration,\n 'weight_name': 'routability',\n 'weight': 0\n }\n ],\n 'waypoints': []\n };\n }\n\n parseResponse(json: OsrmJson, origin: Coordinates, destination: Coordinates, travelMode: TravelMode) {\n\n const transitMode = outputModeCorrespondance.get(travelMode)!;\n\n const { routes: jsonRoutes } = json;\n if (!jsonRoutes) {\n throw RemoteRoutingError.notFound(this.rname, json.message);\n }\n\n return jsonRoutes.map(jsonItinerary => {\n\n const legs = jsonItinerary.legs.map((jsonLeg) => {\n const legCoords = jsonLeg.steps\n .map(step => step.geometry.coordinates.map(this.jsonToCoordinates))\n .flat()\n // Remove duplicates\n .filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));\n\n const startCoords = legCoords[0];\n const endCoords = legCoords[legCoords.length - 1];\n\n const stepsBuilder = new StepsBuilder().setPathCoords(legCoords).setStart(startCoords).setEnd(endCoords);\n jsonLeg.steps?.forEach(({ maneuver, name, distance, duration }) => {\n\n const stepCoords = this.jsonToCoordinates(maneuver.location);\n\n // Sometimes, OSRM step does not have the same coordinates than a point in legCoords.\n // ex: first step of https://routing-orsm.getwemap.com/route/v1/walking/2.33222164147,48.87084765712;2.3320734,48.8730212?geometries=geojson&overview=full&steps=true\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(stepCoords));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('Osrm Parser: Cannot find step coords in leg coordinates');\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name,\n distance,\n duration\n });\n })\n\n return new Leg({\n transitMode,\n duration: jsonLeg.duration,\n coords: legCoords,\n start: {\n coords: startCoords\n },\n end: {\n coords: endCoords\n },\n steps: stepsBuilder.build()\n });\n });\n\n return new Itinerary({\n duration: jsonItinerary.duration,\n origin,\n destination,\n legs\n });\n });\n }\n}\n\nexport default new OsrmRemoteRouter();","import Polyline from '@mapbox/polyline';\n\nimport { Coordinates } from '@wemap/geo';\nimport Logger from '@wemap/logger';\n\nimport Itinerary from '../../model/Itinerary.js';\nimport Leg, { type TransportInfo } from '../../model/Leg.js';\nimport StepsBuilder from '../../model/StepsBuilder.js';\nimport RemoteRouter from '../RemoteRouter.js';\nimport { type TravelMode } from '../../model/TravelMode.js';\nimport { type RouterRequest } from '../../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\ntype OtpCoordinates = { lat: number, lon: number };\ntype FromTo = OtpCoordinates & { name: string };\ntype FromToPT = FromTo & { stopId: string, stopCode: string };\n\ntype CommonLeg = {\n startTime: number,\n endTime: number,\n legGeometry: {\n points: string,\n length: number\n },\n duration: number,\n};\n\ntype LegWalk = CommonLeg & {\n mode: 'WALK',\n from: FromTo,\n to: FromTo,\n steps: (OtpCoordinates & {\n distance: number,\n streetName: string\n })[]\n}\n\ntype LegPT = CommonLeg & {\n mode: 'BUS' | 'TRAM',\n from: FromToPT,\n to: FromToPT,\n intermediateStops: FromToPT,\n routeShortName: 'string',\n routeColor?: 'string',\n routeTextColor?: 'string',\n headsign: 'string'\n}\n\ntype OtpJson = {\n plan: {\n from: FromTo,\n to: FromTo,\n itineraries: {\n duration: number,\n startTime: number,\n endTime: number,\n walkDistance: number,\n legs: (LegWalk | LegPT)[]\n }[]\n }\n}\n\nfunction isLegPT(leg: LegPT | LegWalk): leg is LegPT {\n return leg.mode === 'BUS' || leg.mode === 'TRAM';\n}\n\nfunction jsonToCoordinates(json: OtpCoordinates) {\n return new Coordinates(json.lat, json.lon);\n}\n\n\n/**\n * Input mode correspondance\n */\nconst inputModeCorrespondance = new Map<TravelMode, string>();\ninputModeCorrespondance.set('CAR', 'CAR');\ninputModeCorrespondance.set('WALK', 'WALK');\ninputModeCorrespondance.set('BIKE', 'BICYCLE');\ninputModeCorrespondance.set('TRANSIT', 'WALK,TRANSIT');\n\n/**\n * Singleton.\n */\nclass OtpRemoteRouter extends RemoteRouter {\n\n get rname() { return 'otp' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: RouterRequest) {\n const url = this.getURL(endpointUrl, routerRequest);\n const res = await (fetch(url).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, url);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, url);\n });\n return this.parseResponse(jsonResponse);\n }\n\n getURL(endpointUrl: string, routerRequest: RouterRequest) {\n const { origin, destination, waypoints, travelMode } = routerRequest;\n\n const otpMode = inputModeCorrespondance.get(travelMode);\n if (!otpMode) {\n throw RemoteRoutingError.travelModeUnimplemented(this.rname, travelMode);\n }\n\n if ((waypoints || []).length > 0) {\n Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints?.length})`);\n }\n\n const fromPlace = `fromPlace=${origin.latitude},${origin.longitude}`;\n const toPlace = `toPlace=${destination.latitude},${destination.longitude}`;\n const queryMode = `mode=${otpMode}`;\n\n const url = new URL(endpointUrl);\n let { search } = url;\n search = (search ? `${search}&` : '?') + `${fromPlace}&${toPlace}&${queryMode}`;\n\n return `${url.origin}${url.pathname}${search}`;\n }\n\n\n /**\n * Generate multi itineraries from OTP JSON\n */\n parseResponse(json: OtpJson) {\n\n const { plan: jsonPlan } = json;\n if (!jsonPlan) {\n throw RemoteRoutingError.notFound(this.rname);\n }\n\n const itineraries = [];\n\n const itinerariesOrigin = jsonToCoordinates(jsonPlan.from);\n const itinerariesDestination = jsonToCoordinates(jsonPlan.to);\n\n for (const jsonItinerary of jsonPlan.itineraries) {\n\n const legs: Leg[] = [];\n\n for (const jsonLeg of jsonItinerary.legs) {\n\n const startCoordinates = jsonToCoordinates(jsonLeg.from);\n const endCoordinates = jsonToCoordinates(jsonLeg.to);\n\n const legCoords = Polyline.decode(jsonLeg.legGeometry.points)\n .map(([lat, lon]) => new Coordinates(lat, lon));\n\n let transportInfo: TransportInfo | undefined;\n const stepsBuilder = new StepsBuilder().setStart(startCoordinates).setEnd(endCoordinates).setPathCoords(legCoords);\n\n if (isLegPT(jsonLeg)) {\n\n transportInfo = {\n name: jsonLeg.routeShortName,\n routeColor: jsonLeg.routeColor,\n routeTextColor: jsonLeg.routeTextColor,\n directionName: jsonLeg.headsign\n };\n\n stepsBuilder.addStepInfo({\n coords: legCoords[0],\n name: jsonLeg.headsign\n });\n\n } else {\n\n jsonLeg.steps.forEach(jsonStep => {\n // OTP step does not have the same coordinates than a point in legCoords.\n // That is why we look for the closest point.\n const distances = legCoords.map(coords => coords.distanceTo(jsonToCoordinates(jsonStep)));\n const idStepCoordsInLeg = distances.indexOf(Math.min(...distances));\n if (idStepCoordsInLeg < 0) {\n throw new Error('OTP Parser: Cannot find closest step');\n }\n\n stepsBuilder.addStepInfo({\n coords: legCoords[idStepCoordsInLeg],\n name: jsonStep.streetName\n });\n })\n }\n\n\n const leg = new Leg({\n transitMode: jsonLeg.mode,\n duration: jsonLeg.duration,\n startTime: jsonLeg.startTime,\n endTime: jsonLeg.endTime,\n start: {\n name: jsonLeg.from.name,\n coords: jsonToCoordinates(jsonLeg.from)\n },\n end: {\n name: jsonLeg.to.name,\n coords: jsonToCoordinates(jsonLeg.to)\n },\n coords: legCoords,\n transportInfo,\n steps: stepsBuilder.build()\n });\n\n legs.push(leg);\n\n }\n const itinerary = new Itinerary({\n duration: jsonItinerary.duration,\n startTime: jsonItinerary.startTime,\n endTime: jsonItinerary.endTime,\n origin: itinerariesOrigin,\n destination: itinerariesDestination,\n legs\n });\n itineraries.push(itinerary);\n }\n\n return itineraries;\n }\n}\n\nexport default new OtpRemoteRouter();\n","import { Coordinates } from '@wemap/geo';\n\nimport RemoteRouter from '../RemoteRouter.js';\nimport { RouterRequest } from '../../model/RouterRequest.js';\nimport Itinerary from '../../model/Itinerary.js';\nimport { RemoteRoutingError } from '../../RoutingError.js';\n\n\ntype WemapRouterRequest = Omit<RouterRequest, 'origin' | 'destination' | 'waypoints'> & {\n mapId?: number,\n origin: Coordinates | number | string\n destination: Coordinates | number | string\n waypoints?: (Coordinates | number | string)[]\n}\n\n/**\n * Singleton.\n */\nclass WemapMultiRemoteRouter extends RemoteRouter {\n\n get rname() { return 'wemap-multi' as const; }\n\n async getItineraries(endpointUrl: string, routerRequest: WemapRouterRequest) {\n const { origin, destination, waypoints } = routerRequest;\n const payload = {\n ...routerRequest,\n origin: origin instanceof Coordinates ? origin.toJson() : origin,\n destination: destination instanceof Coordinates ? destination.toJson() : destination,\n ...(waypoints && {waypoints: waypoints.map(w => w instanceof Coordinates ? w.toJson() : w)})\n };\n\n const res = await (fetch(endpointUrl, {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n }).catch(() => {\n throw RemoteRoutingError.unreachableServer(this.rname, endpointUrl);\n }));\n\n const jsonResponse = await res.json().catch(() => {\n throw RemoteRoutingError.responseNotParsing(this.rname, endpointUrl);\n });\n\n if (jsonResponse.error) {\n throw RemoteRoutingError.notFound(this.rname, jsonResponse.error)\n }\n\n return (jsonResponse.itineraries || []).map(Itinerary.fromJson) as Itinerary[];\n }\n\n}\n\nexport default new WemapMultiRemoteRouter();\n","import RemoteRouter from './RemoteRouter.js';\nimport CitywayRemoteRouter from './cityway/CitywayRemoteRouter.js';\nimport DeutscheBahnRemoteRouter from './deutsche-bahn/DeutscheBahnRemoteRouter.js';\nimport IdfmRemoteRouter from './idfm/IdfmRemoteRouter.js';\nimport OsrmRemoteRouter from './osrm/OsrmRemoteRouter.js';\nimport OtpRemoteRouter from './otp/OtpRemoteRouter.js';\nimport WemapMultiRemoteRouter from './wemap-multi/WemapMultiRemoteRouter.js';\nimport { RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError } from '../RoutingError.js';\n\nconst remoteRouters = [\n CitywayRemoteRouter,\n DeutscheBahnRemoteRouter,\n IdfmRemoteRouter,\n OsrmRemoteRouter,\n OtpRemoteRouter,\n WemapMultiRemoteRouter\n] as const;\n\nexport type RemoteRouterName = typeof remoteRouters[number]['rname'];\n\nexport type RoutingFallbackStrategy = { name: RemoteRouterName, endpointUrl: string }[];\n\n/**\n * Singleton\n */\nclass RemoteRouterManager {\n\n getRouterByName(name: RemoteRouterName): RemoteRouter {\n return remoteRouters.find(remoteRouter => remoteRouter.rname === name) as RemoteRouter;\n }\n\n async getItineraries(name: RemoteRouterName, endpointUrl: string, routerRequest: RouterRequest) {\n const router = this.getRouterByName(name);\n if (!router) {\n throw RemoteRoutingError.notFound(name, `Unknown \"${name}\" remote router`);\n }\n return router.getItineraries(endpointUrl, routerRequest);\n }\n\n async getItinerariesWithFallback(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy) {\n let itineraries;\n const errors = [];\n for (const { name, endpointUrl } of fallbackStrategy) {\n try {\n itineraries = await this.getItineraries(name, endpointUrl, routerRequest);\n if (itineraries.length) {\n return itineraries;\n }\n } catch (error) {\n if (error instanceof RemoteRoutingError) {\n errors.push({\n name,\n endpointUrl,\n error\n });\n } else {\n throw error;\n }\n }\n }\n\n const routersNames = fallbackStrategy.map(({ name }) => name).join(', ');\n const errorsMessages = errors.map(routerError => `(${routerError.name}) Could not find an itinerary on endpoint: ${routerError.endpointUrl}. Details: ${routerError.error.message}`).join('\\n');\n\n throw RemoteRoutingError.notFound(routersNames, errorsMessages)\n }\n}\n\nexport default new RemoteRouterManager();\n","/* eslint-disable complexity */\n/* eslint-disable max-statements */\n\nimport CustomGraphMap from './CustomGraphMap.js';\nimport RemoteRouterManager, { type RoutingFallbackStrategy } from '../remote/RemoteRouterManager.js';\nimport Itinerary from '../model/Itinerary.js';\nimport WemapMultiRemoteRouter from '../remote/wemap-multi/WemapMultiRemoteRouter.js';\nimport GraphRoute from '../graph/GraphRoute.js';\nimport GraphRouterOptionsBuilder from '../graph/GraphRouterOptionsBuilder.js';\nimport { type RouterRequest } from '../model/RouterRequest.js';\nimport { RemoteRoutingError, WemapMultiRoutingError } from '../RoutingError.js';\n\n\nclass WemapMultiRouter {\n\n maps: CustomGraphMap[] = [];\n\n get rname() {\n return 'wemap-multi';\n }\n\n addIOMap(customGraphMap: CustomGraphMap) {\n this.maps.push(customGraphMap);\n }\n\n removeIOMap(customGraphMap: CustomGraphMap) {\n this.maps = this.maps.filter(map => map !== customGraphMap);\n }\n\n removeAllMaps() {\n this.maps = [];\n }\n\n getMapByName(mapId: string) {\n return this.maps.find(map => map.name === mapId);\n }\n\n async getItineraries(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy = [], targetMaps = this.maps): Promise<Itinerary[]> {\n\n const { origin, destination } = routerRequest;\n\n /*\n * Here, we try to get the shortest path using io maps networks and a remote router server.\n */\n\n /**\n * ----- 1 -----\n * Parse function params\n * -------------\n */\n\n // Avoid cycles on remoteRouters\n fallbackStrategy = fallbackStrategy.filter(({ name }) => name !== WemapMultiRemoteRouter.rname) || [];\n\n /*\n * ----- 2 -----\n * Retrieve the IO maps to consider for this itinerary\n * -------------\n *\n * By default, all maps in this.maps are considered\n * If options.targetMaps is defined, only use this subset\n */\n // const ioMapsToTest = this.getIoMapsFromOptions(options);\n // TODO: map it with Wemap backend\n const ioMapsToTest = targetMaps;\n\n /*\n * If there is no local map to test, use remote router directly.\n * This should happen:\n * 1 - this.maps is empty\n * 2 - options.targetMaps is defined but empty\n * 3 - intersection of this.maps and options.targetMaps is empty\n */\n if (!ioMapsToTest.length) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n\n /**\n * ----- 3 -----\n * Run the IO Maps - Remote Routers logic\n * -------------\n *\n * For this purpose we have to consider 5 use cases\n *\n */\n\n let ioMapRoute: GraphRoute | null;\n let ioMapItinerary: Itinerary;\n\n // Find the first map where the \"origin\" is inside.\n const mapWithOrigin = ioMapsToTest.find(map => map.isPointInside(origin));\n\n\n // Create GraphRouterOptions from request\n const routerOptions = GraphRouterOptionsBuilder.fromJson(routerRequest.itineraryModifiers || {});\n\n /*\n * Case 1\n *\n * If \"origin\" and \"destination\" are in the same map, use the local router.\n */\n if (mapWithOrigin && mapWithOrigin.isPointInside(destination)) {\n\n ioMapRoute = mapWithOrigin.getRouteInsideMap(origin, destination, routerOptions);\n if (!ioMapRoute) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\")\n }\n\n return [Itinerary.fromGraphRoute(ioMapRoute)];\n }\n\n // Find the first map where the \"destination\" is inside.\n // Note: At this step, mapWithDestination is necessarily different from mapWithOrigin\n const mapWithDestination = ioMapsToTest.find(map => map.isPointInside(destination));\n\n\n let remoteRouterItineraries: Itinerary[];\n\n /*\n * Case 2\n *\n * If no io map have been found for \"origin\" and \"destination\", therefore use remote router.\n */\n if (!mapWithOrigin && !mapWithDestination) {\n return await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);\n }\n\n /**\n * Case 3\n *\n * If a map has been found for the \"origin\" but not for the \"destination\", so:\n * - A first itinerary (firstRoute) is calculated from \"origin\" to an \"entrypoint\"\n * of the IO map network using the wemap router.\n * - A second itinerary (secondRoute) is calculated from an \"entrypoint\" to the\n * \"destination\" using remote routers.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (mapWithOrigin && !mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `A map including the \"origin\" but the \"destination\" has been \n found (${mapWithOrigin.name}), however, no \"entrypoints\" have been found to go out`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" '\n + `to \"entrypoints\" using wemap router on local map \"${mapWithOrigin.name}\" and `\n + 'an itinerary from \"entrypoints\" to \"destination\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}), but failed. `\n + `Details: ${details}.`;\n\n ioMapRoute = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute.end,\n destination,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the the IO map itinerary with the remote router response (for each itinerary)\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(ioMapItinerary, remoteRouterItinerary)\n );\n }\n\n /*\n * Case 4\n *\n * If a map has been found for the \"destination\" but not for the \"origin\", so:\n * - A first itinerary (remoteRouterResponse) is calculated from \"origin\" to an \"entrypoint\"\n * of the IO map network using remote routers.\n * - A second itinerary (ioMapItinerary) is calculated from an \"entrypoint\" to the\n * \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the both itineraries.\n *\n * Note: Check the mapWithDestination.getBestItineraryFromEntryPointsToDestination to understand\n * which \"entrypoint\" is chosen by the algorithm\n */\n if (!mapWithOrigin && mapWithDestination) {\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `A map including the \"destination\" but the \"origin\" has been \n found (${mapWithDestination.name}), however, no \"entrypoints\" have been found to go in`\n )\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints\" '\n + `using remote routers (${fallbackStrategy.map(r => r.name).join(', ')}) and an `\n + 'itinerary from \"entrypoints\" to \"destination\" using wemap router on local map '\n + `\"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`\n\n /*\n * ioMapItinerary is computed before the remoteRouterResponse because it is less expensive to\n * calculate all the routes to entrypoints using local router than all the routes with the\n * remote router.\n */\n ioMapRoute = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin,\n destination: ioMapRoute.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n // Concat the remote router response (for each itinerary) with the IO map itinerary\n ioMapItinerary = Itinerary.fromGraphRoute(ioMapRoute);\n return remoteRouterItineraries.map(\n remoteRouterItinerary => Itinerary.fromItineraries(remoteRouterItinerary, ioMapItinerary)\n );\n }\n\n /**\n * Case 5\n *\n * If maps have been found for the \"origin\" and the \"destination\" but they are different, so:\n * - A first itinerary (ioMapItinerary1) is calculated from \"origin\" to an \"entrypoint\" of\n * the mapWithOrigin using the wemap router.\n * - A second itinerary (remoteRouterResponse) is calculated from an \"entrypoint\" of the\n * mapWithOrigin to an \"entrypoint\" of the destinationWithMap using remote routers.\n * - A third itinerary (ioMapItinerary2) is calculated from an \"entrypoint\" of the mapWithDestination\n * to the \"destination\" using the wemap router.\n * Itinerary returned is the concatenation of the three itineraries.\n */\n if (mapWithOrigin && mapWithDestination) {\n\n if (!mapWithOrigin.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go out of the origin map`\n );\n }\n\n if (!mapWithDestination.entryPoints.length) {\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || '',\n `One map including the \"origin\" (${mapWithOrigin.name}) and another \n including the \"destination\" (${mapWithDestination.name}) has been found, however, no \"entrypoints\" have \n been found to go in the second map`\n );\n }\n\n const customError = (details: string) => 'Tried to calculate an itinerary from \"origin\" to \"entrypoints1\" '\n + `using wemap router on local map \"${mapWithOrigin.name}\", an itinerary from `\n + '\"entrypoints1\" to \"entrypoints2\" using remote routers '\n + `(${fallbackStrategy.map(r => r.name).join(', ')}) and an itinerary from \"entrypoints2\" `\n + `to \"destination\" using wemap router on local map \"${mapWithDestination.name}\", but failed. `\n + `Details: ${details}.`;\n\n\n const ioMapRoute1 = mapWithOrigin.getBestRouteFromOriginToEntryPoints(origin, destination, routerOptions);\n if (!ioMapRoute1) {\n const details = `No route found from ${origin.toString()} to entry points in map: ${mapWithOrigin.name}`;\n throw WemapMultiRoutingError.notFound(mapWithOrigin.name || \"\", customError(details))\n }\n\n const ioMapRoute2 = mapWithDestination.getBestRouteFromEntryPointsToDestination(origin, destination, routerOptions);\n if (!ioMapRoute2) {\n const details = `No route found from entry points to ${destination.toString()} in map: ${mapWithDestination.name}`;\n throw WemapMultiRoutingError.notFound(mapWithDestination.name || \"\", customError(details))\n }\n\n const newRouterRequest: RouterRequest = {\n ...routerRequest,\n origin: ioMapRoute1.end,\n destination: ioMapRoute2.start,\n waypoints: []\n };\n try {\n remoteRouterItineraries = await RemoteRouterManager.getItinerariesWithFallback(newRouterRequest, fallbackStrategy);\n } catch (e) {\n if (e instanceof RemoteRoutingError) {\n e.message = customError(e.message);\n }\n throw e;\n }\n\n\n // Concat the IO map itinerary 2 with the remote router response (for each itinerary)\n // and the IO map itinerary 2\n return remoteRouterItineraries.map(remoteRouterItinerary =>\n Itinerary.fromItineraries(\n Itinerary.fromGraphRoute(ioMapRoute1),\n remoteRouterItinerary,\n Itinerary.fromGraphRoute(ioMapRoute2)\n )\n );\n\n }\n\n throw new Error('Should never happen');\n }\n\n}\n\nexport default WemapMultiRouter;\n","import pointInPolygon from '@turf/boolean-point-in-polygon';\nimport convexHullFn from '@turf/convex';\nimport { Position, MultiPolygon } from '@turf/helpers';\n\nimport { Coordinates, Level } from '@wemap/geo';\nimport { OsmNode, OsmParser } from '@wemap/osm';\n\nimport Graph from '../graph/Graph.js';\nimport GraphRouter from '../graph/GraphRouter.js';\nimport { GraphRouterOptions } from '../graph/GraphRouterOptions.js';\nimport Vertex from '../graph/Vertex.js';\nimport OsmGraphUtils from '../wemap-osm/OsmGraphUtils.js';\n\n\nexport type ParsingErrors = {\n couldNotParseFile: boolean,\n routingIoNotFound: OsmNode[],\n routingBoundsNotFound: boolean\n}\n\nexport default class CustomGraphMap {\n\n name: string | null;\n graph: Graph;\n router: GraphRouter;\n bounds: MultiPolygon;\n entryPoints: Vertex[];\n\n constructor(\n graph: Graph,\n entryPoints: Vertex[],\n bounds: MultiPolygon | null = null,\n name: string | null = null) {\n\n this.name = name;\n this.graph = graph;\n this.router = new GraphRouter(graph);\n\n // Entry points\n entryPoints.forEach(entryPoint => {\n if (!graph.vertices.includes(entryPoint)) {\n throw new Error(`Cannot find entry point ${entryPoint.coords.toString()} in graph \"${name}\"`);\n }\n });\n this.entryPoints = entryPoints;\n\n // Bounds\n if (bounds) {\n this.bounds = bounds;\n } else {\n const polygon = [graph.vertices.map(vertex => [vertex.coords.lng, vertex.coords.lat] as Position)];\n const convexHull = convexHullFn({ type: 'polygon', coordinates: polygon });\n if (!convexHull) {\n throw new Error(`Cannot calculate convexHull of graph \"${name}\"`);\n }\n this.bounds = {\n type: 'MultiPolygon',\n coordinates: [convexHull.geometry.coordinates]\n };\n }\n }\n\n static fromOsmXml(\n osmXmlString: string,\n name: string | null = null,\n callbackErrors?: (errors: ParsingErrors) => void\n ) {\n const errors: ParsingErrors = {\n couldNotParseFile: false,\n routingIoNotFound: [],\n routingBoundsNotFound: false\n };\n\n let osmModel;\n try {\n osmModel = OsmParser.parseOsmXmlString(osmXmlString);\n } catch (e) {\n errors.couldNotParseFile = true;\n callbackErrors?.(errors);\n return;\n }\n let verticesMapping: [nodeId: number, vertex: Vertex][] = []\n const graph = OsmGraphUtils.createGraphFromOsmModel(osmModel, OsmGraphUtils.DEFAULT_WAY_SELECTOR, vm => (verticesMapping = vm));\n\n const entryPointsOsmNodes = osmModel.nodes.filter(node => node.tags['wemap:routing-io']);\n const entryPointsToCheck = entryPointsOsmNodes.map(node => {\n const vertex = verticesMapping.find(v => v[0] === node.id)?.[1]\n if (!vertex) { errors.routingIoNotFound.push(node); }\n return vertex || null;\n });\n const entryPoints = entryPointsToCheck.filter(it => it !== null) as Vertex[];\n entryPoints.forEach(v => graph.exitVertices.add(v));\n\n const bounds: MultiPolygon = {\n type: 'MultiPolygon',\n coordinates: []\n };\n osmModel.ways\n .filter(({ tags }) => tags['wemap:routing-bounds'])\n .forEach(way => {\n bounds.coordinates.push([way.nodes.reduce((acc, node) => {\n acc.push([node.coords.lng, node.coords.lat]);\n return acc;\n }, [] as Position[])\n ]);\n });\n osmModel.relations\n .filter(rel => rel.tags['wemap:routing-bounds'] && rel.isMultipolygon())\n .forEach(rel => {\n const polygon = rel.getGeoJsonPolygon();\n polygon && bounds.coordinates.push(polygon.coordinates);\n });\n\n if (!bounds.coordinates.length) {\n errors.routingBoundsNotFound = true;\n }\n callbackErrors?.(errors);\n return new CustomGraphMap(graph, entryPoints, bounds, name);\n }\n\n isPointInside(coordinates: Coordinates) {\n return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);\n }\n\n /**\n * Get the list of entry points sorted by the lowest distance between:\n * start -> entry point -> end\n * (as the crow flies)\n *\n */\n getOrderedEntryPointsSortedByDistance(start: Coordinates, end: Coordinates) {\n const entryPointsCopy = [...this.entryPoints];\n const levelDiffFactor = 50; // in meters\n return entryPointsCopy.sort((ep1, ep2) => {\n\n const distance2D = Number(ep1.coords.distanceTo(start)) + ep1.coords.distanceTo(end)\n - (ep2.coords.distanceTo(start) + ep2.coords.distanceTo(end))\n\n const levelDiffEp1Start = Math.abs(Level.diff(start.level, ep1.coords.level) || 0);\n const levelDiffEp1End = Math.abs(Level.diff(end.level, ep1.coords.level) || 0);\n const levelDiffEp2Start = Math.abs(Level.diff(start.level, ep2.coords.level) || 0);\n const levelDiffEp2End = Math.abs(Level.diff(end.level, ep2.coords.level) || 0);\n const levelDiff = levelDiffEp1Start + levelDiffEp1End - (levelDiffEp2Start + levelDiffEp2End);\n\n return distance2D + levelDiff * levelDiffFactor;\n });\n }\n\n /**\n * Get the best itinerary from any entry point to an end coordinates.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the first entry point to the end coordinates.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.\n *\n * /!\\ start is only used to sort the entry points (step 1).\n *\n */\n getBestRouteFromEntryPointsToDestination(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(entryPoint.coords, end, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n\n /**\n * Get the best itinerary from start coordinates to any entry point.\n *\n * The algorithm works as following:\n * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end\n * 2 - Try to calculate an itinerary from the start coordinates to the first entry point.\n * 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.\n *\n * /!\\ end is only used to sort the entry points (step 1).\n *\n */\n getBestRouteFromOriginToEntryPoints(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // TODO: use multiple-destinations algorithm\n const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);\n for (const entryPoint of sortedEntryPoints) {\n const route = this.router.calculateShortestPath(start, entryPoint.coords, options).route();\n if (route.hasRoute) {\n return route;\n }\n // no route found\n }\n return null;\n }\n\n getRouteInsideMap(start: Coordinates, end: Coordinates, options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path\n return this.router.calculateShortestPath(start, end, options).route();\n }\n\n getTripInsideMap(waypoints: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest trip itinerary\n return this.router.getShortestTrip(waypoints, options);\n }\n\n getRoutesMultipleDestinationsInsideMap(start: Coordinates, ends: Coordinates[], options: GraphRouterOptions) {\n // Call the Wemap router to get the shortest path for all the input destinations\n return this.router.calculateShortestPathToMultipleDestinations(start, ends, options);\n }\n\n}\n","\nimport { OsmNode } from '@wemap/osm';\n\nimport CustomGraphMap, { type ParsingErrors } from './CustomGraphMap.js';\nimport Vertex from '../graph/Vertex.js';\n\nexport type Report = {\n customGraphMap?: CustomGraphMap,\n errors: Error[],\n}\n\nexport type Error = CouldNotParseFileError\n | MultipleGraphComponentsError\n | RoutingBoundsNotFoundError\n | RoutingIoNotOnGraphError;\n\nexport type CouldNotParseFileError = {\n type: 'could-not-parse-file'\n}\n\nexport type MultipleGraphComponentsError = {\n type: 'multiple-graph-components',\n data: Vertex[][]\n}\n\nexport type RoutingBoundsNotFoundError = {\n type: 'routing-bounds-not-found'\n}\n\nexport type RoutingIoNotOnGraphError = {\n type: 'routing-io-not-on-graph',\n data: OsmNode[]\n}\n\nexport default class CustomGraphMapTester {\n\n static createReport(osmXmlString: string): Report {\n\n let customGraphMapErrors: ParsingErrors | undefined;\n const customGraphMap = CustomGraphMap.fromOsmXml(osmXmlString, null, e => (customGraphMapErrors = e));\n const errors: Error[] = [];\n\n if (customGraphMapErrors?.couldNotParseFile || !customGraphMap) {\n errors.push({\n type: 'could-not-parse-file'\n });\n return { errors };\n }\n\n const components = customGraphMap.router.calculateComponents();\n if (components.length > 1) {\n errors.push({\n type: 'multiple-graph-components',\n data: components\n });\n }\n if (customGraphMapErrors?.routingBoundsNotFound) {\n errors.push({\n type: 'routing-bounds-not-found'\n });\n }\n if (customGraphMapErrors?.routingIoNotFound?.length) {\n errors.push({\n type: 'routing-io-not-on-graph',\n data: customGraphMapErrors.routingIoNotFound\n });\n }\n\n return { customGraphMap, errors };\n }\n\n static reportToJson(report: Report) {\n return {\n graph: report.customGraphMap?.graph?.toCompressedJson(),\n errors: report.errors.map(error => {\n if (error.type === 'multiple-graph-components') {\n return { type: error.type, data: error.data.map(c => c.map(v => v.id)) };\n }\n if (error.type === 'routing-io-not-on-graph') {\n return { type: error.type, data: error.data.map(v => v.id) };\n }\n return { type: error.type };\n })\n }\n }\n\n}\n\n","import { Coordinates } from '@wemap/geo';\n\nimport Itinerary from './model/Itinerary.js';\nimport Leg from './model/Leg.js';\nimport { Step } from './model/Step.js';\nimport Graph from './graph/Graph.js';\nimport GraphProjection from './graph/GraphProjection.js';\nimport Vertex from './graph/Vertex.js';\nimport Edge from './graph/Edge.js';\n\nexport type ItineraryInfo<U extends Coordinates = Coordinates> = {\n nextStep: Step | null;\n previousStep: Step | null;\n projection: GraphProjection<U>;\n leg: Leg;\n traveledDistance: number;\n remainingDistance: number;\n traveledPercentage: number;\n remainingPercentage: number;\n};\n\nclass ItineraryInfoManager {\n\n _itinerary: Itinerary | null = null;\n _graph: Graph | null = null;\n\n _steps: Step[] = [];\n _coordsNextStep: (Step | null)[] = [];\n _coordsPreviousStep: (Step | null)[] = [];\n _coordsDistanceTraveled: number[] = [];\n _coordsLeg: Leg[] = [];\n\n constructor(itinerary: Itinerary | null = null) {\n this.itinerary = itinerary;\n }\n\n get itinerary() {\n return this._itinerary;\n }\n\n set itinerary(itinerary) {\n\n if (itinerary === null) {\n this._itinerary = null;\n return;\n }\n\n this._itinerary = itinerary;\n this._steps = itinerary.steps;\n this._graph = itinerary.toGraph();\n\n this._coordsNextStep = new Array(itinerary.coords.length);\n this._coordsPreviousStep = new Array(itinerary.coords.length);\n this._coordsDistanceTraveled = new Array(itinerary.coords.length);\n this._coordsLeg = new Array(itinerary.coords.length);\n\n let stepId = 0;\n let previousStep: Step | null = null;\n let nextStep: Step | null = this._steps[0];\n let distanceTraveled = 0;\n\n itinerary.coords.forEach((coords, idx, arr) => {\n if (idx !== 0) {\n distanceTraveled += arr[idx - 1].distanceTo(coords);\n }\n\n this._coordsNextStep[idx] = nextStep;\n this._coordsPreviousStep[idx] = previousStep;\n this._coordsDistanceTraveled[idx] = distanceTraveled;\n this._coordsLeg[idx] = itinerary.legs.find(leg => leg.coords.includes(coords)) as Leg;\n\n if (stepId < this._steps.length && this._steps[stepId].coords.equals(coords)) {\n previousStep = this._steps[stepId];\n nextStep = stepId === this._steps.length - 1 ? null : this._steps[stepId + 1];\n stepId++;\n }\n });\n }\n\n getInfo<U extends Coordinates = Coordinates>(position: U) {\n\n if (!this._itinerary || !this._graph) {\n return null;\n }\n\n const projection = this._graph.getProjection(position);\n if (!projection) {\n return null;\n }\n\n let itineraryInfo: ItineraryInfo<U> | null = null;\n\n if (projection.nearestElement instanceof Vertex) {\n const idx = this._itinerary.coords.findIndex(\n coords => (projection.nearestElement as Vertex).coords === coords\n );\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Node)');\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx];\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx],\n previousStep: this._coordsPreviousStep[idx],\n projection: projection,\n leg: this._coordsLeg[idx],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n } else if (projection.nearestElement instanceof Edge) {\n\n let firstNode = projection.nearestElement.vertex1.coords;\n let idx = this._itinerary.coords.findIndex(coords => firstNode === coords);\n if (idx === -1) {\n throw new Error('ItineraryInfoManager: could not find projection in itinerary (Edge)');\n }\n\n // graphEdge is not necessarly ordered. We have to look for the first point\n if (idx === this._itinerary.coords.length - 1\n || this._itinerary.coords[idx + 1] !== projection.nearestElement.vertex2.coords\n ) {\n firstNode = projection.nearestElement.vertex2.coords;\n idx--;\n }\n\n const traveledDistance = this._coordsDistanceTraveled[idx]\n + projection.coords.distanceTo(firstNode);\n const remainingDistance = this._itinerary.distance - traveledDistance;\n itineraryInfo = {\n nextStep: this._coordsNextStep[idx + 1],\n previousStep: this._coordsPreviousStep[idx + 1],\n projection: projection,\n leg: this._coordsLeg[idx + 1],\n traveledDistance,\n remainingDistance,\n traveledPercentage: traveledDistance / this._itinerary.distance,\n remainingPercentage: remainingDistance / this._itinerary.distance\n };\n\n }\n\n return itineraryInfo;\n }\n\n}\n\nexport default ItineraryInfoManager;\n","import { Coordinates } from '@wemap/geo';\nimport { diffAngle, rad2deg, roundFactor } from '@wemap/maths';\nimport ItineraryInfoManager from '../src/ItineraryInfoManager.js';\nimport { Step } from '../src/model/Step.js';\n\nexport default class InstructionManager {\n\n static useProposals = false;\n\n static getTurnInfoFromAngle(_angle: number) {\n\n let direction, directionExtra;\n\n const directionAngle = rad2deg(diffAngle(_angle, Math.PI));\n const directionAngleAbs = Math.abs(directionAngle);\n if (directionAngleAbs <= 20) {\n direction = 'straight';\n } else {\n direction = directionAngle > 0 ? 'left' : 'right';\n if (directionAngleAbs < 55) {\n directionExtra = 'slight';\n } else if (directionAngleAbs > 120) {\n directionExtra = 'sharp';\n }\n }\n\n return { direction, directionExtra };\n }\n\n static getInfoFromStep(step: Step) {\n\n let type, direction, directionExtra, levelChange;\n\n if (step.levelChange) {\n type = 'level-change';\n levelChange = step.levelChange;\n } else {\n type = 'turn';\n const turnInfo = InstructionManager.getTurnInfoFromAngle(step.angle);\n direction = turnInfo.direction;\n directionExtra = turnInfo.directionExtra;\n }\n\n return {\n type,\n direction,\n directionExtra,\n levelChange,\n name: step.name,\n indoor: step.coords.level !== null\n };\n }\n\n // eslint-disable-next-line max-statements, complexity\n static getInstructionFromStep(step: Step) {\n\n const { direction, directionExtra } = InstructionManager.getTurnInfoFromAngle(step.angle);\n const isTurn = direction !== 'straight';\n\n if (step.lastStep) {\n if (isTurn && direction === 'left') {\n return 'Your destination is on your left';\n } else if (isTurn && direction === 'right') {\n return 'Your destination is on your right';\n }\n }\n\n let suffix = '';\n if (step.extras?.isGate) {\n suffix = ` on gate ${step.name}`;\n } else if (step.name) {\n suffix = ` on ${step.name}`;\n }\n\n if (step.levelChange) {\n if (step.levelChange.direction === 'up') {\n if (step.levelChange.type === 'stairs') {\n return 'Go up the stairs';\n }\n if (step.levelChange.type === 'escalator') {\n return 'Go up the escalator';\n }\n if (step.levelChange.type === 'elevator') {\n return 'Go up the elevator';\n }\n if (step.levelChange.type === 'moving walkway') {\n return 'Go up the moving walkway';\n }\n return 'Go up' + suffix;\n }\n if (step.levelChange.direction === 'down') {\n if (step.levelChange.type === 'stairs') {\n return 'Go down the stairs';\n }\n if (step.levelChange.type === 'escalator') {\n return 'Go down the escalator';\n }\n if (step.levelChange.type === 'elevator') {\n return 'Go down the elevator';\n }\n if (step.levelChange.type === 'moving walkway') {\n return 'Go down the moving walkway';\n }\n return 'Go down' + suffix;\n }\n if (step.extras?.subwayEntrance) {\n return `Take exit ${step.extras.subwayEntranceRef}`;\n }\n }\n\n if (isTurn) {\n if (direction === 'left') {\n if (directionExtra === 'slight') {\n return 'Turn slightly left' + suffix;\n }\n return 'Turn left' + suffix;\n }\n if (direction === 'right') {\n if (directionExtra === 'slight') {\n return 'Turn slightly right' + suffix;\n }\n return 'Turn right' + suffix;\n }\n }\n\n return 'Continue straight';\n }\n\n\n\n static getInstructionFromPosition(itineraryInfoManager: ItineraryInfoManager, position: Coordinates) {\n const itineraryInfo = itineraryInfoManager.getInfo(position);\n if (!itineraryInfo) {\n return null;\n }\n\n // If distance between itinerary and position is too far,\n // something went wrong. (mapmatching.maxDistance)\n if (this.useProposals && itineraryInfo.projection.distanceFromNearestElement > 15) {\n return 'It seems that we are a little bit lost, please start again the localization process';\n }\n\n const { nextStep } = itineraryInfo;\n if (!nextStep) {\n return 'You are arrived';\n }\n\n const distNextStep = position.distanceTo(nextStep.coords);\n const distRounded = roundFactor(distNextStep, 5);\n\n if (this.useProposals && distNextStep > 10) {\n return `Continue straight for ${distRounded}m`;\n }\n\n\n let instruction = InstructionManager.getInstructionFromStep(nextStep);\n\n const stepWithImportantInfo = itineraryInfoManager._steps.find(step => step.levelChange\n && step.number > nextStep.number\n && step.coords.distanceTo(nextStep.coords) < 10\n ) || null;\n\n if (stepWithImportantInfo && stepWithImportantInfo.levelChange) {\n const nextBearing = nextStep.coords.bearingTo(stepWithImportantInfo.coords);\n const { direction } = InstructionManager.getTurnInfoFromAngle(nextBearing - nextStep.previousBearing);\n instruction = direction === 'straight' ? 'Continue straight' : `Turn ${direction}`;\n const { direction: levelDirection, type: levelType } = stepWithImportantInfo.levelChange;\n instruction += ` and take the ${levelType} going ${levelDirection}`;\n }\n\n if (distNextStep >= 5) {\n instruction += ` in ${distRounded}m`;\n }\n\n return instruction;\n }\n\n}\n"],"names":["Level","Coordinates","BoundingBox","UserPosition","diffAngleLines","GeoConstants","deg2rad","diffAngle","GeoUtils","window","undefined","regexes","ua","module","exports","this","__defProp","__defNormalProp","__publicField","last","OsmNode","StatusCode","jsonToCoordinates","inputModeCorrespondance","transitModeCorrespondance","positiveMod","rad2deg","CitywayRemoteRouter","DeutscheBahnRemoteRouter","IdfmRemoteRouter","OsrmRemoteRouter","OtpRemoteRouter","WemapMultiRemoteRouter","RemoteRouterManager","OsmParser","roundFactor"],"mappings":"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","x_google_ignoreList":[12]}
|